Scripting Creation Control Splines/Curves like Maya?


Hi, Just wondering, is there a way to script the creation of control splines/curves like in Maya? I’m trying to build a control library where I can just pull them out when I’m rigging. In Maya, the action is recorded so I can just drag and drop them and just click them to appear.
You can see an illustration of what I am aiming for here:

Is there a similar method in C4D?

P.S. The script log does not record the creation of splines
PPS. I understand that you can create control library by just dropping them in Content browser but I’m interested in doing this via script.


It’s not really hard. But it’s a bit long in the tooth to create a curved spline opposed to a spline with sharp edges.
First. Here’s a simple script that will create a square spline object with hard edges.
Changing the number of points and their positions will let you create different shapes:

import c4d
def main():    
    numPoints = 4  #<---Change as needed
    spline = c4d.BaseObject(c4d.Ospline)
    #Set the point positions here
    spline.SetPoint(0, c4d.Vector(-100, 0, -100))
    spline.SetPoint(1, c4d.Vector(-100, 0, 100))
    spline.SetPoint(2, c4d.Vector(100, 0, 100))
    spline.SetPoint(3, c4d.Vector(100, 0, -100))
    spline[c4d.SPLINEOBJECT_CLOSED] = True

if __name__=='__main__':

To create a smooth curved spline you need to create bezier handles and set those handle positions as well as the point positions.
The positions of the handles determines the curve of the spline.
It’s a bit more code to deal with. Plus. There’s a question of how you want to do the task itself:

  • Hard coded by hand
  • Looping through an existing spline’s points and bezier handles and extracting the data. then using that date to re-create it from code

It’s much simpler to save them to the content browser. Or to a .c4d file.



Yeah, saving your presets to the content browser under ‘User Presets’ is probably a smoother way to go in Cinema 4D. You even get thumbnails for browsing them.
But as Scott says, it’s all there in python but not via the kind of ‘macro’ recording you can use in Maya.


Thanks Scott Ayers and Decade

@Scott Ayers

Works as expected! I do not need the bezier handles as my interpolation will be B-spline.
The only problem I have is doing it hard-coded. I’m not familiar with the second method (Looping through an existing spline’s points. . .)

Thanks again mate!


Looping through the points is very simple. But there is one little thing that could trip you up.
If you’re saving these controllers as stand alone object’s. You’ll probably want the point positions in world space coordinates.
But when making spline controllers it’s probably a given that it’s going to be a child of another object. And when getting the point positions you’ll need to use matrix stuff to get the world positions from them.
It’s not hard. But matrix stuff is scary looking if you’ve never used it

This will print the world point positions even if it’s a child of another object:

import c4d
def main():
    #Check to see if you have an object selected(your spline)
    #And also check if it's an editable object
    #If either one is False the script safely stops here without errors
    obj = doc.GetActiveObject()
    if not obj and obj.GetType() != c4d.Opolygon: return
    #Loop through the spline's points and prints their index#s and positions
    #Rather than printing the data you can also save it to a text file...or do whatever you want

    pnts = obj.GetAllPoints()
    for i,v in enumerate(pnts):
        #If your selected spline is the child of another object
        #This code prints the spline's point index#s and their global positions
        if obj.GetUp():
            objMtx = obj.GetMg()     
            print i, objMtx.Mul(pnts[i])                   
        #If the spline has no parent
        #This code print the spline's point index#s and their global positions
            print i,v

if __name__=='__main__':