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

    Add values for enum data type (node graph)

    Cinema 4D SDK
    c++ r25
    3
    9
    1.2k
    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 am trying to create an enum data type with some values (options) added but I can't get the options added to this data type.

      When setting DESCRIPTION::DATA::BASE::ENUM it requires an maxon::Array<Tuple<Id, Data>> as a value type, but even if I create a variable of that type and add some values, its size does not change and stays 0.

      I also tried using BlockToEnumArray() but that would return an BaseArray<Tuple<Id, Data>> which is not accepted in DESCRIPTION::DATA::BASE::ENUM although the comments in the function say it does.

      //----------------------------------------------------------------------------------------
      /// Converts a given Block<TYPE> to a enum list array to use with DESCRIPTION::DATA::BASE::ENUM.
      /// @param[in] enumBlock					Block to convert into a array.
      /// @return												BaseArray on success.
      //----------------------------------------------------------------------------------------
      template <typename TYPE> inline Result<BaseArray<Tuple<Id, Data>>> BlockToEnumArray(const Block<TYPE>& enumBlock)
      

      Also converting BaseArray<Type> to Array<Type> did not work.
      I'm not sure what I am doing wrong.

      Thank you.

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @Ogers
        last edited by ferdinand

        Hey @ogers,

        Thank you for reaching out to us. I think I understand what you are talking about, but just to be sure, when you say:

        I am trying to create an enum data type with some values (options) added but I can't get the options added to this data type.

        Because the word create is ambiguous, this could be interpreted as you wanting to implement some form of maxon::DataType, i.e., what is more or less a struct in canonical C++. But you want to just instantiate some form of maxon::BaseCollection to be used in the field maxon::DESCRIPTION::DATA::BASE::ENUM of a maxon::DataDictionary, right?

        maxon::Array is a type template of datadictionary.h, I never really understood myself why it is there or what it is good for since it does not really do anything. But it is used in many fields of data dictionaries and can be written with some common collection types we have, e.g., BaseArray.

        The field maxon::DESCRIPTION::DATA::BASE::ENUM must be written as a maxon::BaseArray<maxon::Tuple<maxon::Id, maxon::Data>> instance. But it also requires that BaseArray to be built by the function maxon::BlockToEnumArray() as the function formats the BaseArray in a distinct way. Here is some obfuscated code how we write that field internally:

        static const maxon::Block<maxon::Id> GetStuff()
        {
            static maxon::Id stuff[] = {maxon::Id("A"), maxon::Id("B"), maxon::Id("C")};
            return maxon::ToBlock(stuff)
        }
        
        ...
        
        maxon::BaseArray<maxon::Tuple<maxon::Id, maxon::Data>> data = maxon::BlockToEnumArray(GetStuff()) iferr_return;
        someDataDictionary.Set(maxon::DESCRIPTION::DATA::BASE::ENUM, std::move(data)) iferr_return;
        

        I could go into details here, but I think we use this weird form with the function GetStuff() intentionally due to constness requirements of the block, as you are otherwise unable to define a const block with non const elements which is not empty.

        If you run still into problems, I would ask you to provide more code and context for what you are doing and the exact compiler errors you run into.

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

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

          Hello @ferdinand
          Thank you for your reply. Yes, your assumption is right, sorry to confuse you.
          I forgot to mention that I am getting this error when setting the values when using Set function from documentation

          template <typename ATTR> Result<void> Set(const Id& category, const ATTR& attr, const typename ATTR::ValueType& value)
           {
           // Retrieve the category"s and add an attribute.
           iferr_scope;
           DataDictionary& dict = GetPortDictionary(category) iferr_return;
           dict.Set(attr, value) iferr_return;
           return OK;
           }
          
          1 Reply Last reply Reply Quote 0
          • O
            Ogers
            last edited by

            For some reason, I can't even post my full reply here. I thought the system was down yesterday that's why I could not reply, but when making the message shorter today it was posted successfully.
            reply error video.
            I don't know if I should create another thread for this.
            Thank you.

            1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand
              last edited by ferdinand

              Hello @Ogers,

              this is likely caused by the hype aggressive filtering mechanisms of NodeBB. You cannot write 'chr (' without the white space between the r and ( character for example. The issue is likely introduced by either one of your code listings or the console output.

              Please use either Pastebin or a similar site, or reach out to us via mail.

              Cheers,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

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

                I have pasted the message here.
                https://pastebin.com/mB3i8TTM

                Thank you.

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

                  I solved this by having two typename in the template in the Set function.

                  template <typename ATTR, typename VAL> Result<void> Set(const Id& category, const ATTR& attr, const VAL& value)
                   {
                   // Retrieve the category"s and add an attribute.
                   iferr_scope;
                   DataDictionary& dict = GetPortDictionary(category) iferr_return;
                   dict.Set(attr, value) iferr_return;
                   return OK;
                   }
                  

                  Thanks for your time.

                  1 Reply Last reply Reply Quote 0
                  • ManuelM
                    Manuel
                    last edited by Manuel

                    Hi,

                    you can also create your own blockToArray function like so

                    template <typename TYPE> inline Result<Array<Tuple<Id, Data>>> BlockToEnumArray(const Block<TYPE>& enumBlock)
                    {
                    	 iferr_scope;
                    	 Array<Tuple<Id, Data>> codecEnum;
                    	 for (const TYPE& val : enumBlock)
                    	 {
                    		 CString str = FormatCString("@", val);
                    		 Id id;
                    		 id.Init(str) iferr_return;
                    		 codecEnum.Append({ id, Data(val) }) iferr_return;
                    	 }
                    	 return std::move(codecEnum);
                     }
                    

                    Or directly create the array for the enum parameter like so.

                    maxon::Array<maxon::Tuple<maxon::Id, maxon::Data>> data;
                    data.Append({ maxon::Id("Test1") , maxon::Data("Test1")}) iferr_return;
                    data.Append({ maxon::Id("Test2") , maxon::Data("Test2")}) iferr_return;
                    data.Append({ maxon::Id("Test3") , maxon::Data("Test3")}) iferr_return;
                    

                    Doing this, you can use the Setfunction provided.

                    Cheers,
                    Manuel

                    MAXON SDK Specialist

                    MAXON Registered Developer

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

                      Hello,

                      Thanks for the code.
                      Regarding the second one, I have tried it and also mentioned in the first message that the data does not get added and the array size still stays 0.
                      I had forgotten to put iferr_return and now with your example, I am getting a critical error when trying to append those data.

                      RefMemberType<S> CritStop()
                      {
                      CriticalOutput(static_cast<const typename S::ReferenceClass*>(this)->ToString()); return this->PrivateGetRefMember();
                      }
                      
                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post