0
$\begingroup$

I am an experienced Python user but just started Blender a few months ago. I'm looking into making some automations and scripts in Python in Blender 3.4.0 and I am somewhat stuck on this problem. To summarise, I have two (freshly created) objects in my scene, namely "BezierCurve" and "BezierCurve.001". I have constructed a Python loop which goes through each object and subdivide them into 5 segments. Unfortunately, when running the script below, the "BezierCurve" object gets subdivided by 5, as instructed, but "BezierCurve.001" gets divided 20 odd times. I am scratching my head on this one.

Here's the code:

import bpy

# Deselect all objects
def deselect_all():
    bpy.ops.object.select_all(action='DESELECT')

objList = ["BezierCurve","BezierCurve.001"]

def resampleCurve(obj, n):
        
    # Deselect all
    deselect_all()
    # Select Object obj
    bpy.data.objects[obj].select_set(True)
    # Enter Edit mode:
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.curve.subdivide(number_cuts=int(n - 1))
    # Enter Object mode:
    bpy.ops.object.mode_set(mode='OBJECT')
    # Deselect Object obj
    bpy.data.objects[obj].select_set(False)


def resampleCurveAll(objList,res):
    deselect_all()
    for obj in objList:
        resampleCurve(obj, res)

resampleCurveAll(objList,res = 5)

What am I missing? Maybe this is a newbie question. Any help (or pointers) on this would be appreciated.

$\endgroup$

1 Answer 1

0
$\begingroup$

The bpy.ops applies to the selection but also to the active object.

You can change your code this way, for example. Once all deselected, instead of selecting, just set the active object.

import bpy

# Deselect all objects
def deselect_all():
    bpy.ops.object.select_all(action='DESELECT')

objList = ["BezierCurve","BezierCurve.001"]

def resampleCurve(obj, n):
        
    # Set active object
    bpy.context.view_layer.objects.active = bpy.data.objects[obj]
    # Enter Edit mode:
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.curve.subdivide(number_cuts=int(n - 1))
    # Enter Object mode:
    bpy.ops.object.mode_set(mode='OBJECT')


def resampleCurveAll(objList,res):
    deselect_all()
    for obj in objList:
        resampleCurve(obj, res)

resampleCurveAll(objList,res = 5)

Note that you can also subdivide them all at once.

def resampleCurve(n):
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.curve.subdivide(number_cuts=int(n - 1))
    bpy.ops.object.mode_set(mode='OBJECT')

def resampleCurveAll(objList,res):
    deselect_all()
    for obj in objList:
        bpy.context.view_layer.objects.active = bpy.data.objects[obj]
        bpy.data.objects[obj].select_set(True)
    resampleCurve(res)
$\endgroup$
4
  • $\begingroup$ Maybe it's better to have bpy.ops.curve.select_all(action='SELECT') before bpy.ops.curve.subdivide. $\endgroup$
    – tetii
    Jan 29 at 11:22
  • $\begingroup$ Yes @tetii I've not changed this part of the code presuming we have here newly created curves, but you're right. $\endgroup$
    – lemon
    Jan 29 at 11:24
  • $\begingroup$ Thank you very much @lemon for your help on this. I very much appreciate it. I guess I still need to understand and read up on "selecting and activating" objects in Python within Blender. Your solutions make sense. Thank you everyone :-) $\endgroup$
    – Caleb John
    Jan 29 at 14:20
  • $\begingroup$ Thanks also @tetti :-) $\endgroup$
    – Caleb John
    Jan 29 at 14:20

You must log in to answer this question.

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