Performance / Viewport refresh Problems in 2026 - 2027.0.0
-
Question: Did any implementation of
GetState() , c4d.CMD_ENABLED GetMode()change in the SDK that i have to be aware of?I found a performance / Viewport update bug in my Plugin which was no bug in older C4D versions.
These two methods make the viewport slow , and message "blocks" the update till i interact with the viewport.
Tooldata - Point mode tool# Problematic in R2026 def GetState(self, doc): if doc.GetMode() != c4d.Mpoints: c4d_progressbar(text="Go into Point Edit Mode!") return False elif len(doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)) != 1 : c4d_progressbar(text="Only one Object allowed!") return False else: c4d_progressbar(clear=True) return c4d.CMD_ENABLED # Problematic in R2027 def Message(self, doc, parameters, type, t_data): if doc.GetMode() != c4d.Mpoints: self.FreeTool(doc, parameters) return False return Truethank you for your time
mogh -
I changed my message and mode functions to only react if the tool is actively used.
it seems before 2026 and 2027 releases cal message / GetState calls where not that frequent or where blocked catched somewhere .... I can not explain the slowdown otherwise despite my poor coding.
I have not tested this extensively but my viewport stale / "freezes" are gone for now.
anyway here are my methods if somebody finds it usefull:
def GetState(self, doc): if doc.GetMode() == c4d.Mpoints or doc.GetAction() == PLUGIN_ID: return c4d.CMD_ENABLED return False def Message(self, doc, parameters, type, t_data) if type == c4d.MSG_DOCUMENT_MODE_CHANGED: if doc.GetMode() == c4d.Mpoints: self.restore_xray_after_mode_change(doc) else: self.suspend_xray_for_mode_change(doc, parameters) self.update_progressbar_help(doc) return None return True def FreeTool(self, doc, parameters): if self.status_help: c4d_progressbar(clear=True) self.status_help = None del self.lines[:] del self.arc_data[:] del self.movedpoints[:] self.parameters['optionkey'] = None self.xray_restore_link = None self.xray_mode_suspended = False self.xray_off(doc, parameters) returninstead of reacting to messages the tool itsel checks:
def Draw(self, doc, parameters, bd, bh, bt, flags): if doc.GetMode() != c4d.Mpoints: return c4d.TOOLDRAW_NONE -
Hello @mogh,
please excuse the delay. Without your plugin this is not easy to answer. Your
GetStatelooks okayish to me, theGetActiveObjectsandc4d_progressbar(I assume this is a helper for our status bar methods) calls are not great asGetStatecan be called quite often, but I would not expect this to be a huge bottleneck unless the scene is really large (GetActiveObjects implies traversing the scene).The
Messagefunction however is not great. You free there without any safe guard (except for the document mode condition) your tool. Not only would the tool freeing then happen under a random message context, freeing a tool is also something that you can only do on the main thread (see the all new Scene Execution manual), as something could still work under the assumption that this tool is active. So, you would at least also have to add a main thread check there.But even then I would consider this not great code, as this is a bit awkward place to free a tool. Both methods do not look essential to the operation of a plugin. Did you try to remove code or methods to see what exactly makes it slow?
Your second code listing looks much less rogue. As a tip I would still add an
GeIsMainThreadAndNoDrawThreadto yourMSG_DOCUMENT_MODE_CHANGEDcondition. It is very likely that this message is only sent on the MT, but there can always be rogue plugins (or bad Maxon code) which violate such assumptions.Cheers,
Ferdinand