THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 16/04/2012 at 11:55, xxxxxxxx wrote:
Before you read this answer you should should read the chapter "NodeData Management" in the Python SDK.
For programmers who write an object:
A programmer of an object, tag, material... has two possibilities to store data for an object. The most used place is the data
container which is in the BaseList2D (controller) object that can be accessed via GetDataInstance. There you can store
floats, strings, integers, etc.
But sometimes you want to have more control over data that is written/read to/from your object, e.g:
\- to limit values that are passed to the object.
\- to make values dependend on each other, maybe that data ABC can never be higher than XYZ
- the structure does not fit in a data container
(just three of many examples why you don't put data in the data container). Therfore you can set/get
data in/from the underlying NodeData structure which is established with the BaseList2D (controller) object.
In C++ you can do this by overriding GetDParameter/SetDParamter, this is not possible in Python yet.
For programmers who want to access data of an object:
What does that mean for a programmer who wants to access the data of an object? GetDataInstance() is a member of
BaseList2D and just returns the data container of the "controller" object. This is a fast but unsafe because
you don't always know where the programmer stores the data for this ID.
With GetDataInstance() you just have access to this container and no access to data in the NodeData structure.
So when you call GetDataInstance().GetString(MEMBER_123) and the data is stored in the underlying
NodeData structure you can't read it.
The function call which garantuess to extract data from the data container OR the underlying NodeData structure is
BaseList2D::GetParameter/SetParameter in C++ and BaseList2D.__getitem__/__setitem__ in Python. So you should always access this.
In the GetContour() example it would indeed be more consistent to write:
op1[c4d.SPLINEOBJECT_INTERPOLATION] = op2[c4d.SPLINEOBJECT_INTERPOLATION] # safe
bc1.SetLong(c4d.SPLINEOBJECT_INTERPOLATION, bc2.GetLong(c4d.SPLINEOBJECT_INTERPOLATION)) # fast but unsafe
When you execute this example you see that for instance LIGHT_NOISETYPE is not part of the data container.
import c4d
light = c4d.BaseObject(c4d.Olight)
for index, value in light.GetDataInstance() :
if index == c4d.LIGHT_NOISETYPE:
print "found" # will never be printed
bc = op.GetDataInstance()
bc.SetLong(c4d.LIGHT_NOISETYPE, c4d.LIGHT_NOISETYPE_VISIBLE) # has no effect
op[c4d.LIGHT_NOISETYPE] = c4d.LIGHT_NOISETYPE_VISIBLE # works as it works as GetParameter in C++
I hope this helps a bit.
Cheers, Sebastian