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$
2
  • 1
    $\begingroup$ You may want to use answer provided by ThomasL. Also for other reference link by Jeremy Behreandt. $\endgroup$
    – Ratt
    Jan 1, 2019 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, 2019 at 8:34

1 Answer 1

2
$\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$
2
  • $\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, 2019 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, 2019 at 22:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .