Skip to content

Commit

Permalink
feat: add new operator about convert curve to mesh with group infos.
Browse files Browse the repository at this point in the history
- add a new operator which can converte selected object to mesh, and if object is curve and has bevel object, it will copy the virtools group info of bevel object at the same time.
- add a hint in virtools group panel to tell user that the virtools group of non-mesh object will not be saved.
  • Loading branch information
yyc12345 committed Jan 5, 2025
1 parent 76f1cdc commit 6ae8899
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
50 changes: 50 additions & 0 deletions bbp_ng/OP_OBJECT_snoop_group_then_to_mesh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import bpy
import typing
from . import PROP_virtools_group

class BBP_OT_snoop_group_then_to_mesh(bpy.types.Operator):
"""Convert selected objects into mesh objects and try to copy the Virtools Group infos of their associated curve bevel object if they have. """
bl_idname = "bbp.snoop_group_then_to_mesh"
bl_label = "Snoop Group then to Mesh"
bl_options = {'UNDO'}

@classmethod
def poll(cls, context):
return len(context.selected_objects) != 0

def execute(self, context):
for obj in context.selected_objects:
# skip all non-curve object
if obj.type != 'CURVE': continue

# fetch curve data block
curve: bpy.types.Curve = typing.cast(bpy.types.Curve, obj.data)

# if bevel mode is not object, skip
if curve.bevel_mode != 'OBJECT': continue
# if bevel object is None, skip
bevel_obj: bpy.types.Object | None = curve.bevel_object
if bevel_obj is None: continue

# copy bevel object group info into current object
# MARK: VirtoolsGroupsHelper is self-mutex.
# we only can operate one VirtoolsGroupsHelper at the same time.
# so we extract bevel object group infos then apply to target later.
group_infos: tuple[str, ...]
with PROP_virtools_group.VirtoolsGroupsHelper(bevel_obj) as bevel_gp:
group_infos = tuple(bevel_gp.iterate_groups())
with PROP_virtools_group.VirtoolsGroupsHelper(obj) as this_gp:
this_gp.clear_groups()
this_gp.add_groups(group_infos)

# convert all selected object to mesh
# no matter the success of copying virtools group infos and whether selected object is curve
bpy.ops.object.convert(target = 'MESH')

return {'FINISHED'}

def register() -> None:
bpy.utils.register_class(BBP_OT_snoop_group_then_to_mesh)

def unregister() -> None:
bpy.utils.unregister_class(BBP_OT_snoop_group_then_to_mesh)
8 changes: 7 additions & 1 deletion bbp_ng/PROP_virtools_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,13 @@ def poll(cls, context):

def draw(self, context):
layout = self.layout
target = bpy.context.active_object
target = typing.cast(bpy.types.Object, context.active_object)

# notify on non-mesh object
if target.type != 'MESH':
layout.label(text = 'Virtools Group is invalid on non-mesh object!', icon = 'ERROR')

# draw main body

row = layout.row()
row.template_list(
Expand Down
12 changes: 11 additions & 1 deletion bbp_ng/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from . import OP_UV_flatten_uv, OP_UV_rail_uv
from . import OP_MTL_fix_material
from . import OP_ADDS_component, OP_ADDS_bme, OP_ADDS_rail
from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group, OP_OBJECT_naming_convention
from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group, OP_OBJECT_snoop_group_then_to_mesh, OP_OBJECT_naming_convention

#region Menu

Expand Down Expand Up @@ -148,6 +148,12 @@ def menu_drawer_grouping(self, context) -> None:
col.operator(OP_OBJECT_virtools_group.BBP_OT_rm_objects_virtools_group.bl_idname, icon = 'REMOVE', text = "Ungroup from...")
col.operator(OP_OBJECT_virtools_group.BBP_OT_clear_objects_virtools_group.bl_idname, icon = 'TRASH', text = "Clear All Groups")

def menu_drawer_snoop_then_conv(self, context) -> None:
layout: bpy.types.UILayout = self.layout
layout.separator()
layout.label(text = "Ballance")
layout.operator(OP_OBJECT_snoop_group_then_to_mesh.BBP_OT_snoop_group_then_to_mesh.bl_idname, icon = 'OUTLINER_OB_MESH')

def menu_drawer_naming_convention(self, context) -> None:
layout: bpy.types.UILayout = self.layout
layout.separator()
Expand Down Expand Up @@ -187,6 +193,8 @@ def __init__(self, cont: bpy.types.Menu, is_append: bool, menu_func: MenuDrawer_
MenuEntry(bpy.types.TOPBAR_MT_file_export, True, menu_drawer_export),
MenuEntry(bpy.types.VIEW3D_MT_add, True, menu_drawer_add),

MenuEntry(bpy.types.VIEW3D_MT_object_context_menu, True, menu_drawer_snoop_then_conv),

# register double (for 2 menus)
MenuEntry(bpy.types.VIEW3D_MT_object_context_menu, True, menu_drawer_grouping),
MenuEntry(bpy.types.OUTLINER_MT_object, True, menu_drawer_grouping),
Expand Down Expand Up @@ -224,6 +232,7 @@ def register() -> None:

OP_OBJECT_legacy_align.register()
OP_OBJECT_virtools_group.register()
OP_OBJECT_snoop_group_then_to_mesh.register()
OP_OBJECT_naming_convention.register()

# register other classes
Expand All @@ -248,6 +257,7 @@ def unregister() -> None:

# unregister modules
OP_OBJECT_naming_convention.unregister()
OP_OBJECT_snoop_group_then_to_mesh.unregister()
OP_OBJECT_virtools_group.unregister()
OP_OBJECT_legacy_align.unregister()

Expand Down

0 comments on commit 6ae8899

Please sign in to comment.