Browse through description levels [SOLVED]

On 09/11/2015 at 16:21, xxxxxxxx wrote:

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

---------
Howdy,

OK, I understand how to browse through the descriptions, but I'm not sure how to get to the sub levels of the descriptions.

Can you provide simple example?

Adios,
Cactus Dan

On 10/11/2015 at 01:59, xxxxxxxx wrote:

Hello,

if you want to access the ID used to identify sub-structures of custom GUIs and datatypes you could simply load the description. Something like this:

  
AutoAlloc<Description> desc;  
if (!desc)  
 return false;  
  
desc->LoadDescription(DTYPE_VECTOR);  
  
void *browse = desc->BrowseInit();  
const BaseContainer *bc = nullptr;  
DescID tid, groupid;  
while (desc->GetNext(browse, &bc, tid, groupid))  
{  
 if(bc != nullptr)  
 {  
     GePrint("ID: " + String::IntToString(tid[0].id));  
     GePrint("Type: " + String::IntToString(tid[0].dtype));  
     GePrint("Name: " + bc->GetString(DESC_NAME));  
 }  
}  
  
desc->BrowseFree(browse);  

best wishes,
Sebastian

On 10/11/2015 at 07:35, xxxxxxxx wrote:

Howdy,

Well, to be more specific, I want to browse through the descriptions and get the Pose Morph tag's sliders. The sliders seem to all have 2 levels with the first level being 4000.

Here is my browse loop code:

while(desc->GetNext(h, &bc, id, groupid))
{
	if(id[0].id == 4000 && id.GetDepth() > 1)
	{
		LONG dID = id[1].id;
		GeData d;
		if(tag->GetParameter(DescLevel(dID), d, DESCFLAGS_GET_0))
		{
			if(d.GetType() != DA_REAL) GePrint("Not a DA_REAL");
		}
	}
}

But it prints "Not a DA_REAL" every time.

What am I doing wrong?

Adios,
Cactus Dan

On 10/11/2015 at 08:58, xxxxxxxx wrote:

Hello,

the pose morph tag is represented by a special class in the API: CAPoseMorphTag. This class allows you to loop through the sliders and to get their description ID:

  
CAPoseMorphTag* poseMorphTag = static_cast<CAPoseMorphTag*>(tag);  
  
const Int32 count = poseMorphTag->GetMorphCount();  
  
for (Int32 i = 0; i < count; ++i)  
{  
 DescID sliderId = poseMorphTag->GetMorphID(i);  
  
 GeData data;  
 poseMorphTag->GetParameter(sliderId, data, DESCFLAGS_GET_0);  
  
 GePrint("Slider Value: " + String::FloatToString(data.GetFloat()));  
}  

best wishes,
Sebastian

On 10/11/2015 at 09:16, xxxxxxxx wrote:

Howdy,

OK, but that's not available in R12. It's only there in R13+. To do it in R12, I have to go the browse route.

EDIT:
AHA! That is available in R12. It's just not listed in the R12 documentation. 😲

Adios,
Cactus Dan

On 13/11/2015 at 07:39, xxxxxxxx wrote:

Howdy,

OK, I have your code working where I can set the Pose Morph sliders, but I'm having a problem in my test code.

What I'm trying to do is create a clone of the object, then set each Pose Morph slider on the clone to 100%, compare the points of the morphed clone with the original object, and select the points that have moved, but it's not working.

Here is my code:

bool SelectMorphedPoints(BaseDocument *doc)
{
	BaseObject *op = doc->GetActiveObject(); if(!op) return false;
	BaseTag *tag = op->GetTag(1024237); if(!tag) return false;
	
	CAPoseMorphTag* pmTag = static_cast<CAPoseMorphTag*>(tag);
	
	LONG i, mCnt = pmTag->GetMorphCount();
	GeData sSet;
	
	// set all sliders to 0.0
	for(i=0; i<mCnt; ++i)
	{
		DescID sliderId = pmTag->GetMorphID(i);
		sSet = Real(0.0);
		pmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
	}
	
	// clone the object
	BaseObject *clone = (BaseObject* )op->GetClone(COPYFLAGS_0, NULL);
	if(clone)
	{
		Vector *padr = GetPointArray(op);
		Vector *cpadr = GetPointArray(clone);
  
		BaseTag *clTag = clone->GetTag(1024237);
		if(clTag)
		{
			CAPoseMorphTag* cpmTag = static_cast<CAPoseMorphTag*>(clTag);
			if(cpmTag)
			{
				for(i=0; i<mCnt; ++i)
				{
					DescID sliderId = pmTag->GetMorphID(i);
					sSet = Real(1.0);
					pmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
					
					clone->Message(MSG_UPDATE);
					
					BaseSelect *bs = ToPoint(op)->GetPointS();
					if(bs) bs->DeselectAll();
					
					LONG p, pCnt = LMin(ToPoint(op)->GetPointCount(),ToPoint(clone)->GetPointCount());
					for (p=0; p<pCnt; p++)
					{
						if(!VectorEqual(padr[p], cpadr[p], 0.001)) bs->Select(p);
					}
					
					if(bs->GetCount() < 1) GePrint(" no points selected");
					
					sSet = Real(0.0);
					pmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
				}
			}
		}
		BaseObject::Free(clone);
	}
	
	return true;
}

It prints "no points selected" every time. Why is it not working?

Adios,
Cactus Dan

On 13/11/2015 at 09:42, xxxxxxxx wrote:

Hello,

could you post your latest question in a new thread? It seems it is no longer related to this thread's original topic.

Best wishes,
Sebastian