In/Exclude User Data

On 28/03/2014 at 12:44, xxxxxxxx wrote:

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

---------
Hi,
I can't figure out how to get at the items inside of an In/Exclude gizmo when it's created with User Data.
I can get the items from the In/Exclude gizmo just fine when it's created in my plugin code.
But for some strange reason. I can't get at them if it's created with User Data.

  
  //The object that has the In/Exclude UD entry on it  
  BaseObject *obj = doc->SearchObject("HolderObject");  
  
  //Get the master UD container  
  DynamicDescription *ud = obj->GetDynamicDescription();  
  
  //Get the first UD entry where the In/Exclude gizmo is sitting  
  DescID firstUD(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER,0), 1);  
  
   
  InExcludeData *in_ex = (InExcludeData* )ud->Find(firstUD); //<---Wrong?   
  
  
  LONG count = in_ex->GetObjectCount(); //<---Jibberish!!  
  GePrint(LongToString(count));

-ScottA

On 28/03/2014 at 14:40, xxxxxxxx wrote:

Never mind.
After hours of trying everything in my notes. I eventually hit upon the correct code.

Here's an example in case anyone needs it.

    //The object that has the In/Exclude UD entry on it  
  BaseObject *obj = doc->SearchObject("HolderObject");  
  
  //Get the master UD container  
  DynamicDescription *ud = obj->GetDynamicDescription();  
  
  //Get the first UD entry  
  DescID firstUD(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER,0), 1);  
  
  //Get the data from the UD gizmo and put it in "d"  
  GeData d;  
  obj->GetParameter(firstUD, d, DESCFLAGS_GET_0);  
  
  //Put the data from "d" into a new InExcludeData type instance variable called "in_ex"  
  InExcludeData *in_ex = (InExcludeData* )d.GetCustomDataType(CUSTOMDATATYPE_INEXCLUDE_LIST);   
  
  //Get all of the objects inside of the In/Exclude gizmo  
  //Then get their names and global positions  
  LONG count = in_ex->GetObjectCount();  
  if(count > 0)  
  {  
      for(LONG i=0; i<count; ++i)  
      {  
          BaseList2D *entry2D = in_ex->ObjectFromIndex(doc, i);                  
          GePrint(entry2D->GetName());  
          BaseObject *entry = static_cast<BaseObject*>(entry2D);  //Convert from a BaseList2D to a BaseObject type  
          Matrix objMtx = entry->GetMg();  
          GePrint(RealToString(objMtx.off.x) + " " + RealToString(objMtx.off.y) + " " + RealToString(objMtx.off.z));  
      }  
  }

-ScottA

On 10/04/2014 at 12:44, xxxxxxxx wrote:

Hi Scott,

When i use static_cast to convert from the BaseList2D to a BaseObject, I`m getting the error:

C2440: 'type cast' : cannot convert from 'const LVector' to 'int' c:\program files (x86)\microsoft visual studio 10.0\vc\include\numeric

The line of code i`m using is as follows:

BaseObject *curObj = static_cast<BaseObject*>(objList->ObjectFromIndex(doc, i));

Any clues what is going on here?

On 10/04/2014 at 13:51, xxxxxxxx wrote:

That line of code looks ok to me. The problem must be coming from someplace else.
The error seems to indicate that you might be using a vector as the iterator. Instead of LONG(i).
Also make sure that your objList variable is written like this:

InExcludeData *objList = (InExcludeData* )d.GetCustomDataType(CUSTOMDATATYPE_INEXCLUDE_LIST);

Also don't forget about the In/Exclude counter bug too.
If you delete an object from the OM that's in that list. Your code will crash C4D because the iteration count is no longer accurate.

This is a workaround for handling that scenario:

//There is a bug in the In/Exclude list that the count value doesn't update when an object is deleted from the OM  
//This is a workaround to that manually deletes an object from the list if the object doesn't exist in the OM  
  
#include "customgui_inexclude.h"  
  
  
  BaseObject *mylight = doc->SearchObject("Light");       //A pointer to the light object with an inexclude list on it  
  BaseContainer *data = mylight->GetDataInstance();       //Get the lights data  
  
  //Get the light's in/exclude list and assign it to a variable  
  InExcludeData *in_ex_List = (InExcludeData* )data->GetCustomDataType(LIGHT_EXCLUSION_LIST, CUSTOMDATATYPE_INEXCLUDE_LIST);  
  
  if(in_ex_List && in_ex_List->GetObjectCount() > 0)  
  {  
      for(int i=0; i < in_ex_List->GetObjectCount(); ++i)  
      {  
          //Find the objects that are in the in/exclude List and assign them to a variable  
          BaseList2D *ListObj = in_ex_List->ObjectFromIndex(doc,i);                  
          if(!ListObj)  
          {  
              //An object that has been deleted from the OM does not update the list's count value(BUG?)  
      //So we have to manually subtract one from the count value   
              if(!in_ex_List->DeleteObject(i)) break;  //Delete the object from the In/Exclude list it's not in the OM anymore  
  
              mylight->SetDirty(DIRTYFLAGS_DATA);  
      mylight->Message(MSG_UPDATE);  
          }  
   
      }  
  }

-ScottA

On 10/04/2014 at 15:20, xxxxxxxx wrote:

Thanks for the help Scott.

Youre right it isnt with that.  I assumed, as it mentions cast that it was regards the static_cast.

What i figured out was, in VisualStudio ( 2010 Express ) if i go into Tools / Options / Projects and Solutions / Build and Run i can change the Verbosity of the build output..  Pretty useful as it lets me find where the problem is being called..  Turning on line numbers is useful as well :)