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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Stitch and Sew

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 1.4k 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 20/06/2018 at 05:53, xxxxxxxx wrote:

      Can I ask for an example of Stitch and Sew.
      Especially with the shift key to connect 2 edges with different number of points.

      Or if Stitch and Sew is not the best option to connect 2 edges with different number of points, what else to use?

      -Pim

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

        On 20/06/2018 at 06:21, xxxxxxxx wrote:

        Below code, always returns False.
        I have two separate polygon objects (Sphere and Cube), both with an Edge selection.
        I converted the edge selection also to a point selection, giving me the P1 and P2 I need.

        Setting the list with object to [obj1, obj2] did not solve the issue.

        import c4d
        from c4d import gui
          
        def main() :
            obj1 = doc.SearchObject("Sphere")
            obj2 = doc.SearchObject("Cube")
            
            obj1SelectedPoints = obj1.GetPointS()
            nrPoints = obj1.GetPointCount()
            for index in range(nrPoints) :
                if (obj1SelectedPoints.IsSelected(index)) :  
                    p1 = obj1.GetPoint(index)
                    break 
          
            obj2SelectedPoints = obj2.GetPointS()
            nrPoints = obj2.GetPointCount()
            for index in range(nrPoints) :
                if (obj2SelectedPoints.IsSelected(index)) :  
                    p2 = obj2.GetPoint(index)
                    break 
            
            print p1, p2
                                                
            bc = c4d.BaseContainer()
            bc.SetData(c4d.MDATA_STITCHANDSEW_OBJINDEX1, obj1)
            bc.SetData(c4d.MDATA_STITCHANDSEW_OBJINDEX2, obj2) 
            bc.SetData(c4d.MDATA_STITCHANDSEW_SHIFT, True)   
            bc.SetData(c4d.MDATA_STITCHANDSEW_P1, p1)
            bc.SetData(c4d.MDATA_STITCHANDSEW_P2, p2)
            print c4d.utils.SendModelingCommand(c4d.ID_MODELING_STITCHANDSEW_TOOL, [], c4d.MODELINGCOMMANDMODE_EDGESELECTION, bc)
          
            c4d.EventAdd()
          
        if __name__=='__main__':
            main()
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 21/06/2018 at 03:48, xxxxxxxx wrote:

          Hi pgrooff.

          Actually, STITCHANDSEW have a different implementation compared to other ModelingCommand.
          First of all, you need to pass a document and the first object.

          Then additionally in MDATA_STITCHANDSEW_BC1, you have to set point id you actually want to stitch
          Here is the structure of this container (which is currently not documented).

          bc[0] = count of points you want to stitch for the first selection
          bc[10 to 9999] = point ID

          bc[10000] = count of points you want to stitch for the second selection
          bc[10010 and more] = point ID

          Points will be connected in the same order you fill the BaseContainer.
          For example bc[10] = 10 and bc[10010] = 20, you will connect the point ID 10 from the first obj to the point ID 20 of the second obj (which can be the same than the first object).

          So here an example which connects selected points.

          import c4d
            
          def GetPointIdSelected(obj) :
              if not obj:
                  return
              
              ptIds = list()
              ptCnt = obj.GetPointCount()
              bs = obj.GetPointS()
              for index, selected in enumerate(bs.GetAll(ptCnt)) :
                  if not selected: 
                      continue
                   
                  ptIds.append(index)
                  
              return ptIds
            
          def main() :
              obj1 = doc.SearchObject("Cube")
              obj2 = doc.SearchObject("Cube.1")
              
              l1 = GetPointIdSelected(obj1)
              l2 = GetPointIdSelected(obj2)
            
              con = c4d.BaseContainer()
              con[0] = len(l1) # cnt of ptn selected in first object
              con[10000] = len(l2)  # cnt of ptn selected in second object
              
              # assign pt ID for first object and make sure to not overwrite con[10000]
              for i in xrange(min(len(l1), 9989)) :  
                  con[10+i] = l1[i]
                  
              # assign pt ID for second object
              for i in xrange(len(l2)) :
                  con[10010+i] = l2[i]    
              
              bc = c4d.BaseContainer()
              bc.SetLink(c4d.MDATA_STITCHANDSEW_OBJINDEX1, obj1)
              bc.SetLink(c4d.MDATA_STITCHANDSEW_OBJINDEX2, obj2) 
              bc.SetData(c4d.MDATA_STITCHANDSEW_SHIFT, True)
              bc.SetContainer(c4d.MDATA_STITCHANDSEW_BC1, con)
              # Make sure to define [obj1] and doc
              c4d.utils.SendModelingCommand(c4d.ID_MODELING_STITCHANDSEW_TOOL, [obj1], c4d.MODELINGCOMMANDMODE_EDGESELECTION, bc, doc=doc)
            
              c4d.EventAdd()
            
          if __name__=='__main__':
              main()
          

          Cheers,
          Maxime

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

            On 21/06/2018 at 05:50, xxxxxxxx wrote:

            Great, thank you. I will test it, to see if i understand it.

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

              On 21/06/2018 at 07:11, xxxxxxxx wrote:

              Ok, I can get it to work if I define the point sequences manually. 
              Now of course the main question is how to get the correct sequence of the points to Stitch and Sew.

                  l1 = GetPointIdSelected(obj1)
                  l1 = [0,1,3,2]   #this way I define manually the points.
                                   #of course not the way to do it in a plugin.
              

              The sequence of the points is a bit random to me.
              For a cube, when you select one side, this returns [0,1,2,3] =  left under, left upper, right under and right upper.
              Of course I want it to be in left under, left upper, right upper and right under.
              Thus l1 = [0,1,3,2]

              How can I achieve or set both selection in the same way.
              E,g, counter clockwise?

              Also, what are MDATA_STITCHANDSEW_P1 and MDATA_STITCHANDSEW_P2?

              -Pim

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

                On 22/06/2018 at 06:11, xxxxxxxx wrote:

                Hi Pim,

                Unofortually there is no such way to know the selection order or anything like that, you have to make your own algorithm.

                After checking, MDATA_STITCHANDSEW_P1 and MDATA_STITCHANDSEW_P2, they are not used for the moment. So you can avoid them.

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