12
$\begingroup$

I'm trying to create curves from a list of points, I have the xyz coordinates in text files. I could make it manually via the python console for a single curve, but I have to do it many times and I don't know how to correctly implement a loop.

How can I do that?

$\endgroup$
17
$\begingroup$

This should work:

import bpy

# sample data
coords = [(1,1,1), (2,2,2), (1,2,1)]

# create the Curve Datablock
curveData = bpy.data.curves.new('myCurve', type='CURVE')
curveData.dimensions = '3D'
curveData.resolution_u = 2

# map coords to spline
polyline = curveData.splines.new('NURBS')
polyline.points.add(len(coords))
for i, coord in enumerate(coords):
    x,y,z = coord
    polyline.points[i].co = (x, y, z, 1)

# create Object
curveOB = bpy.data.objects.new('myCurve', curveData)

# attach to scene and validate context
scn = bpy.context.scene
scn.objects.link(curveOB)
scn.objects.active = curveOB
curveOB.select = True
$\endgroup$
  • 3
    $\begingroup$ It creates a NURBS curve. The type for curveData.splines.new(type) can be chosen from ('POLY', 'BEZIER', 'BSPLINE', 'CARDINAL', 'NURBS'). $\endgroup$ – pink vertex Feb 4 '14 at 17:44
  • $\begingroup$ Thanks, but I already did something similar actually. Is there a way to make it a function that reads the coords from a text file passed as an argument? Something like CreatePolyLine('coords_file_name.txt')... $\endgroup$ – Matteo Caffini Feb 4 '14 at 20:15
  • 1
    $\begingroup$ If you install NumPy (which comes bundled with the Linux version), you could replace the fourth line with coords=np.loadtxt('filename.txt'), and add import numpy at the top... otherwise there's certainly other ways to read in a text file in Python. $\endgroup$ – Garrett Feb 4 '14 at 21:05
  • 6
    $\begingroup$ Note for anyone who finds this later, if you choose 'BEZIER' for the curveData.spline type you'll need to use .bezier_points.add() and .bezier_points[i].co instead of .points.add() and points[i].co. $\endgroup$ – Cody Reisdorf Dec 23 '14 at 0:02
  • 1
    $\begingroup$ For Bezier, the default (0,0,0) handles won't be adequate, you may want to set them to the points as well: .bezier_points[i].handle_left = .bezier_points[i].handle_right = .bezier_points[i].co $\endgroup$ – rfabbri Jun 16 '16 at 22:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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