CSO from virtual objects
-
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
-
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]
byspline = 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 -
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.c4dmy 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.
-
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
-
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)
Cheers,
Maxime.