@volter/blender-engine 0.1.148 → 0.1.150

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 +22 -5
  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 +66 -129
  185. package/browser/blender-engine.mts +20 -186
  186. package/browser/blender-wali-engine.mts +37 -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 +3 -0
  192. package/browser/protocol.ts +130 -43
  193. package/browser/pull-job.mts +2 -10
  194. package/browser/rna.ts +190 -73
  195. package/browser/runtime.ts +271 -106
  196. package/browser/session-addons.mts +33 -0
  197. package/browser/session-frame.mts +5 -24
  198. package/browser/session.py +1389 -1446
  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 +492 -306
  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 +195 -180
  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,25 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from typing import TYPE_CHECKING
3
+
4
+ from bpy.props import BoolProperty
5
+ from bpy.types import PropertyGroup
6
+
7
+
8
+ # https://github.com/vrm-c/vrm-specification/blob/6fb6baaf9b9095a84fb82c8384db36e1afeb3558/specification/VRMC_springBone-1.0-beta/schema/VRMC_springBone.schema.json
9
+ class NodeConstraint1NodeConstraintPropertyGroup(PropertyGroup):
10
+ # for UI
11
+ show_expanded_roll_constraints: BoolProperty( # type: ignore[valid-type]
12
+ name="Roll Constraint"
13
+ )
14
+ show_expanded_aim_constraints: BoolProperty( # type: ignore[valid-type]
15
+ name="Aim Constraint"
16
+ )
17
+ show_expanded_rotation_constraints: BoolProperty( # type: ignore[valid-type]
18
+ name="Rotation Constraint"
19
+ )
20
+ if TYPE_CHECKING:
21
+ # This code is auto generated.
22
+ # To regenerate, run the `uv run tools/property_typing.py` command.
23
+ show_expanded_roll_constraints: bool # type: ignore[no-redef]
24
+ show_expanded_aim_constraints: bool # type: ignore[no-redef]
25
+ show_expanded_rotation_constraints: bool # type: ignore[no-redef]
@@ -0,0 +1,471 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ # SPDX-FileCopyrightText: 2018 iCyP
3
+ # SPDX-FileCopyrightText: 2024 saturday06
4
+ import json
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING, ClassVar, Optional, TypeVar, cast
7
+ from urllib.parse import urlsplit
8
+
9
+ import bpy
10
+ from bpy.app.translations import pgettext
11
+ from bpy.props import StringProperty
12
+ from bpy.types import (
13
+ Armature,
14
+ Context,
15
+ Event,
16
+ Operator,
17
+ UILayout,
18
+ )
19
+ from bpy_extras.io_utils import ExportHelper, ImportHelper
20
+
21
+ from ..common.deep import make_json
22
+ from ..common.human_bone_mapper.vroid_mapping import (
23
+ FULL_PATTERN,
24
+ symmetrise_vroid_bone_name,
25
+ )
26
+ from ..common.logger import get_logger
27
+ from ..common.vrm0.human_bone import HumanBoneSpecifications
28
+ from ..common.workspace import save_workspace
29
+ from . import search
30
+ from .extension_accessor import get_armature_extension
31
+ from .property_group import BonePropertyGroup
32
+ from .t_pose import PoseBonePose, set_estimated_humanoid_t_pose, setup_humanoid_t_pose
33
+
34
+ _logger = get_logger(__name__)
35
+
36
+
37
+ class VRM_OT_simplify_vroid_bones(Operator):
38
+ bl_idname = "vrm.bones_rename"
39
+ bl_label = "Symmetrize VRoid Bone Names on X-Axis"
40
+ bl_description = "Make VRoid bone names editable for X-axis mirroring."
41
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
42
+
43
+ armature_object_name: StringProperty( # type: ignore[valid-type]
44
+ options={"HIDDEN"},
45
+ )
46
+
47
+ @staticmethod
48
+ def vroid_bones_exist(armature: Armature) -> bool:
49
+ return any(map(FULL_PATTERN.search, armature.bones.keys()))
50
+
51
+ def execute(self, context: Context) -> set[str]:
52
+ armature = context.blend_data.objects.get(self.armature_object_name)
53
+ if armature is None or armature.type != "ARMATURE":
54
+ return {"CANCELLED"}
55
+ armature_data = armature.data
56
+ if not isinstance(armature_data, Armature):
57
+ return {"CANCELLED"}
58
+
59
+ with save_workspace(context):
60
+ for bone_name, bone in armature_data.bones.items():
61
+ bone.name = symmetrise_vroid_bone_name(bone_name)
62
+
63
+ return {"FINISHED"}
64
+
65
+ if TYPE_CHECKING:
66
+ # This code is auto generated.
67
+ # To regenerate, run the `uv run tools/property_typing.py` command.
68
+ armature_object_name: str # type: ignore[no-redef]
69
+
70
+
71
+ class VRM_OT_save_human_bone_mappings(Operator, ExportHelper):
72
+ bl_idname = "vrm.save_human_bone_mappings"
73
+ bl_label = "Save Bone Mappings"
74
+ bl_description = "Save bone mappings."
75
+ bl_options: ClassVar = {"REGISTER"}
76
+
77
+ filename_ext = ".json"
78
+ filter_glob: StringProperty( # type: ignore[valid-type]
79
+ default="*.json",
80
+ options={"HIDDEN"},
81
+ )
82
+
83
+ @classmethod
84
+ def poll(cls, context: Context) -> bool:
85
+ return search.armature_exists(context)
86
+
87
+ def execute(self, context: Context) -> set[str]:
88
+ armature = search.current_armature(context)
89
+ if not armature:
90
+ return {"CANCELLED"}
91
+ armature_data = armature.data
92
+ if not isinstance(armature_data, Armature):
93
+ return {"CANCELLED"}
94
+
95
+ mappings = {}
96
+ for human_bone in get_armature_extension(
97
+ armature_data
98
+ ).vrm0.humanoid.human_bones:
99
+ if human_bone.bone not in HumanBoneSpecifications.all_names:
100
+ continue
101
+ if not human_bone.node.bone_name:
102
+ continue
103
+ mappings[human_bone.bone] = human_bone.node.bone_name
104
+
105
+ Path(self.filepath).write_bytes(
106
+ json.dumps(mappings, sort_keys=True, indent=4)
107
+ .replace("\r\n", "\n")
108
+ .encode()
109
+ )
110
+ return {"FINISHED"}
111
+
112
+ def invoke(self, context: Context, event: Event) -> set[str]:
113
+ return ExportHelper.invoke(self, context, event)
114
+
115
+ if TYPE_CHECKING:
116
+ # This code is auto generated.
117
+ # To regenerate, run the `uv run tools/property_typing.py` command.
118
+ filter_glob: str # type: ignore[no-redef]
119
+
120
+
121
+ class VRM_OT_load_human_bone_mappings(Operator, ImportHelper):
122
+ bl_idname = "vrm.load_human_bone_mappings"
123
+ bl_label = "Load Bone Mappings"
124
+ bl_description = "Load bone mappings."
125
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
126
+
127
+ filename_ext = ".json"
128
+ filter_glob: StringProperty( # type: ignore[valid-type]
129
+ default="*.json",
130
+ options={"HIDDEN"},
131
+ )
132
+
133
+ @classmethod
134
+ def poll(cls, context: Context) -> bool:
135
+ return search.armature_exists(context)
136
+
137
+ def execute(self, context: Context) -> set[str]:
138
+ armature = search.current_armature(context)
139
+ if not armature:
140
+ return {"CANCELLED"}
141
+ armature_data = armature.data
142
+ if not isinstance(armature_data, Armature):
143
+ return {"CANCELLED"}
144
+
145
+ obj = make_json(json.loads(Path(self.filepath).read_text(encoding="UTF-8")))
146
+ if not isinstance(obj, dict):
147
+ return {"CANCELLED"}
148
+
149
+ for human_bone_name, bpy_bone_name in obj.items():
150
+ if human_bone_name not in HumanBoneSpecifications.all_names:
151
+ continue
152
+ if not isinstance(bpy_bone_name, str):
153
+ continue
154
+ for human_bone in get_armature_extension(
155
+ armature_data
156
+ ).vrm0.humanoid.human_bones:
157
+ if human_bone.bone == human_bone_name:
158
+ human_bone.node.bone_name = bpy_bone_name
159
+ break
160
+ else:
161
+ human_bone = get_armature_extension(
162
+ armature_data
163
+ ).vrm0.humanoid.human_bones.add()
164
+ human_bone.bone = human_bone_name
165
+ human_bone.node.bone_name = bpy_bone_name
166
+
167
+ return {"FINISHED"}
168
+
169
+ def invoke(self, context: Context, event: Event) -> set[str]:
170
+ return ImportHelper.invoke(self, context, event)
171
+
172
+ if TYPE_CHECKING:
173
+ # This code is auto generated.
174
+ # To regenerate, run the `uv run tools/property_typing.py` command.
175
+ filter_glob: str # type: ignore[no-redef]
176
+
177
+
178
+ class VRM_OT_open_url_in_web_browser(Operator):
179
+ bl_idname = "vrm.open_url_in_web_browser"
180
+ bl_label = "Open"
181
+ bl_description = "Open the URL in the default web browser."
182
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
183
+
184
+ url: StringProperty( # type: ignore[valid-type]
185
+ options={"HIDDEN"}
186
+ )
187
+
188
+ @staticmethod
189
+ def supported(url_str: str) -> bool:
190
+ if not url_str:
191
+ return False
192
+ if url_str != url_str.strip():
193
+ return False
194
+ try:
195
+ url = urlsplit(url_str)
196
+ except ValueError:
197
+ return False
198
+ if url.scheme not in {"http", "https"}:
199
+ return False
200
+ return bool(url.hostname)
201
+
202
+ def execute(self, _context: Context) -> set[str]:
203
+ url = self.url
204
+ if not self.supported(url):
205
+ return {"CANCELLED"}
206
+ return bpy.ops.wm.url_open(url=url)
207
+
208
+ if TYPE_CHECKING:
209
+ # This code is auto generated.
210
+ # To regenerate, run the `uv run tools/property_typing.py` command.
211
+ url: str # type: ignore[no-redef]
212
+
213
+
214
+ class VRM_OT_show_blend_file_compatibility_warning(Operator):
215
+ bl_idname = "vrm.show_blend_file_compatibility_warning"
216
+ bl_label = "File Compatibility Warning"
217
+ bl_description = "Show blend file compatibility warning."
218
+ bl_options: ClassVar = {"REGISTER"}
219
+
220
+ file_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]
221
+ app_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]
222
+
223
+ def execute(self, _context: Context) -> set[str]:
224
+ return {"FINISHED"}
225
+
226
+ def invoke(self, context: Context, _event: Event) -> set[str]:
227
+ return context.window_manager.invoke_props_dialog(self, width=500)
228
+
229
+ def draw(self, _context: Context) -> None:
230
+ column = self.layout.row(align=True).column()
231
+ text = pgettext(
232
+ "The current file is not compatible with the running Blender.\n"
233
+ + "The current file was created in Blender {file_version}, but the running"
234
+ + " Blender version is {app_version}.\n"
235
+ + "This incompatibility may result in data loss or corruption."
236
+ ).format(
237
+ app_version=self.app_version,
238
+ file_version=self.file_version,
239
+ )
240
+ description_outer_column = column.column()
241
+ description_outer_column.emboss = "NONE"
242
+ description_column = description_outer_column.box().column(align=True)
243
+ for i, line in enumerate(text.splitlines()):
244
+ icon = "ERROR" if i == 0 else "NONE"
245
+ description_column.label(text=line, translate=False, icon=icon)
246
+ open_url = layout_operator(
247
+ self.layout,
248
+ VRM_OT_open_url_in_web_browser,
249
+ text="Open Documentation",
250
+ icon="URL",
251
+ )
252
+ open_url.url = "https://developer.blender.org/docs/handbook/guidelines/compatibility_handling_for_blend_files/#forward-compatibility"
253
+
254
+ if TYPE_CHECKING:
255
+ # This code is auto generated.
256
+ # To regenerate, run the `uv run tools/property_typing.py` command.
257
+ file_version: str # type: ignore[no-redef]
258
+ app_version: str # type: ignore[no-redef]
259
+
260
+
261
+ class VRM_OT_show_blend_file_addon_compatibility_warning(Operator):
262
+ bl_idname = "vrm.show_blend_file_addon_compatibility_warning"
263
+ bl_label = "VRM Add-on Compatibility Warning"
264
+ bl_description = "Show blend file and VRM add-on compatibility warning."
265
+ bl_options: ClassVar = {"REGISTER"}
266
+
267
+ file_addon_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]
268
+ installed_addon_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]
269
+
270
+ def execute(self, _context: Context) -> set[str]:
271
+ return {"FINISHED"}
272
+
273
+ def invoke(self, context: Context, _event: Event) -> set[str]:
274
+ return context.window_manager.invoke_props_dialog(self, width=500)
275
+
276
+ def draw(self, _context: Context) -> None:
277
+ column = self.layout.row(align=True).column()
278
+ text = pgettext(
279
+ "The current file is not compatible with the installed VRM Add-on.\n"
280
+ + "The current file was created in VRM Add-on {file_addon_version}, but the"
281
+ + " installed\n"
282
+ + "VRM Add-on version is {installed_addon_version}. This incompatibility\n"
283
+ + "may result in data loss or corruption."
284
+ ).format(
285
+ file_addon_version=self.file_addon_version,
286
+ installed_addon_version=self.installed_addon_version,
287
+ )
288
+ description_outer_column = column.column()
289
+ description_outer_column.emboss = "NONE"
290
+ description_column = description_outer_column.box().column(align=True)
291
+ for i, line in enumerate(text.splitlines()):
292
+ icon = "ERROR" if i == 0 else "NONE"
293
+ description_column.label(text=line, translate=False, icon=icon)
294
+
295
+ if TYPE_CHECKING:
296
+ # This code is auto generated.
297
+ # To regenerate, run the `uv run tools/property_typing.py` command.
298
+ file_addon_version: str # type: ignore[no-redef]
299
+ installed_addon_version: str # type: ignore[no-redef]
300
+
301
+
302
+ __Operator = TypeVar("__Operator", bound=Operator)
303
+
304
+
305
+ def layout_operator(
306
+ layout: UILayout,
307
+ operator_type: type[__Operator],
308
+ *,
309
+ text: Optional[str] = None,
310
+ text_ctxt: str = "",
311
+ translate: bool = True,
312
+ icon: str = "NONE",
313
+ emboss: bool = True,
314
+ depress: bool = False,
315
+ icon_value: int = 0,
316
+ ) -> __Operator:
317
+ if text is None:
318
+ text = operator_type.bl_label
319
+ operator = layout.operator(
320
+ operator_type.bl_idname,
321
+ text=text,
322
+ text_ctxt=text_ctxt,
323
+ translate=translate,
324
+ icon=icon,
325
+ emboss=emboss,
326
+ depress=depress,
327
+ icon_value=icon_value,
328
+ )
329
+
330
+ split = operator_type.bl_idname.split(".")
331
+ if len(split) != 2:
332
+ message = f"Unexpected bl_idname: {operator_type.bl_idname}"
333
+ raise AssertionError(message)
334
+ name = f"{split[0].encode().upper().decode()}_OT_{split[1]}"
335
+ if type(operator).__qualname__ != name:
336
+ raise AssertionError(
337
+ f"{type(operator)} is not compatible with {operator_type}."
338
+ + f"the expected name is {name}"
339
+ )
340
+ return cast("__Operator", operator)
341
+
342
+
343
+ class VRM_OT_apply_humanoid_t_pose(Operator):
344
+ bl_idname = "vrm.apply_humanoid_t_pose"
345
+ bl_label = "Apply"
346
+ bl_description = "Apply the selected VRM T-Pose"
347
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
348
+
349
+ armature_object_name: StringProperty( # type: ignore[valid-type]
350
+ options={"HIDDEN"},
351
+ )
352
+
353
+ def execute(self, context: Context) -> set[str]:
354
+ armature = context.blend_data.objects.get(self.armature_object_name)
355
+ if armature is None:
356
+ return {"CANCELLED"}
357
+ armature_data = armature.data
358
+ if not isinstance(armature_data, Armature):
359
+ return {"CANCELLED"}
360
+
361
+ with setup_humanoid_t_pose(context, armature):
362
+ pose = PoseBonePose.save(armature.pose)
363
+ pose_position = armature_data.pose_position
364
+
365
+ with save_workspace(context, armature, mode="POSE"):
366
+ PoseBonePose.load(context, armature.pose, pose)
367
+ armature_data.pose_position = pose_position
368
+
369
+ context.view_layer.update()
370
+ return {"FINISHED"}
371
+
372
+ if TYPE_CHECKING:
373
+ # This code is auto generated.
374
+ # To regenerate, run the `uv run tools/property_typing.py` command.
375
+ armature_object_name: str # type: ignore[no-redef]
376
+
377
+
378
+ class VRM_OT_make_estimated_humanoid_t_pose(Operator):
379
+ bl_idname = "vrm.make_estimated_humanoid_t_pose"
380
+ bl_label = "Make Estimated T-Pose"
381
+ bl_description = "Create VRM estimated humanoid T-pose."
382
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
383
+
384
+ armature_object_name: StringProperty( # type: ignore[valid-type]
385
+ options={"HIDDEN"},
386
+ )
387
+
388
+ def execute(self, context: Context) -> set[str]:
389
+ armature = context.blend_data.objects.get(self.armature_object_name)
390
+ if armature is None or armature.type != "ARMATURE":
391
+ return {"CANCELLED"}
392
+ if not set_estimated_humanoid_t_pose(context, armature):
393
+ return {"CANCELLED"}
394
+ return {"FINISHED"}
395
+
396
+ if TYPE_CHECKING:
397
+ # This code is auto generated.
398
+ # To regenerate, run the `uv run tools/property_typing.py` command.
399
+ armature_object_name: str # type: ignore[no-redef]
400
+
401
+
402
+ class VRM_OT_assign_bone_to_bone_property_group(Operator):
403
+ bl_idname = "vrm.assign_bone_to_bone_property_group"
404
+ bl_label = "Assign Bone to Bone Property Group"
405
+ bl_description = "Assign selected bone to the bone property group."
406
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
407
+
408
+ armature_data_name: StringProperty( # type: ignore[valid-type]
409
+ options={"HIDDEN"},
410
+ )
411
+ bone_property_group_path: StringProperty( # type: ignore[valid-type]
412
+ options={"HIDDEN"},
413
+ )
414
+ bone_name: StringProperty( # type: ignore[valid-type]
415
+ options={"HIDDEN"},
416
+ )
417
+
418
+ def execute(self, context: Context) -> set[str]:
419
+ armature_data = context.blend_data.armatures.get(self.armature_data_name)
420
+ if not isinstance(armature_data, Armature):
421
+ return {"CANCELLED"}
422
+
423
+ bone_property_group = armature_data.path_resolve(
424
+ self.bone_property_group_path, False
425
+ )
426
+ if not isinstance(bone_property_group, BonePropertyGroup):
427
+ return {"CANCELLED"}
428
+
429
+ bone_property_group.bone_name = self.bone_name
430
+ return {"FINISHED"}
431
+
432
+ if TYPE_CHECKING:
433
+ # This code is auto generated.
434
+ # To regenerate, run the `uv run tools/property_typing.py` command.
435
+ armature_data_name: str # type: ignore[no-redef]
436
+ bone_property_group_path: str # type: ignore[no-redef]
437
+ bone_name: str # type: ignore[no-redef]
438
+
439
+
440
+ class VRM_OT_unassign_bone_to_bone_property_group(Operator):
441
+ bl_idname = "vrm.unassign_bone_to_bone_property_group"
442
+ bl_label = "Unassign Bone"
443
+ bl_description = "Unassign selected bone."
444
+ bl_options: ClassVar = {"REGISTER", "UNDO"}
445
+
446
+ armature_data_name: StringProperty( # type: ignore[valid-type]
447
+ options={"HIDDEN"},
448
+ )
449
+ bone_property_group_path: StringProperty( # type: ignore[valid-type]
450
+ options={"HIDDEN"},
451
+ )
452
+
453
+ def execute(self, context: Context) -> set[str]:
454
+ armature_data = context.blend_data.armatures.get(self.armature_data_name)
455
+ if not isinstance(armature_data, Armature):
456
+ return {"CANCELLED"}
457
+
458
+ bone_property_group = armature_data.path_resolve(
459
+ self.bone_property_group_path, False
460
+ )
461
+ if not isinstance(bone_property_group, BonePropertyGroup):
462
+ return {"CANCELLED"}
463
+
464
+ bone_property_group.bone_name = ""
465
+ return {"FINISHED"}
466
+
467
+ if TYPE_CHECKING:
468
+ # This code is auto generated.
469
+ # To regenerate, run the `uv run tools/property_typing.py` command.
470
+ armature_data_name: str # type: ignore[no-redef]
471
+ bone_property_group_path: str # type: ignore[no-redef]