2
$\begingroup$

I'm trying to write a script which creates a Nurbs path curve, bevels it, and then stores the location of each vertex/point in that curve. I've been writing it based on the code displayed in the info panel, but it doesn't show what the vertices are supposed to be called - so I can't refer to them in the script.

Update: After following Ratt's links, I modified ThomasL's code for Nurbs Path and am now stuck again, though it's still progress. Below is one version I tried out, but the error message says that Curve has no attribute path_points. Of course it doesn't, because I made that up because I don't know what the Nurbs Path equivalent for bezier_points is.

import bpy
import random

def pathPointLoc(cu, typ, points):

    for (n) in enumerate(points):
        nurb = cu.path_points[n]
        print(nurb.location)

    return

cu = bpy.data.curves.new("MyCurve", "CURVE")
ob = bpy.data.objects.new("MyCurveObject", cu)
scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob

cu.bevel_object = bpy.data.objects["BezierCircle"]
cu.taper_object = bpy.data.objects["BezierCircle"]

pathPointLoc(cu, "NURBS", [(0,0,0,1), (0,0,1,random.randint(1,4)), (0,1,1,1), (1,4,1,1)] )
$\endgroup$
  • 1
    $\begingroup$ You may want to use answer provided by ThomasL. Also for other reference link by Jeremy Behreandt. $\endgroup$ – Ratt Jan 1 at 22:04
  • $\begingroup$ Thanks! I learned some new stuff from those, but unfortunately the problem still persists :( I've added my version of ThomasL's code though. $\endgroup$ – flipsies Jan 4 at 8:34
1
$\begingroup$

Based on your starting point script below. Added reference to spline types since bezier curve points are stored differently than nurbs curve points.

import bpy
import random


def pathPointLoc(cpath, points):

    if cpath.type in ['NURBS', 'POLY']:
        cpath.points.add(len(points)-1)
        for (index, point) in enumerate(points):
            cpath.points[index].co = point
            print(cpath.points[index].co)
        cpath.use_endpoint_u = True
    elif cpath.type in ['BEZIER']:
        cpath.bezier_points.add(len(points)-1)
        for (index, point) in enumerate(points):
            x, y, z, w = point
            cpath.bezier_points[index].co = x, y, z
            cpath.bezier_points[index].handle_left = x-1, y-1, z-1
            cpath.bezier_points[index].handle_right = x+1, y+1, z+1
            print(cpath.bezier_points[index].co)
    return

cu = bpy.data.curves.new("MyCurveData", "CURVE")
ob = bpy.data.objects.new("MyCurveObject", cu)
polyline = cu.splines.new('NURBS')  # 'POLY''BEZIER''BSPLINE''CARDINAL''NURBS'

scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob

cu.dimensions = '3D'
cu.bevel_object = bpy.data.objects["BezierCircle"]
cu.taper_object = bpy.data.objects["BezierCircle"]

pts = [(0, 0, 0, 1), (0, 0, random.randint(1,4), 1), (0, 1, 1, 1), (1, 4, 1, 1)]
pathPointLoc(polyline, pts)
$\endgroup$
  • $\begingroup$ Thank you! This works well. And thanks for adding the if-else for the Bezier too, it'll definitely come in handy :) Also I haven't understood what len is for; could you elaborate? It seems important. $\endgroup$ – flipsies Jan 4 at 22:22
  • 1
    $\begingroup$ len is used to count how many vertex points you are adding. In this case we use cpath.points.add(len(points)-1) because when you initially create the spline polyline = cu.splines.new() it must have at least 1 point which is generated automatically. After we add the number of points from the list to the spline we set the position of the points in the for loops. $\endgroup$ – Ratt Jan 4 at 22:48

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.