Quick and dirty python script to apply "use_endpoint_u = True" to all splines?

I’m not a programmer but I wonder if it is possible to write a command or script that will allow me to apply this to all my splines. The workflow is impossibly awkward to select each spline and check the box and none of the usual tricks like apply to selected work.

In my non-programmer mind “bpy.context.object.data.splines[allofthemplease].use_endpoint_u = True” would be it but…

This should work in the Python Console:

for spline in bpy.context.active_object.data.splines: spline.use_endpoint_u = True

Or if you want to do that to all selected curve objects, you can run this from the Text Editor:

import bpy
for ob in bpy.context.selected_editable_objects:
    if ob.type != "CURVE":
        continue
    for spline in ob.data.splines:
        spline.use_endpoint_u = True
2 Likes

Wow. It’s like magic. Maybe I should take the time to learn some Python. Or just turn up here and poach some more code.

I don’t think it’s an accident that your name sounds a bit like a superhero moniker. I dropped the command into my pie menu and it works fabulously.

1 Like

Okay, I have a more annoying case here, let’s see if anyone can do it.

I want to use the property for order_U on a pie menu, so I can tap it up and down for all splines.

The command for one spline is C.object.data.splines[16].order_u

So I’m guessing you can’t just for loop that?

I tried to create an increment button:

for spline in bpy.context.active_object.data.splines: spline.order_u = spline.order_u + 1

…it doesn’t work, surprising no one.

Maybe it’s just syntax? It works for me.

import bpy
try:
    for spl in bpy.context.active_object.data.splines:
        spline.order_u += 1
except:
    print ("select a curve")

is a little bit better

Ah. When I tested it I forgot that it only goes to 3. It works as a pair of buttons for me but making it a property is no good, right?

That is what the C. statement does?

Blender’s Python console automatically does this every time you start Blender:

import bpy
#Convenience Variables:
C = bpy.context
D = bpy.data

And probably a little more than that, too.
C.object.data.splines[16].order_u says to Blender, roughly : “for the object that’s currently selected, poke around in its data, find the sixteenth spline and tell me what it’s order_u property is” So naturally this won’t work if you haven’t got sixteen splines.
But ’ for spline in bpy.context.active_object.data.splines: spline.order_u = spline.order_u + 1 is really close to right. I think you just forgot to import bpy and of course you should have an indent between the : and the for.

I enclosed it in a try/except block, because it’s not a safe bet that there actually is a property called order_u (Bezier splines), let alone spline or data. If the object selected is an empty, it doesn’t have any data associated with it, it’s just the object. The data can be a mesh, a curve, a lattice, an armature, any kind of data-block that can exist in 3D space as an object. Only curves have splines, so I use a try/except block when I don’t want to be careful to check everything. This is kind of a bad habit. Better practice might be:

assert bpy.context.active_object. type = 'CURVE', "Select a curve"
Assert statements are kind of bad practice, but in a script meant for a very particular context, it’s safe to assume that the script should fail if the artist tries to execute it in the wrong context. If you don’t want the script to fail, do something like this:

try:
    assert bpy.context.active_object. type = 'CURVE'
except AssertionError:
    print ("Select a Curve object")

This is exactly the same, except it will not return an error to Blender when you run it.

1 Like

for spline in bpy.context.active_object.data.splines: spline.order_u = spline.order_u - 1
and + 1 work without errors for me as buttons (could be pie menu editor does something fancy to make half done commands work), I suppose one day there might be a built in system to recognise many items and give an average with a symbol denoting so, type in to reset to certain number, or drag either way to increment each.

Since I’m the only one using this script I doubt I’ll goof it up but I’ll try that other snippet when I have some time. Are try and assert Python specific? I know a little c++ and I haven’t heard of statements like that.

C++ has try/catch language construct. There are some syntactic differences and I believe also under the hood in terms of machine code it gets translated to.

There is a C macro for assert, which C++ inherits: https://en.cppreference.com/w/cpp/error/assert
There is also something more modern (C++11), static_assert: https://en.cppreference.com/w/cpp/language/static_assert

1 Like