Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    MCOMMAND_JOIN for objects with different parents

    Scheduled Pinned Locked Moved PYTHON Development
    4 Posts 0 Posters 502 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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[URL-REMOVED]. Thanks.

            Best wishes,
            Sebastian


            [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

            1 Reply Last reply Reply Quote 0
            • First post
              Last post