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.
    • 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