tag container after MCOMMAND_JOIN

On 18/12/2017 at 06:26, xxxxxxxx wrote:

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

Say I have 2 polygon objects with each a polygon selection tag assigned.
After I add a custom container to these tags, I can parse the content of this container.
When I use the "connect" command to merge these 2 objects, the tags are copied over, but the custom container is not present anymore.

Is there a way to keep the custom container in the selection tag?

On 19/12/2017 at 03:09, xxxxxxxx wrote:

Hi Daniel, thanks for writing us.

Can you please better explain what you mean by custom container? Second but not less relevant, can you post the code you're executing for the "Connect" command?

Best, Riccardo

On 19/12/2017 at 05:27, xxxxxxxx wrote:

Hi Riccardo,

Sorry for the lack of decent explanation in my original message.

Here's the code to perform the connect.
I am using the MDATA_JOIN_MERGE_SELTAGS in order to merge the selection tags, I was hoping the original tag got merged, but the custom container is missing.

  BaseDocument* mDoc = GetActiveDocument();  
  AutoAlloc<AtomArray> joinOps; if (!joinOps) return FALSE;  
      BaseContainer bc;  
      ModelingCommandData mcd;  
      mcd.doc = mDoc;  
      mcd.arr = joinOps;  
      mcd.bc = &bc;  
      Bool result = SendModelingCommand(MCOMMAND_JOIN, mcd);  
      if (!result)  
          return result;  
      joined = static_cast<BaseObject*>(mcd.result->GetIndex(0));  
      if (joined)  
          mDoc->InsertObject(joined, parent, pred);  

Following is a script I am using to experiment with creation of custom container in the selection tag.
The script always creates a container if there is none, but I am simply put the lines in comment for reading out (I know I better create 2 scripts, one for writing the container and another for reading, but this was just an experiment)

# obtain valid ID from plugincafe  
def main() :  
  if (op == None) :  
      print "No active object"  
  tag = op.GetFirstTag()  
  while(tag) :  
      if tag.IsInstanceOf(c4d.Tpolygonselection) :  
          bc = tag.GetDataInstance()  
          pgbc = bc.GetContainerInstance(CUSTOMCONTAINER_PLUGIN_ID)  
          if pgbc == None:  
              print "No custom container in selection tag"  
              # add a custom container to the selection tag  
              pgbc = bc.GetContainer(CUSTOMCONTAINER_PLUGIN_ID)  
              pgbc[0] = "Test 2"  
              pgbc[1] = "123456789"  
              bc.SetContainer(CUSTOMCONTAINER_PLUGIN_ID, pgbc)  
              print "custom container in selection tag"  
              # parse the custom container content  
              print "[0] = ", pgbc[0]  
              print "[1] = ", pgbc[1]  
      tag = tag.GetNext()  

What I do is to first apply custom containers to the selection tags of the objects I want to connect.
Then I perform the connect via the plugin and read out the custom container from the selection tags. But there is none on the connected object.

On 21/12/2017 at 05:06, xxxxxxxx wrote:

Hi Daniel, sorry for coming late here.

After some research, the desired behavior you're trying to achieve isn't automatically delivered by our API. The operation designed to take care of the copy the SelectionTag data actually doesn't consider potential BaseContainer attached to the SelectionTag instance but only the data pertinent to the selection.

A workaround to the issue can be found in pre-rolling the objects which are supposed to be joined together, "join" the BaseContainer in a separate data structure, operate the SendModelingCommand and, as final operation, glue back the newly created data structure to the joined object.

Best, Riccardo

On 21/12/2017 at 05:43, xxxxxxxx wrote:

Thanks Riccardo,
I expected the desired behavior wasn't supported by the API.

Well, the workaround is exactly what I wanted to avoid doing.

The selection tags refer to polygons of the objects to be joined.
After the SendModelingCommand the merged selection tags refer to the new polygon indeces. I wanted to take advantage of this in order not to have to do all the translation work of finding out polygon indeces before and after the SendModelingCommand.