- Add core VRM addon infrastructure with manifest and registration - Add common utilities module with file system, logging, and conversion helpers - Add human bone mapper with support for multiple rigging standards (Mixamo, MMD, Unreal, Rigify, etc.) - Add VRM 0.x and 1.x format support with property groups and handlers - Add editor UI panels for VRM metadata, spring bones, and MToon materials - Add exporter with glTF2 extension support for VRM format serialization - Add importer with scene reconstruction and armature generation - Add MToon shader support with auto-setup and material migration - Add spring bone physics simulation with constraint handling - Add node constraint editor for advanced rigging control - Add comprehensive validation and error handling with user dialogs - Add scene watcher for real-time property synchronization - Add workspace management and preference system - Include Python cache files and Blender manifest configuration - This is the initial commit establishing the complete VRM addon ecosystem for Blender
744 lines
25 KiB
Python
744 lines
25 KiB
Python
# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
|
|
# SPDX-FileCopyrightText: 2018 iCyP
|
|
|
|
import re
|
|
from collections.abc import Mapping
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
from typing import ClassVar, Optional
|
|
|
|
|
|
# https://github.com/vrm-c/vrm-specification/tree/b5793b4ca250ed3acbde3dd7a47ee9ee1b3d60e9/specification/0.0#vrm-extension-models-bone-mapping-jsonextensionsvrmhumanoid
|
|
class HumanBoneName(Enum):
|
|
# Torso
|
|
HIPS = "hips"
|
|
SPINE = "spine"
|
|
CHEST = "chest"
|
|
UPPER_CHEST = "upperChest"
|
|
NECK = "neck"
|
|
|
|
# Head
|
|
HEAD = "head"
|
|
LEFT_EYE = "leftEye"
|
|
RIGHT_EYE = "rightEye"
|
|
JAW = "jaw"
|
|
|
|
# Leg
|
|
LEFT_UPPER_LEG = "leftUpperLeg"
|
|
LEFT_LOWER_LEG = "leftLowerLeg"
|
|
LEFT_FOOT = "leftFoot"
|
|
LEFT_TOES = "leftToes"
|
|
RIGHT_UPPER_LEG = "rightUpperLeg"
|
|
RIGHT_LOWER_LEG = "rightLowerLeg"
|
|
RIGHT_FOOT = "rightFoot"
|
|
RIGHT_TOES = "rightToes"
|
|
|
|
# Arm
|
|
LEFT_SHOULDER = "leftShoulder"
|
|
LEFT_UPPER_ARM = "leftUpperArm"
|
|
LEFT_LOWER_ARM = "leftLowerArm"
|
|
LEFT_HAND = "leftHand"
|
|
RIGHT_SHOULDER = "rightShoulder"
|
|
RIGHT_UPPER_ARM = "rightUpperArm"
|
|
RIGHT_LOWER_ARM = "rightLowerArm"
|
|
RIGHT_HAND = "rightHand"
|
|
|
|
# Finger
|
|
LEFT_THUMB_PROXIMAL = "leftThumbProximal"
|
|
LEFT_THUMB_INTERMEDIATE = "leftThumbIntermediate"
|
|
LEFT_THUMB_DISTAL = "leftThumbDistal"
|
|
LEFT_INDEX_PROXIMAL = "leftIndexProximal"
|
|
LEFT_INDEX_INTERMEDIATE = "leftIndexIntermediate"
|
|
LEFT_INDEX_DISTAL = "leftIndexDistal"
|
|
LEFT_MIDDLE_PROXIMAL = "leftMiddleProximal"
|
|
LEFT_MIDDLE_INTERMEDIATE = "leftMiddleIntermediate"
|
|
LEFT_MIDDLE_DISTAL = "leftMiddleDistal"
|
|
LEFT_RING_PROXIMAL = "leftRingProximal"
|
|
LEFT_RING_INTERMEDIATE = "leftRingIntermediate"
|
|
LEFT_RING_DISTAL = "leftRingDistal"
|
|
LEFT_LITTLE_PROXIMAL = "leftLittleProximal"
|
|
LEFT_LITTLE_INTERMEDIATE = "leftLittleIntermediate"
|
|
LEFT_LITTLE_DISTAL = "leftLittleDistal"
|
|
RIGHT_THUMB_PROXIMAL = "rightThumbProximal"
|
|
RIGHT_THUMB_INTERMEDIATE = "rightThumbIntermediate"
|
|
RIGHT_THUMB_DISTAL = "rightThumbDistal"
|
|
RIGHT_INDEX_PROXIMAL = "rightIndexProximal"
|
|
RIGHT_INDEX_INTERMEDIATE = "rightIndexIntermediate"
|
|
RIGHT_INDEX_DISTAL = "rightIndexDistal"
|
|
RIGHT_MIDDLE_PROXIMAL = "rightMiddleProximal"
|
|
RIGHT_MIDDLE_INTERMEDIATE = "rightMiddleIntermediate"
|
|
RIGHT_MIDDLE_DISTAL = "rightMiddleDistal"
|
|
RIGHT_RING_PROXIMAL = "rightRingProximal"
|
|
RIGHT_RING_INTERMEDIATE = "rightRingIntermediate"
|
|
RIGHT_RING_DISTAL = "rightRingDistal"
|
|
RIGHT_LITTLE_PROXIMAL = "rightLittleProximal"
|
|
RIGHT_LITTLE_INTERMEDIATE = "rightLittleIntermediate"
|
|
RIGHT_LITTLE_DISTAL = "rightLittleDistal"
|
|
|
|
@staticmethod
|
|
def from_str(human_bone_name_str: str) -> Optional["HumanBoneName"]:
|
|
try:
|
|
return HumanBoneName(human_bone_name_str)
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
# https://github.com/vrm-c/vrm.dev/blob/cd1d367417c53ba0f1d46588180c17b5e2768e22/docs/univrm/humanoid/humanoid_overview.md?plain=1#L99-L106
|
|
HumanBoneStructure = dict[HumanBoneName, "HumanBoneStructure"]
|
|
HUMAN_BONE_STRUCTURE: HumanBoneStructure = {
|
|
HumanBoneName.HIPS: {
|
|
HumanBoneName.SPINE: {
|
|
HumanBoneName.CHEST: {
|
|
HumanBoneName.UPPER_CHEST: {
|
|
HumanBoneName.NECK: {
|
|
HumanBoneName.HEAD: {
|
|
HumanBoneName.LEFT_EYE: {},
|
|
HumanBoneName.RIGHT_EYE: {},
|
|
HumanBoneName.JAW: {},
|
|
}
|
|
},
|
|
HumanBoneName.LEFT_SHOULDER: {
|
|
HumanBoneName.LEFT_UPPER_ARM: {
|
|
HumanBoneName.LEFT_LOWER_ARM: {
|
|
HumanBoneName.LEFT_HAND: {
|
|
HumanBoneName.LEFT_THUMB_PROXIMAL: {
|
|
HumanBoneName.LEFT_THUMB_INTERMEDIATE: {
|
|
HumanBoneName.LEFT_THUMB_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.LEFT_INDEX_PROXIMAL: {
|
|
HumanBoneName.LEFT_INDEX_INTERMEDIATE: {
|
|
HumanBoneName.LEFT_INDEX_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.LEFT_MIDDLE_PROXIMAL: {
|
|
HumanBoneName.LEFT_MIDDLE_INTERMEDIATE: {
|
|
HumanBoneName.LEFT_MIDDLE_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.LEFT_RING_PROXIMAL: {
|
|
HumanBoneName.LEFT_RING_INTERMEDIATE: {
|
|
HumanBoneName.LEFT_RING_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.LEFT_LITTLE_PROXIMAL: {
|
|
HumanBoneName.LEFT_LITTLE_INTERMEDIATE: {
|
|
HumanBoneName.LEFT_LITTLE_DISTAL: {}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
},
|
|
HumanBoneName.RIGHT_SHOULDER: {
|
|
HumanBoneName.RIGHT_UPPER_ARM: {
|
|
HumanBoneName.RIGHT_LOWER_ARM: {
|
|
HumanBoneName.RIGHT_HAND: {
|
|
HumanBoneName.RIGHT_THUMB_PROXIMAL: {
|
|
HumanBoneName.RIGHT_THUMB_INTERMEDIATE: {
|
|
HumanBoneName.RIGHT_THUMB_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.RIGHT_INDEX_PROXIMAL: {
|
|
HumanBoneName.RIGHT_INDEX_INTERMEDIATE: {
|
|
HumanBoneName.RIGHT_INDEX_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.RIGHT_MIDDLE_PROXIMAL: {
|
|
HumanBoneName.RIGHT_MIDDLE_INTERMEDIATE: {
|
|
HumanBoneName.RIGHT_MIDDLE_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.RIGHT_RING_PROXIMAL: {
|
|
HumanBoneName.RIGHT_RING_INTERMEDIATE: {
|
|
HumanBoneName.RIGHT_RING_DISTAL: {}
|
|
}
|
|
},
|
|
HumanBoneName.RIGHT_LITTLE_PROXIMAL: {
|
|
HumanBoneName.RIGHT_LITTLE_INTERMEDIATE: {
|
|
HumanBoneName.RIGHT_LITTLE_DISTAL: {}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
},
|
|
HumanBoneName.LEFT_UPPER_LEG: {
|
|
HumanBoneName.LEFT_LOWER_LEG: {
|
|
HumanBoneName.LEFT_FOOT: {HumanBoneName.LEFT_TOES: {}}
|
|
}
|
|
},
|
|
HumanBoneName.RIGHT_UPPER_LEG: {
|
|
HumanBoneName.RIGHT_LOWER_LEG: {
|
|
HumanBoneName.RIGHT_FOOT: {HumanBoneName.RIGHT_TOES: {}}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class HumanBoneSpecification:
|
|
name: HumanBoneName
|
|
icon: str
|
|
title: str
|
|
label: str
|
|
label_no_left_right: str
|
|
requirement: bool
|
|
parent_name: Optional[HumanBoneName]
|
|
children_names: list[HumanBoneName]
|
|
|
|
def parent(self) -> Optional["HumanBoneSpecification"]:
|
|
if self.parent_name is None:
|
|
return None
|
|
return HumanBoneSpecifications.get(self.parent_name)
|
|
|
|
def children(self) -> list["HumanBoneSpecification"]:
|
|
return list(map(HumanBoneSpecifications.get, self.children_names))
|
|
|
|
def descendants(self) -> list["HumanBoneSpecification"]:
|
|
result: list[HumanBoneSpecification] = []
|
|
searching_children = self.children()
|
|
while searching_children:
|
|
child = searching_children.pop()
|
|
result.append(child)
|
|
searching_children.extend(child.children())
|
|
return result
|
|
|
|
def connected(self) -> list["HumanBoneSpecification"]:
|
|
children = self.children()
|
|
parent = self.parent()
|
|
if parent is None:
|
|
return children
|
|
return [*children, parent]
|
|
|
|
@staticmethod
|
|
def create(
|
|
human_bone_name: HumanBoneName, *, requirement: bool, icon: str
|
|
) -> "HumanBoneSpecification":
|
|
# https://stackoverflow.com/a/1176023
|
|
words = re.sub(r"(?<!^)(?=[A-Z])", "#", human_bone_name.value).split("#")
|
|
title = " ".join(map(str.capitalize, words))
|
|
label = title + ":"
|
|
label_no_left_right = re.sub(r"Right ", "", re.sub(r"^Left ", "", label))
|
|
|
|
return HumanBoneSpecification(
|
|
name=human_bone_name,
|
|
icon=icon,
|
|
title=title,
|
|
label=label,
|
|
label_no_left_right=label_no_left_right,
|
|
requirement=requirement,
|
|
parent_name=HumanBoneSpecification.find_parent_human_bone_name(
|
|
human_bone_name, None, HUMAN_BONE_STRUCTURE
|
|
),
|
|
children_names=HumanBoneSpecification.find_children_human_bone_names(
|
|
human_bone_name, HUMAN_BONE_STRUCTURE
|
|
),
|
|
)
|
|
|
|
@staticmethod
|
|
def find_parent_human_bone_name(
|
|
child_human_bone_name: HumanBoneName,
|
|
parent_human_bone_name: Optional[HumanBoneName],
|
|
human_bone_structure: HumanBoneStructure,
|
|
) -> Optional[HumanBoneName]:
|
|
for (
|
|
next_human_bone_name,
|
|
next_human_bone_structure,
|
|
) in human_bone_structure.items():
|
|
if child_human_bone_name == next_human_bone_name:
|
|
return parent_human_bone_name
|
|
|
|
name = HumanBoneSpecification.find_parent_human_bone_name(
|
|
child_human_bone_name, next_human_bone_name, next_human_bone_structure
|
|
)
|
|
if name:
|
|
return name
|
|
|
|
return None
|
|
|
|
@staticmethod
|
|
def find_children_human_bone_names(
|
|
human_bone_name: HumanBoneName,
|
|
human_bone_structure: HumanBoneStructure,
|
|
) -> list[HumanBoneName]:
|
|
for (
|
|
next_human_bone_name,
|
|
next_human_bone_structure,
|
|
) in human_bone_structure.items():
|
|
if human_bone_name == next_human_bone_name:
|
|
return list(next_human_bone_structure.keys())
|
|
|
|
children = HumanBoneSpecification.find_children_human_bone_names(
|
|
human_bone_name, next_human_bone_structure
|
|
)
|
|
if children:
|
|
return children
|
|
|
|
return []
|
|
|
|
def is_ancestor_of(
|
|
self, human_bone_specification: "HumanBoneSpecification"
|
|
) -> bool:
|
|
parent = human_bone_specification.parent()
|
|
while parent:
|
|
if parent == self:
|
|
return True
|
|
parent = parent.parent()
|
|
return False
|
|
|
|
|
|
def create_and_append_human_bone_specification(
|
|
human_bone_specifications: list[HumanBoneSpecification],
|
|
human_bone_name: HumanBoneName,
|
|
*,
|
|
requirement: bool,
|
|
icon: str,
|
|
) -> HumanBoneSpecification:
|
|
human_bone_specification = HumanBoneSpecification.create(
|
|
human_bone_name, requirement=requirement, icon=icon
|
|
)
|
|
human_bone_specifications.append(human_bone_specification)
|
|
return human_bone_specification
|
|
|
|
|
|
class HumanBoneSpecifications:
|
|
all_human_bones: ClassVar[list[HumanBoneSpecification]] = []
|
|
|
|
# https://github.com/vrm-c/vrm-specification/tree/b5793b4ca250ed3acbde3dd7a47ee9ee1b3d60e9/specification/0.0#vrm-extension-models-bone-mapping-jsonextensionsvrmhumanoid
|
|
# Torso
|
|
HIPS = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.HIPS,
|
|
requirement=True,
|
|
icon="USER",
|
|
)
|
|
SPINE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.SPINE,
|
|
requirement=True,
|
|
icon="USER",
|
|
)
|
|
CHEST = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.CHEST,
|
|
requirement=True,
|
|
icon="USER",
|
|
)
|
|
UPPER_CHEST = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.UPPER_CHEST,
|
|
requirement=False,
|
|
icon="USER",
|
|
)
|
|
NECK = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.NECK,
|
|
requirement=True,
|
|
icon="USER",
|
|
)
|
|
|
|
# Head
|
|
HEAD = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.HEAD,
|
|
requirement=True,
|
|
icon="USER",
|
|
)
|
|
LEFT_EYE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_EYE,
|
|
requirement=False,
|
|
icon="HIDE_OFF",
|
|
)
|
|
RIGHT_EYE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_EYE,
|
|
requirement=False,
|
|
icon="HIDE_OFF",
|
|
)
|
|
JAW = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.JAW,
|
|
requirement=False,
|
|
icon="USER",
|
|
)
|
|
|
|
# Leg
|
|
LEFT_UPPER_LEG = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_UPPER_LEG,
|
|
requirement=True,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
LEFT_LOWER_LEG = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_LOWER_LEG,
|
|
requirement=True,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
LEFT_FOOT = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_FOOT,
|
|
requirement=True,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
LEFT_TOES = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_TOES,
|
|
requirement=False,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
RIGHT_UPPER_LEG = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_UPPER_LEG,
|
|
requirement=True,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
RIGHT_LOWER_LEG = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_LOWER_LEG,
|
|
requirement=True,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
RIGHT_FOOT = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_FOOT,
|
|
requirement=True,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
RIGHT_TOES = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_TOES,
|
|
requirement=False,
|
|
icon="MOD_DYNAMICPAINT",
|
|
)
|
|
|
|
# Arm
|
|
LEFT_SHOULDER = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_SHOULDER,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_UPPER_ARM = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_UPPER_ARM,
|
|
requirement=True,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_LOWER_ARM = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_LOWER_ARM,
|
|
requirement=True,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_HAND = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_HAND,
|
|
requirement=True,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_SHOULDER = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_SHOULDER,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_UPPER_ARM = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_UPPER_ARM,
|
|
requirement=True,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_LOWER_ARM = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_LOWER_ARM,
|
|
requirement=True,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_HAND = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_HAND,
|
|
requirement=True,
|
|
icon="VIEW_PAN",
|
|
)
|
|
|
|
# Finger
|
|
LEFT_THUMB_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_THUMB_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_THUMB_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_THUMB_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_THUMB_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_THUMB_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_INDEX_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_INDEX_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_INDEX_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_INDEX_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_INDEX_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_INDEX_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_MIDDLE_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_MIDDLE_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_MIDDLE_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_MIDDLE_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_MIDDLE_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_MIDDLE_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_RING_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_RING_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_RING_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_RING_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_RING_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_RING_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_LITTLE_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_LITTLE_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_LITTLE_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_LITTLE_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
LEFT_LITTLE_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.LEFT_LITTLE_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_THUMB_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_THUMB_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_THUMB_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_THUMB_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_THUMB_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_THUMB_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_INDEX_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_INDEX_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_INDEX_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_INDEX_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_INDEX_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_INDEX_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_MIDDLE_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_MIDDLE_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_MIDDLE_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_MIDDLE_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_MIDDLE_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_MIDDLE_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_RING_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_RING_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_RING_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_RING_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_RING_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_RING_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_LITTLE_PROXIMAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_LITTLE_PROXIMAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_LITTLE_INTERMEDIATE = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_LITTLE_INTERMEDIATE,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
RIGHT_LITTLE_DISTAL = create_and_append_human_bone_specification(
|
|
all_human_bones,
|
|
HumanBoneName.RIGHT_LITTLE_DISTAL,
|
|
requirement=False,
|
|
icon="VIEW_PAN",
|
|
)
|
|
|
|
human_bone_name_to_human_bone: Mapping[HumanBoneName, HumanBoneSpecification] = {
|
|
human_bone.name: human_bone for human_bone in all_human_bones
|
|
}
|
|
|
|
all_names = tuple(b.name.value for b in all_human_bones)
|
|
|
|
required_names = tuple(b.name.value for b in all_human_bones if b.requirement)
|
|
|
|
optional_names = tuple(b.name.value for b in all_human_bones if not b.requirement)
|
|
|
|
@staticmethod
|
|
def get(name: HumanBoneName) -> HumanBoneSpecification:
|
|
return HumanBoneSpecifications.human_bone_name_to_human_bone[name]
|
|
|
|
center_req = tuple(b.name.value for b in [HIPS, SPINE, CHEST, NECK, HEAD])
|
|
left_leg_req = tuple(
|
|
b.name.value for b in [LEFT_UPPER_LEG, LEFT_LOWER_LEG, LEFT_FOOT]
|
|
)
|
|
left_arm_req = tuple(
|
|
b.name.value for b in [LEFT_UPPER_ARM, LEFT_LOWER_ARM, LEFT_HAND]
|
|
)
|
|
right_leg_req = tuple(
|
|
b.name.value for b in [RIGHT_UPPER_LEG, RIGHT_LOWER_LEG, RIGHT_FOOT]
|
|
)
|
|
right_arm_req = tuple(
|
|
b.name.value for b in [RIGHT_UPPER_ARM, RIGHT_LOWER_ARM, RIGHT_HAND]
|
|
)
|
|
|
|
requires = (
|
|
*center_req[:],
|
|
*left_leg_req[:],
|
|
*right_leg_req[:],
|
|
*left_arm_req[:],
|
|
*right_arm_req[:],
|
|
)
|
|
|
|
left_arm_def = tuple(
|
|
b.name.value
|
|
for b in [
|
|
LEFT_SHOULDER,
|
|
LEFT_THUMB_PROXIMAL,
|
|
LEFT_THUMB_INTERMEDIATE,
|
|
LEFT_THUMB_DISTAL,
|
|
LEFT_INDEX_PROXIMAL,
|
|
LEFT_INDEX_INTERMEDIATE,
|
|
LEFT_INDEX_DISTAL,
|
|
LEFT_MIDDLE_PROXIMAL,
|
|
LEFT_MIDDLE_INTERMEDIATE,
|
|
LEFT_MIDDLE_DISTAL,
|
|
LEFT_RING_PROXIMAL,
|
|
LEFT_RING_INTERMEDIATE,
|
|
LEFT_RING_DISTAL,
|
|
LEFT_LITTLE_PROXIMAL,
|
|
LEFT_LITTLE_INTERMEDIATE,
|
|
LEFT_LITTLE_DISTAL,
|
|
]
|
|
)
|
|
|
|
right_arm_def = tuple(
|
|
b.name.value
|
|
for b in [
|
|
RIGHT_SHOULDER,
|
|
RIGHT_THUMB_PROXIMAL,
|
|
RIGHT_THUMB_INTERMEDIATE,
|
|
RIGHT_THUMB_DISTAL,
|
|
RIGHT_INDEX_PROXIMAL,
|
|
RIGHT_INDEX_INTERMEDIATE,
|
|
RIGHT_INDEX_DISTAL,
|
|
RIGHT_MIDDLE_PROXIMAL,
|
|
RIGHT_MIDDLE_INTERMEDIATE,
|
|
RIGHT_MIDDLE_DISTAL,
|
|
RIGHT_RING_PROXIMAL,
|
|
RIGHT_RING_INTERMEDIATE,
|
|
RIGHT_RING_DISTAL,
|
|
RIGHT_LITTLE_PROXIMAL,
|
|
RIGHT_LITTLE_INTERMEDIATE,
|
|
RIGHT_LITTLE_DISTAL,
|
|
]
|
|
)
|
|
center_def = (UPPER_CHEST.name.value, JAW.name.value)
|
|
left_leg_def = (LEFT_TOES.name.value,)
|
|
right_leg_def = (RIGHT_TOES.name.value,)
|
|
defines = (
|
|
LEFT_EYE.name.value,
|
|
RIGHT_EYE.name.value,
|
|
*center_def[:],
|
|
*left_leg_def[:],
|
|
*right_leg_def[:],
|
|
*left_arm_def[:],
|
|
*right_arm_def[:],
|
|
)
|