ah got it, thanks for the quick explanation!
so without super i would call SetFloat in an endless loop, because it returns itself.
Best posts made by datamilch
-
RE: set only the value of a dialog gadget
-
how to track if the document has changed?
hi there,
i have a command plugin that is dependent on the state of the active document. so i want to track if the document has changed.
there seems to be no dedicated core message. so i tried the following. but it gives me "basedocument is not alive", which makes senes in a way. but how can i make it work?
class MyDialog( ... doc_old = None ... def CoreMessage(self, cid, msg): doc = c4d.documents.GetActiveDocument() if cid == c4d.EVMSG_CHANGE: if doc != self.doc_old: print ("doc changed") self.doc_old = doc
thanks,
sebastian
Latest posts made by datamilch
-
RE: SAVEDOCUMENTFLAGS_AUTOSAVE still added to the recent file list?
@ferdinand said in SAVEDOCUMENTFLAGS_AUTOSAVE still added to the recent file list?:
But please provide instructions on how to use your code when required in the future.
oh shit, i'm so sorry. you're right. completly missed this one.
...
and of cause thanks for the explaination / clarification. -
SAVEDOCUMENTFLAGS_AUTOSAVE still added to the recent file list?
hi there,
i recreated the autosave functionality (and tweeked the post-fix a bit) to be able to trigger it on demand.
then i noticed the saved files still show up in the recent file list, even though i added the SAVEDOCUMENTFLAGS_AUTOSAVE flag. the documentation says this should not happen. adding SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST makes it work.
is this correct or a bug or something else wrong with my code?cheers sebastian
import c4d, os, datetime doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: # autosave doc_path = doc.GetDocumentPath() doc_name = doc.GetDocumentName() now = datetime.datetime.now().strftime("%Y%d%m_%H%M%S") doc_name_post_fix = f"{doc_name}@export_{now}" prefs = c4d.GetWorldContainerInstance() ausosave_on = prefs[c4d.WPREF_AUTOSAVE_ENABLE] ausosave_dest = prefs[c4d.WPREF_AUTOSAVE_DEST] # 0=project, 1=custom, 2=user if ausosave_on: if ausosave_dest==0: if not doc_path: #print( "no doc path, fallback to user" ) doc_path = c4d.storage.GeGetStartupWritePath() save_path = os.path.join( doc_path, "backup", doc_name_post_fix ) if ausosave_dest==1: doc_path = prefs[c4d.WPREF_AUTOSAVE_DEST_PATH] if not os.path.isdir(doc_path): #print( "no custom path, fallback to user" ) doc_path = c4d.storage.GeGetStartupWritePath() doc_path = os.path.join( doc_path, "backup") save_path = os.path.join( doc_path, doc_name_post_fix ) if ausosave_dest==2: doc_path = c4d.storage.GeGetStartupWritePath() save_path = os.path.join( doc_path, "backup", doc_name_post_fix ) #print( save_path ) res = c4d.documents.SaveDocument(doc, save_path, saveflags=c4d.SAVEDOCUMENTFLAGS_AUTOSAVE | c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, format=c4d.FORMAT_C4DEXPORT) if not res: print( "error writing autosave on export" ) if __name__ == '__main__': main()
-
RE: Docked Dialog Problem with width of CUSTOMGUI_FILENAME
hi, thanks for the info.
i just updated to 2025.2.0 ... but i suppose the fix is not in this one yet? not sure when the release date was ... -
RE: Docked Dialog Problem with width of CUSTOMGUI_FILENAME
Thanks for the preliminary feedback.
I'll wait patiently -
Docked Dialog Problem with width of CUSTOMGUI_FILENAME
hi there,
i'm working on a command plugin with gedialog, that i want to dock in the layout.
one of the gui elements is AddCustomGui c4d.CUSTOMGUI_FILENAME.
the paths that are stored can be quite long.
the problem is, that the dialog wants to show the complete string, which makes the dialog extremely wide.
this only happens when the dialog is docked. then i can not scale the dialog smaller then the length of the string/filename.
if the dialog is not docked i can scale it smaller and the overflowing string is hidden.
sadly AddCustomGui has no properties initw and inith. i tried some combinations of flags but had no success.
am i missing something?i could place the element in a scrollgroup, but then the "open document" button might be hidden in the part that is scrolled away.
any other options or workarouds?cheers, sebastian
here is the code
import c4d, typing ID_PLUGIN_CMD: int = 1025245 class MainDialog(c4d.gui.GeDialog): ID_GRP_MAIN = 1000 ID_TEXT_1 = 1001 ID_TEXT_2 = 1002 extra_long_str = "this is some realy looooooooooooooooooooooooooooooooong text" def __init__(self) -> None: super().__init__() def InitValues(self) -> bool: return super().InitValues() def CreateLayout(self) -> bool: self.SetTitle("My Dialog") self.GroupBegin(id=self.ID_GRP_MAIN, flags=c4d.BFH_SCALEFIT, cols=1) self.GroupSpace(spacex=5, spacey=5) self.GroupBegin(id=0, flags=c4d.BFH_SCALEFIT, cols=2) self.AddStaticText(0, c4d.BFH_LEFT, name="path", initw=0 ) bc = c4d.BaseContainer() self.AddCustomGui(self.ID_TEXT_1, c4d.CUSTOMGUI_FILENAME, '' ,c4d.BFH_SCALEFIT, 0, 0, bc,) self.AddStaticText(0, c4d.BFH_LEFT, name="text", initw=0 ) self.AddEditText(self.ID_TEXT_2, c4d.BFH_FIT, 20,10 ) self.GroupEnd() self.GroupEnd() self.SetString( id=self.ID_TEXT_1, value=self.extra_long_str ) self.SetString( id=self.ID_TEXT_2, value=self.extra_long_str ) return super().CreateLayout() def Command(self, cid: int, msg: c4d.BaseContainer) -> bool: return super().Command(cid, msg) class DialogManagerCommand (c4d.plugins.CommandData): dialog: typing.Optional[MainDialog] = None def Execute(self, doc: c4d.documents.BaseDocument) -> bool: if self.dialog is None: self.dialog = MainDialog() if self.dialog.IsOpen() and not self.dialog.GetFolding(): self.dialog.SetFolding(True) else: self.dialog.Open(c4d.DLG_TYPE_ASYNC, ID_PLUGIN_CMD, -2, -2, defaultw=300, defaulth=200) return True def RestoreLayout(self, secret: any) -> bool: if self.dialog is None: self.dialog = MainDialog() return self.dialog.Restore(ID_PLUGIN_CMD, secret) def GetState(self, doc: c4d.documents.BaseDocument) -> int: result: int = c4d.CMD_ENABLED if self.dialog: if self.dialog.IsOpen() and not self.dialog.GetFolding(): result |= c4d.CMD_VALUE return result def RegisterPlugin() -> bool: return c4d.plugins.RegisterCommandPlugin( id=ID_PLUGIN_CMD, str="filename_test_01", info=c4d.PLUGINFLAG_SMALLNODE, icon=None, help="", dat=DialogManagerCommand()) def main(): if not RegisterPlugin(): raise RuntimeError( f"Failed to register {DialogManagerCommand} plugin." ) if __name__ == '__main__': main()
-
RE: Message from Object or Tag to CommandData/GeDialog Plugin
oh well ... tried option B) as planned.
a python tag tracks the dirty status of some objects and starts a c4d.SpecialEventAdd(). this is received as a core message in my dialog. but when i go looking for the dirty objects, they are not dirty anymore.
my workaround for now is, to have a str userdata on the pyhon tag. once the tag detects a dirty object, it writes its name into the str userdata. my dialog can then read the name of the object and find it. feels quite cumbersome but works for now.would there be a better/more hidden way to store the data?
-
Message from Object or Tag to CommandData/GeDialog Plugin
hi there,
i have a bunch of objects with userdata. then i have a GeDialog plugin with mostly the identical userdata. the dialog plugin is intended to control the objects from one common panel. but there might be cases, where the objects are adjusted direktly, so the dialog needs to be updated. i'm looking for a solution for this case.
A)
am i correct, the change of DIRTYFLAGS_DATA can not be tracked from GeDialog directly via the message system? i could only track things, that trigger a global event?
i suppose it could be done with a timer, that checks the doc/objects every few millyseconds, but that feels very unprecise.B)
with a python tag i can easily track the dirty status of objects, but from what i've read here, i can not send data (list of dirty objects) direkcly to the dialog/command plugin. i can just call my dialog and make it aware to look and find the dirty objects.C)
there also seems to be c4d.GePluginMessage() and PluginMessage(). but i never found a clear statement, which plugin types are supported. i never even got c4d.GePluginMessage() to return True, which made me doubt myself a bit.so i would try to go with option B).
any objections or completly different suggestions?
cheers sebastian -
RE: use thicken generator inside a python generator
hi @i_mazlov,
ok, good to know.
i also tried to insert the thicken generator into a temp_doc, activating the selections and executing passes. but that didn't work either. -
RE: MCOMMAND_SELECTALL and MCOMMAND_SELECTINVERSE not working?
@i_mazlov Thanks!
makes sens. seems i only used the forgiving commands until now.the code is run in a python generator. so by returning the object, it will be inserted into the scene.
-
MCOMMAND_SELECTALL and MCOMMAND_SELECTINVERSE not working?
hi there,
i was shifting around some selections and noticed that some modeling commands seem to have no effect.
MCOMMAND_SELECTALL
MCOMMAND_SELECTINVERSE
i realize i can use SelectAll on the BaseSelect. and i could surely build a loop, to invert the selection. but why are these commands there? they even return true, despite doing nothing.this is my code and a demo file:
import c4d doc: c4d.documents.BaseDocument op: c4d.BaseObject def main() -> c4d.BaseObject: obj = op[c4d.ID_USERDATA,1].GetClone() bs_points = obj.GetPointS() #bs_points.SelectAll( obj.GetPointCount()-1 ) # will select all points c4d.utils.SendModelingCommand( c4d.MCOMMAND_SELECTALL, [ obj ], c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc) # not working c4d.utils.SendModelingCommand( c4d.MCOMMAND_SELECTSHRINK, [ obj ], c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc) c4d.utils.SendModelingCommand( c4d.MCOMMAND_SELECTINVERSE, [ obj ], c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc) # not working bc = c4d.BaseContainer() bc[c4d.MDATA_CONVERTSELECTION_LEFT] = 0 # 0 = points bc[c4d.MDATA_CONVERTSELECTION_RIGHT] = 1 # 1 = edges bc[c4d.MDATA_CONVERTSELECTION_TOLERANT] = False # tolerant conversion res = c4d.utils.SendModelingCommand( c4d.MCOMMAND_CONVERTSELECTION, [ obj ], bc=bc, doc=doc) res = c4d.utils.SendModelingCommand( c4d.MCOMMAND_EDGE_TO_SPLINE, [ obj ], doc=doc) return obj