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!
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It only takes a minute to sign up.Sign up to join this community
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 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 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)