Getting Description information

On 16/07/2013 at 07:24, xxxxxxxx wrote:

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

---------
From the SDK:
_The description class contains information for all description ID of an object. For example it stores a[BaseContainer](file:///Y:/Setups/Maxon/Cinema4D/SDK/C4DR14041SDKHTML20130510/help/pages/c4d_basecontainer/class_BaseContainer62.html) for ID_BASEOBJECT_POSITION that describes that this value is a [Vector](file:///Y:/Setups/Maxon/Cinema4D/SDK/C4DR14041SDKHTML20130510/help/pages/ge_math/class_Vector1539.html), has minimum and maximum values XYZ etc.
_
--
This is excellent, exactly what I am after. I want to know if a description element has the UNIT DEGREE attribute set. But I have no idea how to do this. Have tried it like this:

 AutoAlloc<Description> desc;
node->GetDescription(desc, DESCFLAGS_DESC_0 | DESCFLAGS_DESC_MAPTAGS); 
const BaseContainer* bc = desc->GetParameterI(FOO_ID, NULL); //DESCID_ROOT
if(bc) 
{
  String unitUsed = bc->GetString(DESC_UNIT);
  String elementName = bc->GetString(DESC_NAME);
}
  

I am able to get the element name, but not the unitUsed, which always is of zero length.
The node is generated inside the tag itself, using  GeListNode* node = NodeData::Get();

On 16/07/2013 at 07:43, xxxxxxxx wrote:

DESC_UNIT is not a string, it is a LONG value. This information is in the second column of the three
column table describing the DESC_Ids.

Cheers,
-Niklas

On 16/07/2013 at 08:00, xxxxxxxx wrote:

Hi niklas,
this did not help

LONG usedUnit = bc->GetLong(DESC_UNIT);

because now I either get 0 or 1717856114

from the lib_description.h

	DESC_UNIT	= 12,	// LONG: one of the following values DESC_UNIT_xxx for DTYPE_REAL/DTYPE_VECTOR
	DESC_UNIT_REAL			= 'frea',		//FORMAT_REAL,
	DESC_UNIT_LONG			= 'flng',		//FORMAT_LONG,
	DESC_UNIT_PERCENT		= 'fpct',		//FORMAT_PERCENT,
	DESC_UNIT_DEGREE		= 'fdgr',		//FORMAT_DEGREE,
	DESC_UNIT_METER			= 'fmet',		//FORMAT_METER,
	DESC_UNIT_TIME			= 'ffrm',		//FORMAT_FRAMES,

I still have no idea how to find out it the element has a UNIT DEGREE attribute.

On 16/07/2013 at 09:25, xxxxxxxx wrote:

Hi Ingvar,

enumerations are always integers. 'fdgr' is a so-called multi-character constant.

http://coliru.stacked-crooked.com/view?id=4ca282541e2f80a136b5b08bcb70dd9b-a618d2239b73732723b7a95695ce0794

1717856114 == 'fdgr' == DESC_UNIT_DEGREE

On 16/07/2013 at 09:25, xxxxxxxx wrote:

I don't have an answer for you, but I've posted this code before that you might find useful...

  
static String VecToString(const Vector& vec)  
{  
  return String(RealToString(vec.x)+" "+RealToString(vec.y)+" "+RealToString(vec.z));  
}  
  
static void DumpMatrix(Matrix xform)  
{  
  GePrint("===================");  
  GePrint("v1  = " + VecToString(xform.v1));  
  GePrint("v2  = " + VecToString(xform.v2));  
  GePrint("v3  = " + VecToString(xform.v3));  
  GePrint("off = " + VecToString(xform.off));  
  GePrint("===================");  
}  
  
void container_dump(BaseContainer *pBc, LONG tab=0)  
{  
  if(!pBc)    return;  
  
  LONG id, j, i=0;  
  String tabStr;  
  
  for(j=0; j<tab; j++)  
      tabStr += "____";  
  
  while (TRUE)  
  {  
      id = pBc->GetIndexId(i++);  
      if (id==NOTOK) break;  
  
      BaseContainer *pSubc = NULL;  
      GeData data = pBc->GetData(id);  
      switch(data.GetType())  
      {  
          case DA_NIL:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_NIL");                                                    break;  
          case DA_VOID:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_VOID");                                                    break;  
          case DA_LONG:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_LONG ("+LongToString(data.GetLong())+")");                break;  
          case DA_REAL:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_REAL ("+RealToString(data.GetReal())+")");                break;  
          case DA_TIME:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_TIME ("+RealToString(data.GetTime().GetNumerator())+" / "+RealToString(data.GetTime().GetDenominator())+")");    break;  
          case DA_VECTOR:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_VECTOR ("+VecToString(data.GetVector())+")");            break;  
          case DA_MATRIX:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_MATRIX...");    DumpMatrix(data.GetMatrix());            break;  
          case DA_LLONG:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_LLONG ("+LLongToString(data.GetLLong())+")");            break;  
          case DA_BYTEARRAY:        GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_BYTEARRAY");                                            break;  
          case DA_STRING:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_STRING (\""+data.GetString()+"\")");                    break;  
          case DA_FILENAME:        GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_FILENAME (\""+data.GetFilename().GetString()+"\")");    break;  
          case DA_CONTAINER:        GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_CONTAINER");    pSubc = data.GetContainer();    container_dump(pSubc, tab+1);    break;  
          case DA_ALIASLINK:        GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_ALIASLINK");                                            break;  
          case DA_MARKER:            GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_MARKER");                                                break;  
          case DA_MISSINGPLUG:    GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_MISSINGPLUG");                                            break;  
          case DA_CUSTOMDATATYPE:    GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - DA_CUSTOMDATATYPE");                                        break;  
          default:                GePrint(tabStr+LongToString(i)+"| id: "+LongToString(id)+" - unknown");                                                    break;  
      }  
  }  
}  

...try dumping out some containers to see if you can figure out what you're looking for.

Cheers.

On 16/07/2013 at 10:46, xxxxxxxx wrote:

Originally posted by xxxxxxxx

1717856114 == 'fdgr' == DESC_UNIT_DEGREE

Hi Niklas,
I have to say this: :joy: plus this: :blush:

I never thought that this huge number had any meaning, as long as the other constants are so low. So I had the answer there after all, I just overlooked it! I am a C++ beginner, indeed. I wonder why Maxon uses multi-character constants, what purpose they serve. Nevertheless, I got what I wished for and will experiment further.
Thanks a lot!!
And thanks to Giblet too, very useful code you posted!

On 22/07/2013 at 06:01, xxxxxxxx wrote:

Howdy,

Originally posted by xxxxxxxx

... I wonder why Maxon uses multi-character constants, what purpose they serve...

So you can do something like this:

switch(bc->GetLong(DESC_UNIT)
{
	case DESC_UNIT_REAL:
		GePrint("Real");
		break;
	case DESC_UNIT_LONG:
		GePrint("Long");
		break;
	case DESC_UNIT_PERCENT:
		GePrint("Percent");
		break;
	case DESC_UNIT_DEGREE:
		GePrint("Degree");
		break;
	case DESC_UNIT_METER:
		GePrint("Meter");
		break;
	case DESC_UNIT_TIME:
		GePrint("Time");
		break;
}

If any of the defined constant values are changed in the future, the above code would still work. :wink:

You really need not worry about what a defined constant's value is, because you can use the definition "DESC_UNIT_DEGREE" in your code (as in the above code). The use of the value of 'fdgr' may only be a convenience to the original programmer for debugging purposes or something.

Adios,
Cactus Dan

On 22/07/2013 at 07:05, xxxxxxxx wrote:

Hi Dan,
thanks!
I am not "worrying" about anything in particular, but I am, and have always been, very curious! I always want to open the lid, to watch inside. That slows me often down, with most of the things I do. Making things work, is not enough for me, I want to find out why and because  :wink:
My plugins were mostly done, mostly working well, already in June. But I and diving into stuff all the time, do I see a yet another door, I just have to open it!

On 22/07/2013 at 11:01, xxxxxxxx wrote:

I think the question was more like "why multi character constants instead of any other integral numbers"?
Well, it's like choosing between octal, decimal and hexadecimal. :)

On 24/07/2013 at 06:54, xxxxxxxx wrote:

Howdy,

Well, your curiosity got my curiosity up, and I found this from a c++ forum:

Question:
I'm curious about this code:
cout << 'test'; // Note the single quotes.
gives me an output of 1952805748.
My question: Is the output an address in memory or something?

Answer:
No, it's not an address. It's the so-called multibyte character.
Typically, it's the ASCII values of the four characters combined.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74; So 0x74657374 is 1952805748.

According to Bjarne Stroustrup (the author of c++) in his book "The C++ Programming Language", the use of the ' operator declares a character literal and that character literals are mainly used to make programs more portable.

Adios,
Cactus Dan

On 25/07/2013 at 15:14, xxxxxxxx wrote:

Great Dan,
reminds me of the old days when I programmed in assembler. I used a decimal number to search for a four characters long string in a file.

On 25/07/2013 at 16:26, xxxxxxxx wrote:

Are they using mulichars in the ListView gizmo?

This is in the ge_prepass.h file:

    LV_COLUMN_TEXT      = C4D_FOUR_BYTE(0,'t','x','t'),  
  LV_COLUMN_EDITTEXT  = C4D_FOUR_BYTE(0,'e','d','t'),  
  LV_COLUMN_BMP       = C4D_FOUR_BYTE(0,'b','m','p'),  
  LV_COLUMN_CHECKBOX  = C4D_FOUR_BYTE(0,'c','h','k'),  
  LV_COLUMN_BUTTON    = C4D_FOUR_BYTE(0,'b','t','n'),  
  LV_COLUMN_USERDRAW  = C4D_FOUR_BYTE(0,'u','s','r'),  
  LV_COLUMN_COLORVIEW = C4D_FOUR_BYTE(0,'c','l','v'),

Does this mean that each char inside of the parenthesis () is a hexidecimal representaion of an ID#?
The "C4D_FOUR_BYTE" code is very odd looking code to me too.

-ScottA

On 26/07/2013 at 08:55, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Are they using mulichars in the ListView gizmo?

This is in the ge_prepass.h file:

    LV_COLUMN_TEXT      = C4D_FOUR_BYTE(0,'t','x','t'),  
  LV_COLUMN_EDITTEXT  = C4D_FOUR_BYTE(0,'e','d','t'),  
  LV_COLUMN_BMP       = C4D_FOUR_BYTE(0,'b','m','p'),  
  LV_COLUMN_CHECKBOX  = C4D_FOUR_BYTE(0,'c','h','k'),  
  LV_COLUMN_BUTTON    = C4D_FOUR_BYTE(0,'b','t','n'),  
  LV_COLUMN_USERDRAW  = C4D_FOUR_BYTE(0,'u','s','r'),  
  LV_COLUMN_COLORVIEW = C4D_FOUR_BYTE(0,'c','l','v'),

Does this mean that each char inside of the parenthesis () is a hexadecimal representation of an ID#?
The "C4D_FOUR_BYTE" code is very odd looking code to me too.

Hi Scott,

C4D_FOUR_BYTE is used to define multi-character constants from 3 characters only because writing

LV_COLUMN_TEXT = 'txt'

won't give a valid and unique constant.
You can see that it's used in only one another place to define QUICKTAB_BAR:

#define QUICKTAB_BAR    C4D_FOUR_BYTE(0,'b','a','r')

On 26/07/2013 at 09:56, xxxxxxxx wrote:

Thanks for the answer Yannick.

Is it safe to use the C4D_FOUR_BYTE() function in our plugins if we wanted. Or is it something that we should not use?

-ScottA

On 26/07/2013 at 10:17, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Is it safe to use the C4D_FOUR_BYTE() function in our plugins if we wanted. Or is it something that we should not use?

Yes you can use the macro C4D_FOUR_BYTE in 3rd party plugins.

On 26/07/2013 at 10:41, xxxxxxxx wrote:

OK.
Thanks.

-ScottA