I'm trying to create a function that takes a list of xyz points and creates a nurbs curve in Autodesk Maya, using python.
To generate the points, I've been grabbing the points from an existing curve that was made manually, using this:
import maya.cmds as cmds
import maya.api.OpenMaya as OpenMaya2
mayaSel = cmds.ls(selection=True)[0]
msel = om2.MSelectionList()
msel.add(mayaSel)
curveMob = msel.getDependNode(0)
curvFn = om2.MFnNurbsCurve(curveMob)
points = om2.MPointArray()
points = curvFn.cvPositions()
pointArray = []
for point in points:
pointTuple = (point.x, point.y, point.z)
pointArray.append(pointTuple)
print (pointArray)
I then pass the given pointArray to this:
curv = cmds.curve(p=pointArray)
And it is working! The curve is being created - But the ends of the curve seem to to overshoot somehow, making the shape slightly different to the original curve:
Original Curve: IMG
Curve created from the control points of the original curve: IMG
I tried messing with the open/close curve options, and while it does close the curve, I can't find a way to maintain the original shape.
I suspect it maaay have something to do with the knots of the curve? But I'm not too sure, and my knowledge of curve knots is a bit limited. If anyone can point me in the right direction, I would really appreciate it! :)
Probably something to do with the knots yes. It looks as though the original curve was periodic? (i.e. the curve loops back on itself, to form a closed loop), but it looks as though your recreated curve has been created as an open curve type?
Maya's knots are a little non-standard, but basically if you have a strip of cv's to form a curve that is unconnected (i.e. non-periodic), then the number of knots should be the number of CV's + 2. i.e. the knot vectors will follow this pattern:
4CVs -> 0, 0, 0, 1, 1, 1
5CVs -> 0, 0, 0, 1, 2, 2, 2
6CVs -> 0, 0, 0, 1, 2, 3, 3, 3
7CVs -> 0, 0, 0, 1, 2, 3, 4, 4, 4
etc, etc
For periodic curves, you need to set the curve type to be periodic (instead of open, which is the default), and the knot vectors will follow this pattern instead:
4CVs -> -2, -1, 0, 1, 2, 3
5CVs -> -2, -1, 0, 1, 2, 3, 4
6CVs -> -2, -1, 0, 1, 2, 3, 4, 5
7CVs -> -2, -1, 0, 1, 2, 3, 4, 5, 6
etc, etc
I am assuming that you are specifying the curves using degree 3 here (i.e. cubic, because higher degrees are not typically all that useful....)
For completeness, Maya also provides a closed curve type, which also forms a loop, however the continuity is NOT maintained when crossing from the first to last control points.
I'm assuming that adding the periodic flag will fix this?
curv = cmds.curve(p=pointArray, periodic=True)