finally completed addon

This commit is contained in:
2026-07-27 01:33:05 +08:00
parent 1714643a81
commit bb3bf11914
19 changed files with 362 additions and 65 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"python-envs.defaultEnvManager": "ms-python.python:system"
}
+3 -3
View File
@@ -14,6 +14,7 @@ import os
from bpy.props import FloatProperty, PointerProperty, BoolProperty
from . import rigger_functionality
from . import controlrig_generate
# =========================================================================
# GLOBAL VARIABLES
@@ -289,7 +290,8 @@ class GenerateControlRig(bpy.types.Operator):
bl_label = "Generate Control Rig"
bl_description = "Builds the control rig according to helper placement"
def execute(self, context):
def execute(self, context):
controlrig_generate.generatecontrolrig();
return {'FINISHED'}
# REFRESH BUTTON
@@ -432,7 +434,5 @@ def unregister():
if __name__ == "__main__":
# bpy.context.scene.panel_propert.panel2_g1 = True
# bpy.context.scene.panel_propert.panel3_g1 = False
register()
inspect_scene()
@@ -117,7 +117,7 @@ toes_data = [
{
"bone_name": "toe_pinky_01_l",
"head_helper": "toe_pinky_01_l",
"tail_helper": "toe_pinky_02_l"
"tail_helper": "toe_pinky_02_1"
},
{
"bone_name": "toe_pinky_02_l",
+1 -1
View File
@@ -42,7 +42,7 @@ webbing_data = [
{
"bone_name": "web_09_l",
"head_helper": "toe_ring_03_l",
"tail_helper": "toe_pinky_03_l"
"tail_helper": "toe_pinky_03_l"
},
{
"bone_name": "web_10_l",
@@ -0,0 +1,168 @@
import bpy
import math
from . import ctrl_bones_shape_struct
from . import ctrl_bones_color_struct
from . import ik_bones_struct
from . import deform_bones_struct
# Modify Control Bone Shape Function
def modifyctrlbone(bone_name, rotx, roty, rotz, shape_scale, shape_obj_name, wire_width, bone_color, armature):
edit_ctrl_bone = armature.pose.bones.get(bone_name)
shape_object = bpy.data.objects.get(shape_obj_name)
if edit_ctrl_bone:
# Modify control bone shape and color
edit_ctrl_bone.custom_shape = shape_object
edit_ctrl_bone.use_custom_shape_bone_size = False
edit_ctrl_bone.custom_shape_rotation_euler[0] = math.radians(rotx)
edit_ctrl_bone.custom_shape_rotation_euler[1] = math.radians(roty)
edit_ctrl_bone.custom_shape_rotation_euler[2] = math.radians(rotz)
edit_ctrl_bone.custom_shape_scale_xyz[0] = shape_scale
edit_ctrl_bone.custom_shape_scale_xyz[1] = shape_scale
edit_ctrl_bone.custom_shape_scale_xyz[2] = shape_scale
edit_ctrl_bone.use_custom_shape_bone_size = False
edit_ctrl_bone.custom_shape_wire_width = wire_width
edit_ctrl_bone.color.palette = bone_color
# Modify Bone Color Function
def modifyctrlbonecolor(bone_name, bone_color, armature):
edit_ctrl_bone = armature.pose.bones.get(bone_name)
if edit_ctrl_bone:
# Modify control bone color only
edit_ctrl_bone.color.palette = bone_color
# Add IK Function
def addIK(bone_name, ik_target, ik_pole_target, ik_chain, armature):
pose_bone = armature.pose.bones.get(bone_name)
if pose_bone:
ik_constraint = pose_bone.constraints.new(type='IK')
ik_constraint.target = armature
ik_constraint.subtarget = ik_target
if ik_pole_target != "none":
ik_constraint.pole_target = armature
ik_constraint.pole_subtarget = ik_pole_target
ik_constraint.chain_count = ik_chain
print(f"Successfully added IK constraint to {bone_name}")
# Add Copy Scale Function
def addCopyScale(bone_name, parent_bone, parent_influence, armature):
pose_bone = armature.pose.bones.get(bone_name)
if pose_bone:
constraint = pose_bone.constraints.new(type='COPY_SCALE')
constraint.target = armature
constraint.subtarget = parent_bone
constraint.power = parent_influence
print(f"Successfully added Copy Scale constraint to {bone_name}")
# Star Generating Control Rig
def generatecontrolrig():
armaturecheck = bpy.data.objects.get("Armature")
if armaturecheck:
print("Generating Control Rig")
new_amt_obj = bpy.data.objects.get("Armature")
# =========== Setup Control Rig Bone Shapes ===========
custom_bone_shape = ctrl_bones_shape_struct.bone_shape_data
for item in custom_bone_shape:
b_name = item["bone_name"]
rotation_x = float(item["rot_X"])
rotation_y = float(item["rot_Y"])
rotation_z = float(item["rot_Z"])
shape_scale = float(item["scale"])
shape_obj = item["shape"]
shape_color = item["color"]
shape_width = float(item["width"])
print(f"Modifying Bone Shape for: {b_name}")
modifyctrlbone(b_name, rotation_x, rotation_y, rotation_z, shape_scale, shape_obj, shape_width, shape_color, new_amt_obj) # Call Modify Control Bone Shape Function
# =========== Setup Control Rig Bone Colors ===========
custom_bone_color = ctrl_bones_color_struct.bone_color_data
for item in custom_bone_color:
b_name = item["bone_name"]
shape_color = item["color"]
print(f"Modifying Bone Color for: {b_name}")
modifyctrlbonecolor(b_name, shape_color, new_amt_obj) # Call Modify Bone Function
# =========== Setup IK Bones ===========
IK_bones = ik_bones_struct.IK_bones_data
for item in IK_bones:
b_name = item["bone_name"]
ik_target = item["target"]
ik_pole_target = item["pole_target"]
ik_chain = int(item["chain"])
print(f"Adding IK constraint for bone: {b_name}")
addIK(b_name, ik_target, ik_pole_target, ik_chain, new_amt_obj) # Call Add IK Function
# =========== Setup Deform Bones ===========
deformbones = deform_bones_struct.deform_bones_data
for item in deformbones:
b_name = item["bone_name"]
parent_bone = item["parent"]
parent_influence = float(item["influence"])
print(f"Adding copy scale constraint for bone: {b_name}")
addCopyScale(b_name, parent_bone, parent_influence, new_amt_obj) # Call Copy Scale constraints Function
# =========== Cleanup ===========
# Change Rig Display Type
new_amt_obj.data.display_type = 'STICK'
new_amt_obj.data.collections_all["control"].is_visible = True
new_amt_obj.data.collections_all["skeleton"].is_visible = False
new_amt_obj.data.collections_all["webbing"].is_visible = False
new_amt_obj.data.collections_all["belly"].is_visible = False
new_amt_obj.data.collections_all["gular"].is_visible = False
new_amt_obj.data.collections_all["nostril"].is_visible = False
new_amt_obj.data.collections_all["metacarpal"].is_visible = False
new_amt_obj.data.collections_all["skeleton"].is_visible = False
new_amt_obj.data.collections_all["metatarsus"].is_visible = False
new_amt_obj.data.collections_all["fingers"].is_visible = False
new_amt_obj.data.collections_all["toes"].is_visible = False
new_amt_obj.data.show_names = False
bpy.data.collections['gular'].hide_viewport = True
bpy.data.collections['belly_l'].hide_viewport = True
bpy.data.collections['belly_r'].hide_viewport = True
bpy.data.collections['nostril_l'].hide_viewport = True
bpy.data.collections['nostril_r'].hide_viewport = True
bpy.data.collections['helpers'].hide_viewport = True
bpy.data.collections['fingers'].hide_viewport = True
bpy.data.collections['toes'].hide_viewport = True
bpy.data.collections['rig_shapes'].hide_viewport = True
bpy.data.objects['belly_mesh'].hide_viewport = True
bpy.data.objects['gular_mesh'].hide_viewport = True
bpy.data.objects['nostril_mesh'].hide_viewport = True
bpy.data.objects['OG_Armature'].hide_viewport = True
bpy.data.objects['Armature'].hide_viewport = False
else:
print("Armature not configured yet")
Binary file not shown.
Binary file not shown.
+186 -60
View File
@@ -6,50 +6,53 @@ from . import bones_fingers_struct
from . import bones_toes_struct
from . import bones_web_struct
# mabulig_coll_name = None
# new_amt_obj = None
# matrix_world_inv = None
# Modify Bone Function
def modifybone(bone, head_empt, tail_empt, armature, matrixworldinv):
bpy.context.view_layer.objects.active = armature
bpy.ops.object.mode_set(mode='EDIT')
edit_bone = armature.data.edit_bones.get(bone)
print(edit_bone)
empty_head = bpy.data.objects.get(head_empt)
empty_tail = bpy.data.objects.get(tail_empt)
allowhead = False
allowtail = False
alloweditbone = False
print(f"modifying bone: {edit_bone}")
# Fetch world coordinates of the empties
if empty_head:
allowhead = True
# else:
# print(f"Helper '{head_empt}' not found.")
if empty_tail:
allowtail = True
# else:
# print(f"Helper '{tail_empt}' not found.")
if edit_bone:
alloweditbone = True
# else:
# print(f"Bone '{bone}' not found.")
if allowhead and allowtail and alloweditbone:
head_world_pos = empty_head.matrix_world.translation
print(f"Head: {head_empt} - success")
tail_world_pos = empty_tail.matrix_world.translation
print(f"Tail: {tail_empt} - success")
# Multiply the inverse matrix by the world positions using the '@' operator
edit_bone.head = matrixworldinv @ head_world_pos
edit_bone.tail = matrixworldinv @ tail_world_pos
# else:
# print("Error")
# Fix StretchTo Function
def fixbonestretching(bone, armature):
bpy.context.view_layer.objects.active = armature
edit_bone = armature.pose.bones.get(bone)
for constaint in edit_bone.constraints:
if constaint.type == 'STRETCH_TO':
constaint.rest_length = 0.0
def startAutoRig():
mabulig_coll_name = "Mabulig-Rig"
og_amt_obj = bpy.data.objects.get("OG_Armature")
@@ -58,6 +61,7 @@ def startAutoRig():
target_coll = bpy.data.collections.get(mabulig_coll_name)
armaturecheck = bpy.data.objects.get("Armature")
if armaturecheck:
print("Armature already exist")
new_amt_obj = armaturecheck
@@ -74,19 +78,65 @@ def startAutoRig():
target_coll.objects.link(new_amt_obj)
new_amt_obj.hide_viewport = False
print("Armature created")
new_amt_obj.hide_viewport = False
# Calculate the armature's inverse world matrix
matrix_world_inv = new_amt_obj.matrix_world.inverted()
print(new_amt_obj.name)
# =========== Initial State Checks ===========
# Check if 'helpers' collection is hidden
if bpy.data.collections['helpers'].hide_viewport:
ishelperscollhidden = True
else:
ishelperscollhidden = False
# Check if 'belly_mesh' is hidden
if bpy.data.objects['belly_mesh'].hide_viewport:
isbellymeshhidden = True
else:
isbellymeshhidden = False
# Check if 'gular_mesh' is hidden
if bpy.data.objects['gular_mesh'].hide_viewport:
isgularmeshhidden = True
else:
isgularmeshhidden = False
# Check if 'nostril_mesh' is hidden
if bpy.data.objects['nostril_mesh'].hide_viewport:
isnostrilmeshhidden = True
else:
isnostrilmeshhidden = False
# Check if 'fingers' collection is hidden
if bpy.data.collections['fingers'].hide_viewport:
isfingerscollhidden = True
else:
isfingerscollhidden = False
# Check if 'toes' collection is hidden
if bpy.data.collections['toes'].hide_viewport:
istoescollhidden = True
else:
istoescollhidden = False
# =========== Skeleton Bones Setup ===========
bone_data_list = bones_skel_struct.bones_data
# Force 'helpers' collection to unhide
bpy.data.collections['helpers'].hide_viewport = False
for item in bone_data_list:
b_name = item["bone_name"]
h_helper = item["head_helper"]
@@ -96,79 +146,155 @@ def startAutoRig():
# # =========== Belly Bones Setup ===========
# =========== Belly Bones Setup ===========
# belly_l_collection = bpy.data.collections.get("belly_l")
# belly_r_collection = bpy.data.collections.get("belly_r")
belly_l_collection = bpy.data.collections.get("belly_l")
belly_r_collection = bpy.data.collections.get("belly_r")
# # For Left Belly
# for obj in belly_l_collection.objects:
# modifybone(obj.name, "belly_base_l", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# Force belly collections to unhide
belly_l_collection.hide_viewport = False
belly_r_collection.hide_viewport = False
# # For Right Belly
# for obj in belly_r_collection.objects:
# modifybone(obj.name, "belly_base_r", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# For Left Belly
for obj in belly_l_collection.objects:
modifybone(obj.name, "belly_base_l", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# For Right Belly
for obj in belly_r_collection.objects:
modifybone(obj.name, "belly_base_r", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# Return belly collections to hidden
belly_l_collection.hide_viewport = True
belly_r_collection.hide_viewport = True
# # =========== Gullar Bones Setup ===========
# gular_collection = bpy.data.collections.get("gular")
# =========== Gullar Bones Setup ===========
# for obj in gular_collection.objects:
# modifybone(obj.name, "gular_base", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
gular_collection = bpy.data.collections.get("gular")
# Force gular collections to unhide
gular_collection.hide_viewport = False
for obj in gular_collection.objects:
modifybone(obj.name, "gular_base", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# Return gular collections to hidden
gular_collection.hide_viewport = True
# # =========== Nostril Bones Setup ===========
# =========== Nostril Bones Setup ===========
# nostril_l_collection = bpy.data.collections.get("nostril_l")
# nostril_r_collection = bpy.data.collections.get("nostril_r")
nostril_l_collection = bpy.data.collections.get("nostril_l")
nostril_r_collection = bpy.data.collections.get("nostril_r")
# # For Left Nostril
# for obj in nostril_l_collection.objects:
# modifybone(obj.name, "nostril_base_l", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# Force nostril collections to unhide
nostril_l_collection.hide_viewport = False
nostril_r_collection.hide_viewport = False
# For Left Nostril
for obj in nostril_l_collection.objects:
modifybone(obj.name, "nostril_base_l", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# # For Right Nostril
# for obj in nostril_r_collection.objects:
# modifybone(obj.name, "nostril_base_r", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# For Right Nostril
for obj in nostril_r_collection.objects:
modifybone(obj.name, "nostril_base_r", obj.name, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# Return belly collections to hidden
nostril_l_collection.hide_viewport = True
nostril_r_collection.hide_viewport = True
# # =========== Metacarpal and Finger Bones Setup ===========
# =========== Metacarpal and Finger Bones Setup ===========
# bones_fingers_data_list = bones_fingers_struct.fingers_data
bones_fingers_data_list = bones_fingers_struct.fingers_data
# for item in bones_fingers_data_list:
# b_name = item["bone_name"]
# h_helper = item["head_helper"]
# t_helper = item["tail_helper"]
# Force 'helpers' collection to unhide
bpy.data.collections['fingers'].hide_viewport = False
for item in bones_fingers_data_list:
b_name = item["bone_name"]
h_helper = item["head_helper"]
t_helper = item["tail_helper"]
# modifybone(b_name, h_helper, t_helper, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
modifybone(b_name, h_helper, t_helper, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# # =========== Metatarsus and Toe Bones Setup ===========
# =========== Metatarsus and Toe Bones Setup ===========
# bones_toes_data_list = bones_toes_struct.toes_data
bones_toes_data_list = bones_toes_struct.toes_data
# for item in bones_toes_data_list:
# b_name = item["bone_name"]
# h_helper = item["head_helper"]
# t_helper = item["tail_helper"]
# Force 'toes' collection to unhide
bpy.data.collections['toes'].hide_viewport = False
for item in bones_toes_data_list:
b_name = item["bone_name"]
h_helper = item["head_helper"]
t_helper = item["tail_helper"]
# modifybone(b_name, h_helper, t_helper, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
modifybone(b_name, h_helper, t_helper, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
# # =========== Webbing Bones ===========
# =========== Webbing Bones ===========
# bones_web_data_list = bones_web_struct.webbing_data
bones_web_data_list = bones_web_struct.webbing_data
# for item in bones_web_data_list:
# b_name = item["bone_name"]
# h_helper = item["head_helper"]
# t_helper = item["tail_helper"]
for item in bones_web_data_list:
b_name = item["bone_name"]
h_helper = item["head_helper"]
t_helper = item["tail_helper"]
# modifybone(b_name, h_helper, t_helper, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
modifybone(b_name, h_helper, t_helper, new_amt_obj, matrix_world_inv) # Call Modify Bone Function
fixbonestretching(b_name, new_amt_obj) # Call Fix StretchTo Function
# Returns 'helpers' collection to restore hide state prior to bone modification
if ishelperscollhidden:
bpy.data.collections['helpers'].hide_viewport = True
else:
bpy.data.collections['helpers'].hide_viewport = False
# Returns belly collections and mesh to restore hide state prior to bone modification
if isbellymeshhidden:
bpy.data.objects['belly_mesh'].hide_viewport = True
else:
bpy.data.objects['belly_mesh'].hide_viewport = False
# Returns gular collection and mesdh to restore hide state prior to bone modification
if isgularmeshhidden:
bpy.data.objects['gular_mesh'].hide_viewport = True
else:
bpy.data.objects['gular_mesh'].hide_viewport = False
# Returns nostril collection and mesh to restore hide state prior to bone modification
if isnostrilmeshhidden:
bpy.data.objects['nostril_mesh'].hide_viewport = True
else:
bpy.data.objects['nostril_mesh'].hide_viewport = False
# Returns 'fingers' collection to restore hide state prior to bone modification
if isfingerscollhidden:
bpy.data.collections['fingers'].hide_viewport = True
else:
bpy.data.collections['fingers'].hide_viewport = False
# Returns 'toes' collection to restore hide state prior to bone modification
if istoescollhidden:
bpy.data.collections['toes'].hide_viewport = True
else:
bpy.data.collections['toes'].hide_viewport = False
# Return to Object Mode
bpy.ops.object.mode_set(mode='OBJECT')