@volter/blender-engine 0.1.147 → 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,41 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ # SPDX-FileCopyrightText: 2018 iCyP
3
+
4
+ from . import registration
5
+ from .exporter import gltf2_export_user_extension
6
+ from .importer import gltf2_import_user_extension
7
+
8
+ bl_info = {
9
+ "name": "VRM format",
10
+ "author": "saturday06, iCyP",
11
+ "version": (
12
+ 4, # x-release-please-major
13
+ 10, # x-release-please-minor
14
+ 3, # x-release-please-patch
15
+ ),
16
+ "location": "File > Import-Export",
17
+ "description": "Import-Edit-Export VRM",
18
+ "blender": (2, 93, 0),
19
+ "warning": "",
20
+ "support": "COMMUNITY",
21
+ "wiki_url": "",
22
+ "doc_url": "https://vrm-addon-for-blender.info",
23
+ "tracker_url": "https://github.com/saturday06/VRM-Addon-for-Blender/issues",
24
+ "category": "Import-Export",
25
+ }
26
+
27
+
28
+ def register() -> None:
29
+ registration.register()
30
+
31
+
32
+ def unregister() -> None:
33
+ registration.unregister()
34
+
35
+
36
+ class glTF2ImportUserExtension(gltf2_import_user_extension.glTF2ImportUserExtension):
37
+ pass
38
+
39
+
40
+ class glTF2ExportUserExtension(gltf2_export_user_extension.glTF2ExportUserExtension):
41
+ pass
@@ -0,0 +1,16 @@
1
+ schema_version = "1.0.0"
2
+ id = "vrm"
3
+ version = "4.10.3"
4
+ name = "VRM format"
5
+ tagline = "VRM import, export and editing capabilities"
6
+ maintainer = "Isamu Mogi <dyob@lunaport.net>"
7
+ type = "add-on"
8
+ website = "https://vrm-addon-for-blender.info"
9
+ tags = ["Animation", "Import-Export", "Material", "Modeling", "Physics"]
10
+ blender_version_min = "4.2.0"
11
+ blender_version_max = "5.3.0"
12
+ license = ["SPDX:MIT", "SPDX:GPL-3.0-or-later"]
13
+ copyright = ["2020 Isamu Mogi", "2018 iCyP"]
14
+
15
+ [permissions]
16
+ files = "Import/export VRM from/to disk"
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
@@ -0,0 +1,58 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Final
5
+
6
+ from bpy.app.handlers import persistent
7
+ from bpy.types import Context
8
+
9
+ from .logger import get_logger
10
+
11
+ _logger = get_logger(__name__)
12
+
13
+
14
+ @dataclass
15
+ class State:
16
+ during_animation_playback: bool = False
17
+ during_frame_change: bool = False
18
+
19
+
20
+ _state: Final = State()
21
+
22
+
23
+ def _is_animation_playing(context: Context) -> bool:
24
+ if _state.during_animation_playback:
25
+ return True
26
+ screen = context.screen
27
+ if not screen:
28
+ return False
29
+ return screen.is_animation_playing
30
+
31
+
32
+ def defer_shape_key_update(context: Context) -> bool:
33
+ return _is_animation_playing(context) or _state.during_frame_change
34
+
35
+
36
+ @persistent
37
+ def animation_playback_pre(_unused: object) -> None:
38
+ _state.during_animation_playback = True
39
+
40
+
41
+ @persistent
42
+ def animation_playback_post(_unused: object) -> None:
43
+ _state.during_animation_playback = False
44
+
45
+
46
+ @persistent
47
+ def frame_change_pre(_unused: object) -> None:
48
+ _state.during_frame_change = True
49
+
50
+
51
+ @persistent
52
+ def frame_change_post(_unused: object) -> None:
53
+ _state.during_frame_change = False
54
+
55
+
56
+ def clear_global_variables() -> None:
57
+ _state.during_animation_playback = False
58
+ _state.during_frame_change = False
@@ -0,0 +1,82 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ import re
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class BlenderManifest:
10
+ id: str
11
+ version: tuple[int, int, int]
12
+ blender_version_min: tuple[int, int, int]
13
+ blender_version_max: Optional[tuple[int, int, int]]
14
+
15
+ @classmethod
16
+ def default_blender_manifest_path(cls) -> Path:
17
+ return Path(__file__).parent.parent / "blender_manifest.toml"
18
+
19
+ @classmethod
20
+ def _read_str(cls, blender_manifest: str, key: str) -> Optional[str]:
21
+ # When the version of Python used by the minimum supported version of Blender
22
+ # exceeds 3.11, it is rewritten in the tomllib library.
23
+ lines = [line.strip() for line in blender_manifest.splitlines()]
24
+
25
+ pattern = key + r' = "([^"]+)"'
26
+ for line in lines:
27
+ match = re.fullmatch(pattern, line)
28
+ if not match:
29
+ continue
30
+ return match[1]
31
+
32
+ return None
33
+
34
+ @classmethod
35
+ def _read_3_tuple_version(
36
+ cls, blender_manifest: str, key: str
37
+ ) -> Optional[tuple[int, int, int]]:
38
+ # When the version of Python used by the minimum supported version of Blender
39
+ # exceeds 3.11, it is rewritten in the tomli library.
40
+ lines = [line.strip() for line in blender_manifest.splitlines()]
41
+
42
+ pattern = key + r' = "(\d+)\.(\d+)\.(\d+)"'
43
+ for line in lines:
44
+ match = re.fullmatch(pattern, line)
45
+ if not match:
46
+ continue
47
+ return (int(match[1]), int(match[2]), int(match[3]))
48
+
49
+ return None
50
+
51
+ @classmethod
52
+ def read(cls, blender_manifest: Optional[str] = None) -> "BlenderManifest":
53
+ if blender_manifest is None:
54
+ blender_manifest = cls.default_blender_manifest_path().read_text(
55
+ encoding="UTF-8"
56
+ )
57
+
58
+ addon_id = cls._read_str(blender_manifest, "id")
59
+ if addon_id is None:
60
+ message = "'id' was not found in blender manifest"
61
+ raise ValueError(message)
62
+
63
+ version = cls._read_3_tuple_version(blender_manifest, "version")
64
+ if version is None:
65
+ message = "'version' was not found in blender manifest"
66
+ raise ValueError(message)
67
+
68
+ blender_version_min = cls._read_3_tuple_version(
69
+ blender_manifest, "blender_version_min"
70
+ )
71
+ if blender_version_min is None:
72
+ message = "'blender_version_min' was not found in blender manifest"
73
+ raise ValueError(message)
74
+
75
+ return BlenderManifest(
76
+ id=addon_id,
77
+ version=version,
78
+ blender_version_min=blender_version_min,
79
+ blender_version_max=cls._read_3_tuple_version(
80
+ blender_manifest, "blender_version_max"
81
+ ),
82
+ )
@@ -0,0 +1,16 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ from collections.abc import Mapping
3
+ from typing import Final
4
+
5
+ INTERNAL_NAME_PREFIX: Final = "\N{FULLWIDTH BROKEN BAR}"
6
+ """
7
+ The letter to be prefixed when naming internal invisible objects. It was chosen so that
8
+ the sort order would be backward and also so that it would be easy to identify the
9
+ object as internal.
10
+ """
11
+
12
+ DISABLE_TRANSLATION: Final = "\N{ZERO WIDTH SPACE}"
13
+
14
+ FULLWIDTH_ASCII_TO_ASCII_MAP: Final[Mapping[str, str]] = {
15
+ chr(ascii_char + 0x0000_FEE0): chr(ascii_char) for ascii_char in range(0x21, 0x7E)
16
+ }
@@ -0,0 +1,287 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ import math
3
+ from collections.abc import Iterator, Mapping, Sequence
4
+ from sys import float_info
5
+ from typing import Final, Optional, Union
6
+
7
+ from . import convert_any
8
+ from .logger import get_logger
9
+
10
+ _logger = get_logger(__name__)
11
+
12
+ BPY_TRACK_AXIS_TO_VRM_AIM_AXIS: Final[Mapping[str, str]] = {
13
+ "TRACK_X": "PositiveX",
14
+ "TRACK_Y": "PositiveY",
15
+ "TRACK_Z": "PositiveZ",
16
+ "TRACK_NEGATIVE_X": "NegativeX",
17
+ "TRACK_NEGATIVE_Y": "NegativeY",
18
+ "TRACK_NEGATIVE_Z": "NegativeZ",
19
+ }
20
+
21
+ VRM_AIM_AXIS_TO_BPY_TRACK_AXIS: Final[Mapping[str, str]] = {
22
+ v: k for k, v in BPY_TRACK_AXIS_TO_VRM_AIM_AXIS.items()
23
+ }
24
+
25
+
26
+ Json = Union[
27
+ None,
28
+ bool,
29
+ int,
30
+ float,
31
+ str,
32
+ list["Json"],
33
+ dict[str, "Json"],
34
+ ]
35
+
36
+ JsonView = Union[
37
+ None,
38
+ bool,
39
+ int,
40
+ float,
41
+ str,
42
+ Sequence["JsonView"],
43
+ Mapping[str, "JsonView"],
44
+ ]
45
+
46
+
47
+ def iterator_or_none(v: object) -> Optional[Iterator[object]]:
48
+ try:
49
+ # "isinstance(v, Iterable)" doesn't work.
50
+ # https://github.com/python/cpython/blob/3.9/Doc/library/collections.abc.rst?plain=1#L126-L127
51
+ iterator = iter(v) # type: ignore[call-overload]
52
+ except TypeError:
53
+ return None
54
+ return convert_any.iterator_to_object_iterator(iterator)
55
+
56
+
57
+ def sequence_or_none(
58
+ sequence_object: object,
59
+ ) -> Optional[Sequence[object]]:
60
+ iterator = iterator_or_none(sequence_object)
61
+ if iterator is None:
62
+ return None
63
+ return list(iterator)
64
+
65
+
66
+ def mapping_or_none(
67
+ mapping_object: object,
68
+ ) -> Optional[Mapping[object, object]]:
69
+ return convert_any.mapping_to_object_mapping(mapping_object)
70
+
71
+
72
+ def vrm_json_vector3_to_tuple(
73
+ value: Json,
74
+ ) -> Optional[tuple[float, float, float]]:
75
+ if not isinstance(value, dict):
76
+ return None
77
+ x = float_or(value.get("x"), 0.0)
78
+ y = float_or(value.get("y"), 0.0)
79
+ z = float_or(value.get("z"), 0.0)
80
+ return (x, y, z)
81
+
82
+
83
+ def vrm_json_curve_to_list(curve: Json) -> Optional[list[float]]:
84
+ if not isinstance(curve, list):
85
+ return None
86
+ values: list[float] = [float_or(v, 0.0) for v in curve]
87
+ while len(values) < 8:
88
+ values.append(0)
89
+ while len(values) > 8:
90
+ values.pop()
91
+ return values
92
+
93
+
94
+ def vrm_json_array_to_float_vector(
95
+ input_values: Json, defaults: list[float]
96
+ ) -> list[float]:
97
+ if not isinstance(input_values, list):
98
+ return defaults
99
+
100
+ output_values: list[float] = []
101
+ for index, default in enumerate(defaults):
102
+ if index >= len(input_values):
103
+ output_values.append(default)
104
+ continue
105
+
106
+ input_value = float_or(input_values[index], default)
107
+ output_values.append(input_value)
108
+
109
+ return output_values
110
+
111
+
112
+ def mtoon_shading_toony_1_to_0(shading_toony: float, shading_shift: float) -> float:
113
+ base = 2 - shading_toony + shading_shift
114
+ if abs(base) < float_info.epsilon:
115
+ # https://github.com/Santarh/MToon/blob/43f02fe8c9b19c3cf9f3238003b7d8b332933833/MToon/Resources/Shaders/MToon.shader#L17
116
+ return 0.9
117
+ return max(0, min((shading_toony + shading_shift) / base, 1))
118
+
119
+
120
+ def mtoon_shading_shift_1_to_0(shading_toony: float, shading_shift: float) -> float:
121
+ return max(-1, min(shading_toony - shading_shift - 1, 1))
122
+
123
+
124
+ def mtoon_gi_equalization_to_intensity(gi_equalization: float) -> float:
125
+ return max(0, min(1.0, 1.0 - gi_equalization))
126
+
127
+
128
+ # https://github.com/vrm-c/UniVRM/blob/f3479190c330ec6ecd2b40be919285aa93a53aff/Assets/VRMShaders/VRM10/MToon10/Runtime/MToon10Migrator.cs#L10-L19
129
+ def mtoon_shading_toony_0_to_1(
130
+ shading_toony_0x: float, shading_shift_0x: float
131
+ ) -> float:
132
+ (range_min, range_max) = _get_shading_range_0x(shading_toony_0x, shading_shift_0x)
133
+ return max(0, min(1.0, (2.0 - (range_max - range_min)) * 0.5))
134
+
135
+
136
+ # https://github.com/vrm-c/UniVRM/blob/f3479190c330ec6ecd2b40be919285aa93a53aff/Assets/VRMShaders/VRM10/MToon10/Runtime/MToon10Migrator.cs#L21-L30
137
+ def mtoon_shading_shift_0_to_1(
138
+ shading_toony_0x: float, shading_shift_0x: float
139
+ ) -> float:
140
+ (range_min, range_max) = _get_shading_range_0x(shading_toony_0x, shading_shift_0x)
141
+ return max(-1, min(1.0, ((range_max + range_min) * 0.5 * -1)))
142
+
143
+
144
+ # https://github.com/vrm-c/UniVRM/blob/f3479190c330ec6ecd2b40be919285aa93a53aff/Assets/VRMShaders/VRM10/MToon10/Runtime/MToon10Migrator.cs#L32-L38
145
+ def mtoon_intensity_to_gi_equalization(gi_intensity_0x: float) -> float:
146
+ return max(0, min(1.0, 1.0 - gi_intensity_0x))
147
+
148
+
149
+ # https://github.com/vrm-c/UniVRM/blob/f3479190c330ec6ecd2b40be919285aa93a53aff/Assets/VRMShaders/VRM10/MToon10/Runtime/MToon10Migrator.cs#L40-L46
150
+ def _get_shading_range_0x(
151
+ shading_toony_0x: float, shading_shift_0x: float
152
+ ) -> tuple[float, float]:
153
+ range_min = shading_shift_0x
154
+ range_max = (1 - shading_toony_0x) + shading_toony_0x * shading_shift_0x
155
+ return (range_min, range_max)
156
+
157
+
158
+ def float_or_none(
159
+ v: object,
160
+ min_value: float = -float_info.max,
161
+ max_value: float = float_info.max,
162
+ ) -> Optional[float]:
163
+ if isinstance(v, float):
164
+ if math.isnan(v):
165
+ return None
166
+ return max(min_value, min(v, max_value))
167
+
168
+ if isinstance(v, bool):
169
+ return max(min_value, min(1.0 if v else 0.0, max_value))
170
+
171
+ if isinstance(v, int):
172
+ return max(min_value, min(float(v), max_value))
173
+
174
+ return None
175
+
176
+
177
+ def float_or(
178
+ v: object,
179
+ default: float,
180
+ min_value: float = -float_info.max,
181
+ max_value: float = float_info.max,
182
+ ) -> float:
183
+ float_or_none_value = float_or_none(v, min_value, max_value)
184
+ if float_or_none_value is not None:
185
+ return float_or_none_value
186
+
187
+ if min_value <= default <= max_value:
188
+ return default
189
+
190
+ _logger.warning(
191
+ "Default float value %s is out of range [%s, %s]", default, min_value, max_value
192
+ )
193
+
194
+ return max(min_value, min(default, max_value))
195
+
196
+
197
+ def float4_or_none(value4: object) -> Optional[tuple[float, float, float, float]]:
198
+ value4_iterator = iterator_or_none(value4)
199
+ if value4_iterator is None:
200
+ return None
201
+
202
+ result: list[float] = []
203
+ for value in value4_iterator:
204
+ if len(result) == 4:
205
+ return None
206
+ float_value = float_or_none(value)
207
+ if float_value is None:
208
+ return None
209
+ result.append(float_value)
210
+ if len(result) != 4:
211
+ return None
212
+ return (result[0], result[1], result[2], result[3])
213
+
214
+
215
+ def float4_or(
216
+ value4: object, default: tuple[float, float, float, float]
217
+ ) -> tuple[float, float, float, float]:
218
+ float4 = float4_or_none(value4)
219
+ return float4 if float4 is not None else default
220
+
221
+
222
+ def float3_or_none(value3: object) -> Optional[tuple[float, float, float]]:
223
+ value3_iterator = iterator_or_none(value3)
224
+ if value3_iterator is None:
225
+ return None
226
+
227
+ result: list[float] = []
228
+ for value in value3_iterator:
229
+ if len(result) == 3:
230
+ return None
231
+ float_value = float_or_none(value)
232
+ if float_value is None:
233
+ return None
234
+ result.append(float_value)
235
+ if len(result) != 3:
236
+ return None
237
+ return (result[0], result[1], result[2])
238
+
239
+
240
+ def float3_or(
241
+ value3: object, default: tuple[float, float, float]
242
+ ) -> tuple[float, float, float]:
243
+ float3 = float3_or_none(value3)
244
+ return float3 if float3 is not None else default
245
+
246
+
247
+ def float2_or_none(value2: object) -> Optional[tuple[float, float]]:
248
+ value2_iterator = iterator_or_none(value2)
249
+ if value2_iterator is None:
250
+ return None
251
+ result: list[float] = []
252
+ for value in value2_iterator:
253
+ if len(result) == 2:
254
+ return None
255
+ float_value = float_or_none(value)
256
+ if float_value is None:
257
+ return None
258
+ result.append(float_value)
259
+ if len(result) != 2:
260
+ return None
261
+ return (result[0], result[1])
262
+
263
+
264
+ def axis_blender_to_gltf(vector3: Sequence[float]) -> tuple[float, float, float]:
265
+ return (
266
+ -vector3[0],
267
+ vector3[2],
268
+ vector3[1],
269
+ )
270
+
271
+
272
+ def linear_to_srgb(
273
+ non_color: Sequence[float],
274
+ ) -> Sequence[float]:
275
+ return [
276
+ math.pow(channel_value, 1.0 / 2.2) if channel_index < 3 else channel_value
277
+ for channel_index, channel_value in enumerate(non_color)
278
+ ]
279
+
280
+
281
+ def srgb_to_linear(
282
+ srgb_color: Sequence[float],
283
+ ) -> Sequence[float]:
284
+ return [
285
+ math.pow(channel_value, 2.2) if channel_index < 3 else channel_value
286
+ for channel_index, channel_value in enumerate(srgb_color)
287
+ ]
@@ -0,0 +1,48 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ """A module provides a function to convert a variable of type Any to a concrete type.
3
+
4
+ Inevitably, variables of type Any may occur, and such variables cannot be handled
5
+ in type checkers in strict mode. Any is allowed only in the module here.
6
+ """
7
+
8
+ import sys
9
+ from collections.abc import Iterator, Mapping
10
+ from typing import (
11
+ Any, # Any is allowed only in the module here.
12
+ Optional,
13
+ )
14
+
15
+
16
+ def to_object( # type: ignore[explicit-any]
17
+ any_object: Any, # noqa: ANN401 # Any is allowed only in the module here.
18
+ ) -> object:
19
+ # Interpret Unknown as object
20
+ # https://github.com/microsoft/pyright/issues/3650
21
+ if not isinstance(any_object, object):
22
+ if sys.version_info >= (3, 11):
23
+ from typing import assert_never
24
+
25
+ assert_never(any_object)
26
+ raise TypeError
27
+ return any_object
28
+
29
+
30
+ def iterator_to_object_iterator( # type: ignore[explicit-any]
31
+ any_iterator: Any, # noqa: ANN401 # Any is allowed only in the module here.
32
+ ) -> Optional[Iterator[object]]:
33
+ any_iterator_without_partial_type_narrowing = any_iterator
34
+ if not isinstance(any_iterator, Iterator):
35
+ return None
36
+ return map(to_object, any_iterator_without_partial_type_narrowing)
37
+
38
+
39
+ def mapping_to_object_mapping( # type: ignore[explicit-any]
40
+ any_mapping: Any, # noqa: ANN401 # Any is allowed only in the module here.
41
+ ) -> Optional[Mapping[object, object]]:
42
+ any_mapping_without_partial_type_narrowing = any_mapping
43
+ if not isinstance(any_mapping, Mapping):
44
+ return None
45
+ return {
46
+ to_object(k): to_object(v)
47
+ for k, v in any_mapping_without_partial_type_narrowing.items()
48
+ }
@@ -0,0 +1,40 @@
1
+ # SPDX-License-Identifier: MIT OR GPL-3.0-or-later
2
+ import math
3
+ from collections.abc import Sequence
4
+ from typing import Union
5
+
6
+ from mathutils import Matrix, Quaternion, Vector
7
+
8
+
9
+ def dump(v: Union[Matrix, Vector, Quaternion, float]) -> str:
10
+ if isinstance(v, (float, int)):
11
+ return str(v)
12
+
13
+ if isinstance(v, Matrix):
14
+ t, r, s = v.decompose()
15
+ return f"Matrix(T={dump(t)},R={dump(r)},S={dump(s)})"
16
+
17
+ if isinstance(v, Vector):
18
+ return f"({v.x:.3f},{v.y:.3f},{v.z:.3f})"
19
+
20
+ x, y, z = (round(math.degrees(xyz)) for xyz in v.to_euler()[:])
21
+ return f"Euler({x},{y},{z})"
22
+
23
+
24
+ def assert_vector3_equals(
25
+ expected: Vector, actual: Sequence[float], message: str
26
+ ) -> None:
27
+ if len(actual) != 3:
28
+ message = f"actual length is not 3: {actual}"
29
+ raise AssertionError(message)
30
+
31
+ threshold = 0.0001
32
+ if abs(expected[0] - actual[0]) > threshold:
33
+ message = f"{message}: {tuple(expected)} is different from {tuple(actual)}"
34
+ raise AssertionError(message)
35
+ if abs(expected[1] - actual[1]) > threshold:
36
+ message = f"{message}: {tuple(expected)} is different from {tuple(actual)}"
37
+ raise AssertionError(message)
38
+ if abs(expected[2] - actual[2]) > threshold:
39
+ message = f"{message}: {tuple(expected)} is different from {tuple(actual)}"
40
+ raise AssertionError(message)