1
$\begingroup$

I want to do this:

myLocation = (-0.9056, -0.0628, -3.000)
SplinePoint.co = myLocation

Where myLocation is a blender Vector.

i.e. I want to assign a vector to a spline point's co attribute ...

in other words I want to convert a vector object into an array that matches the co attribute per:

https://docs.blender.org/api/blender_python_api_current/bpy.types.SplinePoint.html?highlight=splinepoint

Note: SplinePoint.co requires 4 values in its array (not sure why???) This is the error I'm getting.

Traceback (most recent call last):
File "/home/iainm/Desktop/objects/dev_space.blend/Text", line 209, in <module>
ValueError: bpy_struct: item.attr = val: sequences of dimension 0 should contain 4 items, not 3
Error: Python script fail, look in the console for now...
$\endgroup$
  • $\begingroup$ Worth noting that the SplinePoint.co must be: "Type: float array of 4 items in [-inf, inf], default (0.0, 0.0, 0.0, 0.0)" Per the docs linked in the question... $\endgroup$ – gl2748 Jul 5 '17 at 2:17
2
$\begingroup$

You don't need to convert a vector to an array, you can just assign it to the location. A vector is created from one value which is a set of three (or four) numbers, so you need the extra pair of parenthesis around the three values.

Any location, rotation and scale value can all take a vector or array as input values. All of the following work.

obj = bpy.data.objects['Cube']
obj.location = Vector((-0.9056, -0.0628, -3.000))
obj.location = [-0.9056, -0.0628, -3.000]
obj.location = (-0.9056, -0.0628, -3.000)
obj.rotation_euler = Vector((-0.9056, -0.0628, -3.000))

For bezier curves the same applies to it's curve points

# for bezier curve points
bezcurve = bpy.data.objects['BezierCurve']
SplinePoint = bezcurve.data.splines[0].bezier_points[0]
myLocation = Vector((-0.9056, -0.0628, -3.000))

SplinePoint.co = myLocation
SplinePoint.co = Vector((-0.9056, -0.0628, -3.000))
SplinePoint.co = [-0.9056, -0.0628, -3.000]
SplinePoint.co = (-0.9056, -0.0628, -3.000)

For nurbs paths each point is four values instead of three. The first three values are the x,y,z for the location as above while the fourth value (shown as w in the UI) controls the influence the point has on the curve, where a bezier point has handles that define the angle and strength of the curve leaving the point, a nurbs path only has an influence that pulls the path closer to the point the larger the value.

# for nurbs paths points
nurbpath = bpy.data.objects['NurbsPath']
SplinePoint = nurbpath.data.splines[0].points[0]
myLocation = Vector((-0.9056, -0.0628, -3.000, 1.0))

SplinePoint.co = myLocation
SplinePoint.co = Vector((-0.9056, -0.0628, -3.000, 1.0))
SplinePoint.co = [-0.9056, -0.0628, -3.000, 1.0]
SplinePoint.co = (-0.9056, -0.0628, -3.000, 1.0)

If you are getting a location as a vector from somewhere else you can use resize_4d() or the to_4d() to use the location in the nurbs point. You can then alter the influence with either SplinePoint.co[3] = 1.0 or SplinePoint.co.w = 1.0.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Ok, right, i don't have the word literally in there, just expressing what the blender console outputs when I print what myLocation is. The problem is that the array for the co of the spline requires 4 values (check the doc linked in the Q) to confirm ... $\endgroup$ – gl2748 Jul 5 '17 at 2:17
  • $\begingroup$ got it, had to call to_4d() on the vector. $\endgroup$ – gl2748 Jul 5 '17 at 2:37
  • $\begingroup$ @gl2748 - right I should have noticed you where looking at nurbs points and not bezier points. I expanded the answer to clarify things. $\endgroup$ – sambler Jul 5 '17 at 7:10

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.