Copying UD from Groups?



  • On 02/02/2017 at 10:57, xxxxxxxx wrote:

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

    ---------
    Hi,
    I'm trying to copy a specific UD item from one object to another. But I'm getting a strange, buggy behavior from it if that UD item is a child of a UD Group.
    The item is indeed copied. But it does not show up in the AM until I open the UD manager and then press "OK".
    Even using this core message does not make it update:
    SendCoreMessage(COREMSG_CINEMA, BaseContainer(COREMSG_CINEMA_FORCE_AM_UPDATE));

    If the item I'm copying is not a child of a group. It all works properly as expected.
    I'm also getting the same buggy behavior in python.

        BaseObject *source = doc->SearchObject("Cube");  
      if (!source) return false;  
      BaseObject *target = doc->SearchObject("Sphere");  
      if (!target) return false;  
      
      DynamicDescription *s_ud = source->GetDynamicDescription();  
      DynamicDescription *t_ud = target->GetDynamicDescription();  
      
      doc->AddUndo(UNDOTYPE_CHANGE, target);  
       
      LONG level = 2;  //<---Change this to get the other UD items as desired  
      
      DescID item(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER, 0), level);  
      const BaseContainer *sbc = s_ud->Find(item);  
      String name = sbc->GetString(DESC_NAME);  
      LONG type = sbc->GetLong(DESC_CUSTOMGUI);  
      LONG unit = sbc->GetLong(DESC_UNIT);  
      GePrint(name + "  " + LongToString(type) + "  " + LongToString(unit));  
      
      //Get the value of the UD item     
      GeData d;  
      source->GetParameter(item, d, DESCFLAGS_GET_0);  
      
      //Copy the UD item to another object's UD master container and also copy the value  
      DescID udCopy(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER, 0), DescLevel(level));  
      const BaseContainer clonedBC = *sbc->GetClone(COPYFLAGS_0, NULL);  
      udCopy = t_ud->Alloc(clonedBC);  
      target->SetParameter(DescID(udCopy), GeData(d), DESCFLAGS_SET_0);  
      t_ud->Set(udCopy, clonedBC, target);
    

    Can anyone tell me what's going on?
    Why does the AM not update correctly when copying UD items that are children of a Group?

    -ScottA



  • On 03/02/2017 at 11:14, xxxxxxxx wrote:

    I found the problem.
    When copying a UD item that is a child item to the another object where it will not be a child item. It's very important to change it's parent ID value to 700(not a child of any group).
    If you don't do this. C4D freaks out and gets all confused about how to insert the copied UD item into the other object's UD container.
    The way C4D freaks out is the AM does not update unless you open the UD manager and click the "OK" button.

    This code copies a UD item to a different object properly. Even if it was a child of a Group

        BaseObject *source = doc->SearchObject("Cube");  
      if (!source) return false;  
      BaseObject *target = doc->SearchObject("Sphere");  
      if (!target) return false;  
      
      DynamicDescription *s_ud = source->GetDynamicDescription();  
      DynamicDescription *t_ud = target->GetDynamicDescription();  
      
      doc->AddUndo(UNDOTYPE_CHANGE, target);  
        
      LONG level = 2;  //<---Change this to get the other UD items as desired  
        
      DescID item(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER, 0), level);  
      const BaseContainer *sbc = s_ud->Find(item);  
      String name = sbc->GetString(DESC_NAME);  
      LONG type = sbc->GetLong(DESC_CUSTOMGUI);  
      LONG unit = sbc->GetLong(DESC_UNIT);  
      GePrint(name + "  " + LongToString(type) + "  " + LongToString(unit));  
      
      //Get the value of the UD item      
      GeData d;  
      source->GetParameter(item, d, DESCFLAGS_GET_0);  
      
      //Copy the UD item to another object's UD master container and also copy the value  
      //NOTE: be sure to change the parent ID value to 700 so that any copied UD item that was a child item inserts properly!!!   
      DescID udCopy(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER, 0), DescLevel(level));  
      BaseContainer clonedBC = *sbc->GetClone(COPYFLAGS_0, NULL);  
      clonedBC.SetData(DESC_PARENTGROUP, 700);  //<---- Very important!!!!  
      udCopy = t_ud->Alloc(clonedBC);  
      target->SetParameter(DescID(udCopy), GeData(d), DESCFLAGS_SET_0);  
      t_ud->Set(udCopy, clonedBC, target);  
        
      if (target->IsDirty(DIRTYFLAGS_DATA)) GePrint("target obj Changed");
    

    -ScottA

    -Edit Ackkk!!
    Ok now that I've found the problem. And I know that changing the parent level# to 700 fixes it.
    The way I'm doing it is wrong. Because it changes the DescID entry to a LONG data type.
    How the heck do we CHANGE just the first value inside of the DescID to 700?
    The code in the R18 doesn't show how to change a DescID. And I'm having a hard time grasping these DescID's.


Log in to reply