Python Tag how to hide a mogragh object
-
Hello everyone,
I want to hide an object from a cloner, I test in a python effector and work well , but in a python tag in didn't work anymore . what is wrong with the codes?
from typing import Optional import c4d doc: c4d.documents.BaseDocument # The document evaluating this tag op: c4d.BaseTag # The Python scripting tag flags: int # c4d.EXECUTIONFLAGS priority: int # c4d.EXECUTIONPRIORITY tp: Optional[c4d.modules.thinkingparticles.TP_MasterSystem] # Particle system thread: Optional[c4d.threading.BaseThread] # The thread executing this tag def main() -> None: obj = op.GetObject() moData = c4d.modules.mograph.GeGetMoData(obj) if moData is None: return False cnt = moData.GetCount() marr = moData.GetArray(c4d.MODATA_MATRIX) farr = moData.GetArray(c4d.MODATA_FLAGS) #hasField = op[c4d.FIELDS].HasContent() #fall = moData.GetFalloffs() farr[4] &= ~ (c4d.MOGENFLAG_CLONE_ON) moData.SetArray(c4d.MODATA_FLAGS, farr, 0) moData.SetArray(c4d.MODATA_MATRIX, marr, 0)
Cheers~
DunHou -
hi,
I got the feeling it will not work but i need to investigate a lot more. Either you are modifying the MoData too early, and the cloner will erase/initialise them after you modified them, or you are modifying them after the cloner have generated the clones.
That is why we have the effectors to modify the Modata before the cloner have generated the clones.
Is there any reason you want to use a tag instead of an effector?
Cheers,
Manuel -
Hi @Dunhou,
for the time being you can modify the clones from a python tag via the help of a MoSelection tag.
Cheers,
Sebastianfrom typing import Optional import c4d doc: c4d.documents.BaseDocument # The document evaluating this tag op: c4d.BaseTag # The Python scripting tag flags: int # c4d.EXECUTIONFLAGS priority: int # c4d.EXECUTIONPRIORITY tp: Optional[c4d.modules.thinkingparticles.TP_MasterSystem] # Particle system thread: Optional[c4d.threading.BaseThread] # The thread executing this tag def main() -> None: """Example showing a workaround on how to modify clones via a python tag. To get this working we need a MoSelection tag as a man in the middle to transfer modified data from this python tag to a e.g. cloner object. """ moselection = op[c4d.ID_USERDATA,1] # Userdata link filed where you are supposed to drop your MoSelection tag. obj = op.GetObject() if not obj or not moselection: # Bail if there is no host object or no MoSelection tag. return baseselect = c4d.modules.mograph.GeGetMoDataSelection(moselection) # Retrieve a c4d.BaseSelect from the MoSelection tag. moData = c4d.modules.mograph.GeGetMoData(obj) if moData is None: return False farr = moData.GetArray(c4d.MODATA_FLAGS) # Read the MoData array you want to modify. farr[4] &= ~ (c4d.MOGENFLAG_CLONE_ON) # Modify the array to your liking. baseselect.SetAll(states=farr) # Set the c4d.BaseSelect from the modified array data. c4d.modules.mograph.GeSetMoDataSelection(op=moselection, selection=baseselect) # Write back the c4d.BaseSelect to your MoSelection tag. """ def message(id: int, data: object) -> bool: # Called when the tag receives messages. Similar to TagData.Message. # Write your code here return super().Message(id, data) def draw(bd: c4d.BaseDraw) -> bool: # Called to display some visual element in the viewport. Similar to TagData.Draw. # Write your code here return True """
-
Hi @Manuel ,
It is pretty strange , I want use python tag because of a I am work with a tag plugin that pin a object of a cloner , now I want add a option to hide the index,
see also : tag plugin crashAnd Thanks for @HerrMay , you helped a lot about those tag plugin topics , A big shout out!
-
so I found that it is actually possible to modify the flags of the clones via a python tag.
Try the following code on a matrix object. You'll see that the clones will be hidden.
It still seems to be a bug of some sort as you can observe a refresh issue when you scrub the timeline. And of course, if it works on matrix objects only that's not really an option.
Setting a cloner to object mode and cloning on that matrix will also not really work as all clones will still be visible at render time. I tried changing the execution priority of the python tag as well but no luck.
Let's hope @Manuel will come back with good news on that one. Although I'm afraid I already know the answer.
Cheers,
Sebastianfrom typing import Optional import c4d doc: c4d.documents.BaseDocument # The document evaluating this tag op: c4d.BaseTag # The Python scripting tag flags: int # c4d.EXECUTIONFLAGS priority: int # c4d.EXECUTIONPRIORITY tp: Optional[c4d.modules.thinkingparticles.TP_MasterSystem] # Particle system thread: Optional[c4d.threading.BaseThread] # The thread executing this tag def main() -> None: # Called when the tag is executed. It can be called multiple time per frame. Similar to TagData.Execute. # Write your code here obj = op.GetMain() moData = c4d.modules.mograph.GeGetMoData(obj) if moData is None: return False farr = moData.GetArray(c4d.MODATA_FLAGS) farr = [1 if i < 5 else 0 for i, num in enumerate(farr)] moData.SetArray(c4d.MODATA_FLAGS, farr, False) """ def message(id: int, data: object) -> bool: # Called when the tag receives messages. Similar to TagData.Message. # Write your code here return super().Message(id, data) def draw(bd: c4d.BaseDraw) -> bool: # Called to display some visual element in the viewport. Similar to TagData.Draw. # Write your code here return True """
-
hi,
well the main problem is not where but when to change that MoData. Specially in python i see no solution.
With c++ you could find a hacky way of doing it but i did not tried.One way of doing it would be to create a setup inside the message function of the tag (so you are on the main thread). Creating a formula effector, hide it inside the object manager and use the formula to hide the object you want. something like
id!=2&id!=3
will work. Of course, you need to include that effector to the cloner's effector list. I would not call that a "good solution", but it will work.Cheers,
Manuel. -