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
    1. Maxon Developers Forum
    2. Cankar001
    3. Posts
    C
    • Profile
    • Following 0
    • Followers 0
    • Topics 5
    • Posts 21
    • Best 2
    • Controversial 0
    • Groups 0

    Posts made by Cankar001

    • RE: Retrieve the current Unit and listen to changes

      Hi @ferdinand,
      thank you very much for your detailed answer! It helped me a lot understanding the unit system better, I have now written 2 functions, that retrieve the current set unit of the document, which are then used to A) display the current unit in the viewport and B) to scale the distances based on the unit scale:

      static maxon::String GetCurrentSelectedUnit(const BaseDocument* document)
      {
      	if (!document)
      		return ""_s;
      
      	const UnitScaleData* unitScale = document->GetDataInstanceRef().GetCustomDataType<UnitScaleData>(DOCUMENT_DOCUNIT);
      	return unitScale->ToUnitString();
      }
      
      static Float GetCurrentUnitScale(const BaseDocument* document)
      {
      	if (!document)
      	{
      		ApplicationOutput("Failed to retrieve the current document.");
      		return 1.0f;
      	}
      
      	const UnitScaleData* unitScale = document->GetDataInstanceRef().GetCustomDataType<UnitScaleData>(DOCUMENT_DOCUNIT);
      	if (unitScale)
      	{
      		Float currentScale = 1.0f;
      		DOCUMENT_UNIT currentUnit = DOCUMENT_UNIT::UNDEFINED;
      		if (!unitScale->GetUnitScale(currentScale, currentUnit))
      		{
      			ApplicationOutput("Failed to retrieve the current unit multiplier.");
      			return 1.0f;
      		}
      
      		if (currentUnit == DOCUMENT_UNIT::UNDEFINED)
      		{
      			ApplicationOutput("Failed to extract the current set unit.");
      			return 1.0f;
      		}
      
      		return currentScale;
      	}
      
      	ApplicationOutput("Failed to retrieve the current unit scale.");
      	return 1.0f;
      }
      

      Those two functions seem to behave as expected now and the text changes, when the project scale is changed and also when changing the scalar value, the distance gets scaled properly. Thank you a lot for the video as well, it helped a lot to see the actual values change live 😄

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Retrieve the current Unit and listen to changes

      @m_adam Thanks for your quick reply! I wrote a more detailed mail to the mail address you provided 😄

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Retrieve the current Unit and listen to changes

      @m_adam Thanks for the clarification! What I am trying to achieve is that the whole units for the user get changed. When I change the display setting manually, all the units in the UI also change and the values get re-calculated for the selected unit. My high level goal is, that my plugin also should do these re-calculations, once the user changes the unit in the settings, because right now my plugin would show the wrong values, when the unit gets changed from the default unit. So yes I would need to listen to the display unit I think, because the calculations should be done when the user wanted the units to change

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Retrieve the current Unit and listen to changes

      @m_adam And how exactly would I retrieve and change the unit itself? I tried it this way:

      Bool UnitChangeDetector::CoreMessage(Int32 id, const BaseContainer& bc)
      {
      	if (id == EVMSG_CHANGE)
      	{
      		BaseDocument* doc = GetActiveDocument();
      		if (!doc)
      		{
      			ApplicationOutput("Failed to get active document!");
      			return true;
      		}
      
      		BaseContainer data = doc->GetData(DOCUMENTSETTINGS::GENERAL);
      		data.SetInt32(DOCUMENT_DOCUNIT, (Int32)DOCUMENT_UNIT::KM);
      		doc->SetData(DOCUMENTSETTINGS::GENERAL, data);
      	}
      
      	return true;
      }
      

      (Only for testing of course, the final version would not look like this)

      But when I check the settings in Edit > Program Settings > Units > Display it still says Centimeters instead of the expected kilometers.

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Retrieve the current Unit and listen to changes

      Hi Maxime, I don't have any UI in my plugin, as the control flow is controlled pureley over a websocket. The plugin calculates some data, when the command is received over the websocket and displays some debug ui in the rendering viewport (basic line rendering), but that's about it so I don't have any plugin setting or UI panel. Is it possible to get notified by a core message about the unit change?

      posted in Cinema 4D SDK
      C
      Cankar001
    • Retrieve the current Unit and listen to changes

      Hello, I need a way to retrieve not only the current unit of the editor and the world matrices, but also to get notified in my plugin, when the user changes the unit in the settings window, because then I will also need to re-calculate the data generated by my plugin to fit the new unit. Is there a way to subscribe to those type of changes, or would I have to write a more complex system to always stay up-to-date with the latest unit settings?
      The default unit of the editor should be centimeters I believe, but most use cases of my plugin would probably be millimeters, or even nanometers sometimes.

      Thanks for any help!

      posted in Cinema 4D SDK c++ s24
      C
      Cankar001
    • RE: Making changes to the document through a websocket

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

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Making changes to the document through a websocket

      @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 😄

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Making changes to the document through a websocket

      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! 🙂

      posted in Cinema 4D SDK
      C
      Cankar001
    • Making changes to the document through a websocket

      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!

      posted in Cinema 4D SDK windows s24 c++
      C
      Cankar001
    • RE: WebSocket usage in C++

      Hi @m_adam, following your typescript example it worked now to connect! Thank you very much for your help 🙂

      Merry Christmas and a Happy New Year!

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: WebSocket usage in C++

      Hi @m_adam,

      thank you again for the code suggestions, I got it compiling and running now, but now I do have a runtime failure, I am trying to test the websocket connection with postman, and I get a 500 error, the logs of Cinema 4D say this:

      <net.maxon.datatype.internedid> net.maxon.http.type : <uint32> 1
      <net.maxon.datatype.internedid> net.maxon.http.file : <net.maxon.interface.string-C> index.html
      <net.maxon.interface.string-C> sec-websocket-extensions : <net.maxon.interface.string-C> permessage-deflate; client_max_window_bits
      <net.maxon.interface.string-C> sec-websocket-version : <net.maxon.interface.string-C> 13
      <net.maxon.interface.string-C> sec-websocket-key : <net.maxon.interface.string-C> j+y86BlBpKXcFzGDp/BOXg==
      <net.maxon.interface.string-C> host : <net.maxon.interface.string-C> localhost:19923
      <net.maxon.datatype.internedid> net.maxon.http.connection : <net.maxon.interface.string-C> Upgrade
      <net.maxon.interface.string-C> upgrade : <net.maxon.interface.string-C> websocket
      protocol not found
      Connection: Stopped with error httpcode [network_websocket_base_impl.cpp(556)] 
        Cause: websocket protocol not found [network_websocket_base_impl.cpp(646)].
      httpcode [network_websocket_base_impl.cpp(556)] 
        Cause: websocket protocol not found [network_websocket_base_impl.cpp(646)]
      

      This is my current websocket implementation:

      	WebSocket::WebSocket(int port)
      		: mPort(port)
      	{
      	}
      
      	WebSocket::~WebSocket()
      	{
      		maxon::Result<void> res = mWebSocketServer.StopWebServer();
      		if (res.GetErrorPointer() != nullptr)
      		{
      			ApplicationOutput("Failed to shutdown the websocket!");
      		}
      	}
      
      	maxon::Result<void> WebSocket::Start()
      	{
      		iferr_scope;
      
      		maxon::NetworkIpAddrPort addr(127, 0, 0, 1, mPort);
      		mWebSocketServer = maxon::NetworkWebSocketServerClass().Create() iferr_return;
      
      		WebSocket* instance = this;
      		mWebSocketServer.ObservableConnected(true).AddObserver(
      			[instance](const maxon::NetworkWebSocketConnectionRef& webSocket, const maxon::DataDictionary& request) -> maxon::Result<void>
      			{
      				return instance->OnConnected(webSocket, request);
      			}) iferr_return;
      
      		mWebSocketServer.ObservableDisconnected(true).AddObserver(
      			[instance](const maxon::NetworkWebSocketConnectionRef& webSocket) -> void
      			{
      				instance->OnDisconnected(webSocket);
      			}) iferr_return;
      
      		mWebSocketServer.ObservableHandshake(true).AddObserver(
      			[instance](const maxon::NetworkWebSocketConnectionRef& webSocket, const maxon::DataDictionary& request) -> maxon::Result<String>
      			{
      				return instance->OnHandShake(webSocket, request);
      			}) iferr_return;
      
      		mWebSocketServer.ObservableMessage(true).AddObserver(
      			[instance](const maxon::NetworkWebSocketConnectionRef& webSocket, maxon::WEBSOCKET_OPCODE opCode, const maxon::BaseArray<Char>& data) -> maxon::Result<void>
      			{
      				return instance->OnMessage(webSocket, opCode, data);
      			}) iferr_return;
      
      		mWebSocketServer.StartWebServer(addr, false, "<tried different values here but no change>"_s) iferr_return;
      
      		return maxon::OK;
      	}
      
      	maxon::Result<void> WebSocket::OnConnected(const maxon::NetworkWebSocketConnectionRef& webSocket, const maxon::DataDictionary& request)
      	{
      		iferr_scope;
      
      		return maxon::OK;
      	}
      
      	void WebSocket::OnDisconnected(const maxon::NetworkWebSocketConnectionRef& webSocket)
      	{
      		iferr_scope_handler
      		{
      			return;
      		};
      	}
      
      	maxon::Result<String> WebSocket::OnHandShake(const maxon::NetworkWebSocketConnectionRef& webSocket, const maxon::DataDictionary& request)
      	{
      		iferr_scope;
      		return ""_s;
      	}
      
      	maxon::Result<void> WebSocket::OnMessage(const maxon::NetworkWebSocketConnectionRef& webSocket, maxon::WEBSOCKET_OPCODE opCode, const maxon::BaseArray<Char>& data)
      	{
      		iferr_scope;
      
      		return maxon::OK;
      	}
      

      Do you know, what could cause this error? Thank you very much for your help already!

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: WebSocket usage in C++

      Thank you so much @m_adam! I will take a deeper look into it and come back if I have any questions, also very good to see that there is a json parser as well already, as I was also planning to send json strings over the web socket 🙂

      posted in Cinema 4D SDK
      C
      Cankar001
    • WebSocket usage in C++

      Hi, i've spent quite some time now, setting up a websocket server in my plugin. The documentation unfortunately doesn't have many usage examples of the network.framework. Here is my current code that should setup and start the websocket correctly:
      Unbenannt.PNG
      The instance of this class is global in the plugin main file and gets deleted when the

      PluginEnd
      

      function is called. The problem that I currently have is this line:

      mWebSocketServer.ObservableConnected(true).AddObserver(
          [](const maxon::NetworkWebSocketConnectionRef& webSocket, const maxon::DataDictionary& request) -> maxon::Result<void>
          {
              return maxon::OK;
          }, nullptr);
      

      This code does not compile, as the lambda can not be converted to maxon::ObserverObjectInterface*. But the docs here: https://developers.maxon.net/docs/cpp/2025_1_0/page_maxonapi_observers_usage.html state that Observers can take in lambdas and according to the header file the parameters of the lambda should be correct?

      About some hints into the right direction I would be very happy 🙂

      posted in Cinema 4D SDK c++ windows macos s24
      C
      Cankar001
    • RE: Error compiling S24 plugin

      @ferdinand Thank you very much! I rewrote my code to your example provided, and now it works. I had another issue, where I tried to set the rendering config data right in the PluginStart method, but to that time no renderer interface seemed to be running already, so I moved this dependent code to another thread, that tries to retrieve the renderer instance from the hashmap and waits every time, when it failed to retrieve the instance and sets the data if it succeeded. This workflow seems to work very good now, the config data is always provided and now I have the ability to decide in the PluginStart() function already, which debug rendering features I want to enable 🙂

      I only didn't understand, why the initial errors occurred, as I didn't include any typeinfo header directly (maybe caused by another std header then). But moving the code away from std seemed to help with that too.

      posted in General Talk
      C
      Cankar001
    • Error compiling S24 plugin

      Hello,

      I have worked for some weeks now on my plugin for the S24 version, but suddenly I got some compile errors, pointing to the platform toolset of visual studio. Has this happened to someone else as well? I am using VS2022, but the generator for S24 generated a VS2019 solution (or at least the projects are using the platform toolset of VS2019). Is this a known issue and does someone have a quick fix for this? 🙂
      This is the error message I am getting:

      1>main.cpp
      1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(39,18): error C3668: "std::bad_cast::_Doraise": Die Methode mit dem Überschreibungsspezifizierer "override" hat keine Basisklassenmethoden überschrieben. (Quelldatei wird kompiliert ..\source\SomeClass.cpp)
      1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(40,9): error C3861: "_RAISE": Bezeichner wurde nicht gefunden. (Quelldatei wird kompiliert ..\source\SomeClass.cpp)
      1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(51,18): error C3668: "std::bad_typeid::_Doraise": Die Methode mit dem Überschreibungsspezifizierer "override" hat keine Basisklassenmethoden überschrieben. (Quelldatei wird kompiliert ..\source\SomeClass.cpp)
      1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(52,9): error C3861: "_RAISE": Bezeichner wurde nicht gefunden. (Quelldatei wird kompiliert ..\source\SomeClass.cpp)
      

      The class SomeClass looks like this:

      #pragma once
      
      #include <unordered_map>
      
      class DebugRenderer;
      
      class SomeClass
      {
      public:
      
      	static SomeClass *GetInstance();
      
      	void RegisterDebugRenderer(int inCommandId, DebugRenderer *inRenderer);
      	void UnregisterDebugRenderer(int inCommandId, DebugRenderer *inRenderer);
      	DebugRenderer *FindDebugRenderer(int inCommandId);
      
      private:
      
      	std::unordered_map<int, DebugRenderer*> mDebugRenderers;
      };
      
      

      The class DebugRenderer registers itself in this singleton when being constructed and unregisters when its destructor is called.

      Thank you for your time!

      All the best,
      Can

      Edit: I just tried out to remove the source files for SomeClass.h and SomeClass.cpp from the project and comment out every usage, then everything compiles successfully again. I added the files normally into the source directory and re-generated the project solution after that, so that it shows up inside visual studio and wrote the code normally inside VS. So I am not sure why this doesn't compile, any guidance would be greatly appreciated!

      posted in General Talk s24 windows macos c++
      C
      Cankar001
    • RE: Rendering debug UI in the viewport via plugin

      @ferdinand Thank you very much! I got the min and max distances also working with your input! I used the code example from the docs to traverse through the DeformCache and it worked instantly 🙂

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Rendering debug UI in the viewport via plugin

      Hi @ferdinand,

      thank you, I managed to get it working!
      cubes.jpg
      This is what I tried to achieve, basically showing the distances between the objects.

      I still have one question, is it also possible to extract the submeshes of a mesh? The next feature I wanted to implement is to also show the min and max distances between the objects and for that I wanted to extract the submesh data, from which I could calculate the distance more precisely than from the object transform. Basically I want to be able to calculate the distance between objects from any location on the surface. How would I retrieve the surface data?

      I tried doing something like this:

                     // current and next are two BaseObject*
      		if (current->IsInstanceOf(Opolygon) && next->IsInstanceOf(Opolygon))
      		{
      			PolygonObject *currentPolygon = static_cast<PolygonObject*>(current);
      			PolygonObject *nextPolygon = static_cast<PolygonObject*>(next);
      
      		}
      

      But this doesn't seem to work if I test it with cubes, is there any other conversion function maybe that lets me extract the mesh surface data? Maybe extracting the faces of the object would already work for my purpose.

      Thank you again!

      Cheers,
      Can

      posted in Cinema 4D SDK
      C
      Cankar001
    • RE: Rendering debug UI in the viewport via plugin

      Hi @ferdinand,

      thank you for your detailed explanation! The first debug feature I planned is to draw lines between 3D objects, I think this use case then should work with the scene hooks draw method. But isn't there any other Draw method, that gets called per-frame? It seems a bit unnatural to me, that something basic like this seems to be missing. I come from a game engine background, so methods called per frame were always the first thing to implement 🙂

      About the second question I had, is it possible to activate the plugin right after startup and draw the debug lines right away, without requiring the user to enable the plugin?

      Thank you for your time and efforts!

      Cheers,
      Can

      posted in Cinema 4D SDK
      C
      Cankar001