1
$\begingroup$

How can I use Python to select one (spline control) point of a NURBS curve? I want to select and then move each point to a desired location. If this is not possible, I am happy to start with the locations and create a NURBS curve that ‘joins the dots’.

$\endgroup$

2 Answers 2

2
$\begingroup$

IMO would join the dots.

I want to select and then move each point to a desired location.

If the idea is to take a set of points and "join the dots" it is quite possibly a lot simpler to to create the spline.

Here is an example using NURBS answser from Create curve from Numpy Array using Python

enter image description here Result displayed in EDIT mode, after running script in OBJECT mode

Set the coordinates as desired, run the script in object mode, creates a curve object with control points at the input coordinates. Removes need to select points, mode toggle, and use operators.

Using numpy and in particular foreach_get(set) is going to be way quicker for a lot of points.

In this example have given each 4D NURB coordinate a weight w of 1.

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

x, y, z = np.array(
    (
        (0, 0, 0),
        (1, 1, 1),
        (0, 1, 1),
        (0, 0, 1),
    )
).T

w = np.ones(len(x))
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
spline.points.add(x.size - 1)
spline.points.foreach_set("co", flatten(x, y, z, w))

spline.use_endpoint_v = True
spline.use_endpoint_u = True
ob = bpy.data.objects.new("NURBS", cu)     
context.collection.objects.link(ob)
context.view_layer.objects.active = ob
ob.select_set(True)

And for example sake,

enter image description here

running a loop and changing the weight assigned to the 4th coordinate

for j in range(1, 100, 10):
    w = np.ones(len(x))
    w[3] = j

Note.

If the desired result is to have the curve pass through the control points, it may be an idea to choose a curve type other than NURBS.

$\endgroup$
1
  • $\begingroup$ I agree. Joining the dots is much more sensible.I asked the wrong question (cf The XY Problem). I came up with something that has a similar structure as your code but is far less sophisticated. I used from mathutils import Vector. I would share it but don't seem to be able to use the mini-Markdown formatting in a comment. $\endgroup$ May 1, 2021 at 17:56
2
$\begingroup$
import bpy
   
for p in bpy.context.object.data.splines.active.points:
    p.co.z = p.co.z + 1
bpy.ops.object.mode_set(mode='EDIT')

This works.

UPDATE: (only change selected points)

bpy.ops.object.mode_set(mode='OBJECT')
    
counter = 0
for p in bpy.context.object.data.splines.active.points:
    print("counter = ",counter)
    if p.select == True:
        p.co.z = p.co.z - 1
        print("selected")
    counter = counter + 1
bpy.ops.object.mode_set(mode='EDIT')
$\endgroup$
8
  • $\begingroup$ Thanks! I must be doing something wrong. I assume I start in Object Mode, with the curve selected. I am then trying your code by pasting into Python Console. From: the_curve_data = bpy.context.scene.objects.active.data I get: AttributeError: 'bpy_prop_collection' object has no attribute 'active' $\endgroup$ May 1, 2021 at 8:20
  • $\begingroup$ i am sorry - my mistake. i update the answer. this time i tested it ;) $\endgroup$
    – Chris
    May 1, 2021 at 9:03
  • $\begingroup$ Almost there. I think. I have tried your code with the last line indented (is that right?). No errors, but it does not select just one point. The curve is selected, not just a point. What do I add to say which point should be selected? $\endgroup$ May 1, 2021 at 10:08
  • $\begingroup$ Yes, it moves all points, but hopefully you can add an if Statement in the for loop yourself. Can you? $\endgroup$
    – Chris
    May 1, 2021 at 10:34
  • $\begingroup$ I can't! Could you please show the point selection and the translation?? $\endgroup$ May 1, 2021 at 10:47

You must log in to answer this question.

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