MCOMMAND_JOIN for objects with different parents



  • On 16/02/2015 at 02:01, xxxxxxxx wrote:

    Hi

    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[0])
        c4d.EventAdd()
      
    main()
    

    Is there a way without temporarily restructuring the objects?

    Thanks,
    Niklas



  • On 16/02/2015 at 09:02, xxxxxxxx wrote:

    Hello,

    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.

    Best wishes,
    Sebastian



  • 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[0].Remove()
            result[0].SetMl(c4d.Matrix())
            result[0].SetName(context[0][0].GetName())
            return result[0]
      
        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.

    Best,
    Niklas



  • On 24/02/2015 at 01:22, xxxxxxxx wrote:

    Hello,

    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.

    Best wishes,
    Sebastian


Log in to reply