Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    id PluginMessage () when the scene loaded

    Cinema 4D SDK
    python sdk
    4
    12
    1.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      ac3
      last edited by ac3

      Hello!
      I need to find the Message ID when the scene has already loaded, so that after that I can run the plugin that will work with objects on the scene, it is important to make this plugin automatic, that is, without clicking on the button in the plugin gui. As it should be: Cinema4d started > Scene loaded > plugin started > plugin get objects > plugin work with objects. Please help, Google does not help

      1 Reply Last reply Reply Quote 0
      • C4DSC
        C4DS
        last edited by

        I don't think this will work for a Python plugin, but with C++ you can provide a SceneHook and use message MSG_DOCUMENTINFO_TYPE_LOAD

        A 1 Reply Last reply Reply Quote 1
        • A
          ac3 @C4DS
          last edited by

          @C4DS, Hi!
          it is very sad. I don't really want to rewrite the plugin from Python to C++ 😢

          1 Reply Last reply Reply Quote 0
          • A
            ac3
            last edited by

            @C4DS said in id PluginMessage () when the scene loaded:

            I don't think this will work for a Python plugin, but with C++ you can provide a SceneHook and use message MSG_DOCUMENTINFO_TYPE_LOAD

            Maybe there is another way to start the plugin automatically? Mb is not PluginMessage ()

            1 Reply Last reply Reply Quote 0
            • ManuelM
              Manuel
              last edited by Manuel

              hi,

              you can see in this thread that it's not possible with python.
              But maybe you can use another workflow. You can have another plugin asking for a directory, load every document on that directory, call your script that will work on the document, and close the document.

              You can only write the SceneHookData with c++ and that SceneHookData will call your python command so you don't need to rewrite it.

              Cheers,
              Manuel

              MAXON SDK Specialist

              MAXON Registered Developer

              A 2 Replies Last reply Reply Quote 0
              • A
                ac3 @Manuel
                last edited by ac3

                @m_magalhaes, Hi!
                Thanks for the answer, I will try this and answer later.

                1 Reply Last reply Reply Quote 0
                • A
                  ac3 @Manuel
                  last edited by

                  You can only write the SceneHookData with c++ and that SceneHookData will call your python command so you don't need to rewrite it.

                  Hi!
                  Do you have examples of a plugin written with SceneHookData? I am more proficient in python than c ++ 😢

                  1 Reply Last reply Reply Quote 0
                  • A
                    ac3
                    last edited by

                    @m_magalhaes, Hi, can you answer me? plz

                    1 Reply Last reply Reply Quote 0
                    • ferdinandF
                      ferdinand
                      last edited by

                      Hi,

                      if my memory does not betray me, MSG_DOCUMENTINFO is being broadcasted to all nodes in the scene. So if you want to stay in Python, you could simply hijack a node type. One promising candidate could be PreferenceData, although I cannot guarantee that Cinema will also send document notifications to these nodes, since they are not part of a scene.

                      Cheers,
                      zipit

                      MAXON SDK Specialist
                      developers.maxon.net

                      1 Reply Last reply Reply Quote -1
                      • ManuelM
                        Manuel
                        last edited by

                        hi,
                        Sorry for the delay.

                        we have this example.
                        The most important is ou c++ documentation

                        you can see an example in the BaseDocument Manual

                        
                        class pc12835_scenehook : public SceneHookData
                        {
                        public:
                        	static NodeData* Alloc() { return NewObjClear(pc12835_scenehook); }
                        	Bool Message(GeListNode* node, Int32 type, void* data) override
                        	{
                        		if (type == MSG_DOCUMENTINFO)
                        		{
                        			DocumentInfoData* const msg = static_cast<DocumentInfoData*>(data);
                        			if (msg == nullptr)
                        				return false;
                        			// switch message sub-type
                        			switch (msg->type)
                        			{
                        				case MSG_DOCUMENTINFO_TYPE_LOAD:
                        				{
                        					ApplicationOutput("document is loaded"_s);
                        					break;
                        				}
                        				case MSG_DOCUMENTINFO_TYPE_UNDO:
                        				case MSG_DOCUMENTINFO_TYPE_REDO:
                        				{
                        					ApplicationOutput("undo or redo done"_s);
                        					break;
                        				}
                        			}
                        			
                        			return true;
                        		}
                        		return SceneHookData::Message(node, type, data);
                        	};
                        
                        };
                        
                        

                        As @zipit said, the message is broadcast to all NodeData so using a PreferenceData.
                        We have an example on github but you don't need all that code.
                        After trying it myself, i couldn't make it work. It seems that the Message function is never called.

                        Cheers,
                        Manuel

                        MAXON SDK Specialist

                        MAXON Registered Developer

                        A 1 Reply Last reply Reply Quote 0
                        • A
                          ac3 @Manuel
                          last edited by

                          @m_magalhaes Hi, where in this code does the script start to run and call the python code? Or did I misunderstand something?

                          1 Reply Last reply Reply Quote 0
                          • ManuelM
                            Manuel
                            last edited by Manuel

                            hi,
                            sorry I was focused on calling a command and not a script.

                            Even if it's pretty simple, it's not as simple as i expected to run a python script, sorry about that.
                            Be careful that you need to create the script and relaunch c4d to be able to find it by its name.

                            The idea is to retrieve the ID of the script and use callCommand to execute it. (as you can do with any commandData IDs)
                            you can retrieve the ScriptList with GetScriptHead witch return a GeListHead

                            So you can retrieve the first with GetFirst and compare the name.
                            If you find one, you can simply return it's IDs using GetDynamicScriptID and return it.

                            You now just have to use CallCommand with this ID. (be aware that this CallCommand will create an undo step in the undo stack)

                            So your script will be executed when a new document is loaded.

                            #include "maxon/apibase.h"
                            #include "maxon/errorbase.h"
                            #include "maxon/errortypes.h"
                            #include "maxon/file_utilities.h"
                            #include "maxon/application.h"
                            
                            #include "c4d_general.h"
                            #include "c4d_commanddata.h"
                            #include "c4d_baseplugin.h"
                            #include "c4d_scenehookdata.h"
                            #include "c4d_baselist.h"
                            
                            static Int32 GetScriptID(const maxon::String& scriptName)
                            {
                            	iferr_scope;
                            	
                            	// check all script
                            	// Retrieves the script head
                            	BaseList2D* scriptHead = static_cast<BaseList2D*>(GetScriptHead(0)->GetFirst());
                            
                            	// for all script
                            	for (BaseList2D* script = scriptHead; script != nullptr; script = script->GetNext())
                            	{
                            		// retrieves the name of the script
                            		maxon::String name = script->GetName();
                            		// if the name match the argument, return the id of the script
                            		if (name.IsEqual(scriptName))
                            			return GetDynamicScriptID(script);
                            	}
                            
                            	// return NOTOK if no script founded.
                            	return NOTOK;
                            }
                            
                            class pc12835_scenehook : public SceneHookData
                            {
                            public:
                            	static NodeData* Alloc() { return NewObjClear(pc12835_scenehook); }
                            	Bool Message(GeListNode* node, Int32 type, void* data) override
                            	{
                            		if (type == MSG_DOCUMENTINFO)
                            		{
                            			DocumentInfoData* const msg = static_cast<DocumentInfoData*>(data);
                            			if (msg == nullptr)
                            				return false;
                            			// switch message sub-type
                            			switch (msg->type)
                            			{
                            				case MSG_DOCUMENTINFO_TYPE_LOAD:
                            				{
                            					// define my script name
                            					maxon::String scriptName = "myscript"_s;
                            					// search the ID of the scrip
                            					const Int32 scriptID = GetScriptID(scriptName);
                            					// if the script have been founded, execute it.
                            					if (scriptID != NOTOK)
                            						CallCommand(scriptID);
                            					break;
                            				}
                            				case MSG_DOCUMENTINFO_TYPE_UNDO:
                            				case MSG_DOCUMENTINFO_TYPE_REDO:
                            				{
                            					ApplicationOutput("undo or redo done"_s);
                            					break;
                            				}
                            			}
                            			
                            			return true;
                            		}
                            		return SceneHookData::Message(node, type, data);
                            	};
                            
                            };
                            
                            

                            Of course you need to register your sceneHookData with RegisterSceneHookPlugin

                            Cheers,
                            Manuel

                            MAXON SDK Specialist

                            MAXON Registered Developer

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post