Spanki opened this issue on Mar 24, 2008 · 7 posts
Spanki posted Mon, 24 March 2008 at 4:22 PM
Part II - New Instance vs. Pointer / Reference
My second question has to do with how various data/objects get returned from my new 'type' implementations... for example, here are two new types implemented by the extension...
Type: <VectorType><br></br>
Members:<br></br>
x - <FloatType> ( aliases:
vec.u, vec.r, vec.wgt0, vec[0] )<br></br>
y - <FloatType> ( aliases:
vec.v, vec.g, vec.wgt1, vec[1] )<br></br>
z - <FloatType> ( aliases:
vec.w, vec.b, vec.wgt2, vec[2] )<br></br><br></br>
Type: <TriPolyType><br></br>
Members:<br></br>
v0
- <IntType> ( triangle vertex
indices... )<br></br>
v1
- <IntType><br></br>
v2 - <IntType><br></br>
uv0
- <IntType> ( triangle texture vertex
indices... )<br></br>
uv1
- <IntType> <br></br>
uv2
- <IntType><br></br>
polyIndex -
<IntType> ( index of ngon that spawned
the tripoly )<br></br>
triangleIndex - <IntType> ( index of
triangle within the above ngon )<br></br>
plane -
<FloatType> ( pre-computed plane equation )<br></br>
normal -
<VectorType> ( face normal vector )<br></br>
...Note that internally, my code doesn't store pointers to Python Objects for simple types like ints or floats, but for complex data types (like the 'normal' member of the TriPolyType), it does (incrementing and decrementing the reference counts as needed).
The next thing to note is that, as a 'type' implementation / extension, my C code is basically a 'handler' for any data of the new type, so the Python interpreter calls some routine in my code any time it needs to get info about or operate on my new type. So let's look at some simple example code...
verts = [Vector(0.0, 0.0, 0.0) for i in range(3)] #
create 3 new vectors with not-very-useful positions<br></br>
norm = Vector(0.0, 1.0, 0.0) # psuedo normal vector,
pointing up (maybe down :) )<br></br>
tp = TriPoly(0, 1,
2) # create a
new tripoly,with 0/1/2 indices - we'll fill in the normal
afterwards<br></br>
tp.normal = norm<br></br>
...ok, so most of the actual values being used above psuedo code are meaningless (all 3 vertices or the tripoly would be at 0.0, etc), so I just wanted some 'structure' to talk about :). Given the above, if we do:
ndx0 = tp.v0
...then what gets returned from my
newnorm = tp.normal
...currently, what my code does it bump the reference count on the normal member (a pointer to a Python Object of type
It's only recently occured to me that, while handy in some cases, it might also be the cause of some hard to track down bugs in people's python scripts. Consider the following...
newnorm.y = -1.0
...now, not only does the script's local 'newnorm' varible have it's y axis set to -1.0, but the normal stored in "tp.normal" also got changed (and this is a pretty simplistic example.. that tripoly might well be some nth index into a larger list of them, which might be part of an even larger mesh-type structure, etc).
My new
newnorm = tp.normal.clone()
...that would end up with a new instance/copy of the normal, instead of a pointer to the existing one, but I'm fairly fast closing in on the decision/opinion to just always return a new instance/copy of the normal, instead of a pointer/reference.
Thoughts / Comments?
Thanks,
Keith
Cinema4D Plugins (Home of Riptide, Riptide Pro, Undertow, Morph Mill, KyamaSlide and I/Ogre plugins) Poser products Freelance Modelling, Poser Rigging, UV-mapping work for hire.