@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.
- package/LICENSE +16 -0
- package/README.md +4 -11
- package/browser/addons/vrm/LICENSE_(OPTION1)_MIT.txt +22 -0
- package/browser/addons/vrm/LICENSE_(OPTION2)_GPL-3_0.txt +674 -0
- package/browser/addons/vrm/LICENSE_MAIN.txt +1 -0
- package/browser/addons/vrm/README.txt +3 -0
- package/browser/addons/vrm/__init__.py +41 -0
- package/browser/addons/vrm/blender_manifest.toml +16 -0
- package/browser/addons/vrm/common/__init__.py +1 -0
- package/browser/addons/vrm/common/animation.py +58 -0
- package/browser/addons/vrm/common/blender_manifest.py +82 -0
- package/browser/addons/vrm/common/char.py +16 -0
- package/browser/addons/vrm/common/convert.py +287 -0
- package/browser/addons/vrm/common/convert_any.py +48 -0
- package/browser/addons/vrm/common/debug.py +40 -0
- package/browser/addons/vrm/common/deep.py +162 -0
- package/browser/addons/vrm/common/error_dialog.py +274 -0
- package/browser/addons/vrm/common/fs.py +71 -0
- package/browser/addons/vrm/common/gl.py +20 -0
- package/browser/addons/vrm/common/gltf.py +1149 -0
- package/browser/addons/vrm/common/human_bone_mapper/__init__.py +1 -0
- package/browser/addons/vrm/common/human_bone_mapper/biped_mapping.py +84 -0
- package/browser/addons/vrm/common/human_bone_mapper/cats_blender_plugin_fix_model_mapping.py +63 -0
- package/browser/addons/vrm/common/human_bone_mapper/human_bone_mapper.py +203 -0
- package/browser/addons/vrm/common/human_bone_mapper/microsoft_rocketbox_mapping.py +69 -0
- package/browser/addons/vrm/common/human_bone_mapper/mixamo_mapping.py +62 -0
- package/browser/addons/vrm/common/human_bone_mapper/mmd_mapping.py +115 -0
- package/browser/addons/vrm/common/human_bone_mapper/mpfb_mapping.py +120 -0
- package/browser/addons/vrm/common/human_bone_mapper/ready_player_me_mapping.py +65 -0
- package/browser/addons/vrm/common/human_bone_mapper/reallusion_mapping.py +94 -0
- package/browser/addons/vrm/common/human_bone_mapper/rigify_meta_rig_mapping.py +65 -0
- package/browser/addons/vrm/common/human_bone_mapper/structure_based_mapping.py +891 -0
- package/browser/addons/vrm/common/human_bone_mapper/unreal_mapping.py +62 -0
- package/browser/addons/vrm/common/human_bone_mapper/vrm_addon_mapping.py +112 -0
- package/browser/addons/vrm/common/human_bone_mapper/vroid_mapping.py +89 -0
- package/browser/addons/vrm/common/legacy_gltf.py +16 -0
- package/browser/addons/vrm/common/logger.py +84 -0
- package/browser/addons/vrm/common/mtoon0.blend +0 -0
- package/browser/addons/vrm/common/mtoon1.blend +0 -0
- package/browser/addons/vrm/common/mtoon1_outline.blend +0 -0
- package/browser/addons/vrm/common/mtoon_auto_setup.blend +0 -0
- package/browser/addons/vrm/common/mtoon_unversioned.py +62 -0
- package/browser/addons/vrm/common/ops/__init__.py +10 -0
- package/browser/addons/vrm/common/ops/export_scene.py +67 -0
- package/browser/addons/vrm/common/ops/icyp.py +53 -0
- package/browser/addons/vrm/common/ops/import_scene.py +57 -0
- package/browser/addons/vrm/common/ops/vrm.py +2380 -0
- package/browser/addons/vrm/common/ops/wm.py +167 -0
- package/browser/addons/vrm/common/preferences.py +362 -0
- package/browser/addons/vrm/common/progress.py +87 -0
- package/browser/addons/vrm/common/rotation.py +89 -0
- package/browser/addons/vrm/common/safe_removal.py +46 -0
- package/browser/addons/vrm/common/scene_watcher.py +230 -0
- package/browser/addons/vrm/common/shader.py +2243 -0
- package/browser/addons/vrm/common/shape_key_mapper/__init__.py +1 -0
- package/browser/addons/vrm/common/shape_key_mapper/arkit_mapping.py +168 -0
- package/browser/addons/vrm/common/shape_key_mapper/mmd_mapping.py +62 -0
- package/browser/addons/vrm/common/shape_key_mapper/ready_player_me_mapping.py +52 -0
- package/browser/addons/vrm/common/shape_key_mapper/vrchat_mapping.py +17 -0
- package/browser/addons/vrm/common/third_party_user_extension.py +214 -0
- package/browser/addons/vrm/common/transparent_z_write.blend +0 -0
- package/browser/addons/vrm/common/version.py +161 -0
- package/browser/addons/vrm/common/vrm0/__init__.py +1 -0
- package/browser/addons/vrm/common/vrm0/human_bone.py +662 -0
- package/browser/addons/vrm/common/vrm0/material_property.py +346 -0
- package/browser/addons/vrm/common/vrm1/__init__.py +1 -0
- package/browser/addons/vrm/common/vrm1/expression_preset.py +207 -0
- package/browser/addons/vrm/common/vrm1/human_bone.py +822 -0
- package/browser/addons/vrm/common/workspace.py +227 -0
- package/browser/addons/vrm/common/writable_context.py +77 -0
- package/browser/addons/vrm/documentation/en-us/animation/index.md +63 -0
- package/browser/addons/vrm/documentation/en-us/create-humanoid-vrm-from-scratch/index.md +131 -0
- package/browser/addons/vrm/documentation/en-us/create-simple-vrm-from-scratch/index.md +30 -0
- package/browser/addons/vrm/documentation/en-us/development/index.md +136 -0
- package/browser/addons/vrm/documentation/en-us/index.md +41 -0
- package/browser/addons/vrm/documentation/en-us/installation/index.md +152 -0
- package/browser/addons/vrm/documentation/en-us/material-mtoon/index.md +122 -0
- package/browser/addons/vrm/documentation/en-us/material-pbr/index.md +94 -0
- package/browser/addons/vrm/documentation/en-us/scripting-api/index.md +391 -0
- package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrm/index.md +57 -0
- package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrma/index.md +17 -0
- package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrm/index.md +61 -0
- package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrma/index.md +13 -0
- package/browser/addons/vrm/documentation/ja-jp/animation/index.md +57 -0
- package/browser/addons/vrm/documentation/ja-jp/create-humanoid-vrm-from-scratch/index.md +129 -0
- package/browser/addons/vrm/documentation/ja-jp/create-simple-vrm-from-scratch/index.md +29 -0
- package/browser/addons/vrm/documentation/ja-jp/development/index.md +137 -0
- package/browser/addons/vrm/documentation/ja-jp/index.md +37 -0
- package/browser/addons/vrm/documentation/ja-jp/installation/index.md +150 -0
- package/browser/addons/vrm/documentation/ja-jp/material-mtoon/index.md +113 -0
- package/browser/addons/vrm/documentation/ja-jp/material-pbr/index.md +90 -0
- package/browser/addons/vrm/documentation/ja-jp/scripting-api/index.md +389 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrm/index.md +55 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrma/index.md +19 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrm/index.md +56 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrma/index.md +14 -0
- package/browser/addons/vrm/editor/__init__.py +1 -0
- package/browser/addons/vrm/editor/extension.py +425 -0
- package/browser/addons/vrm/editor/extension_accessor.py +75 -0
- package/browser/addons/vrm/editor/handler.py +84 -0
- package/browser/addons/vrm/editor/khr_character/__init__.py +1 -0
- package/browser/addons/vrm/editor/khr_character/panel.py +69 -0
- package/browser/addons/vrm/editor/khr_character/property_group.py +27 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/__init__.py +1 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/ops.py +464 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/panel.py +136 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/property_group.py +83 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/ui_list.py +198 -0
- package/browser/addons/vrm/editor/make_armature.py +709 -0
- package/browser/addons/vrm/editor/menu.py +147 -0
- package/browser/addons/vrm/editor/migration.py +297 -0
- package/browser/addons/vrm/editor/mtoon1/__init__.py +1 -0
- package/browser/addons/vrm/editor/mtoon1/handler.py +20 -0
- package/browser/addons/vrm/editor/mtoon1/migration.py +536 -0
- package/browser/addons/vrm/editor/mtoon1/ops.py +304 -0
- package/browser/addons/vrm/editor/mtoon1/panel.py +442 -0
- package/browser/addons/vrm/editor/mtoon1/property_group.py +4977 -0
- package/browser/addons/vrm/editor/mtoon1/scene_watcher.py +381 -0
- package/browser/addons/vrm/editor/node_constraint1/__init__.py +1 -0
- package/browser/addons/vrm/editor/node_constraint1/panel.py +317 -0
- package/browser/addons/vrm/editor/node_constraint1/property_group.py +25 -0
- package/browser/addons/vrm/editor/ops.py +471 -0
- package/browser/addons/vrm/editor/panel.py +315 -0
- package/browser/addons/vrm/editor/property_group.py +888 -0
- package/browser/addons/vrm/editor/search.py +682 -0
- package/browser/addons/vrm/editor/spring_bone1/__init__.py +1 -0
- package/browser/addons/vrm/editor/spring_bone1/handler.py +994 -0
- package/browser/addons/vrm/editor/spring_bone1/menu.py +246 -0
- package/browser/addons/vrm/editor/spring_bone1/migration.py +86 -0
- package/browser/addons/vrm/editor/spring_bone1/ops.py +1679 -0
- package/browser/addons/vrm/editor/spring_bone1/panel.py +605 -0
- package/browser/addons/vrm/editor/spring_bone1/property_group.py +1457 -0
- package/browser/addons/vrm/editor/spring_bone1/ui_list.py +408 -0
- package/browser/addons/vrm/editor/subscription.py +123 -0
- package/browser/addons/vrm/editor/t_pose.py +713 -0
- package/browser/addons/vrm/editor/validation.py +1271 -0
- package/browser/addons/vrm/editor/vrm0/__init__.py +1 -0
- package/browser/addons/vrm/editor/vrm0/gizmo_group.py +63 -0
- package/browser/addons/vrm/editor/vrm0/handler.py +23 -0
- package/browser/addons/vrm/editor/vrm0/menu.py +145 -0
- package/browser/addons/vrm/editor/vrm0/migration.py +761 -0
- package/browser/addons/vrm/editor/vrm0/ops.py +2145 -0
- package/browser/addons/vrm/editor/vrm0/panel.py +1333 -0
- package/browser/addons/vrm/editor/vrm0/property_group.py +1818 -0
- package/browser/addons/vrm/editor/vrm0/ui_list.py +688 -0
- package/browser/addons/vrm/editor/vrm1/__init__.py +1 -0
- package/browser/addons/vrm/editor/vrm1/handler.py +28 -0
- package/browser/addons/vrm/editor/vrm1/menu.py +76 -0
- package/browser/addons/vrm/editor/vrm1/migration.py +321 -0
- package/browser/addons/vrm/editor/vrm1/ops.py +2679 -0
- package/browser/addons/vrm/editor/vrm1/panel.py +1243 -0
- package/browser/addons/vrm/editor/vrm1/property_group.py +2087 -0
- package/browser/addons/vrm/editor/vrm1/scene_watcher.py +90 -0
- package/browser/addons/vrm/editor/vrm1/ui_list.py +533 -0
- package/browser/addons/vrm/exporter/__init__.py +1 -0
- package/browser/addons/vrm/exporter/abstract_base_vrm_exporter.py +628 -0
- package/browser/addons/vrm/exporter/export_scene.py +930 -0
- package/browser/addons/vrm/exporter/gltf2_export_user_extension.py +45 -0
- package/browser/addons/vrm/exporter/khr_character_exporter.py +34 -0
- package/browser/addons/vrm/exporter/vrm0_exporter.py +4020 -0
- package/browser/addons/vrm/exporter/vrm1_exporter.py +3682 -0
- package/browser/addons/vrm/exporter/vrm_animation_exporter.py +1035 -0
- package/browser/addons/vrm/external/__init__.py +1 -0
- package/browser/addons/vrm/external/auto_rig_pro_support.py +3 -0
- package/browser/addons/vrm/external/io_scene_gltf2_support.py +418 -0
- package/browser/addons/vrm/external/rigify_support.py +1 -0
- package/browser/addons/vrm/importer/__init__.py +1 -0
- package/browser/addons/vrm/importer/abstract_base_vrm_importer.py +1548 -0
- package/browser/addons/vrm/importer/file_handler.py +34 -0
- package/browser/addons/vrm/importer/gltf2_import_user_extension.py +268 -0
- package/browser/addons/vrm/importer/import_scene.py +646 -0
- package/browser/addons/vrm/importer/license_validation.py +198 -0
- package/browser/addons/vrm/importer/vrm0_importer.py +1723 -0
- package/browser/addons/vrm/importer/vrm1_importer.py +2014 -0
- package/browser/addons/vrm/importer/vrm_animation_importer.py +763 -0
- package/browser/addons/vrm/importer/vrm_diff.py +316 -0
- package/browser/addons/vrm/locale/__init__.py +1 -0
- package/browser/addons/vrm/locale/ja_jp.py +826 -0
- package/browser/addons/vrm/locale/ruff.toml +8 -0
- package/browser/addons/vrm/locale/translation_dictionary.py +10 -0
- package/browser/addons/vrm/locale/zh_hans.py +928 -0
- package/browser/addons/vrm/registration.py +670 -0
- package/browser/addons/vrm.json +18 -0
- package/browser/blender-emscripten-engine.mts +60 -128
- package/browser/blender-engine.mts +20 -186
- package/browser/blender-wali-engine.mts +35 -81
- package/browser/describe-thrown.mts +3 -6
- package/browser/document-chunks.mts +4 -16
- package/browser/gltf_export.py +3161 -0
- package/browser/heap-growth.mts +23 -0
- package/browser/index.ts +2 -0
- package/browser/protocol.ts +119 -35
- package/browser/pull-job.mts +2 -10
- package/browser/rna.ts +190 -73
- package/browser/runtime.ts +197 -82
- package/browser/session-addons.mts +33 -0
- package/browser/session-frame.mts +5 -24
- package/browser/session.py +1338 -1427
- package/browser/three/attach-presenter.ts +11 -39
- package/browser/three/blender-base64.ts +1 -36
- package/browser/three/blender-corner-normals.ts +1 -23
- package/browser/three/blender-display-shaders.json +1 -1
- package/browser/three/blender-display-shaders.lut +0 -0
- package/browser/three/blender-display-transform.ts +2 -1
- package/browser/three/blender-frame-columns.ts +5 -13
- package/browser/three/blender-graph-material.ts +18 -3
- package/browser/three/blender-node-graph.ts +10 -34
- package/browser/three/blender-physical-material.ts +2 -31
- package/browser/three/blender-runtime-armature.ts +7 -60
- package/browser/three/blender-runtime-frame.ts +9 -23
- package/browser/three/blender-runtime-geometry.ts +22 -26
- package/browser/three/blender-runtime-lighting.ts +48 -178
- package/browser/three/blender-runtime-shadows.ts +187 -1
- package/browser/three/blender-runtime-skeleton.ts +53 -1
- package/browser/three/blender-runtime-view.ts +505 -283
- package/browser/three/blender-runtime-weights.ts +9 -72
- package/browser/three/blender-sky.ts +13 -33
- package/browser/three/blender-triangulate.ts +7 -35
- package/browser/three/blender-viewport-sampling.ts +235 -0
- package/browser/three/blender-workbench-material.ts +25 -29
- package/browser/three/blender-workbench-outline.ts +199 -0
- package/browser/three/blender-world-volume.ts +62 -10
- package/browser/three/presenter.ts +10 -26
- package/browser/three/release.ts +5 -21
- package/browser/three/sky-precompute-worker.ts +1 -18
- package/browser/three/sky-worker.ts +5 -23
- package/browser/three/world-field-sampler.ts +12 -26
- package/browser/volter_three.py +9 -105
- package/browser/worker.ts +156 -151
- package/package.json +5 -2
- package/wasm/BUNDLE.json +17 -17
- package/wasm/DEPENDENCY-LICENSES.txt +14 -0
- package/wasm/blender_browser.data.br +0 -0
- package/wasm/blender_browser.js +1 -1
- package/wasm/blender_browser.wasm.br +0 -0
- package/browser/frame-transfer.mts +0 -19
- package/browser/three/agx-base-srgb.lut +0 -0
- package/browser/three/agx-look-medium-high-contrast.lut +0 -0
- package/browser/three/agx-look-punchy.lut +0 -0
- package/browser/three/blender-agx.ts +0 -235
- package/browser/three/blender-display-lut.ts +0 -145
- package/browser/three/blender-filmic.ts +0 -49
- package/browser/three/blender-standard.ts +0 -68
- package/browser/three/blender-world-visibility.ts +0 -278
- package/browser/three/filmic-srgb.lut +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
|
|
2
|
+
import sys
|
|
3
|
+
from collections.abc import Generator
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import bpy
|
|
10
|
+
from bpy.types import Context, Object
|
|
11
|
+
from mathutils import Matrix
|
|
12
|
+
|
|
13
|
+
from .logger import get_logger
|
|
14
|
+
|
|
15
|
+
_logger = get_logger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class SavedWorkspace:
|
|
20
|
+
# Be careful not to include objects that might disappear before and after yield
|
|
21
|
+
cursor_matrix: Matrix
|
|
22
|
+
previous_object_name: Optional[str]
|
|
23
|
+
previous_object_mode: Optional[str]
|
|
24
|
+
active_object_name: Optional[str]
|
|
25
|
+
active_object_hide_viewport: bool
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _enter_save_workspace(
|
|
29
|
+
context: Context, obj: Optional[Object] = None, *, mode: str = "OBJECT"
|
|
30
|
+
) -> SavedWorkspace:
|
|
31
|
+
# Save the position of the 3D cursor
|
|
32
|
+
cursor_matrix = context.scene.cursor.matrix.copy()
|
|
33
|
+
|
|
34
|
+
previous_object_name = None
|
|
35
|
+
previous_object_mode = None
|
|
36
|
+
previous_object = context.view_layer.objects.active
|
|
37
|
+
if previous_object:
|
|
38
|
+
# previous_object may disappear after yield.
|
|
39
|
+
# We intern it just in case, but it might not be necessary.
|
|
40
|
+
previous_object_name = sys.intern(previous_object.name)
|
|
41
|
+
previous_object_mode = sys.intern(previous_object.mode)
|
|
42
|
+
|
|
43
|
+
# If an obj argument is passed, set the mode to "OBJECT". If the mode
|
|
44
|
+
# stays as is, it may not be possible to change the active object
|
|
45
|
+
if previous_object != obj and previous_object_mode != "OBJECT":
|
|
46
|
+
previous_object_hide_viewport = previous_object.hide_viewport
|
|
47
|
+
if previous_object_hide_viewport:
|
|
48
|
+
# If hide_viewport is True, mode_set may fail if left as is
|
|
49
|
+
previous_object.hide_viewport = False
|
|
50
|
+
bpy.ops.object.mode_set(mode="OBJECT")
|
|
51
|
+
if previous_object.hide_viewport != previous_object_hide_viewport:
|
|
52
|
+
previous_object.hide_viewport = previous_object_hide_viewport
|
|
53
|
+
|
|
54
|
+
# If an object is passed, make it active
|
|
55
|
+
if obj is not None:
|
|
56
|
+
context.view_layer.objects.active = obj
|
|
57
|
+
context.view_layer.update()
|
|
58
|
+
|
|
59
|
+
active_object_name = None
|
|
60
|
+
active_object_hide_viewport = False
|
|
61
|
+
# Change the mode of the active object
|
|
62
|
+
active_object = context.view_layer.objects.active
|
|
63
|
+
if active_object:
|
|
64
|
+
# active_object may disappear after yield.
|
|
65
|
+
# We intern it just in case, but it might not be necessary.
|
|
66
|
+
active_object_name = sys.intern(active_object.name)
|
|
67
|
+
active_object_hide_viewport = active_object.hide_viewport
|
|
68
|
+
# If hide_viewport is True, mode_set may fail if left as is
|
|
69
|
+
# Currently we force it to be visible even when not changing mode,
|
|
70
|
+
# but this may be inappropriate
|
|
71
|
+
if active_object_hide_viewport:
|
|
72
|
+
active_object.hide_viewport = False
|
|
73
|
+
if active_object.mode != mode:
|
|
74
|
+
bpy.ops.object.mode_set(mode=mode)
|
|
75
|
+
|
|
76
|
+
return SavedWorkspace(
|
|
77
|
+
cursor_matrix=cursor_matrix,
|
|
78
|
+
previous_object_name=previous_object_name,
|
|
79
|
+
previous_object_mode=previous_object_mode,
|
|
80
|
+
active_object_name=active_object_name,
|
|
81
|
+
active_object_hide_viewport=active_object_hide_viewport,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _exit_save_workspace(context: Context, saved_workspace: SavedWorkspace) -> None:
|
|
86
|
+
cursor_matrix = saved_workspace.cursor_matrix
|
|
87
|
+
previous_object_name = saved_workspace.previous_object_name
|
|
88
|
+
previous_object_mode = saved_workspace.previous_object_mode
|
|
89
|
+
active_object_name = saved_workspace.active_object_name
|
|
90
|
+
active_object_hide_viewport = saved_workspace.active_object_hide_viewport
|
|
91
|
+
|
|
92
|
+
previous_object = None
|
|
93
|
+
if previous_object_name is not None:
|
|
94
|
+
previous_object = context.blend_data.objects.get(previous_object_name)
|
|
95
|
+
|
|
96
|
+
current_active_object = context.view_layer.objects.active
|
|
97
|
+
|
|
98
|
+
# Set the mode of the currently active object to "OBJECT". If the mode stays as is,
|
|
99
|
+
# it may not be possible to change the active object
|
|
100
|
+
if (
|
|
101
|
+
current_active_object
|
|
102
|
+
and current_active_object != previous_object
|
|
103
|
+
and current_active_object.mode != "OBJECT"
|
|
104
|
+
):
|
|
105
|
+
current_active_object_hide_viewport = current_active_object.hide_viewport
|
|
106
|
+
if current_active_object.hide_viewport:
|
|
107
|
+
current_active_object.hide_viewport = False
|
|
108
|
+
bpy.ops.object.mode_set(mode="OBJECT")
|
|
109
|
+
if current_active_object.hide_viewport != current_active_object_hide_viewport:
|
|
110
|
+
current_active_object.hide_viewport = current_active_object_hide_viewport
|
|
111
|
+
|
|
112
|
+
# Restore the hide_viewport of the activated object
|
|
113
|
+
if active_object_name is not None:
|
|
114
|
+
active_object = context.blend_data.objects.get(active_object_name)
|
|
115
|
+
if active_object and active_object.hide_viewport != active_object_hide_viewport:
|
|
116
|
+
active_object.hide_viewport = active_object_hide_viewport
|
|
117
|
+
|
|
118
|
+
# Return to the originally active object
|
|
119
|
+
previous_object = None
|
|
120
|
+
if previous_object_name is not None:
|
|
121
|
+
previous_object = context.blend_data.objects.get(previous_object_name)
|
|
122
|
+
|
|
123
|
+
if context.view_layer.objects.active != previous_object:
|
|
124
|
+
context.view_layer.objects.active = previous_object
|
|
125
|
+
context.view_layer.update()
|
|
126
|
+
|
|
127
|
+
# Restore the mode of the originally active object
|
|
128
|
+
if (
|
|
129
|
+
previous_object
|
|
130
|
+
and previous_object_mode is not None
|
|
131
|
+
and previous_object_mode != previous_object.mode
|
|
132
|
+
):
|
|
133
|
+
# If hide_viewport is True, mode_set may fail if left as is
|
|
134
|
+
# Restore hide_viewport after mode_set is completed
|
|
135
|
+
previous_object_hide_viewport = previous_object.hide_viewport
|
|
136
|
+
if previous_object_hide_viewport:
|
|
137
|
+
previous_object.hide_viewport = False
|
|
138
|
+
bpy.ops.object.mode_set(mode=previous_object_mode)
|
|
139
|
+
if previous_object.hide_viewport != previous_object_hide_viewport:
|
|
140
|
+
previous_object.hide_viewport = previous_object_hide_viewport
|
|
141
|
+
|
|
142
|
+
# Restore the 3D cursor position
|
|
143
|
+
context.scene.cursor.matrix = cursor_matrix
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@contextmanager
|
|
147
|
+
def save_workspace(
|
|
148
|
+
context: Context, obj: Optional[Object] = None, *, mode: str = "OBJECT"
|
|
149
|
+
) -> Generator[None]:
|
|
150
|
+
saved_workspace = _enter_save_workspace(context, obj, mode=mode)
|
|
151
|
+
try:
|
|
152
|
+
yield
|
|
153
|
+
# After yield, bpy native objects may be deleted or become invalid
|
|
154
|
+
# as frames advance. Accessing them in this state can cause crashes,
|
|
155
|
+
# so be careful not to access potentially invalid native objects
|
|
156
|
+
# after yield
|
|
157
|
+
finally:
|
|
158
|
+
_exit_save_workspace(context, saved_workspace)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def wm_append_without_library(
|
|
162
|
+
context: Context,
|
|
163
|
+
blend_path: Path,
|
|
164
|
+
*,
|
|
165
|
+
append_filepath: str,
|
|
166
|
+
append_filename: str,
|
|
167
|
+
append_directory: str,
|
|
168
|
+
) -> set[str]:
|
|
169
|
+
"""Call wm.append and remove the added libraries.
|
|
170
|
+
|
|
171
|
+
Used to work around the issue where wm.append adding libraries causes
|
|
172
|
+
asset library addition to fail.
|
|
173
|
+
https://github.com/saturday06/VRM-Addon-for-Blender/issues/631
|
|
174
|
+
https://github.com/saturday06/VRM-Addon-for-Blender/issues/646
|
|
175
|
+
"""
|
|
176
|
+
# https://projects.blender.org/blender/blender/src/tag/v2.93.18/source/blender/windowmanager/intern/wm_files_link.c#L85-L90
|
|
177
|
+
with save_workspace(context):
|
|
178
|
+
# List of pointers for library addition detection.
|
|
179
|
+
# Used only for addition detection. Be careful not to dereference,
|
|
180
|
+
# as it is dangerous.
|
|
181
|
+
existing_library_pointers: list[int] = [
|
|
182
|
+
library.as_pointer() for library in context.blend_data.libraries
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
result = bpy.ops.wm.append(
|
|
186
|
+
filepath=append_filepath,
|
|
187
|
+
filename=append_filename,
|
|
188
|
+
directory=append_directory,
|
|
189
|
+
link=False,
|
|
190
|
+
)
|
|
191
|
+
if result != {"FINISHED"}:
|
|
192
|
+
return result
|
|
193
|
+
|
|
194
|
+
# Remove one added library.
|
|
195
|
+
# Reverse order to handle recursive calls, but effectiveness is unconfirmed.
|
|
196
|
+
for library in reversed(list(context.blend_data.libraries)):
|
|
197
|
+
try:
|
|
198
|
+
library_path = Path(bpy.path.abspath(library.filepath))
|
|
199
|
+
if not library_path.exists() or not blend_path.samefile(library_path):
|
|
200
|
+
continue
|
|
201
|
+
except OSError:
|
|
202
|
+
message = f'Failed to access library path for "{library.name}"'
|
|
203
|
+
_logger.warning(message)
|
|
204
|
+
continue
|
|
205
|
+
|
|
206
|
+
if library.as_pointer() in existing_library_pointers:
|
|
207
|
+
continue
|
|
208
|
+
|
|
209
|
+
if bpy.app.version >= (3, 2) and library.use_extra_user:
|
|
210
|
+
library.use_extra_user = False
|
|
211
|
+
if library.users:
|
|
212
|
+
if bpy.app.version >= (3, 2):
|
|
213
|
+
_logger.warning(
|
|
214
|
+
'Failed to remove "%s" with %d users'
|
|
215
|
+
" while appending blend file:"
|
|
216
|
+
' filepath="%s" filename="%s" directory="%s"',
|
|
217
|
+
library.name,
|
|
218
|
+
library.users,
|
|
219
|
+
append_filepath,
|
|
220
|
+
append_filename,
|
|
221
|
+
append_directory,
|
|
222
|
+
)
|
|
223
|
+
else:
|
|
224
|
+
context.blend_data.libraries.remove(library)
|
|
225
|
+
|
|
226
|
+
break
|
|
227
|
+
return result
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Final, Optional, Protocol
|
|
5
|
+
|
|
6
|
+
import bpy
|
|
7
|
+
from bpy.app.handlers import persistent
|
|
8
|
+
from bpy.types import Context
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class WritableContextBecomesAvailableOnceHandler(Protocol):
|
|
12
|
+
def __call__(self, context: Context, *, load_post: bool) -> None: ...
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class State:
|
|
17
|
+
registered_handlers: Final[list[WritableContextBecomesAvailableOnceHandler]] = (
|
|
18
|
+
field(default_factory=list[WritableContextBecomesAvailableOnceHandler])
|
|
19
|
+
)
|
|
20
|
+
pending_handlers: Final[list[WritableContextBecomesAvailableOnceHandler]] = field(
|
|
21
|
+
default_factory=list[WritableContextBecomesAvailableOnceHandler]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
_state: Final = State()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def register_writable_context_becomes_available_once_handler(
|
|
29
|
+
handler: WritableContextBecomesAvailableOnceHandler,
|
|
30
|
+
) -> None:
|
|
31
|
+
if handler not in _state.registered_handlers:
|
|
32
|
+
_state.registered_handlers.append(handler)
|
|
33
|
+
if handler not in _state.pending_handlers:
|
|
34
|
+
_state.pending_handlers.append(handler)
|
|
35
|
+
|
|
36
|
+
if not bpy.app.timers.is_registered(
|
|
37
|
+
_writable_context_becomes_available_timer_callback
|
|
38
|
+
):
|
|
39
|
+
bpy.app.timers.register(_writable_context_becomes_available_timer_callback)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _writable_context_becomes_available_timer_callback() -> Optional[float]:
|
|
43
|
+
context = bpy.context
|
|
44
|
+
trigger_writable_context_becomes_available_once_handlers(context, load_post=False)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def trigger_writable_context_becomes_available_once_handlers(
|
|
48
|
+
context: Context, *, load_post: bool
|
|
49
|
+
) -> None:
|
|
50
|
+
try:
|
|
51
|
+
while _state.pending_handlers:
|
|
52
|
+
handler = _state.pending_handlers.pop()
|
|
53
|
+
handler(context, load_post=load_post)
|
|
54
|
+
finally:
|
|
55
|
+
_state.pending_handlers.clear()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@persistent
|
|
59
|
+
def load_post(_unused: object) -> None:
|
|
60
|
+
context = bpy.context
|
|
61
|
+
for handler in _state.registered_handlers:
|
|
62
|
+
if handler not in _state.pending_handlers:
|
|
63
|
+
_state.pending_handlers.append(handler)
|
|
64
|
+
trigger_writable_context_becomes_available_once_handlers(context, load_post=True)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@persistent
|
|
68
|
+
def depsgraph_update_pre(_unused: object) -> None:
|
|
69
|
+
context = bpy.context
|
|
70
|
+
trigger_writable_context_becomes_available_once_handlers(context, load_post=False)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def clear_writable_context_becomes_available_once_handlers() -> None:
|
|
74
|
+
_state.registered_handlers.clear()
|
|
75
|
+
_state.pending_handlers.clear()
|
|
76
|
+
if bpy.app.timers.is_registered(_writable_context_becomes_available_timer_callback):
|
|
77
|
+
bpy.app.timers.unregister(_writable_context_becomes_available_timer_callback)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "VRM Animation"
|
|
3
|
+
description: "How to import and export VRM Animation files."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
This section explains how to import and export VRM Animation files.
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
An English tutorial is currently being written.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
VRM Animationのインポートとエクスポートの解説です。
|
|
15
|
+
|
|
16
|
+
## VRM Animationファイルのエクスポート
|
|
17
|
+
|
|
18
|
+
VRM Animationのエクスポートには、VRM
|
|
19
|
+
1.0のアーマチュアが必要です。エクスポートされるアニメーションは次の通りです
|
|
20
|
+
|
|
21
|
+
- Humanoidボーンの回転値
|
|
22
|
+
- Humanoid Hipsボーンの移動値
|
|
23
|
+
- Expressionのプレビュー値 (Look At値のエクスポートは現在未対応)
|
|
24
|
+
|
|
25
|
+
最低限のアニメーションをエクスポートしてみます。
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+

|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
## VRM Animationファイルのインポート
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+

|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Create Humanoid VRM"
|
|
3
|
+
description: "We will create a simple Humanoid VRM model."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
We will create a simple Humanoid VRM model.
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
After starting Blender, place the mouse cursor on the 3D Viewport and press the
|
|
11
|
+
`n` key.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
This will open a Sidebar from the right side. Select the `VRM` tab and click the
|
|
16
|
+
`Create VRM Model` button.
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
Then an armature suitable for VRM output will be created automatically. An
|
|
21
|
+
armature represents the bone structure of a 3D model. This add-on uses armature
|
|
22
|
+
to represent the skeletal structure of the human figure in VRM.
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
We will use the default Cube as a torso.
|
|
27
|
+
|
|
28
|
+
Select the Cube in the 3D Viewport, select the tab with the
|
|
29
|
+
"" icon in the lower right
|
|
30
|
+
corner, go to `Transform` > `Scale`, and set all values to `0.2` to make it
|
|
31
|
+
small enough to be used as a torso.
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
We associate the torso with the bones of the armature. Go to `Relations`, and
|
|
36
|
+
set `Parent` to `Armature`, `Parent Type` to `Bone`, and `Parent Bone` to
|
|
37
|
+
`spine`. The torso will move to the spine of the 3D model.
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
The next step is to create the head, press `Shift + a` in the 3D viewport to
|
|
42
|
+
bring up an additional menu, select `Mesh` -> `UV Sphere`.
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
A `Sphere` will be added.
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+
It is too big so we will shrink it.
|
|
51
|
+
|
|
52
|
+
Select the tab with the "" icon
|
|
53
|
+
in the lower right corner, go to `Transform` > `Scale`, and set all values to
|
|
54
|
+
`0.25`.
|
|
55
|
+
|
|
56
|
+

|
|
57
|
+
|
|
58
|
+
Associate this sphere with the armature's bone. Go to `Relations`, and set
|
|
59
|
+
`Parent` to `Armature`, `Parent Type` to `Bone`, and `Parent Bone` to `head`.
|
|
60
|
+
The sphere will move to the head of the 3D model.
|
|
61
|
+
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
Next, we will add the limbs: in the 3D viewport, press `Shift + a` to bring up
|
|
65
|
+
the Add menu, and select `Mesh` -> `Ico Sphere`.
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
The `Icosphere` will be added, and at the same time, you will see
|
|
70
|
+
`> Add Ico Sphere` in the lower-left corner of the 3D viewport. Click on this
|
|
71
|
+
message.
|
|
72
|
+
|
|
73
|
+

|
|
74
|
+
|
|
75
|
+
You can then set up the new Ico Sphere to be added. We feel that the radius is
|
|
76
|
+
too large so we will change the radius value to `0.1 m`.
|
|
77
|
+
|
|
78
|
+

|
|
79
|
+
|
|
80
|
+
Select the tab with the "" icon
|
|
81
|
+
in the lower right corner, go to `Relations`, set `Parent` to `Armature`, set
|
|
82
|
+
`Parent Type` to `Bone`, and set `Parent Bone` to `upper_arm.L`. The sphere will
|
|
83
|
+
move to the left upper arm of the 3D model.
|
|
84
|
+
|
|
85
|
+

|
|
86
|
+
|
|
87
|
+
Add the Ico sphere as before, and now associate it with the `hand.L` bone. The
|
|
88
|
+
Ico sphere will move to the left hand.
|
|
89
|
+
|
|
90
|
+

|
|
91
|
+
|
|
92
|
+
Similarly, we will associate it with the `upper_arm.R` bone.
|
|
93
|
+
|
|
94
|
+

|
|
95
|
+
|
|
96
|
+
Associate with the `hand.R` bone.
|
|
97
|
+
|
|
98
|
+

|
|
99
|
+
|
|
100
|
+
Associate with the `upper_leg.L` bone.
|
|
101
|
+
|
|
102
|
+

|
|
103
|
+
|
|
104
|
+
Associate with the `lower_leg.L` bone.
|
|
105
|
+
|
|
106
|
+

|
|
107
|
+
|
|
108
|
+
Associate with the `upper_leg.R` bone.
|
|
109
|
+
|
|
110
|
+

|
|
111
|
+
|
|
112
|
+
Finally, associate it with the `lower_leg.R` bone.
|
|
113
|
+
|
|
114
|
+

|
|
115
|
+
|
|
116
|
+
Save this model as a VRM. Select `File` → `Export` → `VRM (.vrm)` from the menu.
|
|
117
|
+
|
|
118
|
+

|
|
119
|
+
|
|
120
|
+
Enter the filename and destination when the File View window appears and press
|
|
121
|
+
`Export VRM`.
|
|
122
|
+
|
|
123
|
+

|
|
124
|
+
|
|
125
|
+
If successful, the VRM file will be saved to the specified location.
|
|
126
|
+
|
|
127
|
+

|
|
128
|
+
|
|
129
|
+
You can check the operation on this page.
|
|
130
|
+
|
|
131
|
+
- https://hub.vroid.com/en/characters/6595382014094436897/models/1372267393572384142
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Create Simple VRM"
|
|
3
|
+
description: "Convert the cube displayed from the beginning when you start Blender to a VRM model."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Convert the cube displayed from the beginning when you start Blender to a VRM
|
|
7
|
+
model.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
First, start Blender and make sure that the cube is displayed.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
Next, select `File` → `Export` → `VRM (.vrm)` from the menu.
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
Enter the filename and destination when the File View window appears and press
|
|
20
|
+
`Export VRM`.
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
If successful, the VRM file will be saved to the specified location.
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
You can check the operation on this page.
|
|
29
|
+
|
|
30
|
+
- https://hub.vroid.com/en/characters/2535511199028537879/models/127230567429676411
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Development How-To"
|
|
3
|
+
description: "Set up the development environment for VRM Add-on for Blender."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Instructions for setting up the add-on development environment.
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
[The repository](https://github.com/saturday06/VRM-Addon-for-Blender) contains
|
|
11
|
+
source code, code formatting settings, code type checking settings, and software
|
|
12
|
+
testing settings. These are strongly dependent on the tool
|
|
13
|
+
[astral-sh/uv](https://docs.astral.sh/uv/), so you will need to install that
|
|
14
|
+
first. Alternatively, you can use [Dev Container](https://containers.dev/) to
|
|
15
|
+
set them up automatically.
|
|
16
|
+
|
|
17
|
+
## Link the repository to the add-on folder
|
|
18
|
+
|
|
19
|
+
The
|
|
20
|
+
[src/io_scene_vrm](https://github.com/saturday06/VRM-Addon-for-Blender/tree/main/src/io_scene_vrm)
|
|
21
|
+
folder contains the main add-on code. By creating a symbolic link to this folder
|
|
22
|
+
in Blender's `user_default` or `addons` directory, you can install the
|
|
23
|
+
development source code as an add-on in Blender, making it easy to test changes
|
|
24
|
+
efficiently.
|
|
25
|
+
|
|
26
|
+
### How to create a development link for Blender 4.2 or later
|
|
27
|
+
|
|
28
|
+
#### Linux
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
blender_version=4.5
|
|
32
|
+
mkdir -p "$HOME/.config/blender/$blender_version/extensions/user_default"
|
|
33
|
+
ln -Ts "$PWD/src/io_scene_vrm" "$HOME/.config/blender/$blender_version/extensions/user_default/vrm"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### macOS
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
blender_version=4.5
|
|
40
|
+
mkdir -p "$HOME/Library/Application Support/Blender/$blender_version/extensions/user_default"
|
|
41
|
+
ln -s "$PWD/src/io_scene_vrm" "$HOME/Library/Application Support/Blender/$blender_version/extensions/user_default/vrm"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Windows PowerShell
|
|
45
|
+
|
|
46
|
+
```powershell
|
|
47
|
+
$blenderVersion = "4.5"
|
|
48
|
+
New-Item -ItemType Directory -Path "$Env:APPDATA\Blender Foundation\Blender\$blenderVersion\extensions\user_default" -Force
|
|
49
|
+
New-Item -ItemType Junction -Path "$Env:APPDATA\Blender Foundation\Blender\$blenderVersion\extensions\user_default\vrm" -Value "$(Get-Location)\src\io_scene_vrm"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### How to create a development link for Blender 4.1.1 or earlier
|
|
53
|
+
|
|
54
|
+
#### Linux
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
blender_version=3.6
|
|
58
|
+
mkdir -p "$HOME/.config/blender/$blender_version/scripts/addons"
|
|
59
|
+
ln -Ts "$PWD/src/io_scene_vrm" "$HOME/.config/blender/$blender_version/scripts/addons/io_scene_vrm"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### macOS
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
blender_version=3.6
|
|
66
|
+
mkdir -p "$HOME/Library/Application Support/Blender/$blender_version/scripts/addons"
|
|
67
|
+
ln -s "$PWD/src/io_scene_vrm" "$HOME/Library/Application Support/Blender/$blender_version/scripts/addons/io_scene_vrm"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Windows PowerShell
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
$blenderVersion = "3.6"
|
|
74
|
+
New-Item -ItemType Directory -Path "$Env:APPDATA\Blender Foundation\Blender\$blenderVersion\scripts\addons" -Force
|
|
75
|
+
New-Item -ItemType Junction -Path "$Env:APPDATA\Blender Foundation\Blender\$blenderVersion\scripts\addons\io_scene_vrm" -Value "$(Get-Location)\src\io_scene_vrm"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## To format the code, follow these steps
|
|
79
|
+
|
|
80
|
+
1. Install [astral-sh/uv](https://docs.astral.sh/uv/).
|
|
81
|
+
2. Double-click `tools\format.bat` in the repository to run it.
|
|
82
|
+
|
|
83
|
+
## To format the code in Visual Studio Code, follow these steps
|
|
84
|
+
|
|
85
|
+
1. Install the `Ruff` extension in Visual Studio Code.
|
|
86
|
+
2. Run Visual Studio Code's `Format Document`.
|
|
87
|
+
|
|
88
|
+
## To run type checking of the code, follow these steps
|
|
89
|
+
|
|
90
|
+
1. Install [astral-sh/uv](https://docs.astral.sh/uv/).
|
|
91
|
+
2. Double-click `tools\lint.bat` in the repository and run it.
|
|
92
|
+
|
|
93
|
+
## To run type checking of the code in Visual Studio Code, follow these steps
|
|
94
|
+
|
|
95
|
+
1. Install the `Pyright` extension in Visual Studio Code.
|
|
96
|
+
2. Open the Python file you want to type check.
|
|
97
|
+
|
|
98
|
+
## To run the software tests of the code, follow these steps
|
|
99
|
+
|
|
100
|
+
1. Install [astral-sh/uv](https://docs.astral.sh/uv/).
|
|
101
|
+
2. Double-click `tools\test.bat` in the repository and run it.
|
|
102
|
+
|
|
103
|
+
## To run the software tests of the code in Visual Studio Code, follow these steps
|
|
104
|
+
|
|
105
|
+
1. Install [astral-sh/uv](https://docs.astral.sh/uv/).
|
|
106
|
+
2. In the Visual Studio Code terminal, run the `uv sync` command.
|
|
107
|
+
3. Select `Testing` from the left icon in Visual Studio Code.
|
|
108
|
+
4. Select `Configure Python Tests`.
|
|
109
|
+
5. Select `unittests` as the test library.
|
|
110
|
+
6. Select `Root Directory` as the test folder.
|
|
111
|
+
7. Select `test_*` as the test file pattern.
|
|
112
|
+
8. Press `Run Tests`.
|
|
113
|
+
|
|
114
|
+
## How to create a distribution build
|
|
115
|
+
|
|
116
|
+
You can create a distribution build on Ubuntu Linux LTS.
|
|
117
|
+
|
|
118
|
+
1. Run the `sudo ./tools/install_ubuntu_packages.sh` command to install the
|
|
119
|
+
required packages.
|
|
120
|
+
2. Run the `./tools/build_release.sh` command.
|
|
121
|
+
3. If you see the following output, the build was successful:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
|
|
|
125
|
+
| Release Build Completed
|
|
126
|
+
|
|
|
127
|
+
| - Blender 4.2 or later:
|
|
128
|
+
| /workspace/release_output/VRM_Addon_for_Blender-Extension-0_0_0.zip
|
|
129
|
+
|
|
|
130
|
+
| - Blender 2.93 - 4.1:
|
|
131
|
+
| /workspace/release_output/VRM_Addon_for_Blender-0_0_0.zip
|
|
132
|
+
|
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
For more details, refer to the GitHub Actions code at
|
|
136
|
+
https://github.com/saturday06/VRM-Addon-for-Blender/blob/v3.11.5/.github/workflows/release-please.yml#L51-L54.
|