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

Ken Hughes khughes at pacific.edu
Sun Jul 3 08:25:18 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.

I've been trying to come up with a fool-proof way of implementing this
and ran into some problems.  Bottom line now is: I don't think there is
one without tracking the Python objects, unless we really want to slow
down the speed of the methods inside the BezTriple and BNURBPoints.

What I've implemented so far -- and what works for many circumstances --
is each control point object has two pointers:  one, the pointer to
the control point array (passed to the object when it's created) and
another pointer to the pointer to the control point array within the
curnurb/ipocurve.  So for example, we have

PyObject *BezTriple_CreatePyObject ( BezTriple **ptr, int index)
{
...
     self->parent = ptr;
     self->bezt = *ptr;
}

and in Ipocurve.c we have

     PyObject *obj = BezTriple_CreatePyObject ( &self->ipocurve->bezt, i);

Each of the BezTriple methods/attributes check to see if their
copy of the pointer matches the parent's, and if not they throw
an exception.

Why save the pointer to the pointer?  Because BezTriples can belong
to either CurNurbs or IpoCurves, so we can't just point back to the
actual parent object unless we also know what type it is.  (This
is not currently a problem for BNURBPoints, but I did the same
implementation anyway).

This method still has one remaining problem: it's possible for the
control point list to be changed without being able to detect it
(i.e., two changes to the list result in MEM_mallocN() giving
us the original pointer back).  In this case, memory can still
be corrupted if the new list is smaller than the original, since
there is no way to know the current list's size.  Which brings
me to the next idea....

The only other solution I've can think of requires a pointer to the
parent BPy object (IpoCurve or CurNurb) in each control point.
With this, a check could be made which compares the index to the
list's size, and also uses the pointer stored in the parent.
We would also know which type of object we're dealing with so
that we would know whether to use ipocurve->bezt or nurb->bezt.
But it's going to be slower, plus we're just moving the problem
somewhat; if the curve is deleted, we still have bogus pointers
and the potential for memory corruption.

Long story short: I'm going to start implementing the second
solution unless someone tells me otherwise.  It's the last thing
I need to finish before uploading the second set of patches (a
test set of patches is in the patch tracker for BNURBPoints, but
you really can't do much without the full IpoCurve/CurNurb
sequence/iterator stuff).  I hope to finish this Sunday and
upload, then move onto stage 3 (sequence/iterator operators in
the Ipo module).

Ken



More information about the Bf-python mailing list