# Create curve from Numpy Array using Python

I have looked through previous questions on this and many other boards and I cannot seem to find a previous answer.

I have a largish Numpy generated ndarray that represents a harmonograph output (40000,3) using coords_list=np.column_stack((x,y,z)) of the individual axis outputs. Its all in one plane at the moment but this may change. Snippet shown below.

[[ 9.66087215e-01  1.78218213e-01  0.00000000e+00]
[ 9.81957877e-01  2.04711827e-01  0.00000000e+00]
[ 9.97284974e-01  2.31680099e-01  0.00000000e+00]
...
[-5.26862572e-07 -5.59294782e-05  0.00000000e+00]
[ 4.18313552e-07 -3.48825009e-05  0.00000000e+00]
[ 5.71013430e-07 -1.62274906e-05  0.00000000e+00]]


Is blender to be able to read this array to create a curve. I've seen a number of questions that are similar but when I replace the list with an array I get errors as a list was expected rather than an array.

For example - ( How to make a curve path from scratch given a list of (x, y, z) points?). Many others seem to casually say that the lists can be replaced by an array but with no examples, I am a bit flummoxed.

I have also looked at using the foreach_set method to extract vertices from the NumPy array. But it's way over my head at the moment.

Do I need to convert my array to another format so they can define a curve?

• I have also looked at this. Note the comment regarding the array replacement. link Commented May 27, 2020 at 15:40

Create POLY type curve from numpy array

Script below creates a POLY type curve from 4d SplinePoint.co numpy array.

Script result in edit mode

import bpy
import numpy as np

def flatten(*args):
c = np.empty(sum(arg.size for arg in args))
l = len(args)
for i, arg in enumerate(args):
c[i::l] = arg
return c

context = bpy.context

# emulate numpy data
x = np.arange(0, 10, 0.1)
y = 2 * np.sin(x)
z = np.cos(4 * x)
w = np.ones(len(x))

cu = bpy.data.curves.new(name="poly", type='CURVE')
cu.dimensions = '3D'

spline = cu.splines.new('POLY') # poly type
# spline is created with one point add more to match data
spline.points.foreach_set("co", flatten(x, y, z, w))

ob = bpy.data.objects.new("Poly", cu)


For a simple two point NURBS curve from local coordinates (0, 0, 0) to (1, 1, 1) the coordinates can be defined

NURBS

For NURBS required to define the end_path_u How to specify Nurbs path vertices in python?

Have introduced for each point having radius of r and setting this as well.

# emulate numpy data
x, y, z, w, r = np.array(
(
(0, 0, 0, 1, 0.5),
(1, 1, 1, 1, 3.0),
)
).T
cu = bpy.data.curves.new(name="poly", type='CURVE')
cu.dimensions = '3D'

spline = cu.splines.new('NURBS') # poly type
# spline is created with one point add more to match data

Notice in the foreach_ methods require us to ravel (or flatten) the array. Flattening data as shown in https://blender.stackexchange.com/a/172973/15543 the stackoverflow link suggests slicing is quickest.