Getting Two Level DescID's Descriptions



  • On 03/01/2013 at 13:54, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R13 
    Platform:    Mac  ;  
    Language(s) :     C++  ;

    ---------
    Hello everyone,

    I've been trying to copy the descriptions of attributes off an object.  It seems to be working fine with single level DescIDs, so integers, floats, etc.  But it won't work with attributes with more then one level, like a vector.

      
    AutoAlloc<Description> desc;  
    BaseContainer* bcdesc;  
      
    op->GetDescription(desc, DESCFLAGS_DESC_0);  
                       
    DescID relpos(ID_BASEOBJECT_REL_POSITION);//position vector of an object  
    bcdesc = desc->GetParameterI(relpos, NULL);//This works  
      
    //DescID relposx(ID_BASEOBJECT_REL_POSITION,VECTOR_X);// x position of an object  
    //bcdesc = desc->GetParameterI(relposx, NULL);//This doesn't work, it crashes Cinema  
    

    So I can get the entire vector, but I can't get just the X,Y, or Z out of it.  If I run the commented code then Cinema crashes right away.  From my tests it seems like it is because it has two levels.  If I popped the top level off the second example it would correctly return the entire vector again.

    I saw this function:

      
    #### Bool GetSubDescriptionWithData(const DescID& did, const AtomArray& op, RESOURCEDATATYPEPLUGIN* resdatatypeplugin, const BaseContainer& bc, DescID* singledescid)_<_h4_>_  
    

    But I haven't been able to get that to work yet, and I'm not  sure if that's what I need anyway.  If anyone has any ideas I'd appreciate it.

    Thanks,
    Dan



  • On 03/01/2013 at 17:15, xxxxxxxx wrote:

    Hi Dan,

    Not sure if this is what you're looking for or not.
    But this is one way to get the X position value of an object and assign it to a variable:

        BaseObject *obj = doc->GetActiveObject();  
      if(!obj) return FALSE;  
      
      //Create an empty GeData variable to store what we get using the GetParameter() function  
      GeData d;  
      
      //Get the X position value from the selected object. And store that value in the "d" variable  
      obj->GetParameter(DescID(ID_BASEOBJECT_REL_POSITION, VECTOR_X), d, DESCFLAGS_GET_0);  
      
      //The X position value is now saved in the "d" variable. And we can assign a variable to it to make it easer to use   
      Real posX = d.GetReal();  
      GePrint(RealToString(posX));
    

    -ScottA



  • On 03/01/2013 at 19:03, xxxxxxxx wrote:

    The DescID constructor doesn't accept integers as parameters, but DescLevels. there is also
    an overloaded constructor which accepts directly an integer ID for a single level DescID i think, 
    but for more levels you have to set the DescLevels (datatypes).

    to get hold of a 2 level DescID, do the following (in Python, my cpp is awful) :

    dLVector = c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION, c4d.DTYPE_VECTOR)
    dlReal   = c4d.DescLevel(c4d.VECTOR_X, c4d.DTYPE_REAL)
    dID = c4d.DescID(dLVector, dlReal)
    

    however, crashing seems to be a rather extreme result for this mistake, you should report this
    as a bug for the DescLevel constructor, something has to be wrong there, when this is causing
    c4d to crash.

    edit : Scott, have you tested your code ? i haven't red your posting before I posted mine and
    confuses me a bit that you are posting alomst the same code as the OP (passing two LONG
    values as constructor parameters to a DescLevel).

    I took a look into the cpp sdk and by the book this constructor call shouldn't be working. or is 
    there some implicit declaration going on  I am missing ?

    the constructors :

    DescID();
    DescID(const DescID& src);
    DescID(const DescLevel& id1);
    DescID(const DescLevel& id1, const DescLevel& id2);
    DescID(const DescLevel& id1, const DescLevel& id2, const DescLevel& id3);
    DescID(LONG id1);



  • On 04/01/2013 at 08:12, xxxxxxxx wrote:

    Yes. The code I posted is tested and works.
    I use it all of the time.

    -ScottA



  • On 04/01/2013 at 09:54, xxxxxxxx wrote:

    Hello,
    Thanks for the help both of you.   I've used code almost  exactly like Scott's before, that definitely works fine.

    Scott, I'm trying to access the description of the attribute, not the actual value of it.

    Ferdinand,  I did some more testing and it looks like

      
    bcdesc =desc->GetParameterI(dID, NULL);  
    

    doesn't cause the crash, but it isn't correctly assigning the base container when it deals with a two level DescID.  Trying to access the base container when it wasn't valid is what was causing the crash.  I tried what you suggested but it hasn't given me the correct container back as of yet.

    Thanks both of you for the help,
    Dan



  • On 04/01/2013 at 13:29, xxxxxxxx wrote:

    One more try at this. Then I quit. 😉

        BaseObject *obj = doc->GetActiveObject();  
      
      //Get the X object's position by it's description ID  
      DescID posXid = DescID(DescLevel(ID_BASEOBJECT_REL_POSITION, DTYPE_VECTOR,0), DescLevel(VECTOR_X, DTYPE_REAL,0));  
      
      //This will let us change the value of the X position if desired  
      GeData d;  
      d.SetReal(100.0);    
      
      //Use the value in "d" to control the description attribute "posXid" to set the new X position value  
      obj->SetParameter(posXid, d, DESCFLAGS_SET_0); 
    

    I know you didn't ask about changing the X position value.
    But I put it in there because someone else might find it useful.

    -Scott


Log in to reply