Skip to content

Commit

Permalink
feat: auto t-pose
Browse files Browse the repository at this point in the history
  • Loading branch information
saturday06 committed Aug 16, 2024
1 parent 93e656e commit a26b996
Show file tree
Hide file tree
Showing 13 changed files with 715 additions and 23 deletions.
32 changes: 32 additions & 0 deletions src/io_scene_vrm/common/debug.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import math
from collections.abc import Sequence
from typing import Union

import bpy
from bpy.types import Context
from mathutils import Matrix, Quaternion, Vector


Expand All @@ -17,3 +20,32 @@ def dump(v: Union[Matrix, Vector, Quaternion, float]) -> str:

x, y, z = (round(math.degrees(xyz)) for xyz in v.to_euler()[:])
return f"Euler({x},{y},{z})"


def assert_vector3_equals(
expected: Vector, actual: Sequence[float], message: str
) -> None:
if len(actual) != 3:
message = f"actual length is not 3: {actual}"
raise AssertionError(message)

threshold = 0.0001
if abs(expected[0] - actual[0]) > threshold:
message = f"{message}: {tuple(expected)} is different from {tuple(actual)}"
raise AssertionError(message)
if abs(expected[1] - actual[1]) > threshold:
message = f"{message}: {tuple(expected)} is different from {tuple(actual)}"
raise AssertionError(message)
if abs(expected[2] - actual[2]) > threshold:
message = f"{message}: {tuple(expected)} is different from {tuple(actual)}"
raise AssertionError(message)


def clean_scene(context: Context) -> None:
if context.view_layer.objects.active:
bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
while context.blend_data.collections:
context.blend_data.collections.remove(context.blend_data.collections[0])
bpy.ops.outliner.orphans_purge(do_recursive=True)
12 changes: 12 additions & 0 deletions src/io_scene_vrm/common/ops/vrm.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ def model_validate(
)


def make_estimated_humanoid_t_pose(
execution_context: str = "EXEC_DEFAULT",
/,
*,
armature_name: str = "",
) -> set[str]:
return bpy.ops.vrm.make_estimated_humanoid_t_pose( # type: ignore[attr-defined, no-any-return]
execution_context,
armature_name=armature_name,
)


def show_blend_file_addon_compatibility_warning(
execution_context: str = "EXEC_DEFAULT",
/,
Expand Down
16 changes: 11 additions & 5 deletions src/io_scene_vrm/editor/make_armature.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,16 +571,22 @@ def fingers(
def setup_as_vrm(
self, context: Context, armature: Object, compare_dict: dict[str, str]
) -> None:
Vrm0HumanoidPropertyGroup.fixup_human_bones(armature)
armature_data = armature.data
if isinstance(armature_data, Armature) and not self.skip_heavy_armature_setup:
if not isinstance(armature_data, Armature):
message = "armature data is not an Armature"
raise TypeError(message)
Vrm0HumanoidPropertyGroup.fixup_human_bones(armature)
ext = get_armature_extension(armature_data)
vrm0_humanoid = ext.vrm0.humanoid
vrm1_humanoid = ext.vrm1.humanoid
if not self.skip_heavy_armature_setup:
for vrm_bone_name, bpy_bone_name in compare_dict.items():
for human_bone in get_armature_extension(
armature_data
).vrm0.humanoid.human_bones:
for human_bone in vrm0_humanoid.human_bones:
if human_bone.bone == vrm_bone_name:
human_bone.node.set_bone_name(bpy_bone_name)
break
vrm0_humanoid.pose = vrm0_humanoid.POSE_REST_POSITION_POSE.identifier
vrm1_humanoid.pose = vrm1_humanoid.POSE_REST_POSITION_POSE.identifier
self.make_extension_setting_and_metas(
armature,
offset_from_head_bone=(-self.eye_depth, self.head_size() / 6, 0),
Expand Down
Loading

0 comments on commit a26b996

Please sign in to comment.