@volter/blender-engine 0.1.148 → 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,1333 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+
3
+ from typing import ClassVar
4
+
5
+ import bpy
6
+ from bpy.app.translations import pgettext
7
+ from bpy.types import (
8
+ Armature,
9
+ Context,
10
+ Mesh,
11
+ Object,
12
+ Panel,
13
+ UILayout,
14
+ )
15
+
16
+ from ...common.shader import LegacyAddonMaterial
17
+ from ...common.vrm0.human_bone import HumanBoneSpecifications
18
+ from ...common.vrm0.material_property import (
19
+ GLTF_PROPERTIES,
20
+ MTOON0_PROPERTIES,
21
+ MaterialPropertyType,
22
+ )
23
+ from .. import ops, search
24
+ from ..extension_accessor import (
25
+ get_armature_extension,
26
+ get_material_extension,
27
+ get_scene_extension,
28
+ )
29
+ from ..menu import VRM_MT_bone_assignment
30
+ from ..migration import defer_migrate
31
+ from ..ops import layout_operator
32
+ from ..panel import (
33
+ VRM_PT_vrm_armature_object_property,
34
+ draw_template_list,
35
+ draw_url_warning,
36
+ )
37
+ from ..search import active_object_is_vrm0_armature
38
+ from . import ops as vrm0_ops
39
+ from .menu import VRM_MT_vrm0_blend_shape_master
40
+ from .ops import draw_bone_prop_search
41
+ from .property_group import (
42
+ Vrm0BlendShapeBindPropertyGroup,
43
+ Vrm0BlendShapeGroupPropertyGroup,
44
+ Vrm0BlendShapeMasterPropertyGroup,
45
+ Vrm0FirstPersonPropertyGroup,
46
+ Vrm0HumanoidPropertyGroup,
47
+ Vrm0MaterialValueBindPropertyGroup,
48
+ Vrm0MetaPropertyGroup,
49
+ Vrm0SecondaryAnimationColliderGroupPropertyGroup,
50
+ Vrm0SecondaryAnimationGroupPropertyGroup,
51
+ Vrm0SecondaryAnimationPropertyGroup,
52
+ )
53
+ from .ui_list import (
54
+ VRM_UL_vrm0_blend_shape_bind,
55
+ VRM_UL_vrm0_blend_shape_group,
56
+ VRM_UL_vrm0_first_person_mesh_annotation,
57
+ VRM_UL_vrm0_material_value_bind,
58
+ VRM_UL_vrm0_secondary_animation_collider_group,
59
+ VRM_UL_vrm0_secondary_animation_collider_group_collider,
60
+ VRM_UL_vrm0_secondary_animation_group,
61
+ VRM_UL_vrm0_secondary_animation_group_bone,
62
+ VRM_UL_vrm0_secondary_animation_group_collider_group,
63
+ )
64
+
65
+
66
+ def draw_vrm0_humanoid_operators_layout(
67
+ armature: Object,
68
+ layout: UILayout,
69
+ ) -> None:
70
+ bone_operator_column = layout.column()
71
+ layout_operator(
72
+ bone_operator_column,
73
+ vrm0_ops.VRM_OT_assign_vrm0_humanoid_human_bones_automatically,
74
+ icon="ARMATURE_DATA",
75
+ ).armature_object_name = armature.name
76
+ save_load_row = bone_operator_column.split(factor=0.5, align=True)
77
+ save_load_row.operator(
78
+ ops.VRM_OT_save_human_bone_mappings.bl_idname,
79
+ icon="EXPORT",
80
+ text="Save",
81
+ )
82
+ save_load_row.operator(
83
+ ops.VRM_OT_load_human_bone_mappings.bl_idname, icon="IMPORT", text="Load"
84
+ )
85
+
86
+
87
+ def draw_vrm0_humanoid_required_bones_layout(
88
+ armature: Object,
89
+ layout: UILayout,
90
+ split_factor: float = 0.2,
91
+ ) -> None:
92
+ armature_data = armature.data
93
+ if not isinstance(armature_data, Armature):
94
+ return
95
+
96
+ layout.label(text="Required VRM Human Bones", icon="ARMATURE_DATA")
97
+ row = layout.row(align=True).split(factor=split_factor, align=True)
98
+ label_column = row.column(align=True)
99
+ label_column.label(text=HumanBoneSpecifications.HEAD.label)
100
+ label_column.label(text=HumanBoneSpecifications.NECK.label)
101
+ label_column.label(text=HumanBoneSpecifications.CHEST.label)
102
+ label_column.label(text=HumanBoneSpecifications.SPINE.label)
103
+ label_column.label(text=HumanBoneSpecifications.HIPS.label)
104
+
105
+ search_column = row.column(align=True)
106
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.HEAD, armature)
107
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.NECK, armature)
108
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.CHEST, armature)
109
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.SPINE, armature)
110
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.HIPS, armature)
111
+
112
+ row = layout.row(align=True).split(factor=split_factor, align=True)
113
+ label_column = row.column(align=True)
114
+ label_column.label(text="", translate=False)
115
+ label_column.label(text=HumanBoneSpecifications.LEFT_UPPER_ARM.label_no_left_right)
116
+ label_column.label(text=HumanBoneSpecifications.LEFT_LOWER_ARM.label_no_left_right)
117
+ label_column.label(text=HumanBoneSpecifications.LEFT_HAND.label_no_left_right)
118
+ label_column.separator()
119
+ label_column.label(text=HumanBoneSpecifications.LEFT_UPPER_LEG.label_no_left_right)
120
+ label_column.label(text=HumanBoneSpecifications.LEFT_LOWER_LEG.label_no_left_right)
121
+ label_column.label(text=HumanBoneSpecifications.LEFT_FOOT.label_no_left_right)
122
+
123
+ search_column = row.column(align=True)
124
+ right_left_row = search_column.row(align=True)
125
+ right_left_row.label(text="Right")
126
+ right_left_row.label(text="Left")
127
+
128
+ right_left_row = search_column.row(align=True)
129
+ draw_bone_prop_search(
130
+ right_left_row, HumanBoneSpecifications.RIGHT_UPPER_ARM, armature
131
+ )
132
+ draw_bone_prop_search(
133
+ right_left_row, HumanBoneSpecifications.LEFT_UPPER_ARM, armature
134
+ )
135
+
136
+ right_left_row = search_column.row(align=True)
137
+ draw_bone_prop_search(
138
+ right_left_row, HumanBoneSpecifications.RIGHT_LOWER_ARM, armature
139
+ )
140
+ draw_bone_prop_search(
141
+ right_left_row, HumanBoneSpecifications.LEFT_LOWER_ARM, armature
142
+ )
143
+
144
+ right_left_row = search_column.row(align=True)
145
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.RIGHT_HAND, armature)
146
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.LEFT_HAND, armature)
147
+
148
+ search_column.separator()
149
+
150
+ right_left_row = search_column.row(align=True)
151
+ draw_bone_prop_search(
152
+ right_left_row, HumanBoneSpecifications.RIGHT_UPPER_LEG, armature
153
+ )
154
+ draw_bone_prop_search(
155
+ right_left_row, HumanBoneSpecifications.LEFT_UPPER_LEG, armature
156
+ )
157
+
158
+ right_left_row = search_column.row(align=True)
159
+ draw_bone_prop_search(
160
+ right_left_row, HumanBoneSpecifications.RIGHT_LOWER_LEG, armature
161
+ )
162
+ draw_bone_prop_search(
163
+ right_left_row, HumanBoneSpecifications.LEFT_LOWER_LEG, armature
164
+ )
165
+
166
+ right_left_row = search_column.row(align=True)
167
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.RIGHT_FOOT, armature)
168
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.LEFT_FOOT, armature)
169
+
170
+
171
+ def draw_vrm0_humanoid_optional_bones_layout(
172
+ armature: Object,
173
+ layout: UILayout,
174
+ split_factor: float = 0.2,
175
+ ) -> None:
176
+ split_factor = 0.2
177
+
178
+ layout.label(text="Optional VRM Human Bones", icon="BONE_DATA")
179
+
180
+ row = layout.row(align=True).split(factor=split_factor, align=True)
181
+ label_column = row.column(align=True)
182
+ label_column.label(text="", translate=False)
183
+ label_column.label(text=HumanBoneSpecifications.LEFT_EYE.label_no_left_right)
184
+ label_column.label(text=HumanBoneSpecifications.JAW.label)
185
+ label_column.label(text=HumanBoneSpecifications.RIGHT_SHOULDER.label_no_left_right)
186
+ label_column.label(text=HumanBoneSpecifications.UPPER_CHEST.label)
187
+ label_column.label(text=HumanBoneSpecifications.RIGHT_TOES.label_no_left_right)
188
+
189
+ search_column = row.column(align=True)
190
+
191
+ right_left_row = search_column.row(align=True)
192
+ right_left_row.label(text="Right")
193
+ right_left_row.label(text="Left")
194
+
195
+ right_left_row = search_column.row(align=True)
196
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.RIGHT_EYE, armature)
197
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.LEFT_EYE, armature)
198
+
199
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.JAW, armature)
200
+
201
+ right_left_row = search_column.row(align=True)
202
+ draw_bone_prop_search(
203
+ right_left_row, HumanBoneSpecifications.RIGHT_SHOULDER, armature
204
+ )
205
+ draw_bone_prop_search(
206
+ right_left_row, HumanBoneSpecifications.LEFT_SHOULDER, armature
207
+ )
208
+
209
+ draw_bone_prop_search(search_column, HumanBoneSpecifications.UPPER_CHEST, armature)
210
+
211
+ right_left_row = search_column.row(align=True)
212
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.RIGHT_TOES, armature)
213
+ draw_bone_prop_search(right_left_row, HumanBoneSpecifications.LEFT_TOES, armature)
214
+
215
+ row = layout.row(align=True).split(factor=split_factor, align=True)
216
+ label_column = row.column(align=True)
217
+ label_column.label(text="", translate=False)
218
+ label_column.label(text="Left Thumb:")
219
+ label_column.label(text="Left Index:")
220
+ label_column.label(text="Left Middle:")
221
+ label_column.label(text="Left Ring:")
222
+ label_column.label(text="Left Little:")
223
+ label_column.separator()
224
+ label_column.label(text="Right Thumb:")
225
+ label_column.label(text="Right Index:")
226
+ label_column.label(text="Right Middle:")
227
+ label_column.label(text="Right Ring:")
228
+ label_column.label(text="Right Little:")
229
+
230
+ search_column = row.column(align=True)
231
+ finger_row = search_column.row(align=True)
232
+ finger_row.label(text="Root")
233
+ finger_row.label(text="", translate=False)
234
+ finger_row.label(text="Tip")
235
+
236
+ finger_row = search_column.row(align=True)
237
+ draw_bone_prop_search(
238
+ finger_row, HumanBoneSpecifications.LEFT_THUMB_PROXIMAL, armature
239
+ )
240
+ draw_bone_prop_search(
241
+ finger_row, HumanBoneSpecifications.LEFT_THUMB_INTERMEDIATE, armature
242
+ )
243
+ draw_bone_prop_search(
244
+ finger_row, HumanBoneSpecifications.LEFT_THUMB_DISTAL, armature
245
+ )
246
+
247
+ finger_row = search_column.row(align=True)
248
+ draw_bone_prop_search(
249
+ finger_row, HumanBoneSpecifications.LEFT_INDEX_PROXIMAL, armature
250
+ )
251
+ draw_bone_prop_search(
252
+ finger_row, HumanBoneSpecifications.LEFT_INDEX_INTERMEDIATE, armature
253
+ )
254
+ draw_bone_prop_search(
255
+ finger_row, HumanBoneSpecifications.LEFT_INDEX_DISTAL, armature
256
+ )
257
+
258
+ finger_row = search_column.row(align=True)
259
+ draw_bone_prop_search(
260
+ finger_row, HumanBoneSpecifications.LEFT_MIDDLE_PROXIMAL, armature
261
+ )
262
+ draw_bone_prop_search(
263
+ finger_row, HumanBoneSpecifications.LEFT_MIDDLE_INTERMEDIATE, armature
264
+ )
265
+ draw_bone_prop_search(
266
+ finger_row, HumanBoneSpecifications.LEFT_MIDDLE_DISTAL, armature
267
+ )
268
+
269
+ finger_row = search_column.row(align=True)
270
+ draw_bone_prop_search(
271
+ finger_row, HumanBoneSpecifications.LEFT_RING_PROXIMAL, armature
272
+ )
273
+ draw_bone_prop_search(
274
+ finger_row, HumanBoneSpecifications.LEFT_RING_INTERMEDIATE, armature
275
+ )
276
+ draw_bone_prop_search(
277
+ finger_row, HumanBoneSpecifications.LEFT_RING_DISTAL, armature
278
+ )
279
+
280
+ finger_row = search_column.row(align=True)
281
+ draw_bone_prop_search(
282
+ finger_row, HumanBoneSpecifications.LEFT_LITTLE_PROXIMAL, armature
283
+ )
284
+ draw_bone_prop_search(
285
+ finger_row, HumanBoneSpecifications.LEFT_LITTLE_INTERMEDIATE, armature
286
+ )
287
+ draw_bone_prop_search(
288
+ finger_row, HumanBoneSpecifications.LEFT_LITTLE_DISTAL, armature
289
+ )
290
+
291
+ search_column.separator()
292
+
293
+ finger_row = search_column.row(align=True)
294
+ draw_bone_prop_search(
295
+ finger_row, HumanBoneSpecifications.RIGHT_THUMB_PROXIMAL, armature
296
+ )
297
+ draw_bone_prop_search(
298
+ finger_row, HumanBoneSpecifications.RIGHT_THUMB_INTERMEDIATE, armature
299
+ )
300
+ draw_bone_prop_search(
301
+ finger_row, HumanBoneSpecifications.RIGHT_THUMB_DISTAL, armature
302
+ )
303
+
304
+ finger_row = search_column.row(align=True)
305
+ draw_bone_prop_search(
306
+ finger_row, HumanBoneSpecifications.RIGHT_INDEX_PROXIMAL, armature
307
+ )
308
+ draw_bone_prop_search(
309
+ finger_row, HumanBoneSpecifications.RIGHT_INDEX_INTERMEDIATE, armature
310
+ )
311
+ draw_bone_prop_search(
312
+ finger_row, HumanBoneSpecifications.RIGHT_INDEX_DISTAL, armature
313
+ )
314
+
315
+ finger_row = search_column.row(align=True)
316
+ draw_bone_prop_search(
317
+ finger_row, HumanBoneSpecifications.RIGHT_MIDDLE_PROXIMAL, armature
318
+ )
319
+ draw_bone_prop_search(
320
+ finger_row, HumanBoneSpecifications.RIGHT_MIDDLE_INTERMEDIATE, armature
321
+ )
322
+ draw_bone_prop_search(
323
+ finger_row, HumanBoneSpecifications.RIGHT_MIDDLE_DISTAL, armature
324
+ )
325
+
326
+ finger_row = search_column.row(align=True)
327
+ draw_bone_prop_search(
328
+ finger_row, HumanBoneSpecifications.RIGHT_RING_PROXIMAL, armature
329
+ )
330
+ draw_bone_prop_search(
331
+ finger_row, HumanBoneSpecifications.RIGHT_RING_INTERMEDIATE, armature
332
+ )
333
+ draw_bone_prop_search(
334
+ finger_row, HumanBoneSpecifications.RIGHT_RING_DISTAL, armature
335
+ )
336
+
337
+ finger_row = search_column.row(align=True)
338
+ draw_bone_prop_search(
339
+ finger_row, HumanBoneSpecifications.RIGHT_LITTLE_PROXIMAL, armature
340
+ )
341
+ draw_bone_prop_search(
342
+ finger_row, HumanBoneSpecifications.RIGHT_LITTLE_INTERMEDIATE, armature
343
+ )
344
+ draw_bone_prop_search(
345
+ finger_row, HumanBoneSpecifications.RIGHT_LITTLE_DISTAL, armature
346
+ )
347
+
348
+
349
+ def _draw_vrm0_humanoid_layout(
350
+ context: Context,
351
+ armature: Object,
352
+ layout: UILayout,
353
+ humanoid: Vrm0HumanoidPropertyGroup,
354
+ ) -> None:
355
+ if defer_migrate(armature.name, heavy_migration=True):
356
+ armature_data = armature.data
357
+ if not isinstance(armature_data, Armature):
358
+ return
359
+ Vrm0HumanoidPropertyGroup.update_all_bone_name_candidates(
360
+ context, armature_data.name
361
+ )
362
+
363
+ data = armature.data
364
+ if not isinstance(data, Armature):
365
+ return
366
+
367
+ armature_box = layout
368
+
369
+ t_pose_box = armature_box.box()
370
+ column = t_pose_box.row().column()
371
+ column.label(text="VRM T-Pose", icon="OUTLINER_OB_ARMATURE")
372
+ row = column.split(factor=0.8, align=True)
373
+ row.prop(humanoid, "pose")
374
+ apply_row = row.row(align=True)
375
+ apply_row.enabled = humanoid.pose != humanoid.POSE_CURRENT_POSE.identifier and (
376
+ humanoid.pose != humanoid.POSE_CUSTOM_POSE.identifier
377
+ or humanoid.pose_library is not None
378
+ )
379
+ layout_operator(
380
+ apply_row, ops.VRM_OT_apply_humanoid_t_pose
381
+ ).armature_object_name = armature.name
382
+ if humanoid.pose == humanoid.POSE_CUSTOM_POSE.identifier:
383
+ label = "Pose Library" if bpy.app.version < (3, 0) else "Pose Asset"
384
+ column.prop_search(
385
+ humanoid,
386
+ "pose_library",
387
+ context.blend_data,
388
+ "actions",
389
+ text=label,
390
+ translate=False,
391
+ )
392
+ pose_library = humanoid.pose_library
393
+ if pose_library and pose_library.pose_markers:
394
+ column.prop_search(
395
+ humanoid,
396
+ "pose_marker_name",
397
+ pose_library,
398
+ "pose_markers",
399
+ text="Pose",
400
+ translate=False,
401
+ )
402
+
403
+ draw_vrm0_humanoid_operators_layout(armature, armature_box)
404
+
405
+ if ops.VRM_OT_simplify_vroid_bones.vroid_bones_exist(data):
406
+ simplify_vroid_bones_op = layout_operator(
407
+ armature_box,
408
+ ops.VRM_OT_simplify_vroid_bones,
409
+ text=pgettext(ops.VRM_OT_simplify_vroid_bones.bl_label),
410
+ icon="GREASEPENCIL",
411
+ )
412
+ simplify_vroid_bones_op.armature_object_name = armature.name
413
+
414
+ layout.prop(humanoid, "filter_by_human_bone_hierarchy")
415
+
416
+ split_factor = 0.2
417
+ draw_vrm0_humanoid_required_bones_layout(armature, armature_box.box(), split_factor)
418
+ draw_vrm0_humanoid_optional_bones_layout(armature, armature_box.box(), split_factor)
419
+
420
+ layout.label(text="Arm", icon="VIEW_PAN")
421
+ layout.prop(
422
+ humanoid,
423
+ "arm_stretch",
424
+ )
425
+ layout.prop(humanoid, "upper_arm_twist")
426
+ layout.prop(humanoid, "lower_arm_twist")
427
+ layout.separator()
428
+ layout.label(text="Leg", icon="MOD_DYNAMICPAINT")
429
+ layout.prop(humanoid, "leg_stretch")
430
+ layout.prop(humanoid, "upper_leg_twist")
431
+ layout.prop(humanoid, "lower_leg_twist")
432
+ layout.prop(humanoid, "feet_spacing")
433
+ layout.separator()
434
+ layout.prop(humanoid, "has_translation_dof")
435
+
436
+
437
+ class VRM_PT_vrm0_humanoid_armature_object_property(Panel):
438
+ bl_idname = "VRM_PT_vrm0_humanoid_armature_object_property"
439
+ bl_label = "VRM 0.x Humanoid"
440
+ bl_space_type = "PROPERTIES"
441
+ bl_region_type = "WINDOW"
442
+ bl_context = "object"
443
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
444
+ bl_parent_id = VRM_PT_vrm_armature_object_property.bl_idname
445
+
446
+ @classmethod
447
+ def poll(cls, context: Context) -> bool:
448
+ return active_object_is_vrm0_armature(context)
449
+
450
+ def draw_header(self, _context: Context) -> None:
451
+ self.layout.label(icon="ARMATURE_DATA")
452
+
453
+ def draw(self, context: Context) -> None:
454
+ active_object = context.active_object
455
+ if not active_object:
456
+ return
457
+ armature_data = active_object.data
458
+ if not isinstance(armature_data, Armature):
459
+ return
460
+ _draw_vrm0_humanoid_layout(
461
+ context,
462
+ active_object,
463
+ self.layout,
464
+ get_armature_extension(armature_data).vrm0.humanoid,
465
+ )
466
+
467
+
468
+ class VRM_PT_vrm0_humanoid_ui(Panel):
469
+ bl_idname = "VRM_PT_vrm0_humanoid_ui"
470
+ bl_label = "VRM 0.x Humanoid"
471
+ bl_space_type = "VIEW_3D"
472
+ bl_region_type = "UI"
473
+ bl_category = "VRM"
474
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
475
+
476
+ @classmethod
477
+ def poll(cls, context: Context) -> bool:
478
+ return search.current_armature_is_vrm0(context)
479
+
480
+ def draw_header(self, _context: Context) -> None:
481
+ self.layout.label(icon="USER")
482
+
483
+ def draw(self, context: Context) -> None:
484
+ armature = search.current_armature(context)
485
+ if not armature:
486
+ return
487
+ armature_data = armature.data
488
+ if not isinstance(armature_data, Armature):
489
+ return
490
+ _draw_vrm0_humanoid_layout(
491
+ context,
492
+ armature,
493
+ self.layout,
494
+ get_armature_extension(armature_data).vrm0.humanoid,
495
+ )
496
+
497
+
498
+ def _draw_vrm0_first_person_layout(
499
+ armature: Object,
500
+ _context: Context,
501
+ layout: UILayout,
502
+ first_person: Vrm0FirstPersonPropertyGroup,
503
+ ) -> None:
504
+ defer_migrate(armature.name, heavy_migration=False)
505
+ armature_data = armature.data
506
+ if not isinstance(armature_data, Armature):
507
+ return
508
+ VRM_MT_bone_assignment.draw_input_layout(
509
+ layout,
510
+ first_person.first_person_bone,
511
+ simple=True,
512
+ )
513
+ layout.prop(first_person, "first_person_bone_offset", icon="BONE_DATA")
514
+ layout.prop(first_person, "look_at_type_name")
515
+ layout.label(text="Mesh Annotations", icon="RESTRICT_RENDER_OFF")
516
+
517
+ (
518
+ mesh_annotation_collection_ops,
519
+ mesh_annotation_collection_item_ops,
520
+ mesh_annotation_index,
521
+ _,
522
+ _,
523
+ ) = draw_template_list(
524
+ layout,
525
+ VRM_UL_vrm0_first_person_mesh_annotation,
526
+ first_person,
527
+ "mesh_annotations",
528
+ "active_mesh_annotation_index",
529
+ vrm0_ops.VRM_OT_add_vrm0_first_person_mesh_annotation,
530
+ vrm0_ops.VRM_OT_remove_vrm0_first_person_mesh_annotation,
531
+ vrm0_ops.VRM_OT_move_up_vrm0_first_person_mesh_annotation,
532
+ vrm0_ops.VRM_OT_move_down_vrm0_first_person_mesh_annotation,
533
+ )
534
+
535
+ for mesh_annotation_collection_op in mesh_annotation_collection_ops:
536
+ mesh_annotation_collection_op.armature_object_name = armature.name
537
+
538
+ for mesh_annotation_collection_item_op in mesh_annotation_collection_item_ops:
539
+ mesh_annotation_collection_item_op.mesh_annotation_index = mesh_annotation_index
540
+
541
+ layout.separator()
542
+ box = layout.box()
543
+ box.label(text="Look At Horizontal Inner", icon="FULLSCREEN_EXIT")
544
+ box.prop(first_person.look_at_horizontal_inner, "curve")
545
+ box.prop(first_person.look_at_horizontal_inner, "x_range")
546
+ box.prop(first_person.look_at_horizontal_inner, "y_range")
547
+ box = layout.box()
548
+ box.label(text="Look At Horizontal Outer", icon="FULLSCREEN_ENTER")
549
+ box.prop(first_person.look_at_horizontal_outer, "curve")
550
+ box.prop(first_person.look_at_horizontal_outer, "x_range")
551
+ box.prop(first_person.look_at_horizontal_outer, "y_range")
552
+ box = layout.box()
553
+ box.label(text="Look At Vertical Up", icon="TRIA_UP")
554
+ box.prop(first_person.look_at_vertical_up, "curve")
555
+ box.prop(first_person.look_at_vertical_up, "x_range")
556
+ box.prop(first_person.look_at_vertical_up, "y_range")
557
+ box = layout.box()
558
+ box.label(text="Look At Vertical Down", icon="TRIA_DOWN")
559
+ box.prop(first_person.look_at_vertical_down, "curve")
560
+ box.prop(first_person.look_at_vertical_down, "x_range")
561
+ box.prop(first_person.look_at_vertical_down, "y_range")
562
+
563
+
564
+ class VRM_PT_vrm0_first_person_armature_object_property(Panel):
565
+ bl_idname = "VRM_PT_vrm0_first_person_armature_object_property"
566
+ bl_label = "VRM 0.x First Person"
567
+ bl_space_type = "PROPERTIES"
568
+ bl_region_type = "WINDOW"
569
+ bl_context = "object"
570
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
571
+ bl_parent_id = VRM_PT_vrm_armature_object_property.bl_idname
572
+
573
+ @classmethod
574
+ def poll(cls, context: Context) -> bool:
575
+ return active_object_is_vrm0_armature(context)
576
+
577
+ def draw_header(self, _context: Context) -> None:
578
+ self.layout.label(icon="HIDE_OFF")
579
+
580
+ def draw(self, context: Context) -> None:
581
+ active_object = context.active_object
582
+ if not active_object:
583
+ return
584
+ armature_data = active_object.data
585
+ if not isinstance(armature_data, Armature):
586
+ return
587
+ ext = get_armature_extension(armature_data)
588
+ _draw_vrm0_first_person_layout(
589
+ active_object,
590
+ context,
591
+ self.layout,
592
+ ext.vrm0.first_person,
593
+ )
594
+
595
+
596
+ class VRM_PT_vrm0_first_person_ui(Panel):
597
+ bl_idname = "VRM_PT_vrm0_first_person_ui"
598
+ bl_label = "VRM 0.x First Person"
599
+ bl_space_type = "VIEW_3D"
600
+ bl_region_type = "UI"
601
+ bl_category = "VRM"
602
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
603
+
604
+ @classmethod
605
+ def poll(cls, context: Context) -> bool:
606
+ return search.current_armature_is_vrm0(context)
607
+
608
+ def draw_header(self, _context: Context) -> None:
609
+ self.layout.label(icon="HIDE_OFF")
610
+
611
+ def draw(self, context: Context) -> None:
612
+ armature = search.current_armature(context)
613
+ if not armature:
614
+ return
615
+ armature_data = armature.data
616
+ if not isinstance(armature_data, Armature):
617
+ return
618
+ _draw_vrm0_first_person_layout(
619
+ armature,
620
+ context,
621
+ self.layout,
622
+ get_armature_extension(armature_data).vrm0.first_person,
623
+ )
624
+
625
+
626
+ def _draw_vrm0_material_value_layout(
627
+ armature: Object,
628
+ context: Context,
629
+ layout: UILayout,
630
+ material_value: Vrm0MaterialValueBindPropertyGroup,
631
+ *,
632
+ blend_shape_group_index: int,
633
+ material_value_index: int,
634
+ ) -> None:
635
+ material_value_column = layout.column()
636
+ material_value_column.prop_search(
637
+ material_value, "material", context.blend_data, "materials"
638
+ )
639
+
640
+ material = material_value.material
641
+ if not material:
642
+ material_value_column.prop(material_value, "property_name", icon="PROPERTIES")
643
+ is_mtoon = False
644
+ else:
645
+ ext = get_material_extension(material)
646
+ if ext.mtoon1.enabled or (
647
+ (legacy_addon_material := LegacyAddonMaterial.try_parse(material))
648
+ and legacy_addon_material.shader_name == "MToon_unversioned"
649
+ ):
650
+ is_mtoon = True
651
+ if bpy.app.version >= (3, 2):
652
+ material_value_column.prop_search(
653
+ material_value,
654
+ "property_name",
655
+ get_scene_extension(context.scene),
656
+ "vrm0_material_mtoon0_property_names",
657
+ icon="PROPERTIES",
658
+ results_are_suggestions=True,
659
+ )
660
+ else:
661
+ material_value_column.prop_search(
662
+ material_value,
663
+ "property_name",
664
+ get_scene_extension(context.scene),
665
+ "vrm0_material_mtoon0_property_names",
666
+ icon="PROPERTIES",
667
+ )
668
+ elif bpy.app.version >= (3, 2):
669
+ is_mtoon = False
670
+ material_value_column.prop_search(
671
+ material_value,
672
+ "property_name",
673
+ get_scene_extension(context.scene),
674
+ "vrm0_material_gltf_property_names",
675
+ icon="PROPERTIES",
676
+ results_are_suggestions=True,
677
+ )
678
+ else:
679
+ is_mtoon = False
680
+ material_value_column.prop_search(
681
+ material_value,
682
+ "property_name",
683
+ get_scene_extension(context.scene),
684
+ "vrm0_material_gltf_property_names",
685
+ icon="PROPERTIES",
686
+ )
687
+
688
+ for material_property in (
689
+ list(MTOON0_PROPERTIES.values()) + list(GLTF_PROPERTIES.values())
690
+ if is_mtoon
691
+ else list(GLTF_PROPERTIES.values()) + list(MTOON0_PROPERTIES.values())
692
+ ):
693
+ if material_property.name != material_value.property_name:
694
+ continue
695
+
696
+ if material_property.type == MaterialPropertyType.RGBA:
697
+ material_value_column.prop(material_value, "target_value_as_rgba")
698
+ return
699
+
700
+ if material_property.type == MaterialPropertyType.RGB:
701
+ material_value_column.prop(material_value, "target_value_as_rgb")
702
+ return
703
+
704
+ if material_property.type == MaterialPropertyType.UV:
705
+ material_value_uv_tiling_row = material_value_column.row(align=True)
706
+ material_value_uv_tiling_row.prop(material_value, "target_value_tiling_s")
707
+ material_value_uv_tiling_row.prop(material_value, "target_value_tiling_t")
708
+ material_value_uv_offset_row = material_value_column.row(align=True)
709
+ material_value_uv_offset_row.prop(material_value, "target_value_offset_s")
710
+ material_value_uv_offset_row.prop(material_value, "target_value_offset_t")
711
+ return
712
+
713
+ if material_property.type == MaterialPropertyType.UV_S:
714
+ material_value_column.prop(material_value, "target_value_tiling_s")
715
+ material_value_column.prop(material_value, "target_value_offset_s")
716
+ return
717
+
718
+ if material_property.type == MaterialPropertyType.UV_T:
719
+ material_value_column.prop(material_value, "target_value_tiling_t")
720
+ material_value_column.prop(material_value, "target_value_offset_t")
721
+ return
722
+
723
+ for target_value_index, target_value in enumerate(material_value.target_value):
724
+ target_value_row = material_value_column.row()
725
+ target_value_row.prop(target_value, "value", text=f"Value {target_value_index}")
726
+ remove_target_value_op = layout_operator(
727
+ target_value_row,
728
+ vrm0_ops.VRM_OT_remove_vrm0_material_value_bind_target_value,
729
+ text="",
730
+ translate=False,
731
+ icon="REMOVE",
732
+ )
733
+ remove_target_value_op.armature_object_name = armature.name
734
+ remove_target_value_op.blend_shape_group_index = blend_shape_group_index
735
+ remove_target_value_op.material_value_index = material_value_index
736
+ remove_target_value_op.target_value_index = target_value_index
737
+ add_target_value_op = layout_operator(
738
+ material_value_column,
739
+ vrm0_ops.VRM_OT_add_vrm0_material_value_bind_target_value,
740
+ icon="ADD",
741
+ )
742
+ add_target_value_op.armature_object_name = armature.name
743
+ add_target_value_op.blend_shape_group_index = blend_shape_group_index
744
+ add_target_value_op.material_value_index = material_value_index
745
+
746
+
747
+ def _draw_vrm0_blend_shape_master_layout(
748
+ armature: Object,
749
+ context: Context,
750
+ layout: UILayout,
751
+ blend_shape_master: Vrm0BlendShapeMasterPropertyGroup,
752
+ ) -> None:
753
+ defer_migrate(armature.name, heavy_migration=False)
754
+ blend_data = context.blend_data
755
+
756
+ (
757
+ blend_shape_group_collection_ops,
758
+ blend_shape_group_collection_item_ops,
759
+ blend_shape_group_index,
760
+ blend_shape_group,
761
+ (add_blend_shape_group_op, _, _, _),
762
+ ) = draw_template_list(
763
+ layout,
764
+ VRM_UL_vrm0_blend_shape_group,
765
+ blend_shape_master,
766
+ "blend_shape_groups",
767
+ "active_blend_shape_group_index",
768
+ vrm0_ops.VRM_OT_add_vrm0_blend_shape_group,
769
+ vrm0_ops.VRM_OT_remove_vrm0_blend_shape_group,
770
+ vrm0_ops.VRM_OT_move_up_vrm0_blend_shape_group,
771
+ vrm0_ops.VRM_OT_move_down_vrm0_blend_shape_group,
772
+ menu_and_context_pointer_set_callback=(
773
+ VRM_MT_vrm0_blend_shape_master,
774
+ VRM_MT_vrm0_blend_shape_master.layout_context_pointer_set(armature),
775
+ ),
776
+ )
777
+
778
+ for blend_shape_group_collection_op in blend_shape_group_collection_ops:
779
+ blend_shape_group_collection_op.armature_object_name = armature.name
780
+
781
+ for blend_shape_group_collection_item_op in blend_shape_group_collection_item_ops:
782
+ blend_shape_group_collection_item_op.blend_shape_group_index = (
783
+ blend_shape_group_index
784
+ )
785
+
786
+ add_blend_shape_group_op.name = "New"
787
+
788
+ if isinstance(blend_shape_group, Vrm0BlendShapeGroupPropertyGroup):
789
+ column = layout.column()
790
+ column.prop(blend_shape_group, "name")
791
+ column.prop(blend_shape_group, "preset_name")
792
+ column.prop(blend_shape_group, "is_binary", icon="IPO_CONSTANT")
793
+ column.prop(blend_shape_group, "preview", icon="PLAY", text="Preview")
794
+ column.separator(factor=0.5)
795
+
796
+ binds_box = column.box()
797
+ binds_box.label(text="Binds", icon="MESH_DATA")
798
+
799
+ (
800
+ bind_collection_ops,
801
+ bind_collection_item_ops,
802
+ bind_index,
803
+ bind,
804
+ _,
805
+ ) = draw_template_list(
806
+ binds_box,
807
+ VRM_UL_vrm0_blend_shape_bind,
808
+ blend_shape_group,
809
+ "binds",
810
+ "active_bind_index",
811
+ vrm0_ops.VRM_OT_add_vrm0_blend_shape_bind,
812
+ vrm0_ops.VRM_OT_remove_vrm0_blend_shape_bind,
813
+ vrm0_ops.VRM_OT_move_up_vrm0_blend_shape_bind,
814
+ vrm0_ops.VRM_OT_move_down_vrm0_blend_shape_bind,
815
+ )
816
+
817
+ for bind_collection_op in bind_collection_ops:
818
+ bind_collection_op.armature_object_name = armature.name
819
+ bind_collection_op.blend_shape_group_index = blend_shape_group_index
820
+
821
+ for bind_collection_item_op in bind_collection_item_ops:
822
+ bind_collection_item_op.bind_index = bind_index
823
+
824
+ if isinstance(bind, Vrm0BlendShapeBindPropertyGroup):
825
+ bind_column = binds_box.column()
826
+ bind_column.prop(
827
+ bind.mesh,
828
+ "bpy_object",
829
+ text="Mesh",
830
+ icon="OUTLINER_OB_MESH",
831
+ )
832
+
833
+ mesh_object = blend_data.objects.get(bind.mesh.mesh_object_name)
834
+ if mesh_object:
835
+ mesh_data = mesh_object.data
836
+ if isinstance(mesh_data, Mesh):
837
+ shape_keys = mesh_data.shape_keys
838
+ if shape_keys:
839
+ bind_column.prop_search(
840
+ bind,
841
+ "index",
842
+ shape_keys,
843
+ "key_blocks",
844
+ text="Shape key",
845
+ )
846
+ bind_column.prop(bind, "weight", slider=True)
847
+
848
+ column.separator(factor=0.2)
849
+ material_value_binds_box = column.box()
850
+ material_value_binds_box.label(text="Material Values", icon="MATERIAL")
851
+
852
+ (
853
+ material_value_collection_ops,
854
+ material_value_collection_item_ops,
855
+ material_value_index,
856
+ material_value,
857
+ _,
858
+ ) = draw_template_list(
859
+ material_value_binds_box,
860
+ VRM_UL_vrm0_material_value_bind,
861
+ blend_shape_group,
862
+ "material_values",
863
+ "active_material_value_index",
864
+ vrm0_ops.VRM_OT_add_vrm0_material_value_bind,
865
+ vrm0_ops.VRM_OT_remove_vrm0_material_value_bind,
866
+ vrm0_ops.VRM_OT_move_up_vrm0_material_value_bind,
867
+ vrm0_ops.VRM_OT_move_down_vrm0_material_value_bind,
868
+ )
869
+
870
+ for material_value_bind_collection_op in material_value_collection_ops:
871
+ material_value_bind_collection_op.armature_object_name = armature.name
872
+ material_value_bind_collection_op.blend_shape_group_index = (
873
+ blend_shape_group_index
874
+ )
875
+
876
+ for (
877
+ material_value_bind_collection_item_op
878
+ ) in material_value_collection_item_ops:
879
+ material_value_bind_collection_item_op.material_value_index = (
880
+ material_value_index
881
+ )
882
+
883
+ if isinstance(material_value, Vrm0MaterialValueBindPropertyGroup):
884
+ _draw_vrm0_material_value_layout(
885
+ armature,
886
+ context,
887
+ material_value_binds_box,
888
+ material_value,
889
+ blend_shape_group_index=blend_shape_group_index,
890
+ material_value_index=material_value_index,
891
+ )
892
+
893
+
894
+ class VRM_PT_vrm0_blend_shape_master_armature_object_property(Panel):
895
+ bl_idname = "VRM_PT_vrm0_blend_shape_master_armature_object_property"
896
+ bl_label = "VRM 0.x Blend Shape Proxy"
897
+ bl_space_type = "PROPERTIES"
898
+ bl_region_type = "WINDOW"
899
+ bl_context = "object"
900
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
901
+ bl_parent_id = VRM_PT_vrm_armature_object_property.bl_idname
902
+
903
+ @classmethod
904
+ def poll(cls, context: Context) -> bool:
905
+ return active_object_is_vrm0_armature(context)
906
+
907
+ def draw_header(self, _context: Context) -> None:
908
+ self.layout.label(icon="SHAPEKEY_DATA")
909
+
910
+ def draw(self, context: Context) -> None:
911
+ active_object = context.active_object
912
+ if not active_object:
913
+ return
914
+ armature_data = active_object.data
915
+ if not isinstance(armature_data, Armature):
916
+ return
917
+ ext = get_armature_extension(armature_data)
918
+ _draw_vrm0_blend_shape_master_layout(
919
+ active_object, context, self.layout, ext.vrm0.blend_shape_master
920
+ )
921
+
922
+
923
+ class VRM_PT_vrm0_blend_shape_master_ui(Panel):
924
+ bl_idname = "VRM_PT_vrm0_blend_shape_master_ui"
925
+ bl_label = "VRM 0.x Blend Shape Proxy"
926
+ bl_space_type = "VIEW_3D"
927
+ bl_region_type = "UI"
928
+ bl_category = "VRM"
929
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
930
+
931
+ @classmethod
932
+ def poll(cls, context: Context) -> bool:
933
+ return search.current_armature_is_vrm0(context)
934
+
935
+ def draw_header(self, _context: Context) -> None:
936
+ self.layout.label(icon="SHAPEKEY_DATA")
937
+
938
+ def draw(self, context: Context) -> None:
939
+ armature = search.current_armature(context)
940
+ if not armature:
941
+ return
942
+ armature_data = armature.data
943
+ if not isinstance(armature_data, Armature):
944
+ return
945
+ _draw_vrm0_blend_shape_master_layout(
946
+ armature,
947
+ context,
948
+ self.layout,
949
+ get_armature_extension(armature_data).vrm0.blend_shape_master,
950
+ )
951
+
952
+
953
+ def _draw_vrm0_secondary_animation_layout(
954
+ armature: Object,
955
+ layout: UILayout,
956
+ secondary_animation: Vrm0SecondaryAnimationPropertyGroup,
957
+ ) -> None:
958
+ defer_migrate(armature.name, heavy_migration=False)
959
+ _draw_vrm0_secondary_animation_bone_groups_layout(
960
+ armature, layout, secondary_animation
961
+ )
962
+ _draw_vrm0_secondary_animation_collider_groups_layout(
963
+ armature, layout, secondary_animation
964
+ )
965
+
966
+
967
+ def _draw_vrm0_secondary_animation_bone_groups_layout(
968
+ armature: Object,
969
+ layout: UILayout,
970
+ secondary_animation: Vrm0SecondaryAnimationPropertyGroup,
971
+ ) -> None:
972
+ data = armature.data
973
+ if not isinstance(data, Armature):
974
+ return
975
+
976
+ header_row = layout.row()
977
+ header_row.alignment = "LEFT"
978
+ header_row.prop(
979
+ secondary_animation,
980
+ "show_expanded_bone_groups",
981
+ icon="TRIA_DOWN"
982
+ if secondary_animation.show_expanded_bone_groups
983
+ else "TRIA_RIGHT",
984
+ emboss=False,
985
+ )
986
+ if not secondary_animation.show_expanded_bone_groups:
987
+ return
988
+
989
+ box = layout.box()
990
+
991
+ (
992
+ bone_group_collection_ops,
993
+ bone_group_collection_item_ops,
994
+ bone_group_index,
995
+ bone_group,
996
+ _,
997
+ ) = draw_template_list(
998
+ box,
999
+ VRM_UL_vrm0_secondary_animation_group,
1000
+ secondary_animation,
1001
+ "bone_groups",
1002
+ "active_bone_group_index",
1003
+ vrm0_ops.VRM_OT_add_vrm0_secondary_animation_group,
1004
+ vrm0_ops.VRM_OT_remove_vrm0_secondary_animation_group,
1005
+ vrm0_ops.VRM_OT_move_up_vrm0_secondary_animation_group,
1006
+ vrm0_ops.VRM_OT_move_down_vrm0_secondary_animation_group,
1007
+ )
1008
+
1009
+ for bone_group_collection_op in bone_group_collection_ops:
1010
+ bone_group_collection_op.armature_object_name = armature.name
1011
+
1012
+ for bone_group_collection_item_op in bone_group_collection_item_ops:
1013
+ bone_group_collection_item_op.bone_group_index = bone_group_index
1014
+
1015
+ if not isinstance(bone_group, Vrm0SecondaryAnimationGroupPropertyGroup):
1016
+ return
1017
+
1018
+ column = box.column()
1019
+ column.prop(bone_group, "comment", icon="BOOKMARKS")
1020
+ column.prop(bone_group, "stiffiness", icon="RIGID_BODY_CONSTRAINT")
1021
+ column.prop(bone_group, "drag_force", icon="FORCE_DRAG")
1022
+ column.separator()
1023
+ column.prop(bone_group, "gravity_power", icon="OUTLINER_OB_FORCE_FIELD")
1024
+ column.prop(bone_group, "gravity_dir", icon="OUTLINER_OB_FORCE_FIELD")
1025
+ column.separator()
1026
+ VRM_MT_bone_assignment.draw_input_layout(
1027
+ column,
1028
+ bone_group.center,
1029
+ icon="PIVOT_MEDIAN",
1030
+ text="Center Bone",
1031
+ simple=True,
1032
+ )
1033
+ column.prop(
1034
+ bone_group,
1035
+ "hit_radius",
1036
+ icon="MOD_PHYSICS",
1037
+ )
1038
+ column.separator()
1039
+
1040
+ column.label(text="Bones:")
1041
+
1042
+ (
1043
+ bone_collection_ops,
1044
+ bone_collection_item_ops,
1045
+ bone_index,
1046
+ _bone,
1047
+ _,
1048
+ ) = draw_template_list(
1049
+ column,
1050
+ VRM_UL_vrm0_secondary_animation_group_bone,
1051
+ bone_group,
1052
+ "bones",
1053
+ "active_bone_index",
1054
+ vrm0_ops.VRM_OT_add_vrm0_secondary_animation_group_bone,
1055
+ vrm0_ops.VRM_OT_remove_vrm0_secondary_animation_group_bone,
1056
+ vrm0_ops.VRM_OT_move_up_vrm0_secondary_animation_group_bone,
1057
+ vrm0_ops.VRM_OT_move_down_vrm0_secondary_animation_group_bone,
1058
+ )
1059
+
1060
+ for bone_collection_op in bone_collection_ops:
1061
+ bone_collection_op.armature_object_name = armature.name
1062
+ bone_collection_op.bone_group_index = bone_group_index
1063
+
1064
+ for bone_collection_item_op in bone_collection_item_ops:
1065
+ bone_collection_item_op.bone_index = bone_index
1066
+
1067
+ column.separator()
1068
+ column.label(text="Collider Groups:")
1069
+
1070
+ (
1071
+ collider_group_collection_ops,
1072
+ collider_group_collection_item_ops,
1073
+ collider_group_index,
1074
+ _collider_group,
1075
+ _,
1076
+ ) = draw_template_list(
1077
+ column,
1078
+ VRM_UL_vrm0_secondary_animation_group_collider_group,
1079
+ bone_group,
1080
+ "collider_groups",
1081
+ "active_collider_group_index",
1082
+ vrm0_ops.VRM_OT_add_vrm0_secondary_animation_group_collider_group,
1083
+ vrm0_ops.VRM_OT_remove_vrm0_secondary_animation_group_collider_group,
1084
+ vrm0_ops.VRM_OT_move_up_vrm0_secondary_animation_group_collider_group,
1085
+ vrm0_ops.VRM_OT_move_down_vrm0_secondary_animation_group_collider_group,
1086
+ )
1087
+
1088
+ for collider_group_collection_op in collider_group_collection_ops:
1089
+ collider_group_collection_op.armature_object_name = armature.name
1090
+ collider_group_collection_op.bone_group_index = bone_group_index
1091
+
1092
+ for collider_group_collection_item_op in collider_group_collection_item_ops:
1093
+ collider_group_collection_item_op.collider_group_index = collider_group_index
1094
+
1095
+
1096
+ def _draw_vrm0_secondary_animation_collider_groups_layout(
1097
+ armature: Object,
1098
+ layout: UILayout,
1099
+ secondary_animation: Vrm0SecondaryAnimationPropertyGroup,
1100
+ ) -> None:
1101
+ data = armature.data
1102
+ if not isinstance(data, Armature):
1103
+ return
1104
+
1105
+ header_row = layout.row()
1106
+ header_row.alignment = "LEFT"
1107
+ header_row.prop(
1108
+ secondary_animation,
1109
+ "show_expanded_collider_groups",
1110
+ icon="TRIA_DOWN"
1111
+ if secondary_animation.show_expanded_collider_groups
1112
+ else "TRIA_RIGHT",
1113
+ emboss=False,
1114
+ )
1115
+ if not secondary_animation.show_expanded_collider_groups:
1116
+ return
1117
+
1118
+ box = layout.box()
1119
+
1120
+ (
1121
+ collider_group_collection_ops,
1122
+ collider_group_collection_item_ops,
1123
+ collider_group_index,
1124
+ collider_group,
1125
+ _,
1126
+ ) = draw_template_list(
1127
+ box,
1128
+ VRM_UL_vrm0_secondary_animation_collider_group,
1129
+ secondary_animation,
1130
+ "collider_groups",
1131
+ "active_collider_group_index",
1132
+ vrm0_ops.VRM_OT_add_vrm0_secondary_animation_collider_group,
1133
+ vrm0_ops.VRM_OT_remove_vrm0_secondary_animation_collider_group,
1134
+ vrm0_ops.VRM_OT_move_up_vrm0_secondary_animation_collider_group,
1135
+ vrm0_ops.VRM_OT_move_down_vrm0_secondary_animation_collider_group,
1136
+ )
1137
+
1138
+ for collider_group_collection_op in collider_group_collection_ops:
1139
+ collider_group_collection_op.armature_object_name = armature.name
1140
+
1141
+ for collider_group_collection_item_op in collider_group_collection_item_ops:
1142
+ collider_group_collection_item_op.collider_group_index = collider_group_index
1143
+
1144
+ if not isinstance(collider_group, Vrm0SecondaryAnimationColliderGroupPropertyGroup):
1145
+ return
1146
+
1147
+ column = box.column()
1148
+ column.label(text=collider_group.display_name)
1149
+ VRM_MT_bone_assignment.draw_input_layout(
1150
+ column,
1151
+ collider_group.node,
1152
+ simple=True,
1153
+ )
1154
+ column.label(text="Colliders:")
1155
+
1156
+ (
1157
+ collider_collection_ops,
1158
+ collider_collection_item_ops,
1159
+ collider_index,
1160
+ _,
1161
+ _,
1162
+ ) = draw_template_list(
1163
+ column,
1164
+ VRM_UL_vrm0_secondary_animation_collider_group_collider,
1165
+ collider_group,
1166
+ "colliders",
1167
+ "active_collider_index",
1168
+ vrm0_ops.VRM_OT_add_vrm0_secondary_animation_collider_group_collider,
1169
+ vrm0_ops.VRM_OT_remove_vrm0_secondary_animation_collider_group_collider,
1170
+ vrm0_ops.VRM_OT_move_up_vrm0_secondary_animation_collider_group_collider,
1171
+ vrm0_ops.VRM_OT_move_down_vrm0_secondary_animation_collider_group_collider,
1172
+ )
1173
+
1174
+ for collider_collection_op in collider_collection_ops:
1175
+ collider_collection_op.armature_object_name = armature.name
1176
+ collider_collection_op.collider_group_index = collider_group_index
1177
+
1178
+ for collider_collection_item_op in collider_collection_item_ops:
1179
+ collider_collection_item_op.armature_object_name = armature.name
1180
+ collider_collection_item_op.collider_group_index = collider_group_index
1181
+ collider_collection_item_op.collider_index = collider_index
1182
+
1183
+
1184
+ class VRM_PT_vrm0_secondary_animation_armature_object_property(Panel):
1185
+ bl_idname = "VRM_PT_vrm0_secondary_animation_armature_object_property"
1186
+ bl_label = "VRM 0.x Spring Bone"
1187
+ bl_space_type = "PROPERTIES"
1188
+ bl_region_type = "WINDOW"
1189
+ bl_context = "object"
1190
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
1191
+ bl_parent_id = VRM_PT_vrm_armature_object_property.bl_idname
1192
+
1193
+ @classmethod
1194
+ def poll(cls, context: Context) -> bool:
1195
+ return active_object_is_vrm0_armature(context)
1196
+
1197
+ def draw_header(self, _context: Context) -> None:
1198
+ self.layout.label(icon="PHYSICS")
1199
+
1200
+ def draw(self, context: Context) -> None:
1201
+ active_object = context.active_object
1202
+ if not active_object:
1203
+ return
1204
+ armature_data = active_object.data
1205
+ if not isinstance(armature_data, Armature):
1206
+ return
1207
+ ext = get_armature_extension(armature_data)
1208
+ _draw_vrm0_secondary_animation_layout(
1209
+ active_object, self.layout, ext.vrm0.secondary_animation
1210
+ )
1211
+
1212
+
1213
+ class VRM_PT_vrm0_secondary_animation_ui(Panel):
1214
+ bl_idname = "VRM_PT_vrm0_secondary_animation_ui"
1215
+ bl_label = "VRM 0.x Spring Bone"
1216
+ bl_space_type = "VIEW_3D"
1217
+ bl_region_type = "UI"
1218
+ bl_category = "VRM"
1219
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
1220
+
1221
+ @classmethod
1222
+ def poll(cls, context: Context) -> bool:
1223
+ return search.current_armature_is_vrm0(context)
1224
+
1225
+ def draw_header(self, _context: Context) -> None:
1226
+ self.layout.label(icon="PHYSICS")
1227
+
1228
+ def draw(self, context: Context) -> None:
1229
+ armature = search.current_armature(context)
1230
+ if not armature:
1231
+ return
1232
+ armature_data = armature.data
1233
+ if not isinstance(armature_data, Armature):
1234
+ return
1235
+ _draw_vrm0_secondary_animation_layout(
1236
+ armature,
1237
+ self.layout,
1238
+ get_armature_extension(armature_data).vrm0.secondary_animation,
1239
+ )
1240
+
1241
+
1242
+ def _draw_vrm0_meta_layout(
1243
+ armature: Object,
1244
+ _context: Context,
1245
+ layout: UILayout,
1246
+ meta: Vrm0MetaPropertyGroup,
1247
+ ) -> None:
1248
+ defer_migrate(armature.name, heavy_migration=False)
1249
+
1250
+ thumbnail_column = layout.column()
1251
+ thumbnail_column.label(text="Thumbnail:")
1252
+ thumbnail_column.template_ID_preview(meta, "texture")
1253
+
1254
+ layout.prop(meta, "title", icon="FILE_BLEND")
1255
+ layout.prop(meta, "version", icon="LINENUMBERS_ON")
1256
+ layout.prop(meta, "author", icon="USER")
1257
+ layout.prop(meta, "contact_information", icon="URL")
1258
+ layout.prop(meta, "reference", icon="URL")
1259
+ layout.prop(meta, "allowed_user_name", icon="MATCLOTH")
1260
+ layout.prop(
1261
+ meta,
1262
+ "violent_ussage_name",
1263
+ icon="ORPHAN_DATA",
1264
+ )
1265
+ layout.prop(meta, "sexual_ussage_name", icon="HEART")
1266
+ layout.prop(
1267
+ meta,
1268
+ "commercial_ussage_name",
1269
+ icon="SOLO_OFF",
1270
+ )
1271
+ layout.prop(meta, "other_permission_url", icon="URL")
1272
+ draw_url_warning(layout, meta.other_permission_url)
1273
+ layout.prop(meta, "license_name", icon="COMMUNITY")
1274
+ if meta.license_name == Vrm0MetaPropertyGroup.LICENSE_NAME_OTHER.identifier:
1275
+ layout.prop(meta, "other_license_url", icon="URL")
1276
+ draw_url_warning(layout, meta.other_license_url)
1277
+
1278
+
1279
+ class VRM_PT_vrm0_meta_armature_object_property(Panel):
1280
+ bl_idname = "VRM_PT_vrm0_meta_armature_object_property"
1281
+ bl_label = "VRM 0.x Meta"
1282
+ bl_space_type = "PROPERTIES"
1283
+ bl_region_type = "WINDOW"
1284
+ bl_context = "object"
1285
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
1286
+ bl_parent_id = VRM_PT_vrm_armature_object_property.bl_idname
1287
+
1288
+ @classmethod
1289
+ def poll(cls, context: Context) -> bool:
1290
+ return active_object_is_vrm0_armature(context)
1291
+
1292
+ def draw_header(self, _context: Context) -> None:
1293
+ self.layout.label(icon="FILE_BLEND")
1294
+
1295
+ def draw(self, context: Context) -> None:
1296
+ active_object = context.active_object
1297
+ if not active_object:
1298
+ return
1299
+ armature_data = active_object.data
1300
+ if not isinstance(armature_data, Armature):
1301
+ return
1302
+ ext = get_armature_extension(armature_data)
1303
+ _draw_vrm0_meta_layout(active_object, context, self.layout, ext.vrm0.meta)
1304
+
1305
+
1306
+ class VRM_PT_vrm0_meta_ui(Panel):
1307
+ bl_idname = "VRM_PT_vrm0_meta_ui"
1308
+ bl_label = "VRM 0.x Meta"
1309
+ bl_space_type = "VIEW_3D"
1310
+ bl_region_type = "UI"
1311
+ bl_category = "VRM"
1312
+ bl_options: ClassVar = {"DEFAULT_CLOSED"}
1313
+
1314
+ @classmethod
1315
+ def poll(cls, context: Context) -> bool:
1316
+ return search.current_armature_is_vrm0(context)
1317
+
1318
+ def draw_header(self, _context: Context) -> None:
1319
+ self.layout.label(icon="FILE_BLEND")
1320
+
1321
+ def draw(self, context: Context) -> None:
1322
+ armature = search.current_armature(context)
1323
+ if not armature:
1324
+ return
1325
+ armature_data = armature.data
1326
+ if not isinstance(armature_data, Armature):
1327
+ return
1328
+ _draw_vrm0_meta_layout(
1329
+ armature,
1330
+ context,
1331
+ self.layout,
1332
+ get_armature_extension(armature_data).vrm0.meta,
1333
+ )