Skip to content

Instantly share code, notes, and snippets.

@jamesWalker55
Last active May 11, 2023 12:07
Show Gist options
  • Save jamesWalker55/f8adb2d31fbb7732835c3fbcde3a5173 to your computer and use it in GitHub Desktop.
Save jamesWalker55/f8adb2d31fbb7732835c3fbcde3a5173 to your computer and use it in GitHub Desktop.
Blender addon to convert a curve to a mesh while preserving modifiers. Tested on Blender 3.5.
from typing import Any, NamedTuple
import bpy
class ModifierSpec(NamedTuple):
name: str
type: str
properties: dict[str, Any]
@classmethod
def from_modifier(cls, modifier):
spec = cls(modifier.name, modifier.type, {})
for prop in modifier.bl_rna.properties:
if prop.is_readonly:
continue
name = prop.identifier
spec.properties[name] = getattr(modifier, name)
return spec
def add_to_object(self, obj):
new_modifier = obj.modifiers.get(self.name, None)
if new_modifier is None:
new_modifier = obj.modifiers.new(self.name, self.type)
for name, prop in self.properties.items():
setattr(new_modifier, name, prop)
class ConvertCurvePreservingModifiersOperator(bpy.types.Operator):
bl_idname = "object.convert_curve_preserving_modifiers"
bl_label = "Convert Curve to Mesh Preserving Modifiers"
bl_description = "Converts a NURBS path to mesh while preserving modifiers"
@classmethod
def poll(cls, context):
return len(context.selected_objects) > 0 and any(
obj.type == "CURVE" for obj in context.selected_objects
)
def execute(self, context):
initial_active_object = bpy.context.view_layer.objects.active
for obj in list(context.selected_objects):
if obj.type != "CURVE":
continue
# collect modifiers from object
modifier_specs: list[ModifierSpec] = []
for old_modifier in obj.modifiers:
modifier_specs.append(ModifierSpec.from_modifier(old_modifier))
# make the object the active one
bpy.context.view_layer.objects.active = obj
# convert to mesh
bpy.ops.object.convert(target="MESH")
# add modifiers from spec
for spec in modifier_specs:
spec.add_to_object(obj)
# select the previously-selected objects again
bpy.context.view_layer.objects.active = initial_active_object
return {"FINISHED"}
class ConvertCurvePreservingModifiersPanel(bpy.types.Panel):
# arbitrary id thing
bl_idname = "OBJECT_PT_convert_curve_preserving_modifiers"
# show in UI
bl_region_type = "UI"
# only show in the viewport editor
bl_space_type = "VIEW_3D"
# show in the "Tool" tab
bl_category = "Tool"
# name of the panel header
bl_label = "Convert Curve Preserving Modifiers"
def draw(self, context):
layout = self.layout
row = layout.row()
row.operator(
"object.convert_curve_preserving_modifiers",
text="Convert selected curves",
)
# Register the operator and panel
classes = (
ConvertCurvePreservingModifiersOperator,
ConvertCurvePreservingModifiersPanel,
)
bl_info = {
"name": "Convert Curve to Mesh Preserving Modifiers",
"blender": (3, 2, 0),
"category": "Object",
}
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment