Featured post

new redirect for blender.org bpy docs.

http://www.blender.org/api/blender_python_api_current/ As of 10/11 november 2015 we can now link to the current api docs and not be worr...

July 21, 2012

NURBS tools blender

I spent far too much time manually adjusting NURBS surfaces yesterday, today i will investigate writing some tools to make the NURBS work be less repetitive.

With an active NURBS surface selected,
>>> bpy.context.active_object.type
'SURFACE'
Maybe count the surface points?
>>> len(bpy.context.active_object.data.splines[0].points)
16
The inclusion of splines[0] suggest as expected that the surface object can have multiple separate surfaces. They would be accessed using splines[1], splines[2] etc.

OK, let's see if we can throw some coordinates at it.
bpy.context.active_object.data.splines[0].points[0].co = (1.0, 0.0 ,0.0, 1.0)
That even moves the NURBS point while in edit mode, good. Important to note is the trailing 4th parameter, weight. (x,y,z,w). Weight is how much the point pulls the surface towards it. Experiment with it and you will get some very organic shapes.
import bpy

mdata = bpy.context.active_object.data.splines[0].points

for idx, po in enumerate(mdata):
    if po.select:
        print(idx)
The above prints the indices of the currently selected surface points.

Is it possible to print the 'indices' of neighbouring points? This post will go nowhere until I find a way. But let's soldier on! Here is some NURBS Surface bpy access. This seems very interesting.
>>> for i in bpy.context.object.data.splines[0].points:
...   print(i.co)
... 
Vector (-1.5000, -1.5000, 1.7868, 1.0000)
Vector (-1.5000, -0.5000, 0.0000, 1.0000)
Vector (-1.5000, 0.5000, 0.0000, 1.0000)
Vector (-1.5000, 1.5000, 0.0000, 1.0000)
Vector (-0.5000, -1.5000, 0.0000, 1.0000)
Vector (-0.5000, -0.5000, 1.0000, 1.0000)
Vector (-0.5000, 0.5000, -1.5330, 1.0000)
Vector (-0.5000, 1.5000, 0.0000, 1.0000)
Vector (0.5000, -1.5000, 0.0000, 1.0000)
Vector (0.5000, -0.5000, 1.0000, 1.0000)
Vector (0.5000, 0.5000, -1.5330, 1.0000)
Vector (0.5000, 1.5000, -1.2242, 1.0000)
Vector (1.5000, -1.5000, 0.0000, 1.0000)
Vector (1.5000, -0.5000, 0.0000, 1.0000)
Vector (1.5000, 0.5000, 0.0000, 1.0000)
Vector (1.5000, 1.5000, -1.2242, 1.0000)

#or
>>> for i in bpy.context.object.data.splines[0].points:
...   print(i.co.x, i.co.y, i.co.z, i.co.w)
... 
-1.5 -1.5 1.786833643913269 1.0
-1.5 -0.5 0.0 1.0
-1.5 0.5 0.0 1.0
-1.5 1.5 0.0 1.0
-0.5 -1.5 0.0 1.0
-0.5 -0.5 1.0 1.0
-0.5 0.5 -1.5330145359039307 1.0
-0.5 1.5 0.0 1.0
0.5 -1.5 0.0 1.0
0.5 -0.5 1.0 1.0
0.5 0.5 -1.5330145359039307 1.0
0.5 1.5 -1.2242242097854614 1.0
1.5 -1.5 0.0 1.0
1.5 -0.5 0.0 1.0
1.5 0.5 0.0 1.0
1.5 1.5 -1.2242242097854614 1.0

What about NURBS Surfaces?

My interest at present lies in NURBS Surfaces that use the end points (around the circumference to define the boundary). The next few snippets will show more ways to get information from an existing NURBS surface and ultimately how to generate a surface using python/bpy . Or maybe not.. because it has no python binding yet:/
import bpy
surface_points = bpy.context.object.data.splines[0].points

points = [point.co for point in surface_points]

"""

points = [  Vector((-1.5, -1.5, 1.2507835626602173, 1.0)), 
            Vector((-1.5, -0.5, 0.0, 1.0)), 
            Vector((-1.5, 0.5, 0.0, 1.0)), 
            Vector((-1.5, 1.5, 0.0, 1.0)), 
            Vector((-0.5, -1.5, 0.0, 1.0)), 
            Vector((-0.5, -0.5, 0.699999988079071, 1.0)), 
            Vector((-0.5, 0.5, -1.0731102228164673, 1.0)), 
            Vector((-0.5, 1.5, 0.0, 1.0)), 
            Vector((0.5, -1.5, 0.0, 1.0)), 
            Vector((0.5, -0.5, 0.699999988079071, 1.0)), 
            Vector((0.5, 0.5, -1.0731102228164673, 1.0)), 
            Vector((0.5, 1.5, -0.856956958770752, 1.0)), 
            Vector((1.5, -1.5, 0.0, 1.0)), 
            Vector((1.5, -0.5, 0.0, 1.0)), 
            Vector((1.5, 0.5, 0.0, 1.0)), 
            Vector((1.5, 1.5, -0.856956958770752, 1.0))]
            
"""