A new version of Cineversity has been launched. This legacy site and its tutorials will remain accessible for a limited transition period

Visit the New Cineversity

Navigation

 ·   Wiki Home
 ·   Categories
 ·   Title List
 ·   Uncategorized Pages
 ·   Random Page
 ·   Recent Changes
 ·   RSS
 ·   Atom
 ·   What Links Here

Search:

 

Create or Find Page:

 

View Python: Generator

The Python Generator object is a pre-built wrapper for a Python ObjectData plugin (much like a script is a wrapped CommandData plugin). This provides a convenient way to experiment and create simple Generator objects via Python without writing the full script. Keep in mind that this object only provides a generator - in order to create a deformer you must write a full ObjectData plugin.

Within the Generator, you enter Python code which will generate an object. By default, a cube is generated by simply instancing a new Cube BaseObject and returning it:

 

import c4d

def main():
    return c4d.BaseObject(c4d.Ocube)

 

UserData Input

You can, of course, return a different object - and use userdata elements to adjust the object parameters. Note that op provides easy reference to the Generator object.

 

import c4d

def main():
    cone = c4d.BaseObject(c4d.Ocone)
    cone[c4d.PRIM_CONE_TRAD] = op[c4d.ID_USERDATA,1]
    return cone

 

Object Inputs - Pipe Generator

Many C4D generators use their children as inputs, and you can do that here as well. Simply get the first child with op.GetDown() or all objects with op.GetChildren(). In general, you should get a clone of the input object rather than making changes to the object itself.

You can also create entire hierarchies of objects - simply generate the hierarchy and return the topmost object. The full generated hierarchy will be seen if you select the Generator and run MakeEditable.

Here’s an example of a simple Pipe Generator:

 

import c4d

def main():
    #Get the child object (to use as the sweep spline)
    #Use GetClone so we aren't working on the object itself
    source = op.GetDown().GetClone() 

    #Create a Circle Primitive to act as the sweep profile
    circle = c4d.BaseObject(c4d.Osplinecircle) 
    #Set the radius based on UserData 1
    circle[c4d.PRIM_CIRCLE_RADIUS] = op[c4d.ID_USERDATA,1]
    
    #Create a new SweepNURBS
    sweep = c4d.BaseObject(c4d.Osweep)
    
    #Insert the source sweep spline under the SweepNURBS
    source.InsertUnder(sweep)
    
    #Insert the circle profile spline under the SweepNURBS
    circle.InsertUnder(sweep)
    
    #Return the SweepNURBS
    return sweep

 

Modeling Commands - Edge to Spline

You can also use modeling commands to generate new objects. Again, you’ll want to make sure to perform all actions on a clone of the source object, so you aren’t directly modifying the object in the hierarchy. Here’s a script that outputs a spline for the currently selected edges of a child.

 

import c4d
 
def main():
    #Get the child object
    obj = op.GetDown()
    
    #We can only continue if there was a child
    if not obj: return None

    #Also need to check that it's a poly object
    if not obj.CheckType(c4d.Opolygon): return None
    
    #And that at least one edge is selected
    if obj.GetEdgeS().GetCount() < 1: return None

    #Get a clone
    #Always work on the clone so we aren't changing the object in the OM
    source = obj.GetClone()
    
    #Run EdgeToSpline - returns a Boolean (True)
    #Note that SendModelingCommand expects a list []!
    if c4d.utils.SendModelingCommand(c4d.MCOMMAND_EDGE_TO_SPLINE, [source]):
        #Splines are created as children of the source object
        #Return a clone of the splines, otherwise the won't be "Alive"
        return source.GetDown().GetClone()
    

 

Note that this example requires you to select an edge on the source object (child of the Generator). Also, the generator’s cache doesn’t detect selection changes, so it only really updates properly if Optimize Cache is disabled. Unfortunately with Optimize Cache disabled the Editor Render doesn’t work properly - this is a limitation I think that can only be overcome with a full ObjectData plugin.

Category:Scripting

Categories: