@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,688 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from bpy.types import Armature, Context, Mesh, UILayout, UIList
3
+
4
+ from ...common import convert
5
+ from ...common.logger import get_logger
6
+ from ..menu import VRM_MT_bone_assignment
7
+ from ..property_group import BonePropertyGroup
8
+ from .menu import VRM_MT_vrm0_secondary_animation_group_collider_group
9
+ from .property_group import (
10
+ Vrm0BlendShapeBindPropertyGroup,
11
+ Vrm0BlendShapeGroupPropertyGroup,
12
+ Vrm0FirstPersonPropertyGroup,
13
+ Vrm0MaterialValueBindPropertyGroup,
14
+ Vrm0MeshAnnotationPropertyGroup,
15
+ Vrm0SecondaryAnimationColliderGroupPropertyGroup,
16
+ Vrm0SecondaryAnimationColliderGroupReferencePropertyGroup,
17
+ Vrm0SecondaryAnimationColliderPropertyGroup,
18
+ Vrm0SecondaryAnimationGroupPropertyGroup,
19
+ )
20
+
21
+ _logger = get_logger(__name__)
22
+
23
+
24
+ class VRM_UL_vrm0_first_person_mesh_annotation(UIList):
25
+ bl_idname = "VRM_UL_vrm0_first_person_mesh_annotation"
26
+
27
+ def filter_items(
28
+ self,
29
+ _context: Context,
30
+ data: object,
31
+ propname: str,
32
+ ) -> tuple[list[int], list[int]]:
33
+ items = convert.sequence_or_none(getattr(data, propname, None))
34
+ if items is None:
35
+ return ([], [])
36
+
37
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
38
+ flt_neworder: list[int] = []
39
+
40
+ filter_name: str = self.filter_name.casefold()
41
+ if not filter_name:
42
+ return (flt_flags, flt_neworder)
43
+
44
+ for index, item in enumerate(items):
45
+ if (
46
+ isinstance(item, Vrm0MeshAnnotationPropertyGroup)
47
+ and filter_name in item.mesh.mesh_object_name.casefold()
48
+ ):
49
+ continue
50
+ flt_flags[index] = 0
51
+
52
+ return (flt_flags, flt_neworder)
53
+
54
+ def draw_item(
55
+ self,
56
+ _context: Context,
57
+ layout: UILayout,
58
+ first_person: object,
59
+ mesh_annotation: object,
60
+ _icon: int,
61
+ _active_data: object,
62
+ _active_prop_name: str,
63
+ index: int,
64
+ _flt_flag: int,
65
+ ) -> None:
66
+ if not isinstance(first_person, Vrm0FirstPersonPropertyGroup):
67
+ return
68
+ if not isinstance(mesh_annotation, Vrm0MeshAnnotationPropertyGroup):
69
+ return
70
+
71
+ icon = "OUTLINER_OB_MESH"
72
+
73
+ if self.layout_type == "GRID":
74
+ layout.alignment = "CENTER"
75
+ layout.label(text="", translate=False, icon=icon)
76
+ return
77
+
78
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
79
+ return
80
+
81
+ row = layout.split(factor=0.6, align=True)
82
+ if index == first_person.active_mesh_annotation_index:
83
+ row.prop(
84
+ mesh_annotation.mesh,
85
+ "bpy_object",
86
+ icon=icon,
87
+ text="",
88
+ translate=False,
89
+ )
90
+ else:
91
+ row.label(
92
+ text=mesh_annotation.mesh.mesh_object_name,
93
+ translate=False,
94
+ icon=icon,
95
+ )
96
+ row.prop(mesh_annotation, "first_person_flag", text="", translate=False)
97
+
98
+
99
+ class VRM_UL_vrm0_secondary_animation_group(UIList):
100
+ bl_idname = "VRM_UL_vrm0_secondary_animation_group"
101
+
102
+ def format_label_text(
103
+ self, bone_group: Vrm0SecondaryAnimationGroupPropertyGroup
104
+ ) -> str:
105
+ text = ""
106
+ if bone_group.bones:
107
+ text = (
108
+ "(" + ", ".join(str(bone.bone_name) for bone in bone_group.bones) + ")"
109
+ )
110
+
111
+ if bone_group.center.bone_name:
112
+ if text:
113
+ text = " - " + text
114
+ text = bone_group.center.bone_name + text
115
+
116
+ if bone_group.comment:
117
+ if text:
118
+ text = " / " + text
119
+ text = bone_group.comment + text
120
+
121
+ return text
122
+
123
+ def filter_items(
124
+ self,
125
+ _context: Context,
126
+ data: object,
127
+ propname: str,
128
+ ) -> tuple[list[int], list[int]]:
129
+ items = convert.sequence_or_none(getattr(data, propname, None))
130
+ if items is None:
131
+ return ([], [])
132
+
133
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
134
+ flt_neworder: list[int] = []
135
+
136
+ filter_name: str = self.filter_name.casefold()
137
+ if not filter_name:
138
+ return (flt_flags, flt_neworder)
139
+
140
+ for index, item in enumerate(items):
141
+ if (
142
+ isinstance(item, Vrm0SecondaryAnimationGroupPropertyGroup)
143
+ and filter_name in self.format_label_text(item).casefold()
144
+ ):
145
+ continue
146
+ flt_flags[index] = 0
147
+
148
+ return (flt_flags, flt_neworder)
149
+
150
+ def draw_item(
151
+ self,
152
+ _context: Context,
153
+ layout: UILayout,
154
+ _data: object,
155
+ bone_group: object,
156
+ _icon: int,
157
+ _active_data: object,
158
+ _active_prop_name: str,
159
+ _index: int,
160
+ _flt_flag: int,
161
+ ) -> None:
162
+ if not isinstance(bone_group, Vrm0SecondaryAnimationGroupPropertyGroup):
163
+ return
164
+
165
+ icon = "BONE_DATA"
166
+
167
+ if self.layout_type == "GRID":
168
+ layout.alignment = "CENTER"
169
+ layout.label(text="", translate=False, icon=icon)
170
+ return
171
+
172
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
173
+ return
174
+
175
+ layout.label(
176
+ text=self.format_label_text(bone_group) or "(EMPTY)",
177
+ translate=False,
178
+ icon=icon,
179
+ )
180
+
181
+
182
+ class VRM_UL_vrm0_secondary_animation_group_bone(UIList):
183
+ bl_idname = "VRM_UL_vrm0_secondary_animation_group_bone"
184
+
185
+ def filter_items(
186
+ self,
187
+ _context: Context,
188
+ data: object,
189
+ propname: str,
190
+ ) -> tuple[list[int], list[int]]:
191
+ items = convert.sequence_or_none(getattr(data, propname, None))
192
+ if items is None:
193
+ return ([], [])
194
+
195
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
196
+ flt_neworder: list[int] = []
197
+
198
+ filter_name: str = self.filter_name.casefold()
199
+ if not filter_name:
200
+ return (flt_flags, flt_neworder)
201
+
202
+ for index, item in enumerate(items):
203
+ if (
204
+ isinstance(item, BonePropertyGroup)
205
+ and filter_name in item.bone_name.casefold()
206
+ ):
207
+ continue
208
+ flt_flags[index] = 0
209
+
210
+ return (flt_flags, flt_neworder)
211
+
212
+ def draw_item(
213
+ self,
214
+ _context: Context,
215
+ layout: UILayout,
216
+ bone_group: object,
217
+ bone: object,
218
+ _icon: int,
219
+ _active_data: object,
220
+ _active_prop_name: str,
221
+ index: int,
222
+ _flt_flag: int,
223
+ ) -> None:
224
+ if not isinstance(bone_group, Vrm0SecondaryAnimationGroupPropertyGroup):
225
+ return
226
+ if not isinstance(bone, BonePropertyGroup):
227
+ return
228
+
229
+ icon = "BONE_DATA"
230
+
231
+ if self.layout_type == "GRID":
232
+ layout.alignment = "CENTER"
233
+ layout.label(text="", translate=False, icon=icon)
234
+ return
235
+
236
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
237
+ return
238
+
239
+ if index == bone_group.active_bone_index:
240
+ VRM_MT_bone_assignment.draw_input_layout(
241
+ layout,
242
+ bone,
243
+ icon=icon,
244
+ simple=True,
245
+ )
246
+ else:
247
+ layout.label(text=bone.bone_name, translate=False, icon=icon)
248
+
249
+
250
+ class VRM_UL_vrm0_secondary_animation_group_collider_group(UIList):
251
+ bl_idname = "VRM_UL_vrm0_secondary_animation_group_collider_group"
252
+
253
+ def filter_items(
254
+ self,
255
+ _context: Context,
256
+ data: object,
257
+ propname: str,
258
+ ) -> tuple[list[int], list[int]]:
259
+ items = convert.sequence_or_none(getattr(data, propname, None))
260
+ if items is None:
261
+ return ([], [])
262
+
263
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
264
+ flt_neworder: list[int] = []
265
+
266
+ filter_name: str = self.filter_name.casefold()
267
+ if not filter_name:
268
+ return (flt_flags, flt_neworder)
269
+
270
+ for index, item in enumerate(items):
271
+ if (
272
+ isinstance(
273
+ item, Vrm0SecondaryAnimationColliderGroupReferencePropertyGroup
274
+ )
275
+ and filter_name in item.collider_group_display_name.casefold()
276
+ ):
277
+ continue
278
+ flt_flags[index] = 0
279
+
280
+ return (flt_flags, flt_neworder)
281
+
282
+ def draw_item(
283
+ self,
284
+ _context: Context,
285
+ layout: UILayout,
286
+ bone_group: object,
287
+ collider_group: object,
288
+ _icon: int,
289
+ _active_data: object,
290
+ _active_prop_name: str,
291
+ index: int,
292
+ _flt_flag: int,
293
+ ) -> None:
294
+ if not isinstance(bone_group, Vrm0SecondaryAnimationGroupPropertyGroup):
295
+ return
296
+ if not isinstance(
297
+ collider_group, Vrm0SecondaryAnimationColliderGroupReferencePropertyGroup
298
+ ):
299
+ return
300
+
301
+ armature_data = bone_group.id_data
302
+ if not isinstance(armature_data, Armature):
303
+ _logger.error("Failed to find armature")
304
+ return
305
+
306
+ icon = "PIVOT_INDIVIDUAL"
307
+
308
+ if self.layout_type == "GRID":
309
+ layout.alignment = "CENTER"
310
+ layout.label(text="", translate=False, icon=icon)
311
+ return
312
+
313
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
314
+ return
315
+
316
+ if index == bone_group.active_collider_group_index:
317
+ VRM_MT_vrm0_secondary_animation_group_collider_group.draw_input_layout(
318
+ layout,
319
+ bone_group,
320
+ collider_group,
321
+ icon=icon,
322
+ )
323
+ else:
324
+ layout.label(
325
+ text=collider_group.collider_group_display_name,
326
+ translate=False,
327
+ icon=icon,
328
+ )
329
+
330
+
331
+ class VRM_UL_vrm0_secondary_animation_collider_group(UIList):
332
+ bl_idname = "VRM_UL_vrm0_secondary_animation_collider_group"
333
+
334
+ def filter_items(
335
+ self,
336
+ _context: Context,
337
+ data: object,
338
+ propname: str,
339
+ ) -> tuple[list[int], list[int]]:
340
+ items = convert.sequence_or_none(getattr(data, propname, None))
341
+ if items is None:
342
+ return ([], [])
343
+
344
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
345
+ flt_neworder: list[int] = []
346
+
347
+ filter_name: str = self.filter_name.casefold()
348
+ if not filter_name:
349
+ return (flt_flags, flt_neworder)
350
+
351
+ for index, item in enumerate(items):
352
+ if (
353
+ isinstance(item, Vrm0SecondaryAnimationColliderGroupPropertyGroup)
354
+ and filter_name in item.display_name.casefold()
355
+ ):
356
+ continue
357
+ flt_flags[index] = 0
358
+
359
+ return (flt_flags, flt_neworder)
360
+
361
+ def draw_item(
362
+ self,
363
+ _context: Context,
364
+ layout: UILayout,
365
+ _data: object,
366
+ collider_group: object,
367
+ _icon: int,
368
+ _active_data: object,
369
+ _active_prop_name: str,
370
+ _index: int,
371
+ _flt_flag: int,
372
+ ) -> None:
373
+ if not isinstance(
374
+ collider_group, Vrm0SecondaryAnimationColliderGroupPropertyGroup
375
+ ):
376
+ return
377
+
378
+ icon = "SPHERE"
379
+
380
+ if self.layout_type == "GRID":
381
+ layout.alignment = "CENTER"
382
+ layout.label(text="", translate=False, icon=icon)
383
+ return
384
+
385
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
386
+ return
387
+
388
+ layout.label(text=collider_group.display_name, translate=False, icon=icon)
389
+
390
+
391
+ class VRM_UL_vrm0_secondary_animation_collider_group_collider(UIList):
392
+ bl_idname = "VRM_UL_vrm0_secondary_animation_collider_group_collider"
393
+
394
+ def filter_items(
395
+ self,
396
+ _context: Context,
397
+ data: object,
398
+ propname: str,
399
+ ) -> tuple[list[int], list[int]]:
400
+ items = convert.sequence_or_none(getattr(data, propname, None))
401
+ if items is None:
402
+ return ([], [])
403
+
404
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
405
+ flt_neworder: list[int] = []
406
+
407
+ filter_name: str = self.filter_name.casefold()
408
+ if not filter_name:
409
+ return (flt_flags, flt_neworder)
410
+
411
+ for index, item in enumerate(items):
412
+ if (
413
+ isinstance(item, Vrm0SecondaryAnimationColliderPropertyGroup)
414
+ and (bpy_object := item.bpy_object)
415
+ and filter_name in bpy_object.name.casefold()
416
+ ):
417
+ continue
418
+ flt_flags[index] = 0
419
+
420
+ return (flt_flags, flt_neworder)
421
+
422
+ def draw_item(
423
+ self,
424
+ _context: Context,
425
+ layout: UILayout,
426
+ collider_group: object,
427
+ collider: object,
428
+ _icon: int,
429
+ _active_data: object,
430
+ _active_prop_name: str,
431
+ index: int,
432
+ _flt_flag: int,
433
+ ) -> None:
434
+ if not isinstance(
435
+ collider_group, Vrm0SecondaryAnimationColliderGroupPropertyGroup
436
+ ):
437
+ return
438
+ if not isinstance(collider, Vrm0SecondaryAnimationColliderPropertyGroup):
439
+ return
440
+
441
+ icon = "MESH_UVSPHERE"
442
+
443
+ if self.layout_type == "GRID":
444
+ layout.alignment = "CENTER"
445
+ layout.label(text="", translate=False, icon=icon)
446
+ return
447
+
448
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
449
+ return
450
+
451
+ bpy_object = collider.bpy_object
452
+ if bpy_object is None:
453
+ return
454
+
455
+ row = layout.split(align=True, factor=0.7)
456
+ if index == collider_group.active_collider_index:
457
+ row.prop(
458
+ bpy_object,
459
+ "name",
460
+ icon=icon,
461
+ translate=False,
462
+ text="",
463
+ )
464
+ row.prop(bpy_object, "empty_display_size", text="")
465
+ else:
466
+ row.label(text=bpy_object.name, icon=icon, translate=False)
467
+ row.prop(bpy_object, "empty_display_size", text="", emboss=False)
468
+
469
+
470
+ class VRM_UL_vrm0_blend_shape_group(UIList):
471
+ bl_idname = "VRM_UL_vrm0_blend_shape_group"
472
+
473
+ def filter_items(
474
+ self,
475
+ _context: Context,
476
+ data: object,
477
+ propname: str,
478
+ ) -> tuple[list[int], list[int]]:
479
+ items = convert.sequence_or_none(getattr(data, propname, None))
480
+ if items is None:
481
+ return ([], [])
482
+
483
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
484
+ flt_neworder: list[int] = []
485
+
486
+ filter_name: str = self.filter_name.casefold()
487
+ if not filter_name:
488
+ return (flt_flags, flt_neworder)
489
+
490
+ for index, item in enumerate(items):
491
+ if (
492
+ isinstance(item, Vrm0BlendShapeGroupPropertyGroup)
493
+ and filter_name in item.name.casefold()
494
+ ):
495
+ continue
496
+ flt_flags[index] = 0
497
+
498
+ return (flt_flags, flt_neworder)
499
+
500
+ def draw_item(
501
+ self,
502
+ _context: Context,
503
+ layout: UILayout,
504
+ _data: object,
505
+ item: object,
506
+ _icon: int,
507
+ _active_data: object,
508
+ _active_prop_name: str,
509
+ _index: int,
510
+ _flt_flag: int,
511
+ ) -> None:
512
+ blend_shape_group = item
513
+ if not isinstance(blend_shape_group, Vrm0BlendShapeGroupPropertyGroup):
514
+ return
515
+
516
+ preset = next(
517
+ (
518
+ preset
519
+ for preset in blend_shape_group.preset_name_enum
520
+ if preset.identifier == blend_shape_group.preset_name
521
+ ),
522
+ None,
523
+ )
524
+ if not preset:
525
+ return
526
+
527
+ if self.layout_type == "GRID":
528
+ layout.alignment = "CENTER"
529
+ layout.label(text="", translate=False, icon=preset.icon)
530
+ return
531
+
532
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
533
+ return
534
+
535
+ text = blend_shape_group.name + " / " + preset.name
536
+ split = layout.split(align=True, factor=0.55)
537
+ split.label(text=text, translate=False, icon=preset.icon)
538
+ split.prop(blend_shape_group, "preview", text="Preview")
539
+
540
+
541
+ class VRM_UL_vrm0_blend_shape_bind(UIList):
542
+ bl_idname = "VRM_UL_vrm0_blend_shape_bind"
543
+
544
+ def format_label_text(
545
+ self, context: Context, blend_shape_bind: Vrm0BlendShapeBindPropertyGroup
546
+ ) -> str:
547
+ text = blend_shape_bind.mesh.mesh_object_name
548
+ mesh_object = context.blend_data.objects.get(
549
+ blend_shape_bind.mesh.mesh_object_name
550
+ )
551
+ if mesh_object:
552
+ mesh_data = mesh_object.data
553
+ if isinstance(mesh_data, Mesh):
554
+ shape_keys = mesh_data.shape_keys
555
+ if shape_keys:
556
+ keys = shape_keys.key_blocks.keys()
557
+ if blend_shape_bind.index in keys:
558
+ text += " / " + blend_shape_bind.index
559
+ return text
560
+
561
+ def filter_items(
562
+ self,
563
+ context: Context,
564
+ data: object,
565
+ propname: str,
566
+ ) -> tuple[list[int], list[int]]:
567
+ items = convert.sequence_or_none(getattr(data, propname, None))
568
+ if items is None:
569
+ return ([], [])
570
+
571
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
572
+ flt_neworder: list[int] = []
573
+
574
+ filter_name: str = self.filter_name.casefold()
575
+ if not filter_name:
576
+ return (flt_flags, flt_neworder)
577
+
578
+ for index, item in enumerate(items):
579
+ if (
580
+ isinstance(item, Vrm0BlendShapeBindPropertyGroup)
581
+ and filter_name in self.format_label_text(context, item).casefold()
582
+ ):
583
+ continue
584
+ flt_flags[index] = 0
585
+
586
+ return (flt_flags, flt_neworder)
587
+
588
+ def draw_item(
589
+ self,
590
+ context: Context,
591
+ layout: UILayout,
592
+ _data: object,
593
+ item: object,
594
+ icon: int,
595
+ _active_data: object,
596
+ _active_prop_name: str,
597
+ _index: int,
598
+ _flt_flag: int,
599
+ ) -> None:
600
+ blend_shape_bind = item
601
+ if not isinstance(blend_shape_bind, Vrm0BlendShapeBindPropertyGroup):
602
+ return
603
+
604
+ if self.layout_type == "GRID":
605
+ layout.alignment = "CENTER"
606
+ layout.label(text="", translate=False, icon_value=icon)
607
+ return
608
+
609
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
610
+ return
611
+
612
+ layout.label(
613
+ text=self.format_label_text(context, blend_shape_bind),
614
+ translate=False,
615
+ icon="MESH_DATA",
616
+ )
617
+
618
+
619
+ class VRM_UL_vrm0_material_value_bind(UIList):
620
+ bl_idname = "VRM_UL_vrm0_material_value_bind"
621
+
622
+ def format_label_text(
623
+ self, material_value_bind: Vrm0MaterialValueBindPropertyGroup
624
+ ) -> str:
625
+ text = ""
626
+ material = material_value_bind.material
627
+ if material:
628
+ text = material.name
629
+ if material_value_bind.property_name:
630
+ text += " / " + material_value_bind.property_name
631
+ return text
632
+
633
+ def filter_items(
634
+ self,
635
+ _context: Context,
636
+ data: object,
637
+ propname: str,
638
+ ) -> tuple[list[int], list[int]]:
639
+ items = convert.sequence_or_none(getattr(data, propname, None))
640
+ if items is None:
641
+ return ([], [])
642
+
643
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
644
+ flt_neworder: list[int] = []
645
+
646
+ filter_name: str = self.filter_name.casefold()
647
+ if not filter_name:
648
+ return (flt_flags, flt_neworder)
649
+
650
+ for index, item in enumerate(items):
651
+ if (
652
+ isinstance(item, Vrm0MaterialValueBindPropertyGroup)
653
+ and filter_name in self.format_label_text(item).casefold()
654
+ ):
655
+ continue
656
+ flt_flags[index] = 0
657
+
658
+ return (flt_flags, flt_neworder)
659
+
660
+ def draw_item(
661
+ self,
662
+ _context: Context,
663
+ layout: UILayout,
664
+ _data: object,
665
+ item: object,
666
+ icon: int,
667
+ _active_data: object,
668
+ _active_prop_name: str,
669
+ _index: int,
670
+ _flt_flag: int,
671
+ ) -> None:
672
+ material_value_bind = item
673
+ if not isinstance(material_value_bind, Vrm0MaterialValueBindPropertyGroup):
674
+ return
675
+
676
+ if self.layout_type == "GRID":
677
+ layout.alignment = "CENTER"
678
+ layout.label(text="", translate=False, icon_value=icon)
679
+ return
680
+
681
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
682
+ return
683
+
684
+ layout.label(
685
+ text=self.format_label_text(material_value_bind),
686
+ translate=False,
687
+ icon="MATERIAL",
688
+ )
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
@@ -0,0 +1,28 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+
3
+ import bpy
4
+ from bpy.app.handlers import persistent
5
+ from bpy.types import Depsgraph, Scene
6
+
7
+ from ...common.logger import get_logger
8
+ from ...common.scene_watcher import trigger_scene_watcher
9
+ from .property_group import Vrm1ExpressionPropertyGroup, Vrm1LookAtPropertyGroup
10
+ from .scene_watcher import LookAtPreviewUpdater
11
+
12
+ _logger = get_logger(__name__)
13
+
14
+
15
+ @persistent
16
+ def frame_change_post(_unused: object) -> None:
17
+ context = bpy.context
18
+
19
+ Vrm1ExpressionPropertyGroup.apply_pending_preview_update_to_armatures(context)
20
+ Vrm1LookAtPropertyGroup.update_all_previews(context)
21
+
22
+ # Update materials
23
+ Vrm1ExpressionPropertyGroup.update_materials(context)
24
+
25
+
26
+ @persistent
27
+ def depsgraph_update_post(_scene: Scene, _depsgraph: Depsgraph) -> None:
28
+ trigger_scene_watcher(LookAtPreviewUpdater)