Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    CSO from virtual objects

    Cinema 4D SDK
    python
    2
    5
    1.0k
    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.
    • P
      pyr
      last edited by

      i only need the tracer object as a return value but if i do so the results are empty. so how do i get the cso from the tracer?
      a normal cso from the tracer itself is empty
      if i put all objects into a list the console told me that the object document don't match the document from the modeling command.

      import c4d
      #Welcome to the world of Python
      
      
      def createOutline(invert):
      	
      	bc = c4d.BaseContainer()
      	bc.SetData(c4d.MDATA_SPLINE_OUTLINE, op[c4d.ID_USERDATA,2] * invert)
      	bc.SetData(c4d.MDATA_SPLINE_OUTLINESEPARATE, True)
      	spline = op[c4d.ID_USERDATA,1]    
      	return c4d.utils.SendModelingCommand(command= c4d.MCOMMAND_SPLINE_CREATEOUTLINE,list= [spline],   mode= c4d.MODELINGCOMMANDMODE_ALL, bc = bc, doc        = doc)[0]
      
      
      
      
      def main():
      
      	ll = [] 
      	null = c4d.BaseObject(c4d.Onull)      
      	
      	spline = createOutline(-1)        
      	spline.InsertUnder(null) 
      	
      	
      	matrix = c4d.BaseObject(1018545)   
      	matrix.InsertUnder(spline)
      	matrix[c4d.ID_MG_MOTIONGENERATOR_MODE] = 0
      	matrix[c4d.MG_SPLINE_MODE] = 1
      	matrix[c4d.MG_SPLINE_STEP] = op[c4d.ID_USERDATA,3]
      	matrix [c4d.MG_OBJECT_LINK] = spline       
      	
      	
      	tracer = c4d.BaseObject(1018655)
      	tracer.InsertUnder(matrix)
      	inexclude = c4d.InExcludeData()
      	inexclude.InsertObject(matrix,1)    
      	tracer[c4d.MGTRACEROBJECT_OBJECTLIST] = inexclude
      	tracer[c4d.MGTRACEROBJECT_MODE] = 2
      	tracer[c4d.SPLINEOBJECT_TYPE] = 3
      	tracer[c4d.SPLINEOBJECT_SUB] = 6
      	tracer[c4d.SPLINEOBJECT_INTERPOLATION] = 1  
      	
      	return null
      
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @pyr I was not able to reproduce your issue. I attached my scene.

        On a side note, an this is important and maybe why I don't get any issue but I replaced spline = op[c4d.ID_USERDATA,1] by spline = op[c4d.ID_USERDATA,1].GetClone(c4d.COPYFLAGS_NONE). A Python Generator should never modify stuff outside of him. So When you Get the spline, you actually get the spline within the scene and you apply the modelingCommand to the object within the scene which is not correct and may crash Cinema 4D.

        0_1547459168000_cso-from-object.c4d

        If you have any question please, write explicitly in which context you are executing your python script and also in which Cinema 4D version.
        Cheers,
        Maxime

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 2
        • P
          pyr
          last edited by

          Hey,
          unfortunally this won't work in R18, and it gives me not the desired result.

          I updated my sourcecode a little bit and now i use a clone from my spline to create the outline

          import c4d
          #Welcome to the world of Python
          
          
          def createOutline(spline,invert):
          
          	bc = c4d.BaseContainer()
          	bc.SetData(c4d.MDATA_SPLINE_OUTLINE, op[c4d.ID_USERDATA,2] * invert)
          	bc.SetData(c4d.MDATA_SPLINE_OUTLINESEPARATE, True)
          	return c4d.utils.SendModelingCommand(command= c4d.MCOMMAND_SPLINE_CREATEOUTLINE,list= [spline],   mode= c4d.MODELINGCOMMANDMODE_ALL, bc = bc, doc        = doc)[0]
          
          def main():
          
          	spline = op[c4d.ID_USERDATA,1].GetClone()
          
          	null = c4d.BaseObject(c4d.Onull)
          
          	newSpline = createOutline(spline,-1)
          	newSpline.InsertUnder(null)
          
          	matrix = c4d.BaseObject(1018545)
          	matrix.InsertUnder(newSpline)
          	matrix[c4d.ID_MG_MOTIONGENERATOR_MODE] = 0
          	matrix[c4d.MG_SPLINE_MODE] = 1
          	matrix[c4d.MG_SPLINE_STEP] = op[c4d.ID_USERDATA,3]
          	matrix [c4d.MG_OBJECT_LINK] = newSpline
          
          	tracer = c4d.BaseObject(1018655)
          	tracer.InsertUnder(matrix)
          	inexclude = c4d.InExcludeData()
          	inexclude.InsertObject(matrix,1)
          	tracer[c4d.MGTRACEROBJECT_OBJECTLIST] = inexclude
          	tracer[c4d.MGTRACEROBJECT_MODE] = 2
          	tracer[c4d.SPLINEOBJECT_TYPE] = 3
          	tracer[c4d.SPLINEOBJECT_SUB] = 6
          	tracer[c4d.SPLINEOBJECT_INTERPOLATION] = 1
          
          	return tracer #not alive
          

          i also uploaded a scenefile:
          0_1547554705314_test.c4d

          my plan is to return only the tracer as an spline object to the scene all other objects are only helpers to get the correct shape from the source spline.

          1 Reply Last reply Reply Quote 0
          • P
            pyr
            last edited by pyr

            Ok, another try:

            i actually don't need the matrix and the tracer if i use a spline help and create a new spline object it works like a sharm.

            sampleSpline = c4d.SplineObject(samples,c4d.SPLINETYPE_BSPLINE)
            newPos = []
            for i in range(0,samples):
            	newPos.append(sh.GetPosition(sh.GetOffsetFromReal(i*step),0,realoffset = True,smooth =True))
            sampleSpline.SetAllPoints(newPos)
            sampleSpline.ResizeObject(samples,1)
            sampleSpline.SetSegment(0,samples,True)
            

            sh is a splinehelp from my spline offset, the only thing that bothers me is that the close segment seems to be ignored.

            also a solution for the tracer based solution would be great

            sampleSpline[c4d.SPLINEOBJECT_CLOSED] = True #close the spline

            1 Reply Last reply Reply Quote 0
            • M
              m_adam
              last edited by

              Hey @pyr, the tracer object is inserted, only under the null object, which is stored nowhere. That means at the end of the function, the Python Garbage collect actually free memory and all useless stuff it doesn't need anymore. And since the null which holds everything is stored nowhere else, the null is deleted and all its children even your tracer.
              That's lead to return a no-valid BaseObject.

              So the best way is to get a clone (aka object not inside any hierarchy) from a cache of the Tracer.

              With that's said there is no way to make the Python Generator returning a spline since it's not registered with OBJECT_ISSPLINE flag. So the only way will be to make a plugin. Here the code it's already looking very nice! Nice idea indead! 😄

              import c4d, os
              
              PYOUTLINE_ID  = 1000001  #Plugin ID
              
              class Ooutline(c4d.plugins.ObjectData):
              
                  def createOutline(self, spline, invert):
              
                      bc = c4d.BaseContainer()
                      bc.SetData(c4d.MDATA_SPLINE_OUTLINE, invert)
                      bc.SetData(c4d.MDATA_SPLINE_OUTLINESEPARATE, True)
                      res = c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_SPLINE_CREATEOUTLINE,
                                                          list=[spline],
                                                          mode=c4d.MODELINGCOMMANDMODE_ALL,
                                                          bc=bc)
                      if not res:
                          return False
              
                      return res[0]
              
                  def GetContour(self, op, doc, lod, bt):
                      # Get a clone of the spline
                      spline = op[c4d.ID_USERDATA,1].GetClone()
              
                      # Create a null used to define our hierarchy
                      null = c4d.BaseObject(c4d.Onull)
              
                      # Execute the CreateOutline Function in the created document.
                      newSpline = self.createOutline(spline, op[c4d.ID_USERDATA,2] * -1)
                      if not newSpline: return
              
                      # Insert it into the Tracer and set up a hierarchy to get things done
                      newSpline.InsertUnder(null)
              
                      matrix = c4d.BaseObject(1018545)
                      matrix.InsertUnder(newSpline)
                      matrix[c4d.ID_MG_MOTIONGENERATOR_MODE] = 0
                      matrix[c4d.MG_SPLINE_MODE] = 1
                      matrix[c4d.MG_SPLINE_STEP] = op[c4d.ID_USERDATA,3]
                      matrix [c4d.MG_OBJECT_LINK] = newSpline
              
                      tracer = c4d.BaseObject(1018655)
                      tracer.InsertUnder(matrix)
                      inexclude = c4d.InExcludeData()
                      inexclude.InsertObject(matrix,1)
                      tracer[c4d.MGTRACEROBJECT_OBJECTLIST] = inexclude
                      tracer[c4d.MGTRACEROBJECT_MODE] = 2
                      tracer[c4d.SPLINEOBJECT_TYPE] = 3
                      tracer[c4d.SPLINEOBJECT_SUB] = 6
                      tracer[c4d.SPLINEOBJECT_INTERPOLATION] = 1
              
                      # Create a temporary document to compute the cache of the tracer
                      workDoc = c4d.documents.BaseDocument()
                      workDoc.InsertObject(null)
                      workDoc.ExecutePasses(bt, False, False, True, c4d.BUILDFLAGS_EXPORT)
              
                      # Get the SplineObject from the tracer cache
                      tracerSpline = tracer.GetCache()
                      if not tracerSpline: return
                      
                      outSpline = tracerSpline.GetClone()
              
                      # Close the spline
                      outSpline[c4d.SPLINEOBJECT_CLOSED] = True
                      
                      return outSpline
              
              
              if __name__ == "__main__":
                  bmp = c4d.bitmaps.BaseBitmap()
                  dir, file = os.path.split(__file__)
                  fn = os.path.join(dir, "res", "icon.tif")
                  bmp.InitWith(fn)
                  result          = c4d.plugins.RegisterObjectPlugin(
                      id          = PYOUTLINE_ID, 
                      str         = "Test", 
                      g           = Ooutline, 
                      description = "Ooutline", 
                      info        = c4d.OBJECT_GENERATOR | c4d.OBJECT_ISSPLINE, 
                      icon        = None)
              

              Very Cool
              Cheers,
              Maxime.

              MAXON SDK Specialist

              Development Blog, MAXON Registered Developer

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