[Bf-python] Re: Python Ipocurve/CurNurb module changes

Ken Hughes khughes at pacific.edu
Sat Jun 25 22:30:01 CEST 2005


Stephen Swaney wrote:
> On Sat, Jun 25, 2005 at 11:32:52AM -0700, Ken Hughes wrote:
> 
>>Stephen Swaney wrote:
>>
>>>The thing we are wrapping here is an array contained inside a blender
>>>object, not an independent object.  If we were doing a clean
>>>implementation, I would agree completely.
>>
>>I'm about to start pulling out my code and starting to think about your
>>way.  Can you define "changed too radically"?  Only thing I can think
>>of is a BezTriple sees its index is greater than the curve's list length.
> 
> 
> That is essentially it.
> 
> 
>>[Aside #1: Again, in defense of my approach (as in "elaborate on
>>implementation") it disadvantages are it has a speed penalty when points
>>are added or removed from the curve (but only then), and it incurs extra
>>storage (unused pointers).  Advantage is no segfaults.]

Ok, so can I clarify (wish you were on IRC now, we could probably
straighten this out in 5 minutes):

(BTW, not trying to argue; just trying to make sure we're talking
about the same things.  And hopefully anyone else still following
this thread, especially me, will learn more about how you envision
the internal BPy implementation should work.  Just seems like
curves are one of the more pathological examples.)

> Principle #1: We do not want to change blender's curve data structs
> and all the code that manipulates them.

Do you mean data structs as in
   (a) "struct BezTriple"
   (b) "ipocurve->bezt" (an actual list of BezTriple objects)
   (c) both (a) and (b) ?
I totally agree on (a).  If (b) or (c), then I shouldn't implement
Ipocurve.append(), CurNurb.insert() at all?  Or, I can do this
only so long as there is some already-existing procedure outside
BPython which I can call to add/delete a control point?

> Principle #2: A curve holds a pointer to a chunk of allocated memory -
> the control points.  This should be the only copy of that data.

True.  But what does that mean for a BPy_BezTriple's self->beztriple?
It's not a copy, just a pointer to the actual data.  If I do this:

   x = ipocurve.getPoints()[0]
   y = x
   z = ipocurve.getPoints()[0]

I've got two references to the same object (x and y) and another
object (z), but point at the same data.  So my assumption is that you
would say there is still only one copy of the data.

My approach basically implements "y = x", but maintains a reference
to x in a list of pointers, and returns y.  So I'm not keeping
a copy of Blender's data, I'm keeping a "copy" of the Python object.

However, if you're proposing principle #1(a) above, then my approach
is wrong by violating that.

> Principle #3: segfaults are bad.

I disagree; they give us a reason to live...

> Given the above, I think the best way to wrap control points is for a
> control point to contain a reference to the curve it belongs to and
> the index of that point in the curve's array of control points.  The
> control point wrapper then becomes essentially an alias for curve[i].
> 
> Accessing a curve via operator [] ( or thru the iterator interface )
> is straightforward.  Holding a reference to a control point by doing
> something like 
> 
> a = curve[2] 
> a = [1,2,3,1] 
> 
> is straightforward *until* you start deleteing or inserting points
> into the curve.  Once you modify the underlying curve, all bets are
> off unless your control point index still lies within the curve.

I'll go with your suggestion above (unless I can sway you otherwise;
this is my last attempt), but there's one last advantage I can think
of with my approach.  *It doesn't segfault if the curve is deleted.*
Again, we agree that grabbing any BezTriple from a curve and then
deleting the curve is Bad Programming Practice(tm), but my approach
allows the underlying BezTriples be invalidated so that when
the Stupid User does try to access the control point, they get an
exception instead of accessing bad or nonexistant memory (segfault).

And before you point out "Well, the same thing will happen if they
delete the Ipo or Curve instead", my plan was to propagate this
approach up from CurNurbs/Ipocurves to Curves/Ipos (i.e., they keep
a reference to their "child" objects also, just to keep Stupid
Users safe).  I just hadn't gotten around to that code yet :-)

Ken



More information about the Bf-python mailing list