I am looking for a solution to get the world x, y, z coordinates of a given UV parameter on a NURBS Curve Surface. The output should be a mathutils.Vector
, or at least a Python tuple.
Thanks in advance!
This isn't supported, in general Blender's nurbs support is quite basic.
Blender uses a method of calculating nurbs that steps over the curve in U and V directions at a fixed level of subdivisions (tessellated for drawing in the viewport), and there are no built-in methods to ray-cast into a nurbs surface, though such methods exist and could be added to Blender.
However if you really wanted its possible to take the nurbs data (before tessellation) and evaluate it from Python, but this would be quite an involved task.
As a simple solution you could just get the mesh of a nurbs object and (knowing the order of grid verts/faces), you could find the face that lies on a UV coord, then interpolate across the face... it wont give an accurate location but may be good-enough in some cases.
You can use the tessalation to get the coordinates as has been suggested like this (I tested this for a cylindrical nurb surface which is circular in u):
import bpy
# get spline surface information
ob = bpy.context.selected_objects[0]
splines = ob.data.splines.active
npts_per_knot_u = splines.resolution_u
npts_per_knot_v = splines.resolution_v
nknots_u = splines.point_count_u
nknots_v = splines.point_count_v
npts_u = npts_per_knot_u * nknots_u
npts_v = npts_per_knot_v * nknots_v
# duplicate to convert splines to mesh.
# v is the fast index and u (cyclic) the slow
bpy.ops.object.convert(target='MESH', keep_original=True)
ob_new = bpy.context.selected_objects[0]
rotscaleloc_matrix = ob_new.matrix_world
nvertices = len(ob_new.data.vertices)
for iu in range(npts_u):
for iv in range(npts_v):
# get vertex index:
ivertex = iu * npts_v + iv
x, y, z = rotscaleloc_matrix * ob_new.data.vertices[ivertex].co
print(x, y, z)