How to modify parameters of individual clones of Cloner in Python SDK
-
Hi,
I would like to access the parameters of individual clones of the Cloner object in Python.
Particularly I would like to modify the offset of each clone individually. I am pretty sure this should be possible, however I can't think of a way that does not include some complicated procedure of using the MoGraph Selection Tool. I do have a hunch that using this tool is the way to go, but I have a feeling it should be easier.
My rather complicated guess is:
- create MoGraph selection per individual clone (don't know how yet)
- create equal amount of Plain Effectors
- connect selections with effectors
- modify effectors parameters
As a bonus, I would like to be able to specify the reference object for each individual clone.
So, if I have two reference objectsA
&B
, and I want a cloned linear pattern ofAAABBBABAAAABBBABBABBABBBBAAAABBABABAA
.
My current approach is to keepA
andB
in a separate place and put instances of them as children under the cloner following the pattern. It works, but I am not sure if this is bad practice. After all, Cloner will create then Multiinstances referencing Instances. However, my hunch is that a custom cloning pattern is not possible.
(I thought to combine both questions in one post, as they both refer to modifying individual clones, and possibly have a very similar solution. If this is not true, I am happy to remove this second question for the sake of clarity.)The example code is a minified version of the starting situation, with some hallucinated pseudo code at the last lines. In the end I want to use it in the GetVirtualObjects function of an ObjectData plugin.
# get the obligatory active document to attach our objects to doc = c4d.documents.GetActiveDocument() # construct a cloner object cloner = c4d.BaseObject(c4d.Omgcloner) # use linear mode, so we can better see if it works cloner[c4d.ID_MG_MOTIONGENERATOR_MODE] = c4d.ID_MG_MOTIONGENERATOR_MODE_LINEAR # also here, iterating through the children sounds the most intuitive cloner[c4d.MGCLONER_MODE] = c4d.MGCLONER_MODE_ITERATE # always use 42, as you might accidentally solve all problems of the world cloner[c4d.MG_LINEAR_COUNT] = 42 # might not really matter for this example # but in my particular use case I use multiinstance rendering, # defining it therefore just in case there are side effects when accessing # individual clones cloner[c4d.MGCLONER_VOLUMEINSTANCES_MODE] = ( c4d.MGCLONER_VOLUMEINSTANCES_MODE_RENDERMULTIINSTANCE ) # okay, now we're ready to throw the fish in the water! doc.InsertObject(cloner) # give it some children A = c4d.BaseObject(c4d.Ocube) A.InsertUnderLast(cloner) B = c4d.BaseObject(c4d.Osphere) B.InsertUnderLast(cloner) # now let's do some wishful thinking # to demonstrate in pseudocode what I tried to describe in words pattern = "AAABBBABAAAABBBABBABBABBBBAAAABBABABAA" for i in range(0, len(pattern)): # adjust offset by some arbitrary value cloner.GetCloneByIndex(index).SetOffset(i * 0.2) # move relative to current position along some vector cloner.GetCloneByIndex(index).SetRelPos(c4d.Vector(i)) # bonus: set reference object cloner.GetCloneByIndex(index).SetReferenceObject(A if pattern[i] == "A" else B)
Obviously, the last part will throw errors.
Thank you already for reading this! I am thankful for any hint towards the right direction.
-
Sidenote while researching my answer:
Something I found confusing in the Set MoData Selection Example is that it's not clear what to do with the selection.Wouldn't it make sense to add a
op.MakeTag(c4d.Tmgselection)
before callingGeSetMoDataSelection
?This way, also the Get MoData Selection Example works with it in a tandem.
Do you agree?
If not I'd be curious why.
If you do agree, please check this PR
Thanks! -
Hello @uogygiuol,
Thank you for reaching out to us. When you want to modify MoGraph particle data, you will need an effector. In Python you can use a Python Effector. You technically could also do this for example via
TagData\ObjectData.Execute
, but that would sidestep all the effector pipeline which very much is not recommended and could lead to unintended side effects.MoGraph is also a particle system, not an array of objects. I.e., you interact with particles, on which Cinema 4D then clones geometry upon scene execution. You do not have control over each object as if it was an object in the Object Manager, nor are particles aware of what their particle generator (e.g., a MoGraph cloner) does in its UI. MoGraph particles and their fields are documented here.
Find a simple example for what you want to do below.
Cheers,
FerdinandResult
-
This is fantastic, thank you so much!
This works beautifully.
I see your confusion with the "offset". This is absolutely my fault in formulating the question. Sorry about that. I also wanted the clones to follow a spline with an individual offset, but then thought to remove this part to not overcomplicate the question and accidentally left some traces. However, in your video you gave me valuable insight in how to achieve this as well. I already have a working sketch where I'm daisy chaining your script with a Spline Effector in the right order.
Giving these thoughtful answers is incredibly valuable, you can't believe how motivating this is to go further.