feat(blenvy): overhauled path/directory management a bit

* full paths are now computed properties
 * cleanups of path names
 * various tweaks
This commit is contained in:
kaosat.dev 2024-05-19 11:04:34 +02:00
parent 8abd806d5f
commit c2a847934b
12 changed files with 70 additions and 47 deletions

View File

@ -37,8 +37,7 @@ Assets:
- QUESTION : do we want to include them in the list of assets per level ?
- this would enable pre-loading ALL the assets, but is not ideal in most other cases
- so add an option ?
- [] the assets of local blueprints
- [ ] the assets of local blueprints
Blueprints:
- [x] on save: write IN THE COLLECTION PROPERTIES
@ -50,14 +49,17 @@ Blueprints:
- [ ] scan & inject on save
- [ ] decide where & when to do & store blueprints data
Components:
- [ ] add support for adding components to collections
General things to solve:
- [x] save settings
- [x] load settings
- [ ] add_blueprints_data
- [ ] rename all path stuff using the old naming convention : "export_blueprints_path_full"
- [ ] generate the full paths directly when setting them in the UI
- [ ] problem : how to deal with defaults: do it on start/load ?
- [x] rename all path stuff using the old naming convention : "blueprints_path_full"
- [x] generate the full paths directly when setting them in the UI
- [x] problem : how to deal with defaults: do it on start/load ?
General issues:
- there is no safeguard for naming collisions for naming across blender files

View File

@ -51,7 +51,7 @@ from .core.operators import OT_switch_bevy_tooling
from .core.scene_helpers import (SceneSelector)
from .core.ui.ui import (BLENVY_PT_SidePanel)
from .core.ui.scenes_list import SCENES_LIST_OT_actions, SCENE_UL_Blenvy
from .core.ui.folder_browser import OT_OpenAssetsFolderBrowser
from .core.ui.assets_folder_browser import OT_OpenAssetsFolderBrowser
# this needs to be here, as it is how Blender's gltf exporter callbacks are defined, at the add-on root level

View File

@ -45,17 +45,12 @@ class BlueprintsRegistry(PropertyGroup):
def unregister(cls):
del bpy.types.WindowManager.blueprints_registry
def add_blueprint(self, blueprint):
self.blueprints_list.append(blueprint)
def add_blueprints_data(self):
print("adding blueprints data")
addon_prefs = load_settings(".gltf_auto_export_settings")
if addon_prefs is not None:
print("addon_prefs", addon_prefs)
addon_prefs["export_marked_assets"] = False
addon_prefs = SimpleNamespace(**addon_prefs)
[main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs)
blueprints_data = blueprints_scan(level_scenes, library_scenes, addon_prefs)
self.blueprints_data = blueprints_data
blenvy = bpy.context.window_manager.blenvy
addon_prefs = blenvy
[main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs)
blueprints_data = blueprints_scan(level_scenes, library_scenes, addon_prefs)
self.blueprints_data = blueprints_data

View File

@ -1,3 +1,4 @@
import os
import bpy
from bpy_types import (PropertyGroup)
from bpy.props import (EnumProperty, PointerProperty, StringProperty, CollectionProperty, IntProperty)
@ -13,13 +14,13 @@ def update_scene_lists(self, context):
upsert_settings(blenvy.settings_save_path, {"common_library_scene_names": [scene.name for scene in blenvy.library_scenes]})
def update_asset_folders(self, context):
blenvy = context.window_manager.blenvy
blenvy = self # context.window_manager.blenvy
asset_path_names = ['project_root_path', 'assets_path', 'blueprints_path', 'levels_path', 'materials_path']
for asset_path_name in asset_path_names:
upsert_settings(blenvy.settings_save_path, {asset_path_name: getattr(blenvy, asset_path_name)})
def update_mode(self, context):
blenvy = self # context.window_manager.blenvy
blenvy = self
upsert_settings(blenvy.settings_save_path, {"mode": blenvy.mode })
class BlenvyManager(PropertyGroup):
@ -37,7 +38,6 @@ class BlenvyManager(PropertyGroup):
update=update_mode
) # type: ignore
project_root_path: StringProperty(
name = "Project Root Path",
description="The root folder of your (Bevy) project (not assets!)",
@ -45,6 +45,11 @@ class BlenvyManager(PropertyGroup):
update= update_asset_folders
) # type: ignore
# computed property for the absolute path of assets
project_root_path_full: StringProperty(
get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path))
) # type: ignore
assets_path: StringProperty(
name='Export folder',
description='The root folder for all exports(relative to the root folder/path) Defaults to "assets" ',
@ -52,6 +57,11 @@ class BlenvyManager(PropertyGroup):
options={'HIDDEN'},
update= update_asset_folders
) # type: ignore
# computed property for the absolute path of assets
assets_path_full: StringProperty(
get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path))
) # type: ignore
blueprints_path: StringProperty(
name='Blueprints path',
@ -60,6 +70,11 @@ class BlenvyManager(PropertyGroup):
update= update_asset_folders
) # type: ignore
# computed property for the absolute path of blueprints
blueprints_path_full: StringProperty(
get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path, self.blueprints_path))
) # type: ignore
levels_path: StringProperty(
name='Levels path',
description='path to export the levels (main scenes) to (relative to the assets folder)',
@ -67,6 +82,11 @@ class BlenvyManager(PropertyGroup):
update= update_asset_folders
) # type: ignore
# computed property for the absolute path of blueprints
levels_path_full: StringProperty(
get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path, self.levels_path))
) # type: ignore
materials_path: StringProperty(
name='Materials path',
description='path to export the materials libraries to (relative to the assets folder)',
@ -74,6 +94,11 @@ class BlenvyManager(PropertyGroup):
update= update_asset_folders
) # type: ignore
# computed property for the absolute path of blueprints
materials_path_full: StringProperty(
get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path, self.materials_path))
) # type: ignore
main_scenes: CollectionProperty(name="main scenes", type=SceneSelector) # type: ignore
main_scenes_index: IntProperty(name = "Index for main scenes list", default = 0, update=update_scene_lists) # type: ignore
main_scene_names = [] # FIXME: unsure

View File

@ -4,7 +4,7 @@ import os
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator
from ...core.path_helpers import absolute_path_from_blend_file
from ..path_helpers import absolute_path_from_blend_file
class OT_OpenAssetsFolderBrowser(Operator, ImportHelper):
"""Assets folder's browser"""
@ -46,8 +46,8 @@ class OT_OpenAssetsFolderBrowser(Operator, ImportHelper):
asset_path_names = ['blueprints_path', 'levels_path', 'materials_path']
project_root_path = absolute_path_from_blend_file(operator.project_root_path)
assets_path = operator.assets_path
export_assets_path_full = absolute_path_from_blend_file(os.path.join(project_root_path, assets_path)) #os.path.join(blend_file_folder_path, project_root_path, assets_path)
#print("export_assets_path_full", export_assets_path_full)
assets_path_full = absolute_path_from_blend_file(os.path.join(project_root_path, assets_path)) #os.path.join(blend_file_folder_path, project_root_path, assets_path)
#print("assets_path_full", assets_path_full)
#new_root_path = os.path.join(blend_file_folder_path, new_path)
if target_path_name == 'project_root_path':
@ -74,7 +74,7 @@ class OT_OpenAssetsFolderBrowser(Operator, ImportHelper):
if relative_path is not None:
# and now get absolute path of asset_path
# compute 'old' absolute path
old_absolute_path = os.path.abspath(os.path.join(export_assets_path_full, relative_path))
old_absolute_path = os.path.abspath(os.path.join(assets_path_full, relative_path))
relative_path = os.path.relpath(old_absolute_path, new_assets_path_absolute)
setattr(operator, path_name, relative_path)
@ -89,13 +89,13 @@ class OT_OpenAssetsFolderBrowser(Operator, ImportHelper):
relative_path = getattr(operator, path_name, None)
if relative_path is not None:
# compute 'old' absolute path
old_absolute_path = os.path.abspath(os.path.join(export_assets_path_full, relative_path))
old_absolute_path = os.path.abspath(os.path.join(assets_path_full, relative_path))
relative_path = os.path.relpath(old_absolute_path, new_assets_path_absolute)
setattr(operator, path_name, relative_path)
setattr(operator, target_path_name, new_assets_path_relative)
else:
relative_path = os.path.relpath(new_path, export_assets_path_full)
relative_path = os.path.relpath(new_path, assets_path_full)
setattr(operator, target_path_name, relative_path)
return {'FINISHED'}

View File

@ -44,6 +44,11 @@ class BLENVY_PT_SidePanel(bpy.types.Panel):
library_scene_active = False
active_collection = context.collection
print("BLA", blenvy.assets_path_full)
print("BLA", blenvy.blueprints_path_full)
print("BLA", blenvy.levels_path_full)
print("BLA", blenvy.materials_path_full)
"""current_auto_settings = load_settings(".gltf_auto_export_settings")
current_gltf_settings = load_settings(".gltf_auto_export_gltf_settings")

View File

@ -27,8 +27,6 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
file_path = bpy.data.filepath
# Get the folder
blend_file_path = os.path.dirname(file_path)
print("settings", dict(addon_prefs))
# get the preferences for our addon
project_root_path = getattr(addon_prefs, "project_root_path")
assets_path = getattr(addon_prefs,"assets_path")
@ -38,7 +36,6 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
export_scene_settings = getattr(addon_prefs.auto_export,"export_scene_settings")
do_export_blueprints = getattr(addon_prefs.auto_export,"export_blueprints")
export_materials_library = getattr(addon_prefs.auto_export,"export_materials_library")
print("export_materials_library", export_materials_library)
# standard gltf export settings are stored differently
standard_gltf_exporter_settings = get_standard_exporter_settings()
@ -46,10 +43,10 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
gltf_extension = '.glb' if gltf_extension == 'GLB' else '.gltf'
# generate the actual complete output paths
addon_prefs.export_assets_path_full = os.path.join(blend_file_path, project_root_path, assets_path)
addon_prefs.export_blueprints_path_full = os.path.join(addon_prefs.export_assets_path_full, getattr(addon_prefs,"blueprints_path"))
addon_prefs.export_levels_path_full = os.path.join(addon_prefs.export_assets_path_full, getattr(addon_prefs,"levels_path"))
addon_prefs.export_materials_path_full = os.path.join(addon_prefs.export_assets_path_full, getattr(addon_prefs,"materials_path"))
"""addon_prefs.assets_path_full = os.path.join(blend_file_path, project_root_path, assets_path)
addon_prefs.blueprints_path_full = os.path.join(addon_prefs.assets_path_full, getattr(addon_prefs,"blueprints_path"))
addon_prefs.levels_path_full = os.path.join(addon_prefs.assets_path_full, getattr(addon_prefs,"levels_path"))
addon_prefs.materials_path_full = os.path.join(addon_prefs.assets_path_full, getattr(addon_prefs,"materials_path"))"""
addon_prefs.export_gltf_extension = gltf_extension
[main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs)
@ -59,7 +56,6 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
internal_blueprints = [blueprint.name for blueprint in blueprints_data.internal_blueprints]
external_blueprints = [blueprint.name for blueprint in blueprints_data.external_blueprints]
# we inject the blueprints export path
blueprints_path = getattr(addon_prefs,"blueprints_path")
inject_export_path_into_internal_blueprints(internal_blueprints=blueprints_data.internal_blueprints, blueprints_path=blueprints_path, gltf_extension=gltf_extension)
@ -77,7 +73,7 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
# export
if do_export_blueprints:
print("EXPORTING", blueprints_data)
print("EXPORTING")
# get blueprints/collections infos
(blueprints_to_export) = get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs)

View File

@ -8,7 +8,7 @@ from ..helpers.helpers_scenes import clear_hollow_scene, copy_hollowed_collectio
def export_blueprints(blueprints, addon_prefs, blueprints_data):
export_blueprints_path_full = getattr(addon_prefs, "export_blueprints_path_full")
blueprints_path_full = getattr(addon_prefs, "blueprints_path_full")
gltf_export_preferences = generate_gltf_export_preferences(addon_prefs)
try:
@ -18,7 +18,7 @@ def export_blueprints(blueprints, addon_prefs, blueprints_data):
for blueprint in blueprints:
print("exporting collection", blueprint.name)
gltf_output_path = os.path.join(export_blueprints_path_full, blueprint.name)
gltf_output_path = os.path.join(blueprints_path_full, blueprint.name)
export_settings = { **gltf_export_preferences, 'use_active_scene': True, 'use_active_collection': True, 'use_active_collection_with_nested':True}
# if we are using the material library option, do not export materials, use placeholder instead

View File

@ -11,8 +11,8 @@ from ...blueprints.blueprint_helpers import inject_blueprints_list_into_main_sce
def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data):
gltf_export_preferences = generate_gltf_export_preferences(addon_prefs)
export_assets_path_full = getattr(addon_prefs,"export_assets_path_full")
export_levels_path_full = getattr(addon_prefs,"export_levels_path_full")
assets_path_full = getattr(addon_prefs,"assets_path_full")
levels_path_full = getattr(addon_prefs,"levels_path_full")
export_blueprints = getattr(addon_prefs.auto_export,"export_blueprints")
export_separate_dynamic_and_static_objects = getattr(addon_prefs.auto_export, "export_separate_dynamic_and_static_objects")
@ -27,7 +27,7 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data):
}
if export_blueprints :
gltf_output_path = os.path.join(export_levels_path_full, scene.name)
gltf_output_path = os.path.join(levels_path_full, scene.name)
#inject_blueprints_list_into_main_scene(scene, blueprints_data, addon_prefs)
return
@ -44,7 +44,7 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data):
)
# then export all dynamic objects
gltf_output_path = os.path.join(export_levels_path_full, scene.name+ "_dynamic")
gltf_output_path = os.path.join(levels_path_full, scene.name+ "_dynamic")
generate_and_export(
addon_prefs,
temp_scene_name=TEMPSCENE_PREFIX,
@ -66,7 +66,7 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data):
)
else:
gltf_output_path = os.path.join(export_assets_path_full, scene.name)
gltf_output_path = os.path.join(assets_path_full, scene.name)
print(" exporting gltf to", gltf_output_path, ".gltf/glb")
export_gltf(gltf_output_path, export_settings)

View File

@ -6,7 +6,7 @@ from ...blueprints.blueprint_helpers import find_blueprints_not_on_disk
# TODO: this should also take the split/embed mode into account: if a nested collection changes AND embed is active, its container collection should also be exported
def get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs):
export_gltf_extension = getattr(addon_prefs, "export_gltf_extension", ".glb")
export_blueprints_path_full = getattr(addon_prefs,"export_blueprints_path_full", "")
blueprints_path_full = getattr(addon_prefs,"blueprints_path_full", "")
change_detection = getattr(addon_prefs.auto_export, "change_detection")
collection_instances_combine_mode = getattr(addon_prefs.auto_export, "collection_instances_combine_mode")
@ -23,7 +23,7 @@ def get_blueprints_to_export(changes_per_scene, changed_export_parameters, bluep
# first check if all collections have already been exported before (if this is the first time the exporter is run
# in your current Blender session for example)
blueprints_not_on_disk = find_blueprints_not_on_disk(internal_blueprints, export_blueprints_path_full, export_gltf_extension)
blueprints_not_on_disk = find_blueprints_not_on_disk(internal_blueprints, blueprints_path_full, export_gltf_extension)
for scene in library_scenes:
if scene.name in changes_per_scene:

View File

@ -38,7 +38,7 @@ def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, coll
# this also takes the split/embed mode into account: if a collection instance changes AND embed is active, its container level/world should also be exported
def get_levels_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs):
export_gltf_extension = getattr(addon_prefs, "export_gltf_extension")
export_levels_path_full = getattr(addon_prefs, "export_levels_path_full")
levels_path_full = getattr(addon_prefs, "levels_path_full")
change_detection = getattr(addon_prefs.auto_export, "change_detection")
collection_instances_combine_mode = getattr(addon_prefs.auto_export, "collection_instances_combine_mode")
@ -47,6 +47,6 @@ def get_levels_to_export(changes_per_scene, changed_export_parameters, blueprint
# determine list of main scenes to export
# we have more relaxed rules to determine if the main scenes have changed : any change is ok, (allows easier handling of changes, render settings etc)
main_scenes_to_export = [scene_name for scene_name in main_scene_names if not change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode) or not check_if_blueprint_on_disk(scene_name, export_levels_path_full, export_gltf_extension) ]
main_scenes_to_export = [scene_name for scene_name in main_scene_names if not change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode) or not check_if_blueprint_on_disk(scene_name, levels_path_full, export_gltf_extension) ]
return (main_scenes_to_export)

View File

@ -61,7 +61,7 @@ def clear_materials_scene(temp_scene):
# the name of the output path is <materials_folder>/<name_of_your_blend_file>_materials_library.gltf/glb
def export_materials(collections, library_scenes, addon_prefs):
gltf_export_preferences = generate_gltf_export_preferences(addon_prefs)
export_materials_path_full = getattr(addon_prefs,"export_materials_path_full")
materials_path_full = getattr(addon_prefs,"materials_path_full")
used_material_names = get_all_materials(collections, library_scenes)
current_project_name = Path(bpy.context.blend_data.filepath).stem
@ -75,7 +75,7 @@ def export_materials(collections, library_scenes, addon_prefs):
'export_apply':True
}
gltf_output_path = os.path.join(export_materials_path_full, current_project_name + "_materials_library")
gltf_output_path = os.path.join(materials_path_full, current_project_name + "_materials_library")
print(" exporting Materials to", gltf_output_path, ".gltf/glb")