Store generator's property
-
Hi everyone,
I'm completely misunderstand how to store object's related data.
Read few posts, but there are common words only... Not sure there would be Read/Write/Copy overrides...I'd like to have a selection tag on the Generator object based on UI's bool (CHECKBOX_ID).
If it's already exist - then use existing, otherwise add it automatically.
Link should be updated after save/openPlease point me to a solution, if any.
CHECKBOX_ID = 1001 SOME_ID = 5000 SOME_ID_TAG = 5001 class GeneratorPlugin(c4d.plugins.ObjectData): def Init(self, op): if op is None: raise RuntimeError("Failed to retrieves op.") self.InitAttr(op, bool, CHECKBOX_ID) op[CHECKBOX_ID] = True bc = op[SOME_ID] if bc is None: print "Data Not Exist" bc = c4d.BaseContainer() bc[SOME_ID] = c4d.BaseContainer() else: print "Data Exist", bc.GetLink(SOME_ID_TAG) op[SOME_ID] = bc def GetVirtualObjects(self, op, hh): if op is None or hh is None: raise RuntimeError("Failed to retrieves op or hh.") tmpSel = c4d.BaseSelect() # some calculations tag = op[SOME_ID].GetLink(SOME_ID_TAG) if op[CHECKBOX_ID]: if not tag: tag = c4d.SelectionTag(c4d.Tpolygonselection) op.InsertTag(tag) op[SOME_ID].SetLink(SOME_ID_TAG, tag) tmpSel.CopyTo(tag.GetBaseSelect()) elif tag: tag.Remove() op[SOME_ID].RemoveData(SOME_ID_TAG)
-
hello,
The BaseContainer of an object is saved automatically with the document. As long as you are storing your data in the object's BaseContainer, you don't have to worry to save them with the document.
Read/Write/Copy need to be override when you are storing data somewhere else. In most of the case, If one of those function is implemented, you have to implement all of them.
GVO (GetVirtualObjects) isn't the right place to change the scene. See information about threading
To know if you are on the main thread or not you can use GeIsMainThread
The right place to do something like this is the Message function.
You can react to the message MSG_DESCRIPTION_POSTSETPARAMETER to apply some modifications when a parameter have been changed.
You can also react to the message MSG_MENUPREPARE that is sent before the object is inserted in the scene.Be careful that this selection tag shouldn't be moved from the generator (or it will be reset)
To avoid that, you can change its bit using ChangeNBitHere are an example of what you want to do.
def CreateSelectionTag(self, node): #Creates a selection tag. Remove the tag first if it already exist bc = node.GetDataInstance() if bc is None: return False tag = bc.GetLink(ID_TAGLINK) if tag: tag.Remove() bc.RemoveIndex(ID_TAGLINK) tag = c4d.SelectionTag(c4d.Tpolygonselection) if tag is None: return False tag.ChangeNBit(c4d.NBIT_NO_DELETE, c4d.NBITCONTROL_SET); tag.ChangeNBit(c4d.NBIT_NO_DD, c4d.NBITCONTROL_SET); node.InsertTag(tag) bc.SetLink(ID_TAGLINK, tag) return True def RemoveSeletionTag(self, node): # Remove the tag bc = node.GetDataInstance() if bc is None: return False tag = bc.GetLink(ID_TAGLINK) if tag is None: return False tag.Remove() bc.RemoveIndex(ID_TAGLINK) return True def Init(self, op): op[ID_CHECKBOX] = True return True def Message(self, node, type, data): # MSG_MENUPREPARE is sent before the object (generator here) is inserted in the scene. This is a nice moment to add any tag to the node if type == c4d.MSG_MENUPREPARE: print ("Message mainthread ? ", c4d.threading.GeIsMainThread()) self.CreateSelectionTag(node) # MSG_DESCRIPTION_POSTSETPARAMETER is sent if a parameter have changed. Check here if we should add or remove a tag. elif type == c4d.MSG_DESCRIPTION_POSTSETPARAMETER: print ("Message mainthread ? ", c4d.threading.GeIsMainThread()) if data['descid'][0].id == ID_CHECKBOX: if node[ID_CHECKBOX]: return self.CreateSelectionTag(node) else: return self.RemoveSeletionTag(node) return True # Override method, should generate and return the object. def GetVirtualObjects(self, op, hierarchyhelp): print ("GVO mainthread ? ", c4d.threading.GeIsMainThread()) if op[ID_CHECKBOX]: bc = op.GetDataInstance() tag = bc.GetLink(ID_TAGLINK) if tag: print ("the tag is", tag) else: print ("this should never happen") else: bc = op.GetDataInstance() tag = bc.GetLink(ID_TAGLINK) if tag: print ("this should never happen") else: print ("there's no tag and box isn't checked")
Cheers,
Manuel -
Oh, such a rocket science!
Many thanks Manuel, it seems it works super fine.@m_magalhaes said in Store generator's property:
if op[ID_CHECKBOX]: bc = op.GetDataInstance() tag = bc.GetLink(ID_TAGLINK) if tag: print ("the tag is", tag) else: print ("this should never happen") else: bc = op.GetDataInstance() tag = bc.GetLink(ID_TAGLINK) if tag: print ("this should never happen") else: print ("there's no tag and box isn't checked")
-
hi
can we considered this thread as resolved ?
Cheers,
Manuel