Files
LancerEdit-Model-Utility-Pl…/LancerEditUtility.py
2025-09-19 19:05:10 +02:00

197 lines
6.9 KiB
Python

bl_info = {
"name": "LancerEdit Model Utility Plugin",
"author": "Darklighter",
"version": (0, 0, 1),
"blender": (4, 5, 3),
"location": "3D-Viewport > Sidebar > FLLancerEdit Utility",
"description": "Non-offical LancerEdit Model Utility Plugin for PC-Game Freelancer",
"category": "Development",
}
import bpy
import re
class RenameObjectsAndMeshesOperator(bpy.types.Operator):
bl_idname = "object.rename_objects_and_meshes"
bl_label = "Rename Objects and Mesh Data"
bl_description = "Rename specified objects and their mesh data blocks, and their children"
object_names: bpy.props.StringProperty(
name="Object Names",
description="Comma-separated list of object names to rename",
default=""
)
new_name: bpy.props.StringProperty(
name="New Name",
description="New name for objects and their mesh data blocks",
default=""
)
def execute(self, context):
names_input = self.object_names.strip()
new_name = self.new_name.strip()
if not names_input or not new_name:
self.report({'WARNING'}, "Please enter object names and a new name")
return {'CANCELLED'}
names_list = [name.strip() for name in names_input.split(",") if name.strip()]
for obj_name in names_list:
obj = bpy.data.objects.get(obj_name)
if obj:
# Rename the object
old_mesh_name = obj.data.name if obj.data else None
obj.name = new_name
# Rename the mesh data block if it exists
if obj.data:
obj.data.name = new_name
# Rename children objects starting with 'parent_name.'
for child in bpy.data.objects:
if child.name.startswith(f"{obj_name}."):
suffix = child.name[len(f"{obj_name}."):]
child.name = f"{new_name}.{suffix}"
# Also rename their mesh data if applicable
if child.data:
child.data.name = f"{new_name}.{suffix}"
else:
self.report({'WARNING'}, f"Object '{obj_name}' not found.")
self.report({'INFO'}, "Renaming of objects and mesh data completed.")
return {'FINISHED'}
class RenameChildObjectOperator(bpy.types.Operator):
bl_idname = "object.rename_selected_child"
bl_label = "Rename Selected Child (Hulls/Sur) Objects"
bl_description = "Rename the mesh data of the selected child object and assign a new suffix, filling gaps"
def execute(self, context):
scene = context.scene
base_name = scene.child_object_new_name.strip()
if not base_name:
self.report({'WARNING'}, "New name cannot be empty")
return {'CANCELLED'}
selected_children = [obj for obj in context.selected_objects if obj.parent]
if not selected_children:
self.report({'WARNING'}, "No selected child objects found")
return {'CANCELLED'}
# Collect existing suffixes
pattern = re.compile(rf"{re.escape(base_name)}\.(\d+)\$hull")
used_suffixes = []
for o in bpy.data.objects:
match = pattern.match(o.name)
if match:
used_suffixes.append(int(match.group(1)))
used_suffixes = sorted(set(used_suffixes))
suffixes_to_use = []
# Fill in gaps starting from 1
expected_suffix = 0
for suffix in used_suffixes:
while expected_suffix < suffix:
suffixes_to_use.append(expected_suffix)
expected_suffix += 1
expected_suffix = suffix + 1
# Now, assign suffixes:
suffix_index = 0
for obj in selected_children:
# Check if object already has a suffix
match = pattern.match(obj.name)
if match:
current_suffix = int(match.group(1))
if current_suffix in suffixes_to_use:
# Already assigned, skip
continue
else:
# Object already named properly, skip
continue
else:
# Assign next available gap suffix or new suffix
if suffix_index < len(suffixes_to_use):
suffix_num = suffixes_to_use[suffix_index]
suffix_index += 1
else:
suffix_num = expected_suffix
expected_suffix += 1
new_name = f"{base_name}.{suffix_num}$hull"
if obj.type == 'MESH' and obj.data:
obj.name = new_name
obj.data.name = new_name
else:
self.report({'WARNING'}, f"Object {obj.name} does not have mesh data, skipped.")
self.report({'INFO'}, "Selected child objects renamed successfully")
return {'FINISHED'}
class LancerEditHelpersPanel(bpy.types.Panel):
bl_label = "LancerEdit Model Utility Plugin"
bl_idname = "OBJECT_PT_rename_objects_meshes"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'LancerEdit Utility'
def draw(self, context):
layout = self.layout
scene = context.scene
# Existing renaming section
layout.label(text="Rename Parent Object:")
layout.prop(scene, "object_names")
layout.prop(scene, "new_name")
op = layout.operator("object.rename_objects_and_meshes")
op.object_names = scene.object_names
op.new_name = scene.new_name
# Section for renaming selected child object
layout.separator()
layout.label(text="Rename Selected Child (Hulls/Sur) Objects")
layout.prop(scene, "child_object_new_name")
layout.operator("object.rename_selected_child")
def register():
bpy.utils.register_class(LancerEditHelpersPanel)
bpy.utils.register_class(RenameObjectsAndMeshesOperator)
bpy.utils.register_class(RenameChildObjectOperator)
bpy.types.Scene.object_names = bpy.props.StringProperty(
name="Parent Name",
description="Comma-separated list of object names",
default=""
)
bpy.types.Scene.new_name = bpy.props.StringProperty(
name="Change Name",
description="New name for objects and their mesh data",
default=""
)
bpy.types.Scene.child_object_new_name = bpy.props.StringProperty(
name="Change Name",
description="New name for the selected child object",
default=""
)
def unregister():
bpy.utils.unregister_class(LancerEditHelpersPanel)
bpy.utils.unregister_class(RenameObjectsAndMeshesOperator)
bpy.utils.unregister_class(RenameChildObjectOperator)
del bpy.types.Scene.object_names
del bpy.types.Scene.new_name
del bpy.types.Scene.child_object_new_name
if __name__ == "__main__":
register()