0

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! :)

1 Answers1

1

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)
robthebloke
  • 9,331
  • 9
  • 12
  • Your answer helped me understand a bunch that hadn't clicked about nurbs curves and knots - thank you!! – anotherAmy Mar 10 '23 at 22:40
  • No worries! The above is a very simple explanation of knots - there are a few other things you can do (i.e. duplicate knot values, to pull the curve towards a particular control point). You can also choose the knot range, which can remap the 'u' value. So taking the example with 5 control points, 0,0,0,1,2,2,2 will mean the curve point will be 0->2. However, 0,0,0,0.5,1,1,1 will restrict the value to 0 to 1. The only restrictions are that you need to make sure the knot values are monotonic (i.e. each knot is never less than the last), and that you have 2 more knots than control points... – robthebloke Mar 11 '23 at 00:30