4
$\begingroup$

I'm trying to edit curves via python, but deleting bezier points is causing me trouble. I'm able to do it using high-level operators (see sample code below), but I would prefer edit the data more directly, for speed and cleanliness.

#Define vars
one = bpy.data.objects['Curve']
point_to_remove = one.data.splines[0].bezier_points[0]

#Set 'one' to edit mode
bpy.context.scene.objects.active = one
bpy.ops.object.mode_set(mode = 'EDIT')

#Select point_to_remove and remove it
point_to_remove.select_control_point = True
bpy.ops.curve.dissolve_verts()

I've tried using .add() to create a dummy object with the desired set of bezier points and then setting one.data.splines[0].bezier_points = ..., but bezier_points is read-only.

I've tried python's del() and the blender API's `remove()', but they either aren't supported for bezier points or I'm using them wrong.

Any help would be much appreciated.

Edit: It seems this is a special case of deleting instances of the bpy_struct class, which I also don't know how to do.

$\endgroup$
1
$\begingroup$

Surely there's an easier way to do this.

Had a fiddle with this and came up with code below, which I'm not sure wins on either count of speed nor cleanliness. Adds a new spline with the same coordinates, and handles as bezier points of spline zero in original, with one point popped off. Even with all that code didn't copy handle type for left and right.

import bpy

context = bpy.context
obj = context.object
curve = obj.data
s0 = curve.splines[0]
index = 0 # index of bez point to remove.
points = len(s0.bezier_points)
x = [0] * points * 3 # flat list of vectors
hr = x[:]
hl = x[:]
s0.bezier_points.foreach_get("co", x)
s0.bezier_points.foreach_get("handle_left", hl)
s0.bezier_points.foreach_get("handle_right", hr)
# pop off index 0
for i in range(3):
    j = 3 * index + i
    x.pop(j)
    hl.pop(j)
    hr.pop(j)

# one less for removed, one more less for splines new
points -= 2 

# add a new spline
spline = curve.splines.new('BEZIER')

spline.bezier_points.add(points)
spline.bezier_points.foreach_set("co", x)
spline.bezier_points.foreach_set("handle_left", hl)
spline.bezier_points.foreach_set("handle_right", hr)

#remove spline 0
curve.splines.remove(s0)
$\endgroup$

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.