diff --git a/hifi_tools/__init__.py b/hifi_tools/__init__.py index dc7e43b..a0ba69a 100644 --- a/hifi_tools/__init__.py +++ b/hifi_tools/__init__.py @@ -20,7 +20,7 @@ bl_info = { "name": "HiFi Blender Add-on", "author": "Matti 'Menithal' Lahtinen", - "version": (1, 4, 3), + "version": (1, 4, 4), "blender": (2, 80, 0), "location": "File > Import-Export, Materials, Armature", "description": "Blender tools to allow for easier Content creation for Metaverses, such as High Fidelity", diff --git a/hifi_tools/utils/bones/bones_builder.py b/hifi_tools/utils/bones/bones_builder.py index a449f02..27d10fa 100644 --- a/hifi_tools/utils/bones/bones_builder.py +++ b/hifi_tools/utils/bones/bones_builder.py @@ -205,6 +205,24 @@ def find_armatures(selection): return armatures +def find_armatures_parent(selection): + armatures = [] + for selected in selection: + if selected.parent is not None and selected.type == "ARMATURE": + armatures.append(selected.parent) + return armatures + + +def find_armature_or_armature_parent(selection): + armature = find_armatures(selection) + if armature is None: + armatures = find_armatures_parent(selection) + if len(armatures) > 0: + armature = armatures[0] + + return armature + + def find_armature(selection): for selected in selection: if selected.type == "ARMATURE": @@ -212,6 +230,20 @@ def find_armature(selection): return None +def find_select_armature_and_children(selection): + roots = find_armature_or_armature_parent(selection) + if len(roots) == 0: + return + + bpy.ops.object.select_all(action='DESELECT') + for root in roots: + root.select_set(True) + + if len(root.children) > 0: + for child in root.children: + child.select_set(True) + + def camel_case_split(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) s2 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1) @@ -230,7 +262,6 @@ def pin_common_bones(obj, fix_rolls=True): # Edit Bones bpy.ops.object.mode_set(mode='OBJECT') - reset_scale_rotation(obj) bpy.ops.object.mode_set(mode='EDIT') edit_bones = obj.data.edit_bones @@ -299,7 +330,7 @@ def pin_common_bones(obj, fix_rolls=True): if fix_rolls: correct_bone_rotations(ebone) - correct_scale_rotation(obj, True) + bpy.ops.object.mode_set(mode='OBJECT') def get_bone_side_and_mirrored(bone_name): @@ -537,9 +568,6 @@ def reset_scale_rotation(obj): bpy.context.scene.cursor.location[2] = 0.0 #bpy.context.area.type = current_context bpy.ops.object.mode_set(mode="OBJECT") - bpy.ops.object.select_all(action="DESELECT") - - obj.select_set(state=True) bpy.ops.object.origin_set(type="ORIGIN_CURSOR") bpy.ops.object.transform_apply(location=False, rotation=True, scale=True) @@ -551,9 +579,9 @@ def correct_scale_rotation(obj, rotation): str_angle = -90 * pi/180 if rotation: obj.rotation_euler = Euler((str_angle, 0, 0), "XYZ") - + reset_scale_rotation(obj) - + obj.scale = Vector((0.01, 0.01, 0.01)) if rotation: obj.rotation_euler = Euler((-str_angle, 0, 0), "XYZ") @@ -618,7 +646,7 @@ def retarget_armature(options, selected, selected_only=False): bpy.context.view_layer.objects.active = armature armature.select_set(state=True) bpy.context.object.data.pose_position = 'POSE' - + bpy.ops.object.mode_set(mode="OBJECT") # Make sure to reset the bones first. bpy.ops.object.transform_apply( diff --git a/hifi_tools/utils/bones/custom.py b/hifi_tools/utils/bones/custom.py index 4034536..2a6f4f2 100644 --- a/hifi_tools/utils/bones/custom.py +++ b/hifi_tools/utils/bones/custom.py @@ -326,8 +326,9 @@ def rename_bones_and_fix_most_things(self, context): children = bpy.data.objects for child in children: + + child.select_set(state=True) if child.type == "ARMATURE": - child.select_set(state=True) bones_builder.correct_scale_rotation(child, True) bpy.ops.object.mode_set(mode="POSE") bpy.ops.pose.select_all(action="SELECT") @@ -357,7 +358,6 @@ def rename_bones_and_fix_most_things(self, context): bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.select_all(action="DESELECT") bpy.context.view_layer.objects.active = child - child.select_set(state=True) blocks = child.data.shape_keys.key_blocks for shape_key in blocks: diff --git a/hifi_tools/utils/ui/panels.py b/hifi_tools/utils/ui/panels.py index b226f2c..5399772 100644 --- a/hifi_tools/utils/ui/panels.py +++ b/hifi_tools/utils/ui/panels.py @@ -310,19 +310,19 @@ class OBJECT_OT_METAV_TOOLSET_Fix_Scale_Operator(bpy.types.Operator): bl_category = "High Fidelity" def execute(self, context): + bones_builder.find_select_armature_and_children(bpy.context.selected_objects) selected_objects = bpy.context.selected_objects for selected in selected_objects: bones_builder.correct_scale_rotation(selected, True) - bpy.ops.object.select_all(action="DESELECT") - for selected in selected_objects: - selected.select_set(state=True) + + return {'FINISHED'} class BONES_OT_METAV_TOOLSET_Pin_Problem_Bones(bpy.types.Operator): - """ Pins usually problemative bones to match the HF reference skeleton. """ + """ Correct Rolls AND Pins usually problemative bones to match the HF reference skeleton. """ bl_idname = "metaverse_toolset.hf_pin_problem_bones" bl_label = "Pin Problem Bones" @@ -331,13 +331,10 @@ class BONES_OT_METAV_TOOLSET_Pin_Problem_Bones(bpy.types.Operator): bl_category = "High Fidelity" def execute(self, context): - bpy.ops.object.mode_set(mode="EDIT") - for obj in bpy.data.objects: if obj.type == "ARMATURE": bones_builder.pin_common_bones(obj, False) - bpy.ops.object.mode_set(mode="OBJECT") return {'FINISHED'} @@ -351,25 +348,33 @@ class BONES_OT_METAV_TOOLSET_Fix_Rolls(bpy.types.Operator): bl_category = "High Fidelity" def execute(self, context): + selected = bpy.context.selected_objects + + if selected is None: + selected = bpy.data.objects + bones_builder.find_select_armature_and_children(selected) + + selected = bpy.context.selected_objects + + bpy.ops.object.mode_set(mode="EDIT") - selected = bpy.context.selected_objects if selected is None: selected = bpy.data.objects for obj in selected: if obj.type == "ARMATURE": - print("Lets Do this shit ", obj) - bpy.ops.object.mode_set(mode="OBJECT") - bones_builder.correct_scale_rotation(obj, False) bpy.ops.object.mode_set(mode="EDIT") for ebone in obj.data.edit_bones: bones_builder.correct_bone_rotations(ebone) + + bones_builder.correct_scale_rotation(obj, False) bpy.ops.object.mode_set(mode="OBJECT") bones_builder.clear_pose(selected) - + bpy.ops.object.mode_set(mode="OBJECT") + return {'FINISHED'}