@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,408 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from bpy.types import Armature, Context, UILayout, UIList
3
+
4
+ from ...common import convert
5
+ from ...common.logger import get_logger
6
+ from .menu import (
7
+ VRM_MT_spring_bone1_collider_group_collider,
8
+ VRM_MT_spring_bone1_spring_collider_group,
9
+ )
10
+ from .property_group import (
11
+ SpringBone1ColliderGroupPropertyGroup,
12
+ SpringBone1ColliderGroupReferencePropertyGroup,
13
+ SpringBone1ColliderPropertyGroup,
14
+ SpringBone1ColliderReferencePropertyGroup,
15
+ SpringBone1JointPropertyGroup,
16
+ SpringBone1SpringPropertyGroup,
17
+ )
18
+
19
+ _logger = get_logger(__name__)
20
+
21
+
22
+ class VRM_UL_spring_bone1_collider(UIList):
23
+ bl_idname = "VRM_UL_spring_bone1_collider"
24
+
25
+ def filter_items(
26
+ self,
27
+ _context: Context,
28
+ data: object,
29
+ propname: str,
30
+ ) -> tuple[list[int], list[int]]:
31
+ items = convert.sequence_or_none(getattr(data, propname, None))
32
+ if items is None:
33
+ return ([], [])
34
+
35
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
36
+ flt_neworder: list[int] = []
37
+
38
+ filter_name: str = self.filter_name.casefold()
39
+ if not filter_name:
40
+ return (flt_flags, flt_neworder)
41
+
42
+ for index, item in enumerate(items):
43
+ if (
44
+ isinstance(item, SpringBone1ColliderPropertyGroup)
45
+ and (bpy_object := item.bpy_object)
46
+ and filter_name in bpy_object.name.casefold()
47
+ ):
48
+ continue
49
+ flt_flags[index] = 0
50
+
51
+ return (flt_flags, flt_neworder)
52
+
53
+ def draw_item(
54
+ self,
55
+ _context: Context,
56
+ layout: UILayout,
57
+ _data: object,
58
+ collider: object,
59
+ _icon: int,
60
+ _active_data: object,
61
+ _active_prop_name: str,
62
+ _index: int,
63
+ _flt_flag: int,
64
+ ) -> None:
65
+ if not isinstance(collider, SpringBone1ColliderPropertyGroup):
66
+ return
67
+
68
+ icon = "SPHERE"
69
+
70
+ if self.layout_type == "GRID":
71
+ layout.alignment = "CENTER"
72
+ layout.label(text="", translate=False, icon=icon)
73
+ return
74
+
75
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
76
+ return
77
+
78
+ name = ""
79
+ bpy_object = collider.bpy_object
80
+ if bpy_object:
81
+ name = bpy_object.name
82
+ layout.label(text=name, translate=False, icon=icon)
83
+
84
+
85
+ class VRM_UL_spring_bone1_collider_group(UIList):
86
+ bl_idname = "VRM_UL_spring_bone1_collider_group"
87
+
88
+ def filter_items(
89
+ self,
90
+ _context: Context,
91
+ data: object,
92
+ propname: str,
93
+ ) -> tuple[list[int], list[int]]:
94
+ items = convert.sequence_or_none(getattr(data, propname, None))
95
+ if items is None:
96
+ return ([], [])
97
+
98
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
99
+ flt_neworder: list[int] = []
100
+
101
+ filter_name: str = self.filter_name.casefold()
102
+ if not filter_name:
103
+ return (flt_flags, flt_neworder)
104
+
105
+ for index, item in enumerate(items):
106
+ if (
107
+ isinstance(item, SpringBone1ColliderGroupPropertyGroup)
108
+ and filter_name in item.vrm_name.casefold()
109
+ ):
110
+ continue
111
+ flt_flags[index] = 0
112
+
113
+ return (flt_flags, flt_neworder)
114
+
115
+ def draw_item(
116
+ self,
117
+ _context: Context,
118
+ layout: UILayout,
119
+ _data: object,
120
+ collider_group: object,
121
+ _icon: int,
122
+ _active_data: object,
123
+ _active_prop_name: str,
124
+ _index: int,
125
+ _flt_flag: int,
126
+ ) -> None:
127
+ if not isinstance(collider_group, SpringBone1ColliderGroupPropertyGroup):
128
+ return
129
+
130
+ icon = "PIVOT_INDIVIDUAL"
131
+
132
+ if self.layout_type == "GRID":
133
+ layout.alignment = "CENTER"
134
+ layout.label(text="", translate=False, icon=icon)
135
+ return
136
+
137
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
138
+ return
139
+
140
+ layout.label(text=collider_group.vrm_name, translate=False, icon=icon)
141
+
142
+
143
+ class VRM_UL_spring_bone1_collider_group_collider(UIList):
144
+ bl_idname = "VRM_UL_spring_bone1_collider_group_collider"
145
+
146
+ def filter_items(
147
+ self,
148
+ _context: Context,
149
+ data: object,
150
+ propname: str,
151
+ ) -> tuple[list[int], list[int]]:
152
+ items = convert.sequence_or_none(getattr(data, propname, None))
153
+ if items is None:
154
+ return ([], [])
155
+
156
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
157
+ flt_neworder: list[int] = []
158
+
159
+ filter_name: str = self.filter_name.casefold()
160
+ if not filter_name:
161
+ return (flt_flags, flt_neworder)
162
+
163
+ for index, item in enumerate(items):
164
+ if (
165
+ isinstance(item, SpringBone1ColliderReferencePropertyGroup)
166
+ and filter_name in item.collider_display_name.casefold()
167
+ ):
168
+ continue
169
+ flt_flags[index] = 0
170
+
171
+ return (flt_flags, flt_neworder)
172
+
173
+ def draw_item(
174
+ self,
175
+ _context: Context,
176
+ layout: UILayout,
177
+ collider_group: object,
178
+ collider: object,
179
+ _icon: int,
180
+ _active_data: object,
181
+ _active_prop_name: str,
182
+ index: int,
183
+ _flt_flag: int,
184
+ ) -> None:
185
+ if not isinstance(collider_group, SpringBone1ColliderGroupPropertyGroup):
186
+ return
187
+ if not isinstance(collider, SpringBone1ColliderReferencePropertyGroup):
188
+ return
189
+ icon = "SPHERE"
190
+
191
+ if self.layout_type == "GRID":
192
+ layout.alignment = "CENTER"
193
+ layout.label(text="", translate=False, icon=icon)
194
+ return
195
+
196
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
197
+ return
198
+
199
+ armature_data = collider_group.id_data
200
+ if not isinstance(armature_data, Armature):
201
+ _logger.error("Failed to find armature")
202
+ return
203
+
204
+ if index == collider_group.active_collider_index:
205
+ VRM_MT_spring_bone1_collider_group_collider.draw_input_layout(
206
+ layout,
207
+ collider_group,
208
+ collider,
209
+ icon=icon,
210
+ )
211
+ else:
212
+ layout.label(
213
+ text=collider.collider_display_name, translate=False, icon=icon
214
+ )
215
+
216
+
217
+ class VRM_UL_spring_bone1_spring(UIList):
218
+ bl_idname = "VRM_UL_spring_bone1_spring"
219
+
220
+ def filter_items(
221
+ self,
222
+ _context: Context,
223
+ data: object,
224
+ propname: str,
225
+ ) -> tuple[list[int], list[int]]:
226
+ items = convert.sequence_or_none(getattr(data, propname, None))
227
+ if items is None:
228
+ return ([], [])
229
+
230
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
231
+ flt_neworder: list[int] = []
232
+
233
+ filter_name: str = self.filter_name.casefold()
234
+ if not filter_name:
235
+ return (flt_flags, flt_neworder)
236
+
237
+ for index, item in enumerate(items):
238
+ if (
239
+ isinstance(item, SpringBone1SpringPropertyGroup)
240
+ and filter_name in item.vrm_name.casefold()
241
+ ):
242
+ continue
243
+ flt_flags[index] = 0
244
+
245
+ return (flt_flags, flt_neworder)
246
+
247
+ def draw_item(
248
+ self,
249
+ _context: Context,
250
+ layout: UILayout,
251
+ _data: object,
252
+ spring: object,
253
+ _icon: int,
254
+ _active_data: object,
255
+ _active_prop_name: str,
256
+ _index: int,
257
+ _flt_flag: int,
258
+ ) -> None:
259
+ if not isinstance(spring, SpringBone1SpringPropertyGroup):
260
+ return
261
+
262
+ icon = "PHYSICS"
263
+
264
+ if self.layout_type == "GRID":
265
+ layout.alignment = "CENTER"
266
+ layout.label(text="", translate=False, icon=icon)
267
+ return
268
+
269
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
270
+ return
271
+
272
+ layout.label(text=spring.vrm_name, translate=False, icon=icon)
273
+
274
+
275
+ class VRM_UL_spring_bone1_joint(UIList):
276
+ bl_idname = "VRM_UL_spring_bone1_joint"
277
+
278
+ def filter_items(
279
+ self,
280
+ _context: Context,
281
+ data: object,
282
+ propname: str,
283
+ ) -> tuple[list[int], list[int]]:
284
+ items = convert.sequence_or_none(getattr(data, propname, None))
285
+ if items is None:
286
+ return ([], [])
287
+
288
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
289
+ flt_neworder: list[int] = []
290
+
291
+ filter_name: str = self.filter_name.casefold()
292
+ if not filter_name:
293
+ return (flt_flags, flt_neworder)
294
+
295
+ for index, item in enumerate(items):
296
+ if (
297
+ isinstance(item, SpringBone1JointPropertyGroup)
298
+ and filter_name in item.node.bone_name.casefold()
299
+ ):
300
+ continue
301
+ flt_flags[index] = 0
302
+
303
+ return (flt_flags, flt_neworder)
304
+
305
+ def draw_item(
306
+ self,
307
+ _context: Context,
308
+ layout: UILayout,
309
+ _data: object,
310
+ joint: object,
311
+ _icon: int,
312
+ _active_data: object,
313
+ _active_prop_name: str,
314
+ _index: int,
315
+ _flt_flag: int,
316
+ ) -> None:
317
+ if not isinstance(joint, SpringBone1JointPropertyGroup):
318
+ return
319
+
320
+ icon = "BONE_DATA"
321
+
322
+ if self.layout_type == "GRID":
323
+ layout.alignment = "CENTER"
324
+ layout.label(text="", translate=False, icon=icon)
325
+ return
326
+
327
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
328
+ return
329
+
330
+ layout.label(text=joint.node.bone_name, translate=False, icon=icon)
331
+
332
+
333
+ class VRM_UL_spring_bone1_spring_collider_group(UIList):
334
+ bl_idname = "VRM_UL_spring_bone1_spring_collider_group"
335
+
336
+ def filter_items(
337
+ self,
338
+ _context: Context,
339
+ data: object,
340
+ propname: str,
341
+ ) -> tuple[list[int], list[int]]:
342
+ items = convert.sequence_or_none(getattr(data, propname, None))
343
+ if items is None:
344
+ return ([], [])
345
+
346
+ flt_flags: list[int] = [self.bitflag_filter_item] * len(items)
347
+ flt_neworder: list[int] = []
348
+
349
+ filter_name: str = self.filter_name.casefold()
350
+ if not filter_name:
351
+ return (flt_flags, flt_neworder)
352
+
353
+ for index, item in enumerate(items):
354
+ if (
355
+ isinstance(item, SpringBone1ColliderGroupReferencePropertyGroup)
356
+ and filter_name in item.collider_group_display_name.casefold()
357
+ ):
358
+ continue
359
+ flt_flags[index] = 0
360
+
361
+ return (flt_flags, flt_neworder)
362
+
363
+ def draw_item(
364
+ self,
365
+ _context: Context,
366
+ layout: UILayout,
367
+ spring: object,
368
+ collider_group: object,
369
+ _icon: int,
370
+ _active_data: object,
371
+ _active_prop_name: str,
372
+ index: int,
373
+ _flt_flag: int,
374
+ ) -> None:
375
+ if not isinstance(spring, SpringBone1SpringPropertyGroup):
376
+ return
377
+ if not isinstance(
378
+ collider_group, SpringBone1ColliderGroupReferencePropertyGroup
379
+ ):
380
+ return
381
+
382
+ icon = "PIVOT_INDIVIDUAL"
383
+
384
+ if self.layout_type == "GRID":
385
+ layout.alignment = "CENTER"
386
+ layout.label(text="", translate=False, icon=icon)
387
+ return
388
+
389
+ if self.layout_type not in {"DEFAULT", "COMPACT"}:
390
+ return
391
+
392
+ armature_data = spring.id_data
393
+ if not isinstance(armature_data, Armature):
394
+ _logger.error("Failed to find armature")
395
+ return
396
+ if index == spring.active_collider_group_index:
397
+ VRM_MT_spring_bone1_spring_collider_group.draw_input_layout(
398
+ layout,
399
+ spring,
400
+ collider_group,
401
+ icon=icon,
402
+ )
403
+ else:
404
+ layout.label(
405
+ text=collider_group.collider_group_display_name,
406
+ translate=False,
407
+ icon=icon,
408
+ )
@@ -0,0 +1,123 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from dataclasses import dataclass, field
3
+ from typing import Final
4
+
5
+ import bpy
6
+ from bpy.types import Armature, Bone, Object
7
+
8
+ from ..common.logger import get_logger
9
+ from .extension_accessor import get_armature_extension
10
+ from .migration import migrate_all_objects
11
+ from .mtoon1.property_group import refresh_mtoon1_outline_object
12
+ from .vrm0 import property_group as vrm0_property_group
13
+ from .vrm1 import property_group as vrm1_property_group
14
+
15
+ _logger = get_logger(__name__)
16
+
17
+
18
+ @dataclass
19
+ class Subscription:
20
+ object_mode_subscription_owner: Final[object] = field(default_factory=object)
21
+ object_location_subscription_owner: Final[object] = field(default_factory=object)
22
+ bone_name_subscription_owner: Final[object] = field(default_factory=object)
23
+ armature_name_subscription_owner: Final[object] = field(default_factory=object)
24
+ setup_once: bool = False
25
+
26
+
27
+ _subscription: Final = Subscription()
28
+
29
+
30
+ def setup_subscription(*, load_post: bool) -> None:
31
+ if _subscription.setup_once:
32
+ if load_post:
33
+ # If called by load_post, unsubscribe and setup again.
34
+ teardown_subscription()
35
+ else:
36
+ # If a subscription is already setup, do nothing.
37
+ return
38
+
39
+ _subscription.setup_once = True
40
+
41
+ object_mode_subscribe_to = (Object, "mode")
42
+ bpy.msgbus.subscribe_rna(
43
+ key=object_mode_subscribe_to,
44
+ owner=_subscription.object_mode_subscription_owner,
45
+ args=(),
46
+ notify=_on_change_bpy_object_mode,
47
+ )
48
+
49
+ object_location_subscribe_to = (Object, "location")
50
+ bpy.msgbus.subscribe_rna(
51
+ key=object_location_subscribe_to,
52
+ owner=_subscription.object_location_subscription_owner,
53
+ args=(),
54
+ notify=_on_change_bpy_object_location,
55
+ )
56
+
57
+ bone_name_subscribe_to = (Bone, "name")
58
+ bpy.msgbus.subscribe_rna(
59
+ key=bone_name_subscribe_to,
60
+ owner=_subscription.bone_name_subscription_owner,
61
+ args=(),
62
+ notify=_on_change_bpy_bone_name,
63
+ )
64
+
65
+ armature_name_subscribe_to = (Armature, "name")
66
+ bpy.msgbus.subscribe_rna(
67
+ key=armature_name_subscribe_to,
68
+ owner=_subscription.armature_name_subscription_owner,
69
+ args=(),
70
+ notify=_on_change_bpy_armature_name,
71
+ )
72
+
73
+ bpy.msgbus.publish_rna(key=object_mode_subscribe_to)
74
+ bpy.msgbus.publish_rna(key=object_location_subscribe_to)
75
+ bpy.msgbus.publish_rna(key=bone_name_subscribe_to)
76
+ bpy.msgbus.publish_rna(key=armature_name_subscribe_to)
77
+
78
+
79
+ def teardown_subscription() -> None:
80
+ _subscription.setup_once = False
81
+ bpy.msgbus.clear_by_owner(_subscription.armature_name_subscription_owner)
82
+ bpy.msgbus.clear_by_owner(_subscription.bone_name_subscription_owner)
83
+ bpy.msgbus.clear_by_owner(_subscription.object_location_subscription_owner)
84
+ bpy.msgbus.clear_by_owner(_subscription.object_mode_subscription_owner)
85
+
86
+
87
+ def _on_change_bpy_object_mode() -> None:
88
+ context = bpy.context
89
+
90
+ active_object = context.active_object
91
+ if not active_object:
92
+ return
93
+ refresh_mtoon1_outline_object(context, active_object)
94
+
95
+
96
+ def _on_change_bpy_object_location() -> None:
97
+ context = bpy.context
98
+ active_object = context.active_object
99
+ if not active_object:
100
+ return
101
+ vrm1_property_group.Vrm1LookAtPropertyGroup.update_all_previews(context)
102
+
103
+
104
+ def _on_change_bpy_bone_name() -> None:
105
+ context = bpy.context
106
+
107
+ for armature in context.blend_data.armatures:
108
+ ext = get_armature_extension(armature)
109
+ if tuple(ext.addon_version) == ext.UNMANAGED_ADDON_VERSION:
110
+ continue
111
+
112
+ vrm0_property_group.Vrm0HumanoidPropertyGroup.update_all_bone_name_candidates(
113
+ context, armature.name
114
+ )
115
+ vrm1_property_group.Vrm1HumanBonesPropertyGroup.update_all_bone_name_candidates(
116
+ context, armature.name
117
+ )
118
+
119
+
120
+ def _on_change_bpy_armature_name() -> None:
121
+ context = bpy.context
122
+
123
+ migrate_all_objects(context, heavy_migration=False)