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

    Use existing data for DynamicDescription

    Cinema 4D SDK
    c++ windows r21
    2
    3
    649
    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.
    • O
      Ogers
      last edited by

      Hello,
      I was checking on how to add a new tab in the attributes manager using DynamicDescription object but I could only do so if I create all the data by myself. Is there any way that I can do this but from the data that already exist.
      Example:
      I have a tree-view where you can add different shaders and what I need is that whenever a shader is selected I need to show the attributes of that shader (created in a res file) in the Attributes Manager. Is such a thing possible?
      Thank you.

      1 Reply Last reply Reply Quote 0
      • S
        s_bach
        last edited by

        Hello,

        typically, you can extend the UI of a NodeData based plugin by implementing GetDDescription(). This allows to add new groups and parameters to that element's parameter description.

        • NodeData::GetDDescription() Manual

        Within GetDDescription() you could access another object and use GetDescription() to load its description and copy it to your object's description.

        • Description Manual

        It is also possible to connect these newly created parameters to the original object. This way you can interact with these parameters and edit the original object. Such a connection is created by implementing TranslateDescID().

        This is a quickly thrown together example of a ObjectData plugin's GetDDescription() and TranslateDescID() that copies the parameters of the first object in the scene into its own parameter description:

        Bool GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags)
        {
          if (!description->LoadDescription(node->GetType())) return false;
        
          auto AddDescription = [](GeListNode *node, Description *description) -> maxon::Result<void>
          {
            BaseDocument* const doc = node->GetDocument();
            if(doc == nullptr)
              return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
        
            BaseObject* const firstObject = doc->GetFirstObject();
            if(firstObject == nullptr)
              return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
        
            // don't get description of yourself
            if(firstObject->IsInstanceOf(node->GetType()))
              return maxon::OK;
        
            // add dynamic group
            const DescID groupID = DescLevel(4000, DTYPE_GROUP, 0);
            BaseContainer settings = GetCustomDataTypeDefault(DTYPE_GROUP);
            settings.SetString(DESC_NAME, "Dynamic Group"_s);
            description->SetParameter(groupID, settings, 0);
        
            AutoAlloc<Description> sourceDescription;
            if(sourceDescription == nullptr)
              return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
        
            // get the Description of the given object
            if(!firstObject->GetDescription(sourceDescription, DESCFLAGS_DESC::NONE))
              return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
        
            void* handle = sourceDescription->BrowseInit();
            const BaseContainer* bc = nullptr;
            DescID id, gid;
        
            while (sourceDescription->GetNext(handle, &bc, id, gid))
            {
              // define new ID
              DescLevel topLevel = id[0];
              topLevel.id += 5000;
        
              DescID newID;
              newID.PushId(topLevel);
              
              const Int32 depth = id.GetDepth();
              for (Int32 i = 1; i < depth; ++i)
              {
                newID.PushId(id[i]);
              }
        
              // insert paramter into the dynamic group 
              description->SetParameter(newID, *bc, groupID);
            }
        
            sourceDescription->BrowseFree(handle);
            return maxon::OK;
          };
        
          iferr(AddDescription(node, description))
          {
            DiagnosticOutput("Error: @", err);
          }
        
          flags |= DESCFLAGS_DESC::LOADED;
        
          return SUPER::GetDDescription(node, description, flags);
        }
        
        Bool TranslateDescID(GeListNode *node, const DescID &id, DescID &res_id, C4DAtom *&res_at)
        {
          if (!node)
            return false;
        
          if (id[0].id >= 5000)
          {
            BaseDocument* const doc = node->GetDocument();
            if (doc != nullptr)
            {
              BaseObject* const firstObject = doc->GetFirstObject();
        
              if (firstObject != nullptr)
              {
                res_at = (C4DAtom*)firstObject;
        
                // define new ID
                DescLevel topLevel = id[0];
                topLevel.id -= 5000;
        
                DescID newID;
                newID.PushId(topLevel);
        
                const Int32 depth = id.GetDepth();
                for (Int32 i = 1; i < depth; ++i)
                {
                  newID.PushId(id[i]);
                }
        
                res_id = newID;
                return true;
              }
            }
          }
        
          return ObjectData::TranslateDescID(node, id, res_id, res_at);
        }
        

        best wishes,
        Sebastian

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 2
        • O
          Ogers
          last edited by

          Thanks @s_bach
          This is very helpful.
          Best wishes.

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