@volter/blender-engine 0.1.147 → 0.1.149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +4 -11
  3. package/browser/addons/vrm/LICENSE_(OPTION1)_MIT.txt +22 -0
  4. package/browser/addons/vrm/LICENSE_(OPTION2)_GPL-3_0.txt +674 -0
  5. package/browser/addons/vrm/LICENSE_MAIN.txt +1 -0
  6. package/browser/addons/vrm/README.txt +3 -0
  7. package/browser/addons/vrm/__init__.py +41 -0
  8. package/browser/addons/vrm/blender_manifest.toml +16 -0
  9. package/browser/addons/vrm/common/__init__.py +1 -0
  10. package/browser/addons/vrm/common/animation.py +58 -0
  11. package/browser/addons/vrm/common/blender_manifest.py +82 -0
  12. package/browser/addons/vrm/common/char.py +16 -0
  13. package/browser/addons/vrm/common/convert.py +287 -0
  14. package/browser/addons/vrm/common/convert_any.py +48 -0
  15. package/browser/addons/vrm/common/debug.py +40 -0
  16. package/browser/addons/vrm/common/deep.py +162 -0
  17. package/browser/addons/vrm/common/error_dialog.py +274 -0
  18. package/browser/addons/vrm/common/fs.py +71 -0
  19. package/browser/addons/vrm/common/gl.py +20 -0
  20. package/browser/addons/vrm/common/gltf.py +1149 -0
  21. package/browser/addons/vrm/common/human_bone_mapper/__init__.py +1 -0
  22. package/browser/addons/vrm/common/human_bone_mapper/biped_mapping.py +84 -0
  23. package/browser/addons/vrm/common/human_bone_mapper/cats_blender_plugin_fix_model_mapping.py +63 -0
  24. package/browser/addons/vrm/common/human_bone_mapper/human_bone_mapper.py +203 -0
  25. package/browser/addons/vrm/common/human_bone_mapper/microsoft_rocketbox_mapping.py +69 -0
  26. package/browser/addons/vrm/common/human_bone_mapper/mixamo_mapping.py +62 -0
  27. package/browser/addons/vrm/common/human_bone_mapper/mmd_mapping.py +115 -0
  28. package/browser/addons/vrm/common/human_bone_mapper/mpfb_mapping.py +120 -0
  29. package/browser/addons/vrm/common/human_bone_mapper/ready_player_me_mapping.py +65 -0
  30. package/browser/addons/vrm/common/human_bone_mapper/reallusion_mapping.py +94 -0
  31. package/browser/addons/vrm/common/human_bone_mapper/rigify_meta_rig_mapping.py +65 -0
  32. package/browser/addons/vrm/common/human_bone_mapper/structure_based_mapping.py +891 -0
  33. package/browser/addons/vrm/common/human_bone_mapper/unreal_mapping.py +62 -0
  34. package/browser/addons/vrm/common/human_bone_mapper/vrm_addon_mapping.py +112 -0
  35. package/browser/addons/vrm/common/human_bone_mapper/vroid_mapping.py +89 -0
  36. package/browser/addons/vrm/common/legacy_gltf.py +16 -0
  37. package/browser/addons/vrm/common/logger.py +84 -0
  38. package/browser/addons/vrm/common/mtoon0.blend +0 -0
  39. package/browser/addons/vrm/common/mtoon1.blend +0 -0
  40. package/browser/addons/vrm/common/mtoon1_outline.blend +0 -0
  41. package/browser/addons/vrm/common/mtoon_auto_setup.blend +0 -0
  42. package/browser/addons/vrm/common/mtoon_unversioned.py +62 -0
  43. package/browser/addons/vrm/common/ops/__init__.py +10 -0
  44. package/browser/addons/vrm/common/ops/export_scene.py +67 -0
  45. package/browser/addons/vrm/common/ops/icyp.py +53 -0
  46. package/browser/addons/vrm/common/ops/import_scene.py +57 -0
  47. package/browser/addons/vrm/common/ops/vrm.py +2380 -0
  48. package/browser/addons/vrm/common/ops/wm.py +167 -0
  49. package/browser/addons/vrm/common/preferences.py +362 -0
  50. package/browser/addons/vrm/common/progress.py +87 -0
  51. package/browser/addons/vrm/common/rotation.py +89 -0
  52. package/browser/addons/vrm/common/safe_removal.py +46 -0
  53. package/browser/addons/vrm/common/scene_watcher.py +230 -0
  54. package/browser/addons/vrm/common/shader.py +2243 -0
  55. package/browser/addons/vrm/common/shape_key_mapper/__init__.py +1 -0
  56. package/browser/addons/vrm/common/shape_key_mapper/arkit_mapping.py +168 -0
  57. package/browser/addons/vrm/common/shape_key_mapper/mmd_mapping.py +62 -0
  58. package/browser/addons/vrm/common/shape_key_mapper/ready_player_me_mapping.py +52 -0
  59. package/browser/addons/vrm/common/shape_key_mapper/vrchat_mapping.py +17 -0
  60. package/browser/addons/vrm/common/third_party_user_extension.py +214 -0
  61. package/browser/addons/vrm/common/transparent_z_write.blend +0 -0
  62. package/browser/addons/vrm/common/version.py +161 -0
  63. package/browser/addons/vrm/common/vrm0/__init__.py +1 -0
  64. package/browser/addons/vrm/common/vrm0/human_bone.py +662 -0
  65. package/browser/addons/vrm/common/vrm0/material_property.py +346 -0
  66. package/browser/addons/vrm/common/vrm1/__init__.py +1 -0
  67. package/browser/addons/vrm/common/vrm1/expression_preset.py +207 -0
  68. package/browser/addons/vrm/common/vrm1/human_bone.py +822 -0
  69. package/browser/addons/vrm/common/workspace.py +227 -0
  70. package/browser/addons/vrm/common/writable_context.py +77 -0
  71. package/browser/addons/vrm/documentation/en-us/animation/index.md +63 -0
  72. package/browser/addons/vrm/documentation/en-us/create-humanoid-vrm-from-scratch/index.md +131 -0
  73. package/browser/addons/vrm/documentation/en-us/create-simple-vrm-from-scratch/index.md +30 -0
  74. package/browser/addons/vrm/documentation/en-us/development/index.md +136 -0
  75. package/browser/addons/vrm/documentation/en-us/index.md +41 -0
  76. package/browser/addons/vrm/documentation/en-us/installation/index.md +152 -0
  77. package/browser/addons/vrm/documentation/en-us/material-mtoon/index.md +122 -0
  78. package/browser/addons/vrm/documentation/en-us/material-pbr/index.md +94 -0
  79. package/browser/addons/vrm/documentation/en-us/scripting-api/index.md +391 -0
  80. package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrm/index.md +57 -0
  81. package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrma/index.md +17 -0
  82. package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrm/index.md +61 -0
  83. package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrma/index.md +13 -0
  84. package/browser/addons/vrm/documentation/ja-jp/animation/index.md +57 -0
  85. package/browser/addons/vrm/documentation/ja-jp/create-humanoid-vrm-from-scratch/index.md +129 -0
  86. package/browser/addons/vrm/documentation/ja-jp/create-simple-vrm-from-scratch/index.md +29 -0
  87. package/browser/addons/vrm/documentation/ja-jp/development/index.md +137 -0
  88. package/browser/addons/vrm/documentation/ja-jp/index.md +37 -0
  89. package/browser/addons/vrm/documentation/ja-jp/installation/index.md +150 -0
  90. package/browser/addons/vrm/documentation/ja-jp/material-mtoon/index.md +113 -0
  91. package/browser/addons/vrm/documentation/ja-jp/material-pbr/index.md +90 -0
  92. package/browser/addons/vrm/documentation/ja-jp/scripting-api/index.md +389 -0
  93. package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrm/index.md +55 -0
  94. package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrma/index.md +19 -0
  95. package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrm/index.md +56 -0
  96. package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrma/index.md +14 -0
  97. package/browser/addons/vrm/editor/__init__.py +1 -0
  98. package/browser/addons/vrm/editor/extension.py +425 -0
  99. package/browser/addons/vrm/editor/extension_accessor.py +75 -0
  100. package/browser/addons/vrm/editor/handler.py +84 -0
  101. package/browser/addons/vrm/editor/khr_character/__init__.py +1 -0
  102. package/browser/addons/vrm/editor/khr_character/panel.py +69 -0
  103. package/browser/addons/vrm/editor/khr_character/property_group.py +27 -0
  104. package/browser/addons/vrm/editor/khr_xmp_json_ld/__init__.py +1 -0
  105. package/browser/addons/vrm/editor/khr_xmp_json_ld/ops.py +464 -0
  106. package/browser/addons/vrm/editor/khr_xmp_json_ld/panel.py +136 -0
  107. package/browser/addons/vrm/editor/khr_xmp_json_ld/property_group.py +83 -0
  108. package/browser/addons/vrm/editor/khr_xmp_json_ld/ui_list.py +198 -0
  109. package/browser/addons/vrm/editor/make_armature.py +709 -0
  110. package/browser/addons/vrm/editor/menu.py +147 -0
  111. package/browser/addons/vrm/editor/migration.py +297 -0
  112. package/browser/addons/vrm/editor/mtoon1/__init__.py +1 -0
  113. package/browser/addons/vrm/editor/mtoon1/handler.py +20 -0
  114. package/browser/addons/vrm/editor/mtoon1/migration.py +536 -0
  115. package/browser/addons/vrm/editor/mtoon1/ops.py +304 -0
  116. package/browser/addons/vrm/editor/mtoon1/panel.py +442 -0
  117. package/browser/addons/vrm/editor/mtoon1/property_group.py +4977 -0
  118. package/browser/addons/vrm/editor/mtoon1/scene_watcher.py +381 -0
  119. package/browser/addons/vrm/editor/node_constraint1/__init__.py +1 -0
  120. package/browser/addons/vrm/editor/node_constraint1/panel.py +317 -0
  121. package/browser/addons/vrm/editor/node_constraint1/property_group.py +25 -0
  122. package/browser/addons/vrm/editor/ops.py +471 -0
  123. package/browser/addons/vrm/editor/panel.py +315 -0
  124. package/browser/addons/vrm/editor/property_group.py +888 -0
  125. package/browser/addons/vrm/editor/search.py +682 -0
  126. package/browser/addons/vrm/editor/spring_bone1/__init__.py +1 -0
  127. package/browser/addons/vrm/editor/spring_bone1/handler.py +994 -0
  128. package/browser/addons/vrm/editor/spring_bone1/menu.py +246 -0
  129. package/browser/addons/vrm/editor/spring_bone1/migration.py +86 -0
  130. package/browser/addons/vrm/editor/spring_bone1/ops.py +1679 -0
  131. package/browser/addons/vrm/editor/spring_bone1/panel.py +605 -0
  132. package/browser/addons/vrm/editor/spring_bone1/property_group.py +1457 -0
  133. package/browser/addons/vrm/editor/spring_bone1/ui_list.py +408 -0
  134. package/browser/addons/vrm/editor/subscription.py +123 -0
  135. package/browser/addons/vrm/editor/t_pose.py +713 -0
  136. package/browser/addons/vrm/editor/validation.py +1271 -0
  137. package/browser/addons/vrm/editor/vrm0/__init__.py +1 -0
  138. package/browser/addons/vrm/editor/vrm0/gizmo_group.py +63 -0
  139. package/browser/addons/vrm/editor/vrm0/handler.py +23 -0
  140. package/browser/addons/vrm/editor/vrm0/menu.py +145 -0
  141. package/browser/addons/vrm/editor/vrm0/migration.py +761 -0
  142. package/browser/addons/vrm/editor/vrm0/ops.py +2145 -0
  143. package/browser/addons/vrm/editor/vrm0/panel.py +1333 -0
  144. package/browser/addons/vrm/editor/vrm0/property_group.py +1818 -0
  145. package/browser/addons/vrm/editor/vrm0/ui_list.py +688 -0
  146. package/browser/addons/vrm/editor/vrm1/__init__.py +1 -0
  147. package/browser/addons/vrm/editor/vrm1/handler.py +28 -0
  148. package/browser/addons/vrm/editor/vrm1/menu.py +76 -0
  149. package/browser/addons/vrm/editor/vrm1/migration.py +321 -0
  150. package/browser/addons/vrm/editor/vrm1/ops.py +2679 -0
  151. package/browser/addons/vrm/editor/vrm1/panel.py +1243 -0
  152. package/browser/addons/vrm/editor/vrm1/property_group.py +2087 -0
  153. package/browser/addons/vrm/editor/vrm1/scene_watcher.py +90 -0
  154. package/browser/addons/vrm/editor/vrm1/ui_list.py +533 -0
  155. package/browser/addons/vrm/exporter/__init__.py +1 -0
  156. package/browser/addons/vrm/exporter/abstract_base_vrm_exporter.py +628 -0
  157. package/browser/addons/vrm/exporter/export_scene.py +930 -0
  158. package/browser/addons/vrm/exporter/gltf2_export_user_extension.py +45 -0
  159. package/browser/addons/vrm/exporter/khr_character_exporter.py +34 -0
  160. package/browser/addons/vrm/exporter/vrm0_exporter.py +4020 -0
  161. package/browser/addons/vrm/exporter/vrm1_exporter.py +3682 -0
  162. package/browser/addons/vrm/exporter/vrm_animation_exporter.py +1035 -0
  163. package/browser/addons/vrm/external/__init__.py +1 -0
  164. package/browser/addons/vrm/external/auto_rig_pro_support.py +3 -0
  165. package/browser/addons/vrm/external/io_scene_gltf2_support.py +418 -0
  166. package/browser/addons/vrm/external/rigify_support.py +1 -0
  167. package/browser/addons/vrm/importer/__init__.py +1 -0
  168. package/browser/addons/vrm/importer/abstract_base_vrm_importer.py +1548 -0
  169. package/browser/addons/vrm/importer/file_handler.py +34 -0
  170. package/browser/addons/vrm/importer/gltf2_import_user_extension.py +268 -0
  171. package/browser/addons/vrm/importer/import_scene.py +646 -0
  172. package/browser/addons/vrm/importer/license_validation.py +198 -0
  173. package/browser/addons/vrm/importer/vrm0_importer.py +1723 -0
  174. package/browser/addons/vrm/importer/vrm1_importer.py +2014 -0
  175. package/browser/addons/vrm/importer/vrm_animation_importer.py +763 -0
  176. package/browser/addons/vrm/importer/vrm_diff.py +316 -0
  177. package/browser/addons/vrm/locale/__init__.py +1 -0
  178. package/browser/addons/vrm/locale/ja_jp.py +826 -0
  179. package/browser/addons/vrm/locale/ruff.toml +8 -0
  180. package/browser/addons/vrm/locale/translation_dictionary.py +10 -0
  181. package/browser/addons/vrm/locale/zh_hans.py +928 -0
  182. package/browser/addons/vrm/registration.py +670 -0
  183. package/browser/addons/vrm.json +18 -0
  184. package/browser/blender-emscripten-engine.mts +60 -128
  185. package/browser/blender-engine.mts +20 -186
  186. package/browser/blender-wali-engine.mts +35 -81
  187. package/browser/describe-thrown.mts +3 -6
  188. package/browser/document-chunks.mts +4 -16
  189. package/browser/gltf_export.py +3161 -0
  190. package/browser/heap-growth.mts +23 -0
  191. package/browser/index.ts +2 -0
  192. package/browser/protocol.ts +119 -35
  193. package/browser/pull-job.mts +2 -10
  194. package/browser/rna.ts +190 -73
  195. package/browser/runtime.ts +197 -82
  196. package/browser/session-addons.mts +33 -0
  197. package/browser/session-frame.mts +5 -24
  198. package/browser/session.py +1338 -1427
  199. package/browser/three/attach-presenter.ts +11 -39
  200. package/browser/three/blender-base64.ts +1 -36
  201. package/browser/three/blender-corner-normals.ts +1 -23
  202. package/browser/three/blender-display-shaders.json +1 -1
  203. package/browser/three/blender-display-shaders.lut +0 -0
  204. package/browser/three/blender-display-transform.ts +2 -1
  205. package/browser/three/blender-frame-columns.ts +5 -13
  206. package/browser/three/blender-graph-material.ts +18 -3
  207. package/browser/three/blender-node-graph.ts +10 -34
  208. package/browser/three/blender-physical-material.ts +2 -31
  209. package/browser/three/blender-runtime-armature.ts +7 -60
  210. package/browser/three/blender-runtime-frame.ts +9 -23
  211. package/browser/three/blender-runtime-geometry.ts +22 -26
  212. package/browser/three/blender-runtime-lighting.ts +48 -178
  213. package/browser/three/blender-runtime-shadows.ts +187 -1
  214. package/browser/three/blender-runtime-skeleton.ts +53 -1
  215. package/browser/three/blender-runtime-view.ts +505 -283
  216. package/browser/three/blender-runtime-weights.ts +9 -72
  217. package/browser/three/blender-sky.ts +13 -33
  218. package/browser/three/blender-triangulate.ts +7 -35
  219. package/browser/three/blender-viewport-sampling.ts +235 -0
  220. package/browser/three/blender-workbench-material.ts +25 -29
  221. package/browser/three/blender-workbench-outline.ts +199 -0
  222. package/browser/three/blender-world-volume.ts +62 -10
  223. package/browser/three/presenter.ts +10 -26
  224. package/browser/three/release.ts +5 -21
  225. package/browser/three/sky-precompute-worker.ts +1 -18
  226. package/browser/three/sky-worker.ts +5 -23
  227. package/browser/three/world-field-sampler.ts +12 -26
  228. package/browser/volter_three.py +9 -105
  229. package/browser/worker.ts +156 -151
  230. package/package.json +5 -2
  231. package/wasm/BUNDLE.json +17 -17
  232. package/wasm/DEPENDENCY-LICENSES.txt +14 -0
  233. package/wasm/blender_browser.data.br +0 -0
  234. package/wasm/blender_browser.js +1 -1
  235. package/wasm/blender_browser.wasm.br +0 -0
  236. package/browser/frame-transfer.mts +0 -19
  237. package/browser/three/agx-base-srgb.lut +0 -0
  238. package/browser/three/agx-look-medium-high-contrast.lut +0 -0
  239. package/browser/three/agx-look-punchy.lut +0 -0
  240. package/browser/three/blender-agx.ts +0 -235
  241. package/browser/three/blender-display-lut.ts +0 -145
  242. package/browser/three/blender-filmic.ts +0 -49
  243. package/browser/three/blender-standard.ts +0 -68
  244. package/browser/three/blender-world-visibility.ts +0 -278
  245. package/browser/three/filmic-srgb.lut +0 -0
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
@@ -0,0 +1,84 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from collections.abc import Mapping
3
+
4
+ from bpy.types import Object
5
+
6
+ from ..logger import get_logger
7
+ from ..vrm1.human_bone import HumanBoneSpecification, HumanBoneSpecifications
8
+
9
+ _logger = get_logger(__name__)
10
+
11
+ _biped_mapping = {
12
+ (None, "Pelvis"): HumanBoneSpecifications.HIPS,
13
+ (None, "Spine"): HumanBoneSpecifications.SPINE,
14
+ (None, "Spine2"): HumanBoneSpecifications.CHEST,
15
+ (None, "Neck"): HumanBoneSpecifications.NECK,
16
+ (None, "Head"): HumanBoneSpecifications.HEAD,
17
+ ("R", "Clavicle"): HumanBoneSpecifications.RIGHT_SHOULDER,
18
+ ("R", "UpperArm"): HumanBoneSpecifications.RIGHT_UPPER_ARM,
19
+ ("R", "Forearm"): HumanBoneSpecifications.RIGHT_LOWER_ARM,
20
+ ("R", "Hand"): HumanBoneSpecifications.RIGHT_HAND,
21
+ ("L", "Clavicle"): HumanBoneSpecifications.LEFT_SHOULDER,
22
+ ("L", "UpperArm"): HumanBoneSpecifications.LEFT_UPPER_ARM,
23
+ ("L", "Forearm"): HumanBoneSpecifications.LEFT_LOWER_ARM,
24
+ ("L", "Hand"): HumanBoneSpecifications.LEFT_HAND,
25
+ ("R", "Thigh"): HumanBoneSpecifications.RIGHT_UPPER_LEG,
26
+ ("R", "Calf"): HumanBoneSpecifications.RIGHT_LOWER_LEG,
27
+ ("R", "Foot"): HumanBoneSpecifications.RIGHT_FOOT,
28
+ ("R", "Toe0"): HumanBoneSpecifications.RIGHT_TOES,
29
+ ("L", "Thigh"): HumanBoneSpecifications.LEFT_UPPER_LEG,
30
+ ("L", "Calf"): HumanBoneSpecifications.LEFT_LOWER_LEG,
31
+ ("L", "Foot"): HumanBoneSpecifications.LEFT_FOOT,
32
+ ("L", "Toe0"): HumanBoneSpecifications.LEFT_TOES,
33
+ ("R", "Finger0"): HumanBoneSpecifications.RIGHT_THUMB_METACARPAL,
34
+ ("R", "Finger01"): HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL,
35
+ ("R", "Finger02"): HumanBoneSpecifications.RIGHT_THUMB_DISTAL,
36
+ ("L", "Finger0"): HumanBoneSpecifications.LEFT_THUMB_METACARPAL,
37
+ ("L", "Finger01"): HumanBoneSpecifications.LEFT_THUMB_PROXIMAL,
38
+ ("L", "Finger02"): HumanBoneSpecifications.LEFT_THUMB_DISTAL,
39
+ ("R", "Finger1"): HumanBoneSpecifications.RIGHT_INDEX_PROXIMAL,
40
+ ("R", "Finger11"): HumanBoneSpecifications.RIGHT_INDEX_INTERMEDIATE,
41
+ ("R", "Finger12"): HumanBoneSpecifications.RIGHT_INDEX_DISTAL,
42
+ ("L", "Finger1"): HumanBoneSpecifications.LEFT_INDEX_PROXIMAL,
43
+ ("L", "Finger11"): HumanBoneSpecifications.LEFT_INDEX_INTERMEDIATE,
44
+ ("L", "Finger12"): HumanBoneSpecifications.LEFT_INDEX_DISTAL,
45
+ ("R", "Finger2"): HumanBoneSpecifications.RIGHT_MIDDLE_PROXIMAL,
46
+ ("R", "Finger21"): HumanBoneSpecifications.RIGHT_MIDDLE_INTERMEDIATE,
47
+ ("R", "Finger22"): HumanBoneSpecifications.RIGHT_MIDDLE_DISTAL,
48
+ ("L", "Finger2"): HumanBoneSpecifications.LEFT_MIDDLE_PROXIMAL,
49
+ ("L", "Finger21"): HumanBoneSpecifications.LEFT_MIDDLE_INTERMEDIATE,
50
+ ("L", "Finger22"): HumanBoneSpecifications.LEFT_MIDDLE_DISTAL,
51
+ ("R", "Finger3"): HumanBoneSpecifications.RIGHT_RING_PROXIMAL,
52
+ ("R", "Finger31"): HumanBoneSpecifications.RIGHT_RING_INTERMEDIATE,
53
+ ("R", "Finger32"): HumanBoneSpecifications.RIGHT_RING_DISTAL,
54
+ ("L", "Finger3"): HumanBoneSpecifications.LEFT_RING_PROXIMAL,
55
+ ("L", "Finger31"): HumanBoneSpecifications.LEFT_RING_INTERMEDIATE,
56
+ ("L", "Finger32"): HumanBoneSpecifications.LEFT_RING_DISTAL,
57
+ ("R", "Finger4"): HumanBoneSpecifications.RIGHT_LITTLE_PROXIMAL,
58
+ ("R", "Finger41"): HumanBoneSpecifications.RIGHT_LITTLE_INTERMEDIATE,
59
+ ("R", "Finger42"): HumanBoneSpecifications.RIGHT_LITTLE_DISTAL,
60
+ ("L", "Finger4"): HumanBoneSpecifications.LEFT_LITTLE_PROXIMAL,
61
+ ("L", "Finger41"): HumanBoneSpecifications.LEFT_LITTLE_INTERMEDIATE,
62
+ ("L", "Finger42"): HumanBoneSpecifications.LEFT_LITTLE_DISTAL,
63
+ }
64
+
65
+
66
+ def create_config(
67
+ armature: Object,
68
+ ) -> tuple[str, Mapping[str, HumanBoneSpecification]]:
69
+ mapping: dict[str, HumanBoneSpecification] = {}
70
+ for bone in armature.pose.bones:
71
+ for (bone_lr, bone_suffix), specification in _biped_mapping.items():
72
+ if (
73
+ bone.name.startswith("Bip001")
74
+ and bone.name.endswith(bone_suffix)
75
+ and (bone_lr is None or bone_lr in bone.name)
76
+ ):
77
+ mapping[bone.name] = specification
78
+
79
+ name = "Bip001"
80
+ for specification in HumanBoneSpecifications.all_human_bones:
81
+ if specification.requirement and specification not in mapping.values():
82
+ return (name, {})
83
+
84
+ return (name, mapping)
@@ -0,0 +1,63 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from collections.abc import Mapping
3
+ from typing import Final
4
+
5
+ from ..vrm1.human_bone import HumanBoneSpecification, HumanBoneSpecifications
6
+
7
+ MAPPING: Final[Mapping[str, HumanBoneSpecification]] = {
8
+ "Hips": HumanBoneSpecifications.HIPS,
9
+ "Spine": HumanBoneSpecifications.SPINE,
10
+ "Chest": HumanBoneSpecifications.CHEST,
11
+ "Neck": HumanBoneSpecifications.NECK,
12
+ "Head": HumanBoneSpecifications.HEAD,
13
+ "Eye_R": HumanBoneSpecifications.RIGHT_EYE,
14
+ "Eye_L": HumanBoneSpecifications.LEFT_EYE,
15
+ "Right shoulder": HumanBoneSpecifications.RIGHT_SHOULDER,
16
+ "Right arm": HumanBoneSpecifications.RIGHT_UPPER_ARM,
17
+ "Right elbow": HumanBoneSpecifications.RIGHT_LOWER_ARM,
18
+ "Right wrist": HumanBoneSpecifications.RIGHT_HAND,
19
+ "Left shoulder": HumanBoneSpecifications.LEFT_SHOULDER,
20
+ "Left arm": HumanBoneSpecifications.LEFT_UPPER_ARM,
21
+ "Left elbow": HumanBoneSpecifications.LEFT_LOWER_ARM,
22
+ "Left wrist": HumanBoneSpecifications.LEFT_HAND,
23
+ "Right leg": HumanBoneSpecifications.RIGHT_UPPER_LEG,
24
+ "Right knee": HumanBoneSpecifications.RIGHT_LOWER_LEG,
25
+ "Right ankle": HumanBoneSpecifications.RIGHT_FOOT,
26
+ "Right toe": HumanBoneSpecifications.RIGHT_TOES,
27
+ "Left leg": HumanBoneSpecifications.LEFT_UPPER_LEG,
28
+ "Left knee": HumanBoneSpecifications.LEFT_LOWER_LEG,
29
+ "Left ankle": HumanBoneSpecifications.LEFT_FOOT,
30
+ "Left toe": HumanBoneSpecifications.LEFT_TOES,
31
+ "Thumb0_R": HumanBoneSpecifications.RIGHT_THUMB_METACARPAL,
32
+ "Thumb1_R": HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL,
33
+ "Thumb2_R": HumanBoneSpecifications.RIGHT_THUMB_DISTAL,
34
+ "Thumb0_L": HumanBoneSpecifications.LEFT_THUMB_METACARPAL,
35
+ "Thumb1_L": HumanBoneSpecifications.LEFT_THUMB_PROXIMAL,
36
+ "Thumb2_L": HumanBoneSpecifications.LEFT_THUMB_DISTAL,
37
+ "IndexFinger1_R": HumanBoneSpecifications.RIGHT_INDEX_PROXIMAL,
38
+ "IndexFinger2_R": HumanBoneSpecifications.RIGHT_INDEX_INTERMEDIATE,
39
+ "IndexFinger3_R": HumanBoneSpecifications.RIGHT_INDEX_DISTAL,
40
+ "IndexFinger1_L": HumanBoneSpecifications.LEFT_INDEX_PROXIMAL,
41
+ "IndexFinger2_L": HumanBoneSpecifications.LEFT_INDEX_INTERMEDIATE,
42
+ "IndexFinger3_L": HumanBoneSpecifications.LEFT_INDEX_DISTAL,
43
+ "MiddleFinger1_R": HumanBoneSpecifications.RIGHT_MIDDLE_PROXIMAL,
44
+ "MiddleFinger2_R": HumanBoneSpecifications.RIGHT_MIDDLE_INTERMEDIATE,
45
+ "MiddleFinger3_R": HumanBoneSpecifications.RIGHT_MIDDLE_DISTAL,
46
+ "MiddleFinger1_L": HumanBoneSpecifications.LEFT_MIDDLE_PROXIMAL,
47
+ "MiddleFinger2_L": HumanBoneSpecifications.LEFT_MIDDLE_INTERMEDIATE,
48
+ "MiddleFinger3_L": HumanBoneSpecifications.LEFT_MIDDLE_DISTAL,
49
+ "RingFinger1_R": HumanBoneSpecifications.RIGHT_RING_PROXIMAL,
50
+ "RingFinger2_R": HumanBoneSpecifications.RIGHT_RING_INTERMEDIATE,
51
+ "RingFinger3_R": HumanBoneSpecifications.RIGHT_RING_DISTAL,
52
+ "RingFinger1_L": HumanBoneSpecifications.LEFT_RING_PROXIMAL,
53
+ "RingFinger2_L": HumanBoneSpecifications.LEFT_RING_INTERMEDIATE,
54
+ "RingFinger3_L": HumanBoneSpecifications.LEFT_RING_DISTAL,
55
+ "LittleFinger1_R": HumanBoneSpecifications.RIGHT_LITTLE_PROXIMAL,
56
+ "LittleFinger2_R": HumanBoneSpecifications.RIGHT_LITTLE_INTERMEDIATE,
57
+ "LittleFinger3_R": HumanBoneSpecifications.RIGHT_LITTLE_DISTAL,
58
+ "LittleFinger1_L": HumanBoneSpecifications.LEFT_LITTLE_PROXIMAL,
59
+ "LittleFinger2_L": HumanBoneSpecifications.LEFT_LITTLE_INTERMEDIATE,
60
+ "LittleFinger3_L": HumanBoneSpecifications.LEFT_LITTLE_DISTAL,
61
+ }
62
+
63
+ CONFIG = ("Cats Blender Plugin Fixed Model", MAPPING)
@@ -0,0 +1,203 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ import re
3
+ from collections.abc import Mapping
4
+ from functools import cache
5
+ from typing import Final, Optional
6
+
7
+ from bpy.types import Armature, Bone, Object
8
+
9
+ from ..char import FULLWIDTH_ASCII_TO_ASCII_MAP
10
+ from ..logger import get_logger
11
+ from ..vrm1.human_bone import HumanBoneSpecification, HumanBoneSpecifications
12
+ from . import (
13
+ biped_mapping,
14
+ cats_blender_plugin_fix_model_mapping,
15
+ microsoft_rocketbox_mapping,
16
+ mixamo_mapping,
17
+ mmd_mapping,
18
+ mpfb_mapping,
19
+ ready_player_me_mapping,
20
+ reallusion_mapping,
21
+ rigify_meta_rig_mapping,
22
+ unreal_mapping,
23
+ vrm_addon_mapping,
24
+ vroid_mapping,
25
+ )
26
+ from .structure_based_mapping import create_structure_based_mapping
27
+
28
+ BONE_NAME_LOWER_TO_UPPER_REGEX_SUB: Final = (re.compile(r"([a-z])([A-Z])"), r"\1.\2")
29
+ BONE_NAME_DIGIT_REGEX_SUB: Final = (re.compile(r"(\d+)"), r".\1.")
30
+ BONE_NAME_COMPONENT_SPLIT_REGEX: Final = re.compile(r"[-._: (){}[\]<>]+")
31
+
32
+ _logger = get_logger(__name__)
33
+
34
+
35
+ @cache
36
+ def _canonicalize_bone_name(bone_name: str) -> str:
37
+ bone_name = "".join(FULLWIDTH_ASCII_TO_ASCII_MAP.get(c, c) for c in bone_name)
38
+ bone_name = re.sub(*BONE_NAME_LOWER_TO_UPPER_REGEX_SUB, bone_name)
39
+ bone_name = bone_name.lower()
40
+ bone_name = "".join(" " if c.isspace() else c for c in bone_name)
41
+ bone_name = re.sub(*BONE_NAME_DIGIT_REGEX_SUB, bone_name).strip(".")
42
+ bone_name_components = re.split(BONE_NAME_COMPONENT_SPLIT_REGEX, bone_name)
43
+ for patterns, replacement in {
44
+ ("l", "左"): "left",
45
+ ("r", "右"): "right",
46
+ }.items():
47
+ bone_name_components = [
48
+ replacement if bone_name_component in patterns else bone_name_component
49
+ for bone_name_component in bone_name_components
50
+ ]
51
+ return ".".join(bone_name_components)
52
+
53
+
54
+ def _match_bone_name(bone_name1: str, bone_name2: str) -> bool:
55
+ return _canonicalize_bone_name(bone_name1) == _canonicalize_bone_name(bone_name2)
56
+
57
+
58
+ def _match_count(
59
+ armature: Armature, mapping: Mapping[str, HumanBoneSpecification]
60
+ ) -> int:
61
+ count = 0
62
+
63
+ mapping = {
64
+ bpy_name: specification
65
+ for bpy_name, specification in mapping.items()
66
+ if any(_match_bone_name(bpy_name, bone.name) for bone in armature.bones)
67
+ }
68
+
69
+ # Validate bone ordering
70
+ for bpy_name, specification in mapping.items():
71
+ bone = next(
72
+ (bone for bone in armature.bones if _match_bone_name(bpy_name, bone.name)),
73
+ None,
74
+ )
75
+ if not bone:
76
+ continue
77
+
78
+ parent_specification: Optional[HumanBoneSpecification] = None
79
+ search_parent_specification = specification.parent
80
+ while search_parent_specification:
81
+ if search_parent_specification in mapping.values():
82
+ parent_specification = search_parent_specification
83
+ break
84
+ search_parent_specification = search_parent_specification.parent
85
+
86
+ found = False
87
+ bone: Optional[Bone] = bone.parent
88
+ while bone:
89
+ search_specification = next(
90
+ (
91
+ search_specification
92
+ for bpy_name, search_specification in mapping.items()
93
+ if _match_bone_name(bpy_name, bone.name)
94
+ ),
95
+ None,
96
+ )
97
+ if search_specification:
98
+ found = search_specification == parent_specification
99
+ break
100
+ bone = bone.parent
101
+
102
+ if found or not parent_specification:
103
+ count += 1
104
+ continue
105
+
106
+ return count
107
+
108
+
109
+ def _match_counts(
110
+ armature: object, mapping: Mapping[str, HumanBoneSpecification]
111
+ ) -> tuple[int, int]:
112
+ if not isinstance(armature, Armature):
113
+ message = f"{type(armature)} is not an Armature"
114
+ raise TypeError(message)
115
+ required_mapping = {
116
+ bpy_name: required_specification
117
+ for bpy_name, required_specification in mapping.items()
118
+ if required_specification.requirement
119
+ }
120
+ return (_match_count(armature, required_mapping), _match_count(armature, mapping))
121
+
122
+
123
+ def _sorted_required_first(
124
+ armature: Armature,
125
+ mapping: Mapping[str, HumanBoneSpecification],
126
+ ) -> dict[str, HumanBoneSpecification]:
127
+ bpy_bone_name_mapping: dict[str, HumanBoneSpecification] = {
128
+ bpy_bone_name: specification
129
+ for original_bone_name, specification in mapping.items()
130
+ if (
131
+ bpy_bone_name := next(
132
+ (
133
+ bone.name
134
+ for bone in armature.bones
135
+ if _match_bone_name(original_bone_name, bone.name)
136
+ ),
137
+ None,
138
+ )
139
+ )
140
+ }
141
+ sorted_mapping: dict[str, HumanBoneSpecification] = {}
142
+ sorted_mapping.update(
143
+ {
144
+ bpy_name: specification
145
+ for bpy_name, specification in bpy_bone_name_mapping.items()
146
+ if specification.requirement
147
+ }
148
+ )
149
+ sorted_mapping.update(
150
+ {
151
+ bpy_name: specification
152
+ for bpy_name, specification in bpy_bone_name_mapping.items()
153
+ if not specification.requirement
154
+ }
155
+ )
156
+ return sorted_mapping
157
+
158
+
159
+ def create_human_bone_mapping(
160
+ armature: Object,
161
+ ) -> dict[str, HumanBoneSpecification]:
162
+ armature_data = armature.data
163
+ if not isinstance(armature_data, Armature):
164
+ raise TypeError
165
+ ((required_count, _all_count), name, mapping) = max(
166
+ (_match_counts(armature_data, mapping), name, mapping)
167
+ for name, mapping in (
168
+ mmd_mapping.create_config(armature),
169
+ biped_mapping.create_config(armature),
170
+ mixamo_mapping.CONFIG,
171
+ mpfb_mapping.CONFIG_DEFAULT,
172
+ mpfb_mapping.CONFIG_GAME_ENGINE,
173
+ unreal_mapping.CONFIG,
174
+ ready_player_me_mapping.CONFIG,
175
+ reallusion_mapping.CONFIG,
176
+ cats_blender_plugin_fix_model_mapping.CONFIG,
177
+ microsoft_rocketbox_mapping.CONFIG_BIP01,
178
+ microsoft_rocketbox_mapping.CONFIG_BIP02,
179
+ rigify_meta_rig_mapping.CONFIG,
180
+ vroid_mapping.CONFIG,
181
+ vroid_mapping.CONFIG_SYMMETRICAL,
182
+ vrm_addon_mapping.CONFIG_VRM1,
183
+ vrm_addon_mapping.CONFIG_VRM0,
184
+ )
185
+ )
186
+ result = {}
187
+ wanted_required_count = sum(
188
+ 1 for spec in HumanBoneSpecifications.all_human_bones if spec.requirement
189
+ )
190
+ if required_count < wanted_required_count:
191
+ structure_based_mapping = create_structure_based_mapping(armature)
192
+ structure_base_mapping_required_count = sum(
193
+ 1 for spec in structure_based_mapping.values() if spec.requirement
194
+ )
195
+ if required_count < structure_base_mapping_required_count:
196
+ mapping = structure_based_mapping
197
+ name = "Structure Based Auto Detected"
198
+ required_count = structure_base_mapping_required_count
199
+ if required_count:
200
+ _logger.debug('Treat as "%s" bone mappings', name)
201
+ result = _sorted_required_first(armature_data, mapping)
202
+ _canonicalize_bone_name.cache_clear()
203
+ return result
@@ -0,0 +1,69 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from collections.abc import Mapping
3
+ from typing import Final
4
+
5
+ from ..vrm1.human_bone import HumanBoneSpecification, HumanBoneSpecifications
6
+
7
+ MAPPING_TEMPLATE: Final[Mapping[str, HumanBoneSpecification]] = {
8
+ "Head": HumanBoneSpecifications.HEAD,
9
+ "REye": HumanBoneSpecifications.RIGHT_EYE,
10
+ "LEye": HumanBoneSpecifications.LEFT_EYE,
11
+ "MJaw": HumanBoneSpecifications.JAW,
12
+ "Spine2": HumanBoneSpecifications.CHEST,
13
+ "Spine1": HumanBoneSpecifications.SPINE,
14
+ "Pelvis": HumanBoneSpecifications.HIPS,
15
+ "R Clavicle": HumanBoneSpecifications.RIGHT_SHOULDER,
16
+ "R UpperArm": HumanBoneSpecifications.RIGHT_UPPER_ARM,
17
+ "R Forearm": HumanBoneSpecifications.RIGHT_LOWER_ARM,
18
+ "R Hand": HumanBoneSpecifications.RIGHT_HAND,
19
+ "L Clavicle": HumanBoneSpecifications.LEFT_SHOULDER,
20
+ "L UpperArm": HumanBoneSpecifications.LEFT_UPPER_ARM,
21
+ "L Forearm": HumanBoneSpecifications.LEFT_LOWER_ARM,
22
+ "L Hand": HumanBoneSpecifications.LEFT_HAND,
23
+ "R Thigh": HumanBoneSpecifications.RIGHT_UPPER_LEG,
24
+ "R Calf": HumanBoneSpecifications.RIGHT_LOWER_LEG,
25
+ "R Foot": HumanBoneSpecifications.RIGHT_FOOT,
26
+ "R Toe0": HumanBoneSpecifications.RIGHT_TOES,
27
+ "L Thigh": HumanBoneSpecifications.LEFT_UPPER_LEG,
28
+ "L Calf": HumanBoneSpecifications.LEFT_LOWER_LEG,
29
+ "L Foot": HumanBoneSpecifications.LEFT_FOOT,
30
+ "L Toe0": HumanBoneSpecifications.LEFT_TOES,
31
+ "R Finger0": HumanBoneSpecifications.RIGHT_THUMB_METACARPAL,
32
+ "R Finger01": HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL,
33
+ "R Finger02": HumanBoneSpecifications.RIGHT_THUMB_DISTAL,
34
+ "R Finger1": HumanBoneSpecifications.RIGHT_INDEX_PROXIMAL,
35
+ "R Finger11": HumanBoneSpecifications.RIGHT_INDEX_INTERMEDIATE,
36
+ "R Finger12": HumanBoneSpecifications.RIGHT_INDEX_DISTAL,
37
+ "R Finger2": HumanBoneSpecifications.RIGHT_MIDDLE_PROXIMAL,
38
+ "R Finger21": HumanBoneSpecifications.RIGHT_MIDDLE_INTERMEDIATE,
39
+ "R Finger22": HumanBoneSpecifications.RIGHT_MIDDLE_DISTAL,
40
+ "R Finger3": HumanBoneSpecifications.RIGHT_RING_PROXIMAL,
41
+ "R Finger31": HumanBoneSpecifications.RIGHT_RING_INTERMEDIATE,
42
+ "R Finger32": HumanBoneSpecifications.RIGHT_RING_DISTAL,
43
+ "R Finger4": HumanBoneSpecifications.RIGHT_LITTLE_PROXIMAL,
44
+ "R Finger41": HumanBoneSpecifications.RIGHT_LITTLE_INTERMEDIATE,
45
+ "R Finger42": HumanBoneSpecifications.RIGHT_LITTLE_DISTAL,
46
+ "L Finger0": HumanBoneSpecifications.LEFT_THUMB_METACARPAL,
47
+ "L Finger01": HumanBoneSpecifications.LEFT_THUMB_PROXIMAL,
48
+ "L Finger02": HumanBoneSpecifications.LEFT_THUMB_DISTAL,
49
+ "L Finger1": HumanBoneSpecifications.LEFT_INDEX_PROXIMAL,
50
+ "L Finger11": HumanBoneSpecifications.LEFT_INDEX_INTERMEDIATE,
51
+ "L Finger12": HumanBoneSpecifications.LEFT_INDEX_DISTAL,
52
+ "L Finger2": HumanBoneSpecifications.LEFT_MIDDLE_PROXIMAL,
53
+ "L Finger21": HumanBoneSpecifications.LEFT_MIDDLE_INTERMEDIATE,
54
+ "L Finger22": HumanBoneSpecifications.LEFT_MIDDLE_DISTAL,
55
+ "L Finger3": HumanBoneSpecifications.LEFT_RING_PROXIMAL,
56
+ "L Finger31": HumanBoneSpecifications.LEFT_RING_INTERMEDIATE,
57
+ "L Finger32": HumanBoneSpecifications.LEFT_RING_DISTAL,
58
+ "L Finger4": HumanBoneSpecifications.LEFT_LITTLE_PROXIMAL,
59
+ "L Finger41": HumanBoneSpecifications.LEFT_LITTLE_INTERMEDIATE,
60
+ "L Finger42": HumanBoneSpecifications.LEFT_LITTLE_DISTAL,
61
+ }
62
+
63
+
64
+ def _prefixed_mapping(key_prefix: str) -> dict[str, HumanBoneSpecification]:
65
+ return {key_prefix + k: v for k, v in MAPPING_TEMPLATE.items()}
66
+
67
+
68
+ CONFIG_BIP01: Final = ("Microsoft Rocketbox (Bip01)", _prefixed_mapping("Bip01 "))
69
+ CONFIG_BIP02: Final = ("Microsoft Rocketbox (Bip02)", _prefixed_mapping("Bip02 "))
@@ -0,0 +1,62 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from collections.abc import Mapping
3
+ from typing import Final
4
+
5
+ from ..vrm1.human_bone import HumanBoneSpecification, HumanBoneSpecifications
6
+
7
+ MAPPING: Final[Mapping[str, HumanBoneSpecification]] = {
8
+ "mixamorig:Head": HumanBoneSpecifications.HEAD,
9
+ "mixamorig:Neck": HumanBoneSpecifications.NECK,
10
+ "mixamorig:Spine2": HumanBoneSpecifications.UPPER_CHEST,
11
+ "mixamorig:Spine1": HumanBoneSpecifications.CHEST,
12
+ "mixamorig:Spine": HumanBoneSpecifications.SPINE,
13
+ "mixamorig:Hips": HumanBoneSpecifications.HIPS,
14
+ "mixamorig:RightShoulder": HumanBoneSpecifications.RIGHT_SHOULDER,
15
+ "mixamorig:RightArm": HumanBoneSpecifications.RIGHT_UPPER_ARM,
16
+ "mixamorig:RightForeArm": HumanBoneSpecifications.RIGHT_LOWER_ARM,
17
+ "mixamorig:RightHand": HumanBoneSpecifications.RIGHT_HAND,
18
+ "mixamorig:LeftShoulder": HumanBoneSpecifications.LEFT_SHOULDER,
19
+ "mixamorig:LeftArm": HumanBoneSpecifications.LEFT_UPPER_ARM,
20
+ "mixamorig:LeftForeArm": HumanBoneSpecifications.LEFT_LOWER_ARM,
21
+ "mixamorig:LeftHand": HumanBoneSpecifications.LEFT_HAND,
22
+ "mixamorig:RightUpLeg": HumanBoneSpecifications.RIGHT_UPPER_LEG,
23
+ "mixamorig:RightLeg": HumanBoneSpecifications.RIGHT_LOWER_LEG,
24
+ "mixamorig:RightFoot": HumanBoneSpecifications.RIGHT_FOOT,
25
+ "mixamorig:RightToeBase": HumanBoneSpecifications.RIGHT_TOES,
26
+ "mixamorig:LeftUpLeg": HumanBoneSpecifications.LEFT_UPPER_LEG,
27
+ "mixamorig:LeftLeg": HumanBoneSpecifications.LEFT_LOWER_LEG,
28
+ "mixamorig:LeftFoot": HumanBoneSpecifications.LEFT_FOOT,
29
+ "mixamorig:LeftToeBase": HumanBoneSpecifications.LEFT_TOES,
30
+ "mixamorig:RightHandThumb1": HumanBoneSpecifications.RIGHT_THUMB_METACARPAL,
31
+ "mixamorig:RightHandThumb2": HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL,
32
+ "mixamorig:RightHandThumb3": HumanBoneSpecifications.RIGHT_THUMB_DISTAL,
33
+ "mixamorig:RightHandIndex1": HumanBoneSpecifications.RIGHT_INDEX_PROXIMAL,
34
+ "mixamorig:RightHandIndex2": HumanBoneSpecifications.RIGHT_INDEX_INTERMEDIATE,
35
+ "mixamorig:RightHandIndex3": HumanBoneSpecifications.RIGHT_INDEX_DISTAL,
36
+ "mixamorig:RightHandMiddle1": HumanBoneSpecifications.RIGHT_MIDDLE_PROXIMAL,
37
+ "mixamorig:RightHandMiddle2": HumanBoneSpecifications.RIGHT_MIDDLE_INTERMEDIATE,
38
+ "mixamorig:RightHandMiddle3": HumanBoneSpecifications.RIGHT_MIDDLE_DISTAL,
39
+ "mixamorig:RightHandRing1": HumanBoneSpecifications.RIGHT_RING_PROXIMAL,
40
+ "mixamorig:RightHandRing2": HumanBoneSpecifications.RIGHT_RING_INTERMEDIATE,
41
+ "mixamorig:RightHandRing3": HumanBoneSpecifications.RIGHT_RING_DISTAL,
42
+ "mixamorig:RightHandPinky1": HumanBoneSpecifications.RIGHT_LITTLE_PROXIMAL,
43
+ "mixamorig:RightHandPinky2": HumanBoneSpecifications.RIGHT_LITTLE_INTERMEDIATE,
44
+ "mixamorig:RightHandPinky3": HumanBoneSpecifications.RIGHT_LITTLE_DISTAL,
45
+ "mixamorig:LeftHandThumb1": HumanBoneSpecifications.LEFT_THUMB_METACARPAL,
46
+ "mixamorig:LeftHandThumb2": HumanBoneSpecifications.LEFT_THUMB_PROXIMAL,
47
+ "mixamorig:LeftHandThumb3": HumanBoneSpecifications.LEFT_THUMB_DISTAL,
48
+ "mixamorig:LeftHandIndex1": HumanBoneSpecifications.LEFT_INDEX_PROXIMAL,
49
+ "mixamorig:LeftHandIndex2": HumanBoneSpecifications.LEFT_INDEX_INTERMEDIATE,
50
+ "mixamorig:LeftHandIndex3": HumanBoneSpecifications.LEFT_INDEX_DISTAL,
51
+ "mixamorig:LeftHandMiddle1": HumanBoneSpecifications.LEFT_MIDDLE_PROXIMAL,
52
+ "mixamorig:LeftHandMiddle2": HumanBoneSpecifications.LEFT_MIDDLE_INTERMEDIATE,
53
+ "mixamorig:LeftHandMiddle3": HumanBoneSpecifications.LEFT_MIDDLE_DISTAL,
54
+ "mixamorig:LeftHandRing1": HumanBoneSpecifications.LEFT_RING_PROXIMAL,
55
+ "mixamorig:LeftHandRing2": HumanBoneSpecifications.LEFT_RING_INTERMEDIATE,
56
+ "mixamorig:LeftHandRing3": HumanBoneSpecifications.LEFT_RING_DISTAL,
57
+ "mixamorig:LeftHandPinky1": HumanBoneSpecifications.LEFT_LITTLE_PROXIMAL,
58
+ "mixamorig:LeftHandPinky2": HumanBoneSpecifications.LEFT_LITTLE_INTERMEDIATE,
59
+ "mixamorig:LeftHandPinky3": HumanBoneSpecifications.LEFT_LITTLE_DISTAL,
60
+ }
61
+
62
+ CONFIG: Final = ("Mixamo", MAPPING)
@@ -0,0 +1,115 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from collections.abc import Mapping, Sequence
3
+ from typing import Final
4
+
5
+ from bpy.types import Object
6
+
7
+ from ..logger import get_logger
8
+ from ..vrm1.human_bone import HumanBoneSpecification, HumanBoneSpecifications
9
+
10
+ _logger = get_logger(__name__)
11
+
12
+ # Mapping table for MMD (MikuMikuDance) bone names to VRM human bone specifications.
13
+ # These Japanese bone names are standard MMD naming conventions and should be preserved.
14
+ MMD_BONE_NAME_AND_HUMAN_BONE_SPECIFICATION_PAIRS: Final[
15
+ Sequence[tuple[str, HumanBoneSpecification]]
16
+ ] = [
17
+ ("頭", HumanBoneSpecifications.HEAD),
18
+ ("右目", HumanBoneSpecifications.RIGHT_EYE),
19
+ ("左目", HumanBoneSpecifications.LEFT_EYE),
20
+ ("首", HumanBoneSpecifications.NECK),
21
+ ("上半身2", HumanBoneSpecifications.CHEST),
22
+ ("上半身", HumanBoneSpecifications.SPINE),
23
+ ("センター", HumanBoneSpecifications.HIPS),
24
+ ("右肩", HumanBoneSpecifications.RIGHT_SHOULDER),
25
+ ("右腕", HumanBoneSpecifications.RIGHT_UPPER_ARM),
26
+ ("右ひじ", HumanBoneSpecifications.RIGHT_LOWER_ARM),
27
+ ("右手", HumanBoneSpecifications.RIGHT_HAND),
28
+ ("右手首", HumanBoneSpecifications.RIGHT_HAND),
29
+ ("右足", HumanBoneSpecifications.RIGHT_UPPER_LEG),
30
+ ("右ひざ", HumanBoneSpecifications.RIGHT_LOWER_LEG),
31
+ ("右足首", HumanBoneSpecifications.RIGHT_FOOT),
32
+ ("右つま先", HumanBoneSpecifications.RIGHT_TOES),
33
+ ("右足先EX", HumanBoneSpecifications.RIGHT_TOES),
34
+ ("左肩", HumanBoneSpecifications.LEFT_SHOULDER),
35
+ ("左腕", HumanBoneSpecifications.LEFT_UPPER_ARM),
36
+ ("左ひじ", HumanBoneSpecifications.LEFT_LOWER_ARM),
37
+ ("左手", HumanBoneSpecifications.LEFT_HAND),
38
+ ("左手首", HumanBoneSpecifications.LEFT_HAND),
39
+ ("左足", HumanBoneSpecifications.LEFT_UPPER_LEG),
40
+ ("左ひざ", HumanBoneSpecifications.LEFT_LOWER_LEG),
41
+ ("左足首", HumanBoneSpecifications.LEFT_FOOT),
42
+ ("左つま先", HumanBoneSpecifications.LEFT_TOES),
43
+ ("左足先EX", HumanBoneSpecifications.LEFT_TOES),
44
+ ("右親指0", HumanBoneSpecifications.RIGHT_THUMB_METACARPAL),
45
+ ("右親指1", HumanBoneSpecifications.RIGHT_THUMB_METACARPAL),
46
+ ("右親指1", HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL),
47
+ ("右親指2", HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL),
48
+ ("右親指2", HumanBoneSpecifications.RIGHT_THUMB_DISTAL),
49
+ ("右人指1", HumanBoneSpecifications.RIGHT_INDEX_PROXIMAL),
50
+ ("右人指2", HumanBoneSpecifications.RIGHT_INDEX_INTERMEDIATE),
51
+ ("右人指3", HumanBoneSpecifications.RIGHT_INDEX_DISTAL),
52
+ ("右中指1", HumanBoneSpecifications.RIGHT_MIDDLE_PROXIMAL),
53
+ ("右中指2", HumanBoneSpecifications.RIGHT_MIDDLE_INTERMEDIATE),
54
+ ("右中指3", HumanBoneSpecifications.RIGHT_MIDDLE_DISTAL),
55
+ ("右薬指1", HumanBoneSpecifications.RIGHT_RING_PROXIMAL),
56
+ ("右薬指2", HumanBoneSpecifications.RIGHT_RING_INTERMEDIATE),
57
+ ("右薬指3", HumanBoneSpecifications.RIGHT_RING_DISTAL),
58
+ ("右小指1", HumanBoneSpecifications.RIGHT_LITTLE_PROXIMAL),
59
+ ("右小指2", HumanBoneSpecifications.RIGHT_LITTLE_INTERMEDIATE),
60
+ ("右小指3", HumanBoneSpecifications.RIGHT_LITTLE_DISTAL),
61
+ ("左親指0", HumanBoneSpecifications.LEFT_THUMB_METACARPAL),
62
+ ("左親指1", HumanBoneSpecifications.LEFT_THUMB_METACARPAL),
63
+ ("左親指1", HumanBoneSpecifications.LEFT_THUMB_PROXIMAL),
64
+ ("左親指2", HumanBoneSpecifications.LEFT_THUMB_PROXIMAL),
65
+ ("左親指2", HumanBoneSpecifications.LEFT_THUMB_DISTAL),
66
+ ("左人指1", HumanBoneSpecifications.LEFT_INDEX_PROXIMAL),
67
+ ("左人指2", HumanBoneSpecifications.LEFT_INDEX_INTERMEDIATE),
68
+ ("左人指3", HumanBoneSpecifications.LEFT_INDEX_DISTAL),
69
+ ("左中指1", HumanBoneSpecifications.LEFT_MIDDLE_PROXIMAL),
70
+ ("左中指2", HumanBoneSpecifications.LEFT_MIDDLE_INTERMEDIATE),
71
+ ("左中指3", HumanBoneSpecifications.LEFT_MIDDLE_DISTAL),
72
+ ("左薬指1", HumanBoneSpecifications.LEFT_RING_PROXIMAL),
73
+ ("左薬指2", HumanBoneSpecifications.LEFT_RING_INTERMEDIATE),
74
+ ("左薬指3", HumanBoneSpecifications.LEFT_RING_DISTAL),
75
+ ("左小指1", HumanBoneSpecifications.LEFT_LITTLE_PROXIMAL),
76
+ ("左小指2", HumanBoneSpecifications.LEFT_LITTLE_INTERMEDIATE),
77
+ ("左小指3", HumanBoneSpecifications.LEFT_LITTLE_DISTAL),
78
+ ]
79
+
80
+
81
+ def create_config(
82
+ armature: Object,
83
+ ) -> tuple[str, Mapping[str, HumanBoneSpecification]]:
84
+ mmd_bone_name_to_bpy_bone_name: dict[str, str] = {}
85
+ for bone in armature.pose.bones:
86
+ # https://github.com/UuuNyaa/blender_mmd_tools/blob/97861e3c32ba423833b6c5fc3432127b1ec1182a/mmd_tools/properties/__init__.py#L45-L46
87
+ mmd_bone = getattr(bone, "mmd_bone", None)
88
+ if not mmd_bone:
89
+ continue
90
+
91
+ # https://github.com/UuuNyaa/blender_mmd_tools/blob/97861e3c32ba423833b6c5fc3432127b1ec1182a/mmd_tools/properties/bone.py#L43-L48
92
+ name_j = getattr(mmd_bone, "name_j", None)
93
+ if not isinstance(name_j, str):
94
+ continue
95
+
96
+ mmd_bone_name_to_bpy_bone_name[name_j] = bone.name
97
+
98
+ mapping: dict[str, HumanBoneSpecification] = {}
99
+ for (
100
+ mmd_bone_name,
101
+ human_bone_specification,
102
+ ) in MMD_BONE_NAME_AND_HUMAN_BONE_SPECIFICATION_PAIRS:
103
+ bpy_bone_name = mmd_bone_name_to_bpy_bone_name.get(mmd_bone_name)
104
+ if not bpy_bone_name:
105
+ continue
106
+ if bpy_bone_name in mapping or human_bone_specification in mapping.values():
107
+ continue
108
+ mapping[bpy_bone_name] = human_bone_specification
109
+
110
+ name = "MikuMikuDance"
111
+ for specification in HumanBoneSpecifications.all_human_bones:
112
+ if specification.requirement and specification not in mapping.values():
113
+ return (name, {})
114
+
115
+ return (name, mapping)