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
    1. Maxon Developers Forum
    2. BruceC
    3. Posts
    B
    • Profile
    • Following 0
    • Followers 0
    • Topics 15
    • Posts 40
    • Best 0
    • Controversial 0
    • Groups 0

    Posts made by BruceC

    • RE: Button scaled unexpectedly when it is in the same row with an expanded linkbox

      Thanks for the reply @i_mazlov. Yeah, I already tried the workaround, it worked.

      posted in Cinema 4D SDK
      B
      BruceC
    • Button scaled unexpectedly when it is in the same row with an expanded linkbox

      I have a button and a linkbox placed in the same row, however I found the button is always scaled horizontally when the linkbox is expanded.
      Could you please help me find out how to stop the button being scaled horizontally?
      I have tried applying DESC_SCALEH to FALSE and DESC_FITH to TRUE, but it doesn't work after the linkbox is expanded.

      Before the linkbox is expanded, the button's width is expected.
      ce8c622f-59bb-47da-a5d3-c6bf25da6ffe-image.png
      After the linkbox is expanded, the button is scaled unexpected.
      6dd4884c-6b85-494b-b4eb-22395c2953cd-image.png

      I essentially used the below code snippet to create the button and linkbox in NodeData::GetDDescription()

      Int32 groupID = xxgroupIdxx;
      const DescID groupDescID = CreateDescID(DescLevel(groupID, DTYPE_GROUP, 0));
      {
          BaseContainer bc = GetCustomDataTypeDefault(DTYPE_GROUP);
          bc.SetInt32(DESC_COLUMNS, 2);
          bc.SetInt32(DESC_SCALEH, TRUE);
          description->SetParameter(groupDescID, bc, CreateDescID(DescLevel(AOV_COMP_PARAMS_GRP)));
      }
      
      {
          DescID id = CreateDescID(DescLevel(xxButtonIdxx, DTYPE_BUTTON, 0));
          BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);
          bc.SetString(DESC_NAME, "test"_s);
          bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
          bc.SetBool(DESC_SCALEH, FALSE);   //// <<<<<<<<<<<
          bc.SetBool(DESC_FITH, TRUE);      ////  <<<<<<<<<<<< I have tried using these two flags, but they don't help
          description->SetParameter(id, bc, groupDescID);
      }
      
      {
          const DescID id = CreateDescID(DescLevel(xxLinkIdxx, DTYPE_BASELISTLINK, 0));
          BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BASELISTLINK);
          bc.SetString(DESC_NAME, "test"_s);
          bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LINKBOX);
          bc.SetData(DESC_SCALEH, TRUE);
          bc.SetContainer(DESC_ACCEPT, accept);
          description->SetParameter(id, bc, groupDescID);
      }
      

      Thanks!

      posted in Cinema 4D SDK c++
      B
      BruceC
    • RE: Efficient way of saving array to BaseContainer

      Thank you @ferdinand for the help!

      Write raw memory does help a lot, appreciate!

      posted in Cinema 4D SDK
      B
      BruceC
    • Efficient way of saving array to BaseContainer

      Hi,
      could you please help me to find out the efficient way of saving/reading an array with a large size of vectors to BaseContainer?

      I could store/read each Vector in the array one by one as below, but when the size of the array is large, this method will cause performance issue.

      save()
      {
          maxon::BaseArray<Vector> arrayData;
          BaseContainer dataBC;
          Int dataCount = arrayData.GetCount();
          dataBC.SetInt32(XX_COUNT, dataCount);
          for (Int idx = 0; idx < dataCount; ++idx)
          {
              dataBC.SetVector(XX_ITEM + idx, positions[idx]);
          }
      }
      load()
      {
          maxon::BaseArray<Vector> arrayData;
          BaseContainer dataBC;
      
          Int dataCount = dataBC->GetInt32(XX_COUNT, 0);
          arrayData.resize(dataCount);
      
          for (Int32 idx = 0; idx < dataCount; ++idx)
          {
              arrayData[idx] = dataBC->GetVector(XX_ITEM + idx, Vector(0, 0, 0));
          }
      }
      
      

      Then I remember vertex color tag has a special way of reading the color data stored. So I think C4D supports an efficient way of save/loading large array data.
      I tried the below way by storing a raw memory chunk, but it doesn't work. It seems it only stores the memory address rather than the content of the memory address, and I suspect it will have serialize/deserialize problem when the scene file is opened in another platform (operating system).

      save()
      {
          maxon::BaseArray<Vector> arrayData;
          BaseContainer dataBC;
      
          Int dataCount = dataBC->GetInt32(XX_COUNT, 0);
      
          Vector* rawData = NewMem(Vector, arrayData.GetCount()) iferr_return;
          MemCopy((void*)rawData, (void*)arrayData.GetFirst(), Int(sizeof(Vector) * arrayData.GetCount()));
          GeData data(rawData, VOIDVALUE);
      
          dataBC.SetData(XX_ITEM, data);
      
          DeleteMem(rawData);
      }
      
      load()
      {
          maxon::BaseArray<Vector> arrayData;
          Int32 dataCount = dataBC->GetInt32(XX_COUNT, 0);
          arrayData.resize(dataCount);
      
          const GeData& data = dataBC->GetData(XX_ITEM);
          Vector* rawData = (Vector *)data.GetVoid();
          for (Int32 idx = 0; idx < dataCount; ++idx)
          {
              arrayData[idx] = rawData[idx];
          }
      }
      

      So could you please help me to find out the right efficient way of saving/reading an array with a large size of vectors to BaseContainer?

      Thank you very much!

      posted in Cinema 4D SDK r21 2025 linux macos windows
      B
      BruceC
    • RE: create link parameter accept Alembic tag

      @m_adam, Thank you!

      Yes, Message(GeListNode* node, Int32 type, void* data) works for me.

      I'm wondering shall my plugin just return true after processing MSG_DESCRIPTION_CHECKDRAGANDDROP in the Message() function (set the value of DescriptionCheckDragAndDrop::_result) or still call SUPER::Message(node, type, data); at the end?
      It looks to me that calling SUPER::Message(node, type, data); at the end still works.
      But the example in MSG_DESCRIPTION_CHECKDRAGANDDROP Message doesn't call SUPER::Message(node, type, data);.

      Thanks!

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: Read Alembic tag's data

      @m_adam, Thank you very much, this works for me!

      posted in Cinema 4D SDK
      B
      BruceC
    • create link parameter accept Alembic tag

      Hi,
      Could you please help me find out how to define the link parameter in res file which only accepts Alembic tag? (And the Alembic tag should also converted from a vertex color tag before the object was backed as Alembic)

      I'm developing a plugin, and there is a link parameter, previously, in the res file, I used this to make the parameter only accept a vertex color tag.

      LINK xxx { OPEN; ACCEPT { Tvertexcolor; } }
      

      I'd like to change this link to only accept an Alembic tag which is converted from a vertex color tag.
      I got the "the Alembic tag which is converted from a vertex color tag" by this:
      There is an object with a vertex color tag, then the object is baked as Alembic by using the "Bake as Alembic" menu item popped by right click on the object.
      Then the backed Alembic file is imported automatically, and the original vertex color tag will become an Alembic tag.

      I tried

      LINK xxx { OPEN; ACCEPT { Talembic; } }
      

      However, this somehow broke the res file, and made all other parameters disappear.

      LINK xxx { OPEN; ACCEPT { 1036433; } }
      

      By replacing Talembic with 1036433 (this is the value defined for Talembic in cinema.framework/source/ge_prepass.h), it does give me a link parameter accepts Alembic tags (I don't know why the Talembic doesn't work, but the actual number works here), but it doesn't limit to the Alembic tags converted from vertex color tags (i.e. all kinds of Alembic tags are accepted).

      Thanks!

      posted in Cinema 4D SDK r21 2025 c++
      B
      BruceC
    • Read Alembic tag's data

      Hi,
      Could you please help me find out how to read data from a Talembic tag?

      There is an object with a vertex color tag, then the object is baked as Alembic by using the "Bake as Alembic" menu item popped by right click on the object.
      Then the backed Alembic file is imported automatically. However, the original vertex color tag becomes an Alembic tag.

      Can you please help me find out how to read the vertex color data from the new Alembic tag?
      Thank you very much!

      posted in Cinema 4D SDK r21 2025 c++
      B
      BruceC
    • RE: how to get vertex color tag's data for a specific frame (different with current frame) without modifying current document?

      Thank you very much for all your detailed explanation, @ferdinand!

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: how to get vertex color tag's data for a specific frame (different with current frame) without modifying current document?

      Thank you, @ferdinand.
      No worries at all, I know you must be very busy, just take your time. I appreciate all the help!
      Cheers!

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: how to get vertex color tag's data for a specific frame (different with current frame) without modifying current document?

      The most common "pro" solution to that is caching. E.g., that you write yourself a vertex color cache in your case.

      I'm wondering the example you mentioned here, do you mean create a hidden vertex color tag to cache the data?

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: how to get vertex color tag's data for a specific frame (different with current frame) without modifying current document?

      Thanks for your reply, @ferdinand

      Never user pointers to long term keep track of scene elements. Something not being nullptr does not mean you point to valid data. The node you point to could be long deleted, and then you point to garbage and access attempts will then result in access violations and a crash. Either use a BaseLink to store a reference to a scene element, or use a weak pointer. I.e., a pointer which becomes invalid when the pointed data is being deleted. You can for example see here how to use a maxon::WeakRawPtr.

      True, I didn't really use the pointer to long term keep track of the linked vertex color tag. Although the plugin remembers the vertex color tag's pointer, but it's just used to compare if the vertex tag link parameter changes. i.e. before reading data from the vertex color tag, the plugin always read the vertex color tag link parameter.

      The solution to this can be registering a plugin ID, e.g., ID_FOO_PLUGIN_IS_COMPUTE_PASS. When you then clone your document, or execute the passes on an existing document, you write under that ID for example a bool into the data container of the document. Your tags Execute(tag, ...) then gets the document from tag and checks for that flag being present, to stop what it does that causes the infinite update loop.

      Thank you very much, this works! Glad to learn this trick!

      You can of course also jump to a previous point, but then you do not have to sim from NOW to FUTURE but from 0 to PREVIOUS

      Thanks!

      The most common "pro" solution to that is caching.

      Yes, the linked vertex color tag's data is cached to avoid reading its data again and again as long as the vertex color tag doesn't change.

      And for the question 3) I asked in the previous reply. I found after I use the trick to avoid infinite update loop, the problem is gone, owner of the cloned object is an instance of Opoint again. Do you know what the reason could be?

      Thank you!

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: how to get vertex color tag's data for a specific frame (different with current frame) without modifying current document?

      Thank you for the reply, @ferdinand,

      1. Thanks for the PrerollToTime() function! I didn't know that I need to ExecutePasses() for each frame until the lastFrame.

        I'm writing a tag plugin that has a parameter which is a link to an existing vertex color tag, and a parameter to allow user specify a frame number. These two parameters work together, so the plugin will get the data from the vertex color tag at the specific frame, and use the data to do the rendering across all frames.

        • 1.1 Because the tag plugin depends the linked vertex color tag, so whenever there is a change in the vertex color tag, the plugin needs to update its internal data based on the updated vertex color tag. Currently, I do this in the tag plugin's Execute() function. The tag plugin remembers the vertex color tag's pointer (initialized as nullptr) and dirty checksum (by C4DAtom::GetDirty(), and initialized as 0). So Execute() checks if the vertex color tag read from the link parameter changes or the vertex color tag's dirty checksum changes, if it changes, the vertex color tag's data at the specified frame will be read again.

          However, I found ExecutePasses() called in PrerollToTime() triggers the tag plugin's Execute() function (I think this is the cloned tag in the cloned document), and Execute() function tries to read the linked vertex color tag at the speficied frame again, so PrerollToTime() -> ExecutePasses() is called again, and triggers a new cloned tag in a new cloned document to run its Execute(), and so on.

          This makes me wonder if I'm not using the correct way to check if the linked vertex color tag's change. Could you please help find out what's C4D's recommended way to handle such case?

        • 1.2 According to the sample code PrerollToTime(), the lastFrame (the target frame) must not be earlier than the current scene's time. This means if the scene's current time is later than the frame number (say, user slides the timeline to frame 10, but the frame number parameter is set to 5), there will be no way to get the desired data from the vertex color tag, right? How does C4d handle this kind of situation? Or there is no such situation at all in native C4d?

      2. To get the same tag from the cloned scene, I could use code like below, but I am wondering if there is an existing API to do this, as I think this is a basic need.

      BaseObject* getObjectByMarker(const BaseDocument& doc, const GeMarker& objMarker, BaseObject* start = nullptr)
      {
          for (BaseObject* obj = start ? start : doc.GetFirstObject(); obj != nullptr; obj = obj->GetNext())
          {
              if (obj->GetMarker().IsEqual(objMarker))
              {
                  return obj;
              }
              else
              {
                  // check children
                  BaseObject* childObj = obj->GetDown();
                  if (childObj)
                  {
                      BaseObject* found = getObjectByMarker(doc, objMarker, childObj);
                      if (found)
                      {
                          return found;
                      }
                  }
              }
          }
          return nullptr;
      }
      
      BaseTag* getTagByMarker(const BaseDocument& doc, const GeMarker& objMarker, const GeMarker& tagMarker)
      {
          BaseObject* obj = getObjectByMarker(doc, objMarker);
          if (obj)
          {
              for (BaseTag* tag = obj->GetFirstTag(); tag; tag = tag->GetNext())
              {
                  if (tag->GetMarker().IsEqual(tagMarker))
                  {
                      return tag;
                  }
              }
          }
          return nullptr;
      }
      
      1. I found I cannot read the cloned vertex color tag's data from the cloned document, because the owner of the cloned object is not an instance of Opoint.
        According to the document, to read data from vertex color tag, I need to get the point count of the polyObject who owns the vertex color tag.

        To do that, the BaseObject returned from BaseTag::GetObject() will need to be converted to PointObject, then PointObject::GetPointCount() will be used to to get the point count.
        However, I found if the tag is from a cloned document, the BaseObject returned from BaseTag::GetObject() is not an instance of Opoint, so it cannot be converted to PointObject.

        I can confirm that the BaseObject got from the original tag in the original document can be converted to PointObject.

        I try to use the object from the cloned document, because I think the point count might change in a different frame. (The cloned document is at a different time)

        BTW, the cloned document is created by doc->GetClone(COPYFLAGS::PRIVATE_IDENTMARKER, nullptr).

      Sorry for the long list, please let me know if I need to split above questions to different topics.
      Now, all these questions above make me wonder if the usage is designed appropriately.
      Maybe from C4D design's point of view, it is not a proper design to let user specify the time (different with the current frame, and even can be a earlier frame) when the tag's data should be used to render all frames?

      Thank you!

      posted in Cinema 4D SDK
      B
      BruceC
    • how to get vertex color tag's data for a specific frame (different with current frame) without modifying current document?

      Hi,
      could you please help me find the recommended way to read vertex color tag's color data at a specific frame (different with current frame) without modifying current document?
      I think I should use BaseDocument::GetClone() and change the cloned document's time. However, I didn't find a good way to get the same vertex color tag and the object it belongs from the cloned document.
      Could you please give me a help on this?
      Thank you!

      posted in Cinema 4D SDK c++ r21 2025 windows macos
      B
      BruceC
    • RE: color space of MODATA_COLOR

      Thank you very much for following up with this, @ferdinand.
      At the moment, we are fairly confident about the way of fixing this issue after all the above discussion.
      But I'll reach out with a bug report (even though I don't think this is C4D bug) for further information.

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: color space of MODATA_COLOR

      Thanks, @ferdinand

      1. I think it's easier to reproduce this problem with C4D 2024 (say 2024.5.1).
      2. I don't think this is a bug with C4D. It's a problem with our plugin about how to use C4D MODATA_COLOR from the effector field for Multi Shader in our Render Engine. The viewport always has the expected correct result, it's our plugin who doesn't produce the expected result.

      With more and more thinking and testing, I began to believe that in the scene attached the MODATA_COLOR from the effector field is used to find which texture defined in the Multi Shader should be applied to each cloned instance. (so the MODATA_COLOR values are more like texture indexes). So the MODATA_COLOR values are not really used as colors in the viewport, and shouldn't be treated as gamma-corrected values regardless of the scene's color space.

      If my above understanding is correct, I think our plugin just need to treat the MODATA_COLOR values in this particular case the same way as C4D viewport. Currently, our plugin convert the MODATA_COLOR values from linear to srgb based on the scene's color space, which I think is incorrect, because I think the MODATA_COLOR values are not real colors in this case.

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: color space of MODATA_COLOR

      Thank you very much, @ferdinand
      Yeah, in the video you attached, it looks to me that Linear workflow doesn't affect the final render result.

      I have got the approval to attach this simple test scene that demonstrates the problem I'm experiencing. The setting is a bit different with your scene.

      The scene attached uses Multi Shader. My understanding is that the MODATA_COLOR from the effector field is used to find which texture defined in the Multi Shader should be applied to each cloned instance. (so the MODATA_COLOR values are more like texture indexes). So the MODATA_COLOR values are not really used as colors in the viewport, and shouldn't be treated as gamma-corrected values regardless of the scene's color space.
      Please let me know if my understanding is correct. Thanks again!

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: color space of MODATA_COLOR

      Hi @ferdinand, thanks for all you help.
      I think a cloner's MODATA_COLOR should be interpreted if the cloner uses Multi Shader. Is my understanding correct?

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: color space of MODATA_COLOR

      Thank you very much, @ferdinand

      I think I start understanding it now.

      The MODATA_COLOR values existing in the scene won't get changed by the scene's color space settings, instead, they could be interpreted differently when scene's color space setting changes.

      In the scene I'm testing, the MODATA_COLOR comes from a Linear Field (doesn't necessarily be Linear Filed, it could be other Filed types, like Box Filed, Capsule Filed) of Plain effector's Fields setting. The MODATA_COLOR values are not real colors, they are used to find the texture for each instance from a Multi Shader's setting.
      So I think in this case, it could be safely assume the data is linear values?
      If this is true, is there is a way to find if a MODATA_COLOR from a Field? So I can make sure MODATA_COLOR from Field are treated as linear values.

      Thanks!

      posted in Cinema 4D SDK
      B
      BruceC
    • RE: color space of MODATA_COLOR

      Hi @ferdinand. Thank you very much for the detailed explanation.

      Let me try to answer your questions first.

      What is that 'customized texture object' concretely? I assume the texture node in the material/shader system of your render engine?

      yes, that's true.

      What leads you to the assumption that your colors are wrong?
      How are you writing the data into the texture, and how is your render engine interpreting its input space?

      The colors are used as input texture for a gradient map node in our render engine. So the color is not directly used for a object's color.
      The final rendered image from our render engine should match C4D viewport, so that's how I tell if the result is correct.

      In R2024, I always found "The Application uses Linear Space for Calculations."

      Sorry, as you said this is not true. If I untick "Linear Workflow" checkbox, I will actuall see "The Application uses sRGB Space for Calculations."

      I thought MODATA_COLOR is in computational color space which is controlled by the settings in Scene Settings -> Project -> COLOR MANAGEMENT, that's why I thought I can get the MODATA_COLOR's color space by an API.
      However, the colors values I got from MODATA_COLOR remain the same no matter if "Linear Workflow" checkbox is ticked or not.
      So this means my thought was wrong, otherwise the values of MODATA_COLOR will change if I ticke/untick the "Linear Workflow" checkbox.

      Does this mean that MODATA_COLOR's value won't be affected by any scene level color space settings?

      It seems the color I got from MODATA_COLOR is always linear no matter if "Linear Workflow" checkbox is ticked.
      No matter if "Linear Workflow" checkbox is ticked I can get the expected result in below two ways:

      • If I set the image buffer of our render engine's texture node directly use the MODATA_COLOR's color values, and set the texture node's color space as linear srgb, then I will have the same image as the viewport.
      • I can also call BasicTransformColor() with COLORSPACETRANSFORMATION::LINEAR_TO_SRGB before setting the image buffer, and also set the texture node's color space as srgb, then I will also have the same image as the viewport.

      Although the two way work, I'm not sure if some settings can change the MODATA_COLOR's values I get, so I asked the original question.

      posted in Cinema 4D SDK
      B
      BruceC