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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Making changes to the document through a websocket

    Cinema 4D SDK
    windows s24 c++
    2
    6
    392
    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.
    • C
      Cankar001
      last edited by

      Hi, I am currently working on a way, to trigger different actions through a websocket, for example triggering the undo/redo or to create a simple cube, I searched through the documentation a lot, and found the relevant functions, like creating a cube:

      BaseDocument* const document = GetActiveDocument();
      if (document == nullptr)
          return false;
      
      BaseObject* const cubeObject = BaseObject::Alloc(Ocube);
      if (cubeObject == nullptr)
          return false;
      
      cubeObject->SetName("This is a new object"_s);
      document->InsertObject(cubeObject, nullptr, nullptr);
      
      EventAdd();
      

      but I am not quite sure about the context of how to use them. For example I tried making a hidden CommandData plugin to create a simple cube when it is called, to also include the creation in the undo/redo system but if the plugin is hidden from the user, its Execute function obviously is never called. Similarily, I tried calling the

      BaseDocument *doc = GetActiveDocument();
      if (doc)
          doc->DoUndo(); 
      

      from within the websocket OnMessage function directly, this resultet in a breakpoint being hit inside the DoUndo() function. Probably caused by the networking layer being in a different thread than the main thread (I assume) and thus can not modify the BaseDocument in any way.

      How would a design look like, to trigger such actions from within a websocket? Any help would be greatly appreciated!

      1 Reply Last reply Reply Quote 0
      • C
        Cankar001
        last edited by

        I made some progress now, I changed the message type to be MessageData, to retrieve Core messages and in the websocket layer I now use SpecialEventAdd() with my own event ids, I see that the CoreMessage() method also supports the BaseContainer as a parameter, is it possible to fill it with custom data when calling SpecialEventAdd()? The function only seems to take two Uints as additional parameters, how would I get some custom data into my own CoreMessage method call?

        Thank you again! 🙂

        1 Reply Last reply Reply Quote 0
        • M
          m_adam
          last edited by m_adam

          Hi using MessageData is correct, however the best way is to call ExecuteOnMainThread as you can see in the websocket example I share with you here.

          This lambda will be executed on main thread, therefor it will be safe to create object and perform undo from it. One note make sure to pass a copy of the data to your lambda, since this lambda will be executed when the main thread is free and you do not know exactly when it can happen. And it can be latter than your OnMessage function, so with a copy you are sure that object are not nullptr.

          Cheers,
          Maxime.

          MAXON SDK Specialist

          Development Blog, MAXON Registered Developer

          C 1 Reply Last reply Reply Quote 0
          • C
            Cankar001 @m_adam
            last edited by

            @m_adam Thanks got it! One last unrelated question, how can I switch between world and object coordinates through my plugin? I know that I can switch the tool through

            BaseDocument *doc = GetActiveDocument();
            doc->SetAction(ID_MODELING_MOVE);
            

            But couldn't find any example for the coordinate space, that's the last feature set that I am missing for now 😄

            1 Reply Last reply Reply Quote 0
            • M
              m_adam
              last edited by

              Hi please open new topic for any new question that is not directly related to your initial question.

              If I understand correctly you want to toggle the Coordinate state, if that's the correct you can either use CallCommand(12156) # Coordinate System. You can find this number by opening the Script Log and if you click on the Coordinate System it will give you the Id. However CallCommand have the issue that it automatically add an Undo step, which can be an issue in some case.

              So the proper way would be to call:

              bool enableWorld = true;
              doc->SetParameter(CreateDescID(DOCUMENT_STATEW), enableWorld , DESCFLAGS_SET::NONE);
              

              How I found this, looking at the code internally, sadly it is no documented anywhere...
              If you have any other questions related to this topic, reply to this topic and I will move it to a new topic.

              Cheers,
              Maxime.

              MAXON SDK Specialist

              Development Blog, MAXON Registered Developer

              C 1 Reply Last reply Reply Quote 1
              • C
                Cankar001 @m_adam
                last edited by

                @m_adam Thank you very much for your help in the last days! This worked as well as expected 😄

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