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.


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  
  //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();  


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) :

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(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.


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

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,

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

One more try at this. Then I quit. :wink:

    BaseObject *obj = doc->GetActiveObject();  
  //Get the X object's position by it's description ID  
  //This will let us change the value of the X position if desired  
  GeData d;  
  //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.