Convert a curve to a mesh WITHOUT using bpy.ops (preserve original object ref)

I’ve noticed that certain built-in operators are very crashy when doing bulk operations, and bpy.ops.object.convert() is definitely one of them. Up until recently I had been using it to apply modifiers to hundreds of meshes/curves/etc, and noticed frequent intermittent crashing. After narrowing down the problem to the built-in operator I started working to remove it, and I have done this with meshes by essentially creating a new mesh datablock using a depsgraph snapshot, assigning it to the object’s data, and removing the old data. Instantly I’m noticing that it’s not crashing Blender at all anymore.

I’d like to extend this to curves, but you can’t assign a mesh datablock to an object that is already set up as a curve. I could, of course, create a new object, copy over custom properties, etc- but for my purposes I need the original object reference intact. The built-in operator converts the data and object to a mesh, is there a way to change the object type to enable mesh data assignment?

If I understand correctly, you want a curve converted into a stand-alone mesh type object, while leaving the source alone?

I wrote this some while ago. This uses bpy.data.meshes.new_from_object to do the heavy lifting of converting from a curve to a mesh, and assigns it to a new object.

Ah, close- the kicker is that I need the original object ref to remain intact. So for example, bpy.data.objects[‘mycurve’] simply becomes a mesh. This is how it works with the built-in operator, I was hoping to preserve that ability.

Ah, this is definitely tricky.

There’s no api for in-place conversion except for the operator. Internally Blender creates a mesh data block from the curve, does a pointer swap and changes the type enum from curve to mesh. Definitely possible to do with ctypes, but a nightmare to maintain between versions.

You say the reference needs to stay intact - I’m presume it’s due to the curve object’s dependencies with other objects. But what if you used user_remap to essentially rewire any dependencies? (I haven’t used it myself)

i’m actually cleaning up one of my studio’s utility classes for performance/stability purposes, the intended usage of this particular function is basically fire and forget, you pass a list of objects and those objects become ‘frozen’ in their visible geometry state… modifiers applied, curves to meshes, etc. Most of the scripts using this utility are assuming that no objects are removed in the process, so creating a new object for curves ends up raising a bunch of ReferenceErrors because they are accessing objects that no longer exist.

Not a huge deal, i think the benefit from doing only meshes this way is fine for now, down the road if curves become a problem I’ll revisit the idea and maybe do some refactoring. Thanks for bouncing some ideas around

1 Like

No problem. I guess the sane thing here would be to isolate the cases for when the operator does fail using something like the faulthandler module (attempts to dump a python stack trace to file), and present a bug report so that it can be fixed.

It does sound like there are edge cases where the operator fails spectacularly when instead it should just abort.