Get isoparm length through API

Hi,

Is it possible to get NURBS surface isoparm length with the Python API? I couldn’t find a method for this in the documentation.

I don’t want to extract a curve from the surface to get it’s length if possible.

Are you talking about python in maya API?

You can get a range of your UV with cmds.polyEvaluate( uvComponent=1)
Then get the U and V value for every point with cmds.polyEditUV(q=1)

By comparing the U and V values of each points you should be able to detect isoparms. By comparing min U/V and max U/V for each isoparm, you will get the length.

I should’ve been more clear. Yes, i mean maya api. But I’m talking about NURB surface isoparms.

In maya.cmds you can get it with arclen(). If you absolutely must stay in the api, I think you’d have to create a curveInfo node, feed it your isoparm (or a duplicateCurve made from the isoparm) and then query it.

The things is this is the method I’m using currently. But I don’t want to create a curve or an additional node in the scene just for that.
Ideally a method for this should have come with the MfnNurbsSurface. But apparently there’s no way doing it in code without creating temporary nodes.

I found a solution to this old issue here by Julian Mann posting here for others.

I made a change to his snippet that worked well for me by using curveFn.createWithEditPoints() instead of curveFn.create(). This allowed me to ignore the knot sequence and register the curve directly on the source surface. I also sampled the degree, form, etc from the source surface. I grabbed the eps with the following snippet.

vParam = 0
pts = []
    for uParam in range(tubeFn.numCVsInU):
        pts.append(tubeFn.getPointAtParam(uParam, vParam, world))

leaving his example intact here:

import pymel.core as pm

pts = ( [ 0,0,0 ], [  0,10,0 ], [  0,10,10 ], [ 0,0,10 ])
knots = [0,0,0,1,1,1]

curveFn = om.MFnNurbsCurve()

dataCreator = om.MFnNurbsCurveData()
curveDataObject = dataCreator.create()

curveFn.create(pts, knots, 3, om.MFnNurbsCurve.kOpen, False, False, curveDataObject)

for i in range(11):
    point = curveFn.getPointAtParam (i/10.0)
    pm.spaceLocator(p=(point.x, point.y, point.z))

hey, Zach. this seems promising. thanks for sharing.

though a question about what you did there. I’m new to API so, please bear with me.

In your little snippet you get uParam from the number of CVs. I think this is wrong. There should be no relation between cv count and parameters, at least in this case.
I’m trying to use createWithEditPoints now, and I think what we need is knots and their world positions.

Did your snippet work for you?

Thanks, Zack.
I was able to create a curve which virtually overlaps with the result of the “Duplicate Surface Curves” command with the help of the createWithEditPoints method (used numKnotsInU to find the knots). numKnotsInU returns knot parameters, and from that I get world positions of the knots.

Though something strange occurs and to which I don’t have an elegant or “correct” solution.

The result itself never works with the createWithEditPoints method. In the case of open curves I need to remove repeated knot values from the array and for periodic curves I removed the last four knots to get it to work.

How do I get reliable and expected results from getPointAtParam or make the result work everytime with createWithEditPoints? Does anyone have any idea?