Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hi all,
Hope you are well in these crazy times!
I'm having trouble understanding how ShowPopupDialog currently works in R21, if caught by MessageData plugin's CoreMessage. It keeps freezing Cinema, could be thread related (which I don't know a lot of)?
ShowPopupDialog
CoreMessage
I manage to get the data across externally fine but when creating the menu it freezes immediately after c4d.gui.ShowPopupDialog is called.
c4d.gui.ShowPopupDialog
# Import modules import os import c4d from c4d import documents plugin_ID = 1055685 plugin_ID_loader = 1055684 MENU_ADD_ASSETS = c4d.FIRST_POPUP_ID MENU_ADD_MATERIALS = c4d.FIRST_POPUP_ID + 1 MENU_REPLACE_ASSETS = c4d.FIRST_POPUP_ID + 2 MENU_REPLACE_MATERIALS = c4d.FIRST_POPUP_ID + 3 MENU_REPLACE_TAG = c4d.FIRST_POPUP_ID + 4 class AOMessage(c4d.plugins.MessageData): """ Class for the MessageData plugin. """ def GetTimer(self): """ Called to return a time in milliseconds to receive timer messages (MSG_TIMER) with that interval in CoreMessage. This method is queried again after each message.. :return: The time in miliseconds. """ return 0 def CoreMessage(self, id, bc): """ Called to receive core messages. :param id: The id of the messages received. :param bc: The BaseContainer objects with message data. :return: True if Message is received. """ if id == plugin_ID_loader: world_container = c4d.GetWorldContainerInstance() doc = documents.GetActiveDocument() paths_str = world_container.GetString(plugin_ID_loader) paths_lst = paths_str.split(', ') active_objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0) active_mat = doc.GetActiveMaterial() doc.StartUndo() # Dialog for importing assets menu = c4d.BaseContainer() if active_objs or active_mat: menu.InsData(MENU_REPLACE_ASSETS, 'Replace Asset(s)') menu.InsData(MENU_REPLACE_MATERIALS, 'Replace Material(s)') menu.InsData(MENU_REPLACE_TAG, 'Replace Texture Tag(s)') else: menu.InsData(MENU_ADD_ASSETS, 'Add Asset(s)') menu.InsData(MENU_ADD_MATERIALS, 'Add Material(s)') result = c4d.gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS) doc.EndUndo() world_container.RemoveData(plugin_ID_loader) print("Finished") return True if __name__ == "__main__": c4d.plugins.RegisterMessagePlugin(id=plugin_ID, str="AO Message", info=0, dat=AOMessage())
It works perfectly in R19, so I'm not sure what changed since then. Apologies if this as been asked before.
Thank you very much for your help in advance!
Andre
Hi @AndreAnjos,
it is great that you found the issue. A few points:
c4d.GetWorldContainerInstance()
c4d.GetWorldContainer()
c4d.SetWorldContainer()
Get/SetWorldContainer()
Cheers, Ferdinand
Hi @AndreAnjos unfortunately, I'm not able to make Cinema 4D R21 freezing by copying your plugin and executing it by calling: c4d.SpecialEventAdd(1055684) from the Python console.
c4d.SpecialEventAdd(1055684)
So on which os version? on which exact version of R21 are you (you can check in the about form)?
In which context and how often are you calling SpecianEventAdd? Cheers, Maxime.
@m_adam Hi Maxime,
Cinema R21.207 Build RB303831. Windows 10 1809
I'm calling the SpecialEventAdd on an SceneLoaderPlugin.
SpecialEventAdd
# Import modules import c4d plugin_ID = 1055684 class AOLoader(c4d.plugins.SceneLoaderData): """ Class for the SceneLoaderData plugin. """ def Identify(self, node, name, probe, size): """ Identifies if the format of the custom file captured meets the plugins requirements. :param node: BaseContainer for instance. :param name: Path and file name of the instance. :param probe: The data from the instance. :param size: The data size of the instance. :return: True if meets object requirements. """ file_name = name.lower() if not file_name.endswith('.ao'): return False return True @staticmethod def clean_path_str(txt, chr_lst): """ This method removes specific characters in a path. :param txt: The string to replace character. :param chr_lst: The characters list to be replaced. :return: Returns the path with removed c characters. """ for c in chr_lst: txt = txt.replace(c, '') return txt def read_lines(self, data_file): """ Iterates throught the data until finds the line with path for .c4d asset. :param data_file: The file data returned by Identify method. :return: The path string, not formatted. """ with open(data_file, 'rU') as data: ds_file = data.read().splitlines() paths = "" for line in ds_file: if ".c4d" in line: remove_chrs = self.clean_path_str(line, [')', '"']) paths += remove_chrs.replace("\\\\", "\\") return paths def Load(self, node, name, doc, filterflags, error, bt): """ Loads the data into the active document. In this case, we do not load or merge the file, but send a message to CoreMessage when it is catched with a SpecialEventAdd. The WorldContainer will save the path to be used later. :param node: BaseContainer for the instance. :param name: Path and file name of the instance. :param doc: The active document. :param filterflags: Flags to filter objects to load. :param error: Errors brought by Identify Method. :param bt: The BaseThread for the document. :return: Returns a c4d.FILEERROR_USERBREAK to capture the message. """ paths = self.read_lines(name) world_container = c4d.GetWorldContainerInstance() world_container.SetString(plugin_ID, paths) c4d.SpecialEventAdd(plugin_ID) return c4d.FILEERROR_USERBREAK if __name__ == "__main__": c4d.plugins.RegisterSceneLoaderPlugin(id=plugin_ID, str="AO Loader", g=AOLoader, info=c4d.PLUGINFLAG_SCENELOADER_MERGEORIGINAL, description="")
It's passing the data correctly, so perhaps the call needs to be done somewhere else?
Thank you in advance!
Hi, Unfortunately, I'm not able to reproduce your issue with the code you provided. The only difference is that I'm on windows 20H2. But I don't expect this to be the issue, I will ask someone else to try to reproduce.
Just to be sure If you copy-paste the code you provided us, does it freeze for you?
Cheers, Maxime.
@m_adam Morning Maxime,
Yes, it freezes with the code I provided. I've also tried the way that you mention above by running the c4d.SpecialEventAdd(1055684) and the same happens, as per my video below.
https://drive.google.com/file/d/1v4A9xXKb79Z1TlMnlSdZ-tk9WJFldsv7/view?usp=sharing
Let me know if you need any other information.
Thank you!
Hi @AndreAnjos, hi @m_adam,
@AndreAnjos said in ShowPopupDialog Freezes Cinema R21:
@m_adam Morning Maxime, Yes, it freezes with the code I provided. I've also tried the way that you mention above by running the c4d.SpecialEventAdd(1055684) and the same happens, as per my video below. https://drive.google.com/file/d/1v4A9xXKb79Z1TlMnlSdZ-tk9WJFldsv7/view?usp=sharing Let me know if you need any other information. Thank you! Andre
I just tried it too on R21.207 and it does not freeze for me either (I just added the message id as a print out, not knowing there was already that "finished" statement).
One thing you could do is to try to remove other plugins or scripts that are loaded by your Cinema 4D R21 installation, to make sure sure none of them is interfering with the plugin. When you have done this, you could also test, if opening a popup dialog in general, so something like this in the script manager,
import c4d def main(): """ """ MENU_ADD_ASSETS = c4d.FIRST_POPUP_ID MENU_ADD_MATERIALS = c4d.FIRST_POPUP_ID + 1 MENU_REPLACE_ASSETS = c4d.FIRST_POPUP_ID + 2 MENU_REPLACE_MATERIALS = c4d.FIRST_POPUP_ID + 3 MENU_REPLACE_TAG = c4d.FIRST_POPUP_ID + 4 menu = c4d.BaseContainer() menu.InsData(MENU_REPLACE_ASSETS, 'Replace Asset(s)') menu.InsData(MENU_REPLACE_MATERIALS, 'Replace Material(s)') menu.InsData(MENU_REPLACE_TAG, 'Replace Texture Tag(s)') result = c4d.gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS) if __name__ == '__main__': main()
will freeze your installation.
@ferdinand Hi Ferdinand,
Thank you for your tips!
Unfortunately removing the other plugins does not make a difference, from what I can understand.
I've also run the general popup dialog and it works fine with no freezing.
Not sure what to do about this except perhaps change the c4d.gui.ShowPopupDialog to a c4d.gui.GeDialog and create a simple menu. Any thoughts?
c4d.gui.GeDialog
well are you sure that ShowPopupDialog() is actually the culprit? Because it would be my last guess at the moment and in the end just replacing one buggy part with another feature is not really our understanding of good support here Since we cannot reproduce your problem, you have to do the debugging unfortunately yourself. What I would propose is:
ShowPopupDialog()
print
GetTimer()
AOMessage
CoreMessage()
active_mat= ...
result =
For each step you have to check if it did change anything about the freezing.
Your code in general is rather inconspicuous, so at least I cannot point anything out that would be the obvious culprit. The fact that you start and close an undo-block without using it is a bit weird, but should not freeze Cinema 4D. One rather far-fetched reason could be that you somehow corrupted the world-container of your installation permanently and now accessing it will freeze Cinema 4D. But then this should normally happen all the time, because Cinema 4D does access it all the time (and also in your SceneLoaderData plugin, since it does access the same part of the world container.
SceneLoaderData
So at least from my side this is all mostly speculation. The unfortunate truth of debugging is that you are always samerter after figuring it out
Many thanks for your valid points and I appreciate what you are saying :).
I've made the changes to use a GeDialog instead for the menu and it works.
GeDialog
Here's are my results, based on your proposals:
The undo-block is for something I wrote in between, but for simplification removed it to pinpoint the culprit.
The world-container is definitely a good point. I'm not sure if I should be using it to store data. I think the reasoning behind it was to keep data accessible between loading and unloading of documents, which is mainly what this plugin is doing. Would you recommend perhaps a different container to store the data?
What I found most weird is that works perfectly fine with R19, so perhaps as you pointed out on 2, Cinema needs reinstalling.
It's all learning and I think I know a bit more about it now and even if I cannot find the solution for this, I already have another way of dealing with it. Not elegant, but works with no issues :).
Thank you very much for your help and time!
@ferdinand I just found what perhaps is the issue...
The world-container. It seems that it runs without freezing if the data is not saved and load from the world container. Quiet odd, but perhaps as you said, it corrupted it somehow?
Just need to find a way to storing data outside of the document.
Thank you for your time and help! Will get it sorted with your pointers above.
All the best!