Python - InExcludeData initialization problem
-
I had a problem (again) with InExcludeData. this time with initializing the thing
Also, it seems like there is no way to merge two different InExcludeData fields to make a single InExcludeData list with no object duplicates on it.
Can any of you can explain to me how can I really do this using Python?
It basically was unclear for me as of now... -
Hi,
the docs are trying to tell you that the argument
v
is an optional argument. For the rest, see the attached example.Cheers,
zipit""" Run this in the Script Manager. You will need to select an object in your scene, which has InExcludeData fields as its first and second user data element. The fields should be ideally populated with overlapping sets of objects (e.g. [a, b, c] and [b, c, d]). The script will write the union of those two object sets to the first InExcludeData field. """ import c4d def get_objects(doc, op): """Returns the objects referenced by an InExcludeData as a list. Args: doc (c4d.documents.BaseDocument): The document the referenced objects are attached to. op (c4d.InExcludeData): The InExcludeData to get the objects from. Returns: list[c4d.BaseObject]: The referenced objects. """ return [op.ObjectFromIndex(doc, i) for i in range(op.GetObjectCount())] def main(): """ """ if op is None: return # The two InExcludeData inex_a = op[c4d.ID_USERDATA, 1] inex_b = op[c4d.ID_USERDATA, 2] # Get the objects nodes_a = get_objects(doc, inex_a) nodes_b = get_objects(doc, inex_b) print "nodes in inex_a:", nodes_a print "nodes in inex_b:", nodes_b # Create a new InExcludeData, using the default constructor. inex_c = c4d.InExcludeData() # Unsurprisingly there is nothing in there. print "nodes in inex_c:", get_objects(doc, inex_c) # Create a new InExcludeData, using the copy constructor. inex_d = c4d.InExcludeData(inex_a) # Since we copied from inex_a, it references the same objects. print "nodes in inex_d:", get_objects(doc, inex_d) # Adding the union of the object sets a and b to a new InExcludeData is # a little bit convoluted, because the type InExcludeData is not a set # by nature and nodes not being hashable prevents us from using Python's # sets. nodes_union = nodes_a + [n for n in nodes_b if n not in nodes_a] inex_union = c4d.InExcludeData() for node in nodes_union: inex_union.InsertObject(node, 0) # Write the union back to the first InExcludeData. op[c4d.ID_USERDATA, 1] = inex_union c4d.EventAdd() if __name__=='__main__': main()```
-
Hi @SolarPH, thanks for reaching out us.
With regard to your question, actually initializing the
InExcludeData
has nothing to do with having the list not including duplicates.
Thev
parameter pointed out in the documentation is used to fill the to-be-createdInExcludeData
with the values found in the passedInExcludeData
as @zipit has shown in line 48.
To avoid duplication instead you've to manually browse the items in the lists and pickup from the second only those not found in the first. Again @zippit code perfectly shows this.Cheers, R
-
@zipit Thanks for sharing the code. Now I know that initializing the InExcludeData is not
InExcludeData.__init__
and the correct way wasc4d.InExcludeData()
, which I really did not think of when initializing specialized data containers. -
Hi,
@SolarPH said in Python - InExcludeData initialization problem:
Now I know that initializing the InExcludeData is not
InExcludeData.__init__
and the correct way wasc4d.InExcludeData()
, ...I am not quite sure how you did mean this, but
InExcludeData.__init__
is one of the methods called when you invokec4d.InExcludeData()
. Like all double underscore methods__init__
implements an operator, in that case the construction operator. InvokingSomeClass()
will first call the constructorSomeClass.__new__
and after that the initialisatorSomeClass.__init__
. Due to the fact that__new__
only rarely has to be implemented explicitly and because people are accustomed to talking about constructor functions,__init__
is also often called a constructor, while technically it is just the initialisator. A prime example would be both theInExcludeData
documentation and my example code, which both talk about a copy constructor, but are actually referring to__init__
and not__new__
.Cheers,
zipit