MCOMMAND_JOIN for objects with different parents
On 16/02/2015 at 02:01, xxxxxxxx wrote:
Seems like MCOMMAND_JOIN joins all objects together when they have the same parent object. In this
case, it will only join the first two objects which are in in the Boole 0 object.
import c4d def main() : objects = doc.GetActiveObjects(0) result = c4d.utils.SendModelingCommand( c4d.MCOMMAND_JOIN, objects, doc=doc) doc.InsertObject(result) c4d.EventAdd() main()
Is there a way without temporarily restructuring the objects?
On 16/02/2015 at 09:02, xxxxxxxx wrote:
the MCOMMAND_JOIN command has no further options that would allow to define it's behavior in that regard. You could create temporary clones of your objects, make them child objects of a temporary null object and use that null object as your argument as described in this thread.
On 23/02/2015 at 06:01, xxxxxxxx wrote:
Thank you Sebastian, I think I found a working solution.
import c4d import collections def join_objects(objects, doc) : r""" Connects all polygon or spline objects in the iterable *objects* into a single polygon or spline object and returns it. The operation will be hosted temporarily be hosted by the document *doc*. The resulting object's axis is at the world origin. It is already enough to pass the root object of a hierarchy that contains polygon and/or spline objects to join the complete hierarchy. :raise TypeError: If *objects* is not an iterable object or *doc* is not a BaseDocument. :raise ValueError: If the objects could not be joined. """ # Validate the input parameters. if not isinstance(objects, collections.Iterable) : raise TypeError('objects must be iterable') if not isinstance(doc, c4d.documents.BaseDocument) : raise TypeError('doc must be BaseDocument') # The root object of all objects that need to be joined. root = c4d.BaseObject(c4d.Onull) doc.InsertObject(root) context =  try: # Move all objects under the root object and save the # original state. for obj in objects: mg = obj.GetMg() context.append([obj, obj.GetUp(), obj.GetPred(), mg]) obj.Remove() obj.InsertUnder(root) obj.SetMg(mg) # Execute the join command on the root object. result = c4d.utils.SendModelingCommand( c4d.MCOMMAND_JOIN, root.GetChildren(), doc=doc) if not result: raise ValueError('could not join objects') # Just make sure the object is not in the hierarchy somewhere # and reset the objects matrix as it is strangely offset after # the command executed. result.Remove() result.SetMl(c4d.Matrix()) result.SetName(context.GetName()) return result finally: # Restore the original states of all objects and the document. root.Remove() for obj, parent, pred, mg in context: obj.Remove() if pred: obj.InsertAfter(pred) elif parent: obj.InsertUnder(parent) obj.SetMg(mg)
There seems to be a bug when passing [root] instead of root.GetChildren() as it does not only
use root and its child objects for joining but also roots neighbors on the same hierarchy level.
On 24/02/2015 at 01:22, xxxxxxxx wrote:
great that you found a solution. If you think you found a bug please post some simple code with the described behavior in the Bug subforum. Thanks.