@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,425 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ import math
3
+ from collections.abc import Sequence
4
+ from typing import TYPE_CHECKING, Optional
5
+
6
+ from bpy.props import (
7
+ CollectionProperty,
8
+ EnumProperty,
9
+ IntVectorProperty,
10
+ PointerProperty,
11
+ StringProperty,
12
+ )
13
+ from bpy.types import (
14
+ Armature,
15
+ Context,
16
+ Object,
17
+ PropertyGroup,
18
+ )
19
+ from mathutils import Matrix, Quaternion
20
+
21
+ from ..common.logger import get_logger
22
+ from ..common.preferences import VrmAddonPreferences
23
+ from ..common.vrm0.material_property import GLTF_PROPERTIES, MTOON0_PROPERTIES
24
+ from .extension_accessor import (
25
+ get_armature_extension,
26
+ get_scene_extension,
27
+ )
28
+ from .khr_character.property_group import KhrCharacterPropertyGroup
29
+ from .mtoon1.property_group import Mtoon1MaterialPropertyGroup
30
+ from .node_constraint1.property_group import NodeConstraint1NodeConstraintPropertyGroup
31
+ from .property_group import (
32
+ StringPropertyGroup,
33
+ clear_expression_material_binds,
34
+ property_group_enum,
35
+ )
36
+ from .spring_bone1.property_group import SpringBone1SpringBonePropertyGroup
37
+ from .vrm0.property_group import Vrm0PropertyGroup
38
+ from .vrm1.property_group import Vrm1LookAtPropertyGroup, Vrm1PropertyGroup
39
+
40
+ if TYPE_CHECKING:
41
+ from .property_group import CollectionPropertyProtocol
42
+
43
+ _logger = get_logger(__name__)
44
+
45
+
46
+ class VrmAddonSceneExtensionPropertyGroup(PropertyGroup):
47
+ vrm0_material_gltf_property_names: CollectionProperty( # type: ignore[valid-type]
48
+ type=StringPropertyGroup
49
+ )
50
+
51
+ vrm0_material_mtoon0_property_names: CollectionProperty( # type: ignore[valid-type]
52
+ type=StringPropertyGroup
53
+ )
54
+
55
+ @staticmethod
56
+ def update_vrm0_material_property_names(context: Context) -> None:
57
+ # Unity 2022.3.4 + UniVRM 0.112.0
58
+ gltf_property_names = list(GLTF_PROPERTIES.keys())
59
+
60
+ # UniVRM 0.112.0
61
+ mtoon0_property_names = list(MTOON0_PROPERTIES.keys())
62
+
63
+ for scene in context.blend_data.scenes:
64
+ ext = get_scene_extension(scene)
65
+
66
+ if gltf_property_names != [
67
+ n.value for n in ext.vrm0_material_gltf_property_names
68
+ ]:
69
+ ext.vrm0_material_gltf_property_names.clear()
70
+ for gltf_property_name in gltf_property_names:
71
+ n = ext.vrm0_material_gltf_property_names.add()
72
+ n.value = gltf_property_name
73
+
74
+ if mtoon0_property_names != [
75
+ n.value for n in ext.vrm0_material_mtoon0_property_names
76
+ ]:
77
+ ext.vrm0_material_mtoon0_property_names.clear()
78
+ for mtoon0_property_name in mtoon0_property_names:
79
+ n = ext.vrm0_material_mtoon0_property_names.add()
80
+ n.value = mtoon0_property_name
81
+
82
+ if TYPE_CHECKING:
83
+ # This code is auto generated.
84
+ # To regenerate, run the `uv run tools/property_typing.py` command.
85
+ vrm0_material_gltf_property_names: CollectionPropertyProtocol[ # type: ignore[no-redef]
86
+ StringPropertyGroup
87
+ ]
88
+ vrm0_material_mtoon0_property_names: CollectionPropertyProtocol[ # type: ignore[no-redef]
89
+ StringPropertyGroup
90
+ ]
91
+
92
+
93
+ class VrmAddonBoneExtensionPropertyGroup(PropertyGroup):
94
+ uuid: StringProperty() # type: ignore[valid-type]
95
+
96
+ (
97
+ axis_translation_enum,
98
+ (
99
+ AXIS_TRANSLATION_AUTO,
100
+ AXIS_TRANSLATION_NONE,
101
+ AXIS_TRANSLATION_X_TO_Y,
102
+ AXIS_TRANSLATION_MINUS_X_TO_Y,
103
+ AXIS_TRANSLATION_MINUS_Y_TO_Y_AROUND_Z,
104
+ AXIS_TRANSLATION_Z_TO_Y,
105
+ AXIS_TRANSLATION_MINUS_Z_TO_Y,
106
+ ),
107
+ ) = property_group_enum(
108
+ ("AUTO", "Auto", "", "NONE", 0),
109
+ ("NONE", "None", "", "NONE", 1),
110
+ ("X_TO_Y", "X,Y to Y,-X", "", "NONE", 2),
111
+ ("MINUS_X_TO_Y", "X,Y to -Y,X", "", "NONE", 3),
112
+ ("MINUS_Y_TO_Y_AROUND_Z", "X,Y to -X,-Y", "", "NONE", 4),
113
+ ("Z_TO_Y", "Y,Z to -Z,Y", "", "NONE", 5),
114
+ ("MINUS_Z_TO_Y", "Y,Z to Z,-Y", "", "NONE", 6),
115
+ )
116
+
117
+ @classmethod
118
+ def reverse_axis_translation(cls, axis_translation: str) -> str:
119
+ return {
120
+ cls.AXIS_TRANSLATION_AUTO.identifier: cls.AXIS_TRANSLATION_AUTO,
121
+ cls.AXIS_TRANSLATION_NONE.identifier: cls.AXIS_TRANSLATION_NONE,
122
+ cls.AXIS_TRANSLATION_X_TO_Y.identifier: (cls.AXIS_TRANSLATION_MINUS_X_TO_Y),
123
+ cls.AXIS_TRANSLATION_MINUS_X_TO_Y.identifier: (cls.AXIS_TRANSLATION_X_TO_Y),
124
+ cls.AXIS_TRANSLATION_Z_TO_Y.identifier: (cls.AXIS_TRANSLATION_MINUS_Z_TO_Y),
125
+ cls.AXIS_TRANSLATION_MINUS_Z_TO_Y.identifier: (cls.AXIS_TRANSLATION_Z_TO_Y),
126
+ cls.AXIS_TRANSLATION_MINUS_Y_TO_Y_AROUND_Z.identifier: (
127
+ cls.AXIS_TRANSLATION_MINUS_Y_TO_Y_AROUND_Z
128
+ ),
129
+ }[axis_translation].identifier
130
+
131
+ @classmethod
132
+ def node_constraint_roll_axis_translation(
133
+ cls, axis_translation: str, roll_axis: Optional[str]
134
+ ) -> Optional[str]:
135
+ if roll_axis is None:
136
+ return None
137
+ return {
138
+ cls.AXIS_TRANSLATION_AUTO.identifier: {"X": "X", "Y": "Y", "Z": "Z"},
139
+ cls.AXIS_TRANSLATION_NONE.identifier: {"X": "X", "Y": "Y", "Z": "Z"},
140
+ cls.AXIS_TRANSLATION_X_TO_Y.identifier: {"X": "Y", "Y": "X", "Z": "Z"},
141
+ cls.AXIS_TRANSLATION_MINUS_X_TO_Y.identifier: {
142
+ "X": "Y",
143
+ "Y": "X",
144
+ "Z": "Z",
145
+ },
146
+ cls.AXIS_TRANSLATION_Z_TO_Y.identifier: {"X": "X", "Y": "Z", "Z": "Y"},
147
+ cls.AXIS_TRANSLATION_MINUS_Z_TO_Y.identifier: {
148
+ "X": "X",
149
+ "Y": "Z",
150
+ "Z": "Y",
151
+ },
152
+ cls.AXIS_TRANSLATION_MINUS_Y_TO_Y_AROUND_Z.identifier: {
153
+ "X": "X",
154
+ "Y": "Y",
155
+ "Z": "Z",
156
+ },
157
+ }[axis_translation][roll_axis]
158
+
159
+ @classmethod
160
+ def node_constraint_aim_axis_translation(
161
+ cls, axis_translation: str, aim_axis: Optional[str]
162
+ ) -> Optional[str]:
163
+ if aim_axis is None:
164
+ return None
165
+ return {
166
+ cls.AXIS_TRANSLATION_AUTO.identifier: {
167
+ "PositiveX": "PositiveX",
168
+ "PositiveY": "PositiveY",
169
+ "PositiveZ": "PositiveZ",
170
+ "NegativeX": "NegativeX",
171
+ "NegativeY": "NegativeY",
172
+ "NegativeZ": "NegativeZ",
173
+ },
174
+ cls.AXIS_TRANSLATION_NONE.identifier: {
175
+ "PositiveX": "PositiveX",
176
+ "PositiveY": "PositiveY",
177
+ "PositiveZ": "PositiveZ",
178
+ "NegativeX": "NegativeX",
179
+ "NegativeY": "NegativeY",
180
+ "NegativeZ": "NegativeZ",
181
+ },
182
+ cls.AXIS_TRANSLATION_X_TO_Y.identifier: {
183
+ "PositiveX": "PositiveY",
184
+ "PositiveY": "NegativeX",
185
+ "PositiveZ": "PositiveZ",
186
+ "NegativeX": "NegativeY",
187
+ "NegativeY": "PositiveX",
188
+ "NegativeZ": "NegativeZ",
189
+ },
190
+ cls.AXIS_TRANSLATION_MINUS_X_TO_Y.identifier: {
191
+ "PositiveY": "PositiveX",
192
+ "NegativeX": "PositiveY",
193
+ "PositiveZ": "PositiveZ",
194
+ "NegativeY": "NegativeX",
195
+ "PositiveX": "NegativeY",
196
+ "NegativeZ": "NegativeZ",
197
+ },
198
+ cls.AXIS_TRANSLATION_Z_TO_Y.identifier: {
199
+ "PositiveX": "PositiveX",
200
+ "PositiveY": "NegativeZ",
201
+ "PositiveZ": "PositiveY",
202
+ "NegativeX": "NegativeX",
203
+ "NegativeY": "PositiveZ",
204
+ "NegativeZ": "NegativeY",
205
+ },
206
+ cls.AXIS_TRANSLATION_MINUS_Z_TO_Y.identifier: {
207
+ "PositiveX": "PositiveX",
208
+ "NegativeZ": "PositiveY",
209
+ "PositiveY": "PositiveZ",
210
+ "NegativeX": "NegativeX",
211
+ "PositiveZ": "NegativeY",
212
+ "NegativeY": "NegativeZ",
213
+ },
214
+ cls.AXIS_TRANSLATION_MINUS_Y_TO_Y_AROUND_Z.identifier: {
215
+ "PositiveX": "NegativeX",
216
+ "PositiveY": "NegativeY",
217
+ "PositiveZ": "PositiveZ",
218
+ "NegativeX": "PositiveX",
219
+ "NegativeY": "PositiveY",
220
+ "NegativeZ": "NegativeZ",
221
+ },
222
+ }[axis_translation][aim_axis]
223
+
224
+ @classmethod
225
+ def translate_axis(cls, matrix: Matrix, axis_translation: str) -> Matrix:
226
+ location, rotation, scale = matrix.decompose()
227
+
228
+ if axis_translation == cls.AXIS_TRANSLATION_X_TO_Y.identifier:
229
+ rotation @= Quaternion((0, 0, 1), -math.pi / 2)
230
+ elif axis_translation == cls.AXIS_TRANSLATION_MINUS_X_TO_Y.identifier:
231
+ rotation @= Quaternion((0, 0, 1), math.pi / 2)
232
+ elif axis_translation == cls.AXIS_TRANSLATION_MINUS_Y_TO_Y_AROUND_Z.identifier:
233
+ rotation @= Quaternion((0, 0, 1), math.pi)
234
+ elif axis_translation == cls.AXIS_TRANSLATION_Z_TO_Y.identifier:
235
+ rotation @= Quaternion((1, 0, 0), math.pi / 2)
236
+ elif axis_translation == cls.AXIS_TRANSLATION_MINUS_Z_TO_Y.identifier:
237
+ rotation @= Quaternion((1, 0, 0), -math.pi / 2)
238
+
239
+ # return Matrix.LocRotScale(location, rotation, scale)
240
+ return (
241
+ Matrix.Translation(location)
242
+ @ rotation.to_matrix().to_4x4()
243
+ @ Matrix.Diagonal(scale).to_4x4()
244
+ )
245
+
246
+ axis_translation: EnumProperty( # type: ignore[valid-type]
247
+ items=axis_translation_enum.items(),
248
+ name="Axis Translation on Export",
249
+ )
250
+
251
+ if TYPE_CHECKING:
252
+ # This code is auto generated.
253
+ # To regenerate, run the `uv run tools/property_typing.py` command.
254
+ uuid: str # type: ignore[no-redef]
255
+ axis_translation: str # type: ignore[no-redef]
256
+
257
+
258
+ class VrmAddonObjectExtensionPropertyGroup(PropertyGroup):
259
+ axis_translation: EnumProperty( # type: ignore[valid-type]
260
+ items=VrmAddonBoneExtensionPropertyGroup.axis_translation_enum.items(),
261
+ name="Axis Translation on Export",
262
+ )
263
+
264
+ if TYPE_CHECKING:
265
+ # This code is auto generated.
266
+ # To regenerate, run the `uv run tools/property_typing.py` command.
267
+ axis_translation: str # type: ignore[no-redef]
268
+
269
+
270
+ class VrmAddonArmatureExtensionPropertyGroup(PropertyGroup):
271
+ UNMANAGED_ADDON_VERSION = VrmAddonPreferences.UNMANAGED_ADDON_VERSION
272
+
273
+ addon_version: IntVectorProperty( # type: ignore[valid-type]
274
+ size=3,
275
+ default=UNMANAGED_ADDON_VERSION,
276
+ )
277
+
278
+ vrm0: PointerProperty( # type: ignore[valid-type]
279
+ type=Vrm0PropertyGroup
280
+ )
281
+
282
+ vrm1: PointerProperty( # type: ignore[valid-type]
283
+ type=Vrm1PropertyGroup
284
+ )
285
+
286
+ spring_bone1: PointerProperty( # type: ignore[valid-type]
287
+ type=SpringBone1SpringBonePropertyGroup
288
+ )
289
+
290
+ node_constraint1: PointerProperty( # type: ignore[valid-type]
291
+ type=NodeConstraint1NodeConstraintPropertyGroup
292
+ )
293
+
294
+ khr_character: PointerProperty( # type: ignore[valid-type]
295
+ type=KhrCharacterPropertyGroup
296
+ )
297
+
298
+ SPEC_VERSION_VRM0 = "0.0"
299
+ SPEC_VERSION_VRM1 = "1.0"
300
+ SPEC_VERSION_KHR_CHARACTER = "KHR_character"
301
+ SPEC_VERSION_DEFAULT = str(SPEC_VERSION_VRM1)
302
+ spec_version_items = (
303
+ (SPEC_VERSION_VRM0, "VRM 0.0", "", "NONE", 0),
304
+ (SPEC_VERSION_VRM1, "VRM 1.0", "", "NONE", 1),
305
+ (
306
+ SPEC_VERSION_KHR_CHARACTER,
307
+ "KHR Character (Experimental)",
308
+ "",
309
+ "EXPERIMENTAL",
310
+ 2,
311
+ ),
312
+ )
313
+
314
+ def _update_spec_version(self, context: Context) -> None:
315
+ clear_expression_material_binds(context)
316
+
317
+ for blend_shape_group in self.vrm0.blend_shape_master.blend_shape_groups:
318
+ blend_shape_group.preview = 0
319
+
320
+ for expression in self.vrm1.expressions.all_name_to_expression_dict().values():
321
+ expression.preview = 0
322
+
323
+ vrm0_hidden = True
324
+ vrm1_hidden = True
325
+ if self.spec_version == self.SPEC_VERSION_VRM0:
326
+ vrm0_hidden = False
327
+ elif self.spec_version == self.SPEC_VERSION_VRM1:
328
+ vrm1_hidden = False
329
+ Vrm1LookAtPropertyGroup.update_all_previews(context)
330
+
331
+ for vrm0_collider in (
332
+ collider.bpy_object
333
+ for collider_group in self.vrm0.secondary_animation.collider_groups
334
+ for collider in collider_group.colliders
335
+ if collider.bpy_object
336
+ ):
337
+ vrm0_collider.hide_set(vrm0_hidden)
338
+
339
+ for vrm1_collider in (
340
+ collider.bpy_object
341
+ for collider in self.spring_bone1.colliders
342
+ if collider.bpy_object
343
+ ):
344
+ vrm1_collider.hide_set(vrm1_hidden)
345
+ for child in vrm1_collider.children:
346
+ child.hide_set(vrm1_hidden)
347
+
348
+ spec_version: EnumProperty( # type: ignore[valid-type]
349
+ items=spec_version_items,
350
+ name="Spec Version",
351
+ update=_update_spec_version,
352
+ default=SPEC_VERSION_DEFAULT,
353
+ )
354
+
355
+ def is_vrm0(self) -> bool:
356
+ return str(self.spec_version) == self.SPEC_VERSION_VRM0
357
+
358
+ def is_vrm1(self) -> bool:
359
+ return str(self.spec_version) == self.SPEC_VERSION_VRM1
360
+
361
+ def is_vrm(self) -> bool:
362
+ return (
363
+ str(self.spec_version) == self.SPEC_VERSION_VRM0
364
+ or str(self.spec_version) == self.SPEC_VERSION_VRM1
365
+ )
366
+
367
+ def is_khr_character(self) -> bool:
368
+ return str(self.spec_version) == self.SPEC_VERSION_KHR_CHARACTER
369
+
370
+ @staticmethod
371
+ def has_vrm_model_metadata(obj: Object) -> bool:
372
+ if obj.type != "ARMATURE":
373
+ return False
374
+ armature = obj.data
375
+ if not isinstance(armature, Armature):
376
+ return False
377
+
378
+ # https://github.com/saturday06/VRM-Addon-for-Blender/blob/2_0_3/io_scene_vrm/editor/migration.py#L372-L373
379
+ ext = get_armature_extension(armature)
380
+ if tuple(ext.addon_version) > (2, 0, 1):
381
+ return True
382
+
383
+ # https://github.com/saturday06/VRM-Addon-for-Blender/blob/0_79/importer/model_build.py#L731
384
+ humanoid_params_key = obj.get("humanoid_params")
385
+ if not isinstance(humanoid_params_key, str):
386
+ return False
387
+
388
+ # https://github.com/saturday06/VRM-Addon-for-Blender/blob/0_79/importer/model_build.py#L706
389
+ return "hips" in armature
390
+
391
+ if TYPE_CHECKING:
392
+ # This code is auto generated.
393
+ # To regenerate, run the `uv run tools/property_typing.py` command.
394
+ addon_version: Sequence[int] # type: ignore[no-redef]
395
+ vrm0: Vrm0PropertyGroup # type: ignore[no-redef]
396
+ vrm1: Vrm1PropertyGroup # type: ignore[no-redef]
397
+ spring_bone1: SpringBone1SpringBonePropertyGroup # type: ignore[no-redef]
398
+ node_constraint1: ( # type: ignore[no-redef]
399
+ NodeConstraint1NodeConstraintPropertyGroup
400
+ )
401
+ khr_character: KhrCharacterPropertyGroup # type: ignore[no-redef]
402
+ spec_version: str # type: ignore[no-redef]
403
+
404
+
405
+ class VrmAddonMaterialExtensionPropertyGroup(PropertyGroup):
406
+ mtoon1: PointerProperty( # type: ignore[valid-type]
407
+ type=Mtoon1MaterialPropertyGroup
408
+ )
409
+ if TYPE_CHECKING:
410
+ # This code is auto generated.
411
+ # To regenerate, run the `uv run tools/property_typing.py` command.
412
+ mtoon1: Mtoon1MaterialPropertyGroup # type: ignore[no-redef]
413
+
414
+
415
+ class VrmAddonNodeTreeExtensionPropertyGroup(PropertyGroup):
416
+ UNMANAGED_ADDON_VERSION = VrmAddonPreferences.UNMANAGED_ADDON_VERSION
417
+
418
+ addon_version: IntVectorProperty( # type: ignore[valid-type]
419
+ size=3,
420
+ default=UNMANAGED_ADDON_VERSION,
421
+ )
422
+ if TYPE_CHECKING:
423
+ # This code is auto generated.
424
+ # To regenerate, run the `uv run tools/property_typing.py` command.
425
+ addon_version: Sequence[int] # type: ignore[no-redef]
@@ -0,0 +1,75 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from typing import TYPE_CHECKING, TypeVar
3
+
4
+ from bpy.types import Armature, Bone, Material, NodeTree, Object, Scene
5
+
6
+ if TYPE_CHECKING:
7
+ from .extension import (
8
+ VrmAddonArmatureExtensionPropertyGroup,
9
+ VrmAddonBoneExtensionPropertyGroup,
10
+ VrmAddonMaterialExtensionPropertyGroup,
11
+ VrmAddonNodeTreeExtensionPropertyGroup,
12
+ VrmAddonObjectExtensionPropertyGroup,
13
+ VrmAddonSceneExtensionPropertyGroup,
14
+ )
15
+
16
+ __Extension = TypeVar("__Extension")
17
+
18
+
19
+ def _get_vrm_addon_extension_or_raise(
20
+ obj: object, expected_type: type[__Extension]
21
+ ) -> __Extension:
22
+ extension = getattr(obj, "vrm_addon_extension", None)
23
+ if isinstance(extension, expected_type):
24
+ return extension
25
+
26
+ message = f"{extension} is not a {expected_type} but {type(extension)}"
27
+ raise TypeError(message)
28
+
29
+
30
+ def get_material_extension(
31
+ material: Material,
32
+ ) -> "VrmAddonMaterialExtensionPropertyGroup":
33
+ from .extension import VrmAddonMaterialExtensionPropertyGroup
34
+
35
+ return _get_vrm_addon_extension_or_raise(
36
+ material, VrmAddonMaterialExtensionPropertyGroup
37
+ )
38
+
39
+
40
+ def get_armature_extension(
41
+ armature: Armature,
42
+ ) -> "VrmAddonArmatureExtensionPropertyGroup":
43
+ from .extension import VrmAddonArmatureExtensionPropertyGroup
44
+
45
+ return _get_vrm_addon_extension_or_raise(
46
+ armature, VrmAddonArmatureExtensionPropertyGroup
47
+ )
48
+
49
+
50
+ def get_node_tree_extension(
51
+ node_tree: NodeTree,
52
+ ) -> "VrmAddonNodeTreeExtensionPropertyGroup":
53
+ from .extension import VrmAddonNodeTreeExtensionPropertyGroup
54
+
55
+ return _get_vrm_addon_extension_or_raise(
56
+ node_tree, VrmAddonNodeTreeExtensionPropertyGroup
57
+ )
58
+
59
+
60
+ def get_scene_extension(scene: Scene) -> "VrmAddonSceneExtensionPropertyGroup":
61
+ from .extension import VrmAddonSceneExtensionPropertyGroup
62
+
63
+ return _get_vrm_addon_extension_or_raise(scene, VrmAddonSceneExtensionPropertyGroup)
64
+
65
+
66
+ def get_bone_extension(bone: Bone) -> "VrmAddonBoneExtensionPropertyGroup":
67
+ from .extension import VrmAddonBoneExtensionPropertyGroup
68
+
69
+ return _get_vrm_addon_extension_or_raise(bone, VrmAddonBoneExtensionPropertyGroup)
70
+
71
+
72
+ def get_object_extension(obj: Object) -> "VrmAddonObjectExtensionPropertyGroup":
73
+ from .extension import VrmAddonObjectExtensionPropertyGroup
74
+
75
+ return _get_vrm_addon_extension_or_raise(obj, VrmAddonObjectExtensionPropertyGroup)
@@ -0,0 +1,84 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Final
5
+
6
+ import bpy
7
+ from bpy.app.handlers import persistent
8
+ from bpy.types import Depsgraph, Scene
9
+
10
+ from ..common.logger import get_logger
11
+ from .extension_accessor import get_armature_extension, get_scene_extension
12
+ from .vrm1.ops import update_vrm1_expression_ui_list_elements
13
+
14
+ _logger = get_logger(__name__)
15
+
16
+
17
+ @dataclass
18
+ class State:
19
+ last_scene_names: Final[list[str]] = field(default_factory=list[str])
20
+ last_armature_names: Final[list[str]] = field(default_factory=list[str])
21
+
22
+ def clear(self) -> None:
23
+ self.last_scene_names.clear()
24
+ self.last_armature_names.clear()
25
+
26
+
27
+ _state: Final = State()
28
+
29
+
30
+ @persistent
31
+ def depsgraph_update_post(_scene: Scene, depsgraph: Depsgraph) -> None:
32
+ # This callback is invoked very frequently,
33
+ # so please keep the checks for changes as lightweight as possible.
34
+ # Be careful as this can easily cause recursive calls.
35
+ context = bpy.context
36
+
37
+ if (
38
+ depsgraph.id_type_updated("SCENE")
39
+ and (True, scenes := context.blend_data.scenes)
40
+ and (
41
+ len(scenes) != len(_state.last_scene_names)
42
+ or any(
43
+ last_scene_name != scene.name
44
+ for last_scene_name, scene in zip(_state.last_scene_names, scenes)
45
+ )
46
+ )
47
+ ):
48
+ new_scenes = [
49
+ scene for scene in scenes if scene.name not in _state.last_scene_names
50
+ ]
51
+ _state.last_scene_names.clear()
52
+ _state.last_scene_names.extend(scene.name for scene in scenes)
53
+ for new_scene in new_scenes:
54
+ get_scene_extension(new_scene).update_vrm0_material_property_names(context)
55
+
56
+ if (
57
+ depsgraph.id_type_updated("ARMATURE")
58
+ and (True, armatures := context.blend_data.armatures)
59
+ and (
60
+ len(armatures) != len(_state.last_armature_names)
61
+ or any(
62
+ last_armature_name != armature.name
63
+ for last_armature_name, armature in zip(
64
+ _state.last_armature_names, armatures
65
+ )
66
+ )
67
+ )
68
+ ):
69
+ new_armatures = [
70
+ armature
71
+ for armature in armatures
72
+ if armature.name not in _state.last_armature_names
73
+ ]
74
+ _state.last_armature_names.clear()
75
+ _state.last_armature_names.extend(armature.name for armature in armatures)
76
+ for new_armature in new_armatures:
77
+ ext = get_armature_extension(new_armature)
78
+ expressions = ext.vrm1.expressions
79
+ expressions.fill_missing_expression_names()
80
+ update_vrm1_expression_ui_list_elements(context)
81
+
82
+
83
+ def clear_global_variables() -> None:
84
+ _state.clear()
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
@@ -0,0 +1,69 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+
3
+
4
+ from typing import ClassVar
5
+
6
+ from bpy.types import Armature, Context, Panel
7
+
8
+ from .. import search
9
+ from ..extension_accessor import get_armature_extension
10
+ from ..khr_xmp_json_ld.panel import draw_khr_xmp_json_ld_packet_layout
11
+ from ..panel import VRM_PT_vrm_armature_object_property
12
+
13
+
14
+ class VRM_PT_khr_character_armature_object_property(Panel):
15
+ bl_idname = "VRM_PT_khr_character_armature_object_property"
16
+ bl_label = "XMP Linked Data"
17
+ bl_translation_context = "VRM"
18
+ bl_space_type = "PROPERTIES"
19
+ bl_region_type = "WINDOW"
20
+ bl_context = "object"
21
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
22
+ bl_parent_id = VRM_PT_vrm_armature_object_property.bl_idname
23
+
24
+ @classmethod
25
+ def poll(cls, context: Context) -> bool:
26
+ return search.active_object_is_khr_character_armature(context)
27
+
28
+ def draw(self, context: Context) -> None:
29
+ active_object = context.active_object
30
+ if not active_object or active_object.type != "ARMATURE":
31
+ return
32
+ armature_data = active_object.data
33
+ if not isinstance(armature_data, Armature):
34
+ return
35
+ ext = get_armature_extension(armature_data)
36
+ draw_khr_xmp_json_ld_packet_layout(
37
+ context,
38
+ active_object,
39
+ self.layout,
40
+ ext.khr_character.khr_xmp_json_ld_packet,
41
+ )
42
+
43
+
44
+ class VRM_PT_khr_character_ui(Panel):
45
+ bl_idname = "VRM_PT_khr_character_ui"
46
+ bl_label = "XMP Linked Data"
47
+ bl_space_type = "VIEW_3D"
48
+ bl_region_type = "UI"
49
+ bl_category = "VRM"
50
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
51
+
52
+ @classmethod
53
+ def poll(cls, context: Context) -> bool:
54
+ return search.active_object_is_khr_character_armature(context)
55
+
56
+ def draw(self, context: Context) -> None:
57
+ active_object = context.active_object
58
+ if not active_object or active_object.type != "ARMATURE":
59
+ return
60
+ armature_data = active_object.data
61
+ if not isinstance(armature_data, Armature):
62
+ return
63
+ ext = get_armature_extension(armature_data)
64
+ draw_khr_xmp_json_ld_packet_layout(
65
+ context,
66
+ active_object,
67
+ self.layout,
68
+ ext.khr_character.khr_xmp_json_ld_packet,
69
+ )
@@ -0,0 +1,27 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+
3
+
4
+ from typing import TYPE_CHECKING
5
+
6
+ from bpy.props import (
7
+ PointerProperty,
8
+ )
9
+ from bpy.types import PropertyGroup
10
+
11
+ from ...common.logger import get_logger
12
+ from ..khr_xmp_json_ld.property_group import KhrXmpJsonLdKhrCharacterPacketPropertyGroup
13
+
14
+ _logger = get_logger(__name__)
15
+
16
+
17
+ class KhrCharacterPropertyGroup(PropertyGroup):
18
+ khr_xmp_json_ld_packet: PointerProperty( # type: ignore[valid-type]
19
+ type=KhrXmpJsonLdKhrCharacterPacketPropertyGroup
20
+ )
21
+
22
+ if TYPE_CHECKING:
23
+ # This code is auto generated.
24
+ # To regenerate, run the `uv run tools/property_typing.py` command.
25
+ khr_xmp_json_ld_packet: ( # type: ignore[no-redef]
26
+ KhrXmpJsonLdKhrCharacterPacketPropertyGroup
27
+ )
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later