feat(blenvy): restructuring/ extracting a lot of the auto_export settings to be in the "common" ui/logic

* moved out all folder logic & code
 * moved out all of the scene selector logic & code
 * related tweaks
This commit is contained in:
kaosat.dev 2024-05-16 15:27:30 +02:00
parent 3aed4ab925
commit f561112704
14 changed files with 293 additions and 458 deletions

View File

@ -15,7 +15,6 @@ import bpy
from bpy.app.handlers import persistent
from bpy.props import (StringProperty)
# components management
from .bevy_components.components.operators import CopyComponentOperator, Fix_Component_Operator, OT_rename_component, RemoveComponentFromAllObjectsOperator, RemoveComponentOperator, GenerateComponent_From_custom_property_Operator, PasteComponentOperator, AddComponentOperator, RenameHelper, Toggle_ComponentVisibility
@ -33,24 +32,12 @@ from .bevy_components.components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel)
from .gltf_auto_export import gltf_post_export_callback
from .gltf_auto_export.auto_export.operators import AutoExportGLTF
from .gltf_auto_export.auto_export.tracker import AutoExportTracker
from .gltf_auto_export.auto_export.internals import (SceneLink,
SceneLinks,
CollectionToExport,
BlueprintsToExport,
CUSTOM_PG_sceneName
)
from .gltf_auto_export.ui.main import (GLTF_PT_auto_export_change_detection, GLTF_PT_auto_export_main,
GLTF_PT_auto_export_root,
GLTF_PT_auto_export_general,
GLTF_PT_auto_export_scenes,
GLTF_PT_auto_export_blueprints,
SCENE_UL_GLTF_auto_export,
GLTF_PT_auto_export_SidePanel
)
from .gltf_auto_export.ui.operators import (OT_OpenFolderbrowser, SCENES_LIST_OT_actions)
# asset management
from .assets.ui import Blenvy_assets
from .assets.assets_registry import Asset, AssetsRegistry
@ -62,9 +49,12 @@ from .blueprints.blueprints_registry import BlueprintsRegistry
from .blueprints.operators import OT_select_blueprint
# blenvy core
from .core.ui import BLENVY_PT_SidePanel
from .core.blenvy_manager import BlenvyManager
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_OpenFolderbrowser
# this needs to be here, as it is how Blender's gltf exporter callbacks are defined, at the add-on root level
@ -73,6 +63,12 @@ def glTF2_post_export_callback(data):
classes = [
# common/core
SceneSelector,
SCENE_UL_Blenvy,
SCENES_LIST_OT_actions,
OT_OpenFolderbrowser,
# blenvy
BLENVY_PT_SidePanel,
@ -121,23 +117,13 @@ classes = [
GENERIC_MAP_OT_actions,
# gltf auto export
SceneLink,
SceneLinks,
CUSTOM_PG_sceneName,
SCENE_UL_GLTF_auto_export,
SCENES_LIST_OT_actions,
OT_OpenFolderbrowser,
AutoExportGLTF,
CollectionToExport,
BlueprintsToExport,
GLTF_PT_auto_export_main,
GLTF_PT_auto_export_root,
GLTF_PT_auto_export_general,
GLTF_PT_auto_export_change_detection,
GLTF_PT_auto_export_scenes,
GLTF_PT_auto_export_blueprints,
GLTF_PT_auto_export_SidePanel,
AutoExportTracker,

View File

@ -1,7 +1,7 @@
import bpy
from bpy_types import (PropertyGroup)
from bpy.props import (EnumProperty, PointerProperty, StringProperty)
from bpy.props import (EnumProperty, PointerProperty, StringProperty, CollectionProperty, IntProperty)
from .scene_helpers import SceneSelector
class BlenvyManager(PropertyGroup):
@ -46,14 +46,38 @@ class BlenvyManager(PropertyGroup):
description='path to export the materials libraries to (relative to the assets folder)',
default='materials',
) # type: ignore
main_scenes: CollectionProperty(name="main scenes", type=SceneSelector) # type: ignore
main_scenes_index: IntProperty(name = "Index for main scenes list", default = 0) # type: ignore
library_scenes: CollectionProperty(name="library scenes", type=SceneSelector) # type: ignore
library_scenes_index: IntProperty(name = "Index for library scenes list", default = 0) # type: ignore
def is_scene_ok(self, scene):
try:
operator = bpy.context.space_data.active_operator
return scene.name not in operator.main_scenes and scene.name not in operator.library_scenes
except:
return True
@classmethod
def register(cls):
bpy.types.WindowManager.main_scene = bpy.props.PointerProperty(type=bpy.types.Scene, name="main scene", description="main_scene_picker", poll=cls.is_scene_ok)
bpy.types.WindowManager.library_scene = bpy.props.PointerProperty(type=bpy.types.Scene, name="library scene", description="library_scene_picker", poll=cls.is_scene_ok)
bpy.types.WindowManager.main_scenes_list_index = IntProperty(name = "Index for main scenes list", default = 0)
bpy.types.WindowManager.library_scenes_list_index = IntProperty(name = "Index for library scenes list", default = 0)
bpy.types.WindowManager.blenvy = PointerProperty(type=BlenvyManager)
@classmethod
def unregister(cls):
del bpy.types.WindowManager.blenvy
del bpy.types.WindowManager.main_scene
del bpy.types.WindowManager.library_scene
del bpy.types.WindowManager.main_scenes_list_index
del bpy.types.WindowManager.library_scenes_list_index
def add_asset(self, name, type, path, internal): # internal means it cannot be edited by the user, aka auto generated

View File

@ -1,3 +1,12 @@
import bpy
from .object_makers import make_empty
class SceneSelector(bpy.types.PropertyGroup):
name: bpy.props.StringProperty() # type: ignore
display: bpy.props.BoolProperty() # type: ignore
def add_scene_property(scene, scene_component_name, property_data, limit_to=None):
root_collection = scene.collection
scene_property = None

View File

View File

@ -0,0 +1,77 @@
import bpy
import os
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator
class OT_OpenFolderbrowser(Operator, ImportHelper):
"""Browse for registry json file"""
bl_idname = "generic.open_folderbrowser"
bl_label = "Select folder"
# Define this to tell 'fileselect_add' that we want a directoy
directory: bpy.props.StringProperty(
name="Outdir Path",
description="selected folder"
# subtype='DIR_PATH' is not needed to specify the selection mode.
# But this will be anyway a directory path.
) # type: ignore
# Filters folders
filter_folder: bpy.props.BoolProperty(
default=True,
options={"HIDDEN"}
) # type: ignore
target_property: bpy.props.StringProperty(
name="target_property",
options={'HIDDEN'}
) # type: ignore
def execute(self, context):
"""Do something with the selected file(s)."""
operator = context.window_manager.blenvy
new_path = self.directory
target_path_name = self.target_property
# path to the current blend file
blend_file_path = bpy.data.filepath
# Get the folder
blend_file_folder_path = os.path.dirname(blend_file_path)
print("blend_file_folder_path", blend_file_folder_path)
print("new_path", self.directory, self.target_property, operator)
asset_path_names = ['export_assets_path', 'export_blueprints_path', 'export_levels_path', 'export_materials_path']
export_root_path = operator.export_root_path
export_assets_path = operator.export_assets_path
#export_root_path_absolute = os.path.join(blend_file_folder_path, export_root_path)
export_assets_path_full = os.path.join(blend_file_folder_path, export_root_path, export_assets_path)
print("export_assets_path_full", export_assets_path_full)
#new_root_path = os.path.join(blend_file_folder_path, new_path)
if target_path_name == 'export_root_path':
new_root_path_relative = os.path.relpath(new_path, blend_file_folder_path)
print("changing root new_path to", self.directory, blend_file_folder_path, new_root_path_relative)
# we need to change all other relative paths before setting the new absolute path
for path_name in asset_path_names:
# get current relative path
relative_path = getattr(operator, path_name, None)
if relative_path is not None:
# and now get absolute path of asset_path
absolute_path = os.path.join(export_assets_path_full, relative_path)
print("absolute path for", path_name, absolute_path)
relative_path = os.path.relpath(absolute_path, new_path)
setattr(operator, path_name, relative_path)
# store the root path as relative to the current blend file
setattr(operator, target_path_name, new_path)
elif target_path_name == 'export_assets_path':
pass
else:
relative_path = os.path.relpath(new_path, export_assets_path_full)
setattr(operator, target_path_name, relative_path)
#filename, extension = os.path.splitext(self.filepath)
return {'FINISHED'}

View File

@ -0,0 +1,114 @@
import bpy
from bpy.types import Operator
class SCENE_UL_Blenvy(bpy.types.UIList):
# The draw_item function is called for each item of the collection that is visible in the list.
# data is the RNA object containing the collection,
# item is the current drawn item of the collection,
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
# have custom icons ID, which are not available as enum items).
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
# active item of the collection).
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
# index is index of the current item in the collection.
# flt_flag is the result of the filtering process for this item.
# Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't
# need them.
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
print("DRAW STUFF", self)
ob = data
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
if self.layout_type in {'DEFAULT', 'COMPACT'}:
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
# Note "data" names should never be translated!
#if ma:
# layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
#else:
# layout.label(text="", translate=False, icon_value=icon)
layout.label(text=item.name, icon_value=icon)
#layout.prop(item, "name", text="", emboss=False, icon_value=icon)
# 'GRID' layout type should be as compact as possible (typically a single icon!).
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class SCENES_LIST_OT_actions(Operator):
"""Move items up and down, add and remove"""
bl_idname = "scene_list.list_action"
bl_label = "List Actions"
bl_description = "Move items up and down, add and remove"
bl_options = {'REGISTER'}
action: bpy.props.EnumProperty(
items=(
('UP', "Up", ""),
('DOWN', "Down", ""),
('REMOVE', "Remove", ""),
('ADD', "Add", ""))) # type: ignore
scene_type: bpy.props.StringProperty()# type: ignore #TODO: replace with enum
def invoke(self, context, event):
source = context.window_manager.blenvy
target_name = "library_scenes"
target_index = "library_scenes_index"
if self.scene_type == "level":
target_name = "main_scenes"
target_index = "main_scenes_index"
target = getattr(source, target_name)
idx = getattr(source, target_index)
current_index = getattr(source, target_index)
try:
item = target[idx]
except IndexError:
pass
else:
if self.action == 'DOWN' and idx < len(target) - 1:
target.move(idx, idx + 1)
setattr(source, target_index, current_index +1 )
info = 'Item "%s" moved to position %d' % (item.name, current_index + 1)
self.report({'INFO'}, info)
elif self.action == 'UP' and idx >= 1:
target.move(idx, idx - 1)
setattr(source, target_index, current_index -1 )
info = 'Item "%s" moved to position %d' % (item.name, current_index + 1)
self.report({'INFO'}, info)
elif self.action == 'REMOVE':
info = 'Item "%s" removed from list' % (target[idx].name)
setattr(source, target_index, current_index -1 )
target.remove(idx)
self.report({'INFO'}, info)
if self.action == 'ADD':
new_scene_name = None
if self.scene_type == "level":
if context.window_manager.main_scene:
new_scene_name = context.window_manager.main_scene.name
else:
if context.window_manager.library_scene:
new_scene_name = context.window_manager.library_scene.name
if new_scene_name:
item = target.add()
item.name = new_scene_name#f"Rule {idx +1}"
if self.scene_type == "level":
context.window_manager.main_scene = None
else:
context.window_manager.library_scene = None
#name = f"Rule {idx +1}"
#target.append({"name": name})
setattr(source, target_index, len(target) - 1)
#source[target_index] = len(target) - 1
info = '"%s" added to list' % (item.name)
self.report({'INFO'}, info)
return {"FINISHED"}

View File

@ -1,7 +1,8 @@
import bpy
from ..settings import load_settings
from ...settings import load_settings
######################################################
## ui logic & co
def draw_folder_browser(layout, label, prop_origin, target_property):
row = layout.row()
@ -80,7 +81,6 @@ class BLENVY_PT_SidePanel(bpy.types.Panel):
layout.label(text="Library scene active: "+ str(library_scene_active))
layout.label(text=blenvy.mode)"""
if blenvy.mode == "SETTINGS":
header, panel = layout.panel("auto_export", default_closed=False)
header.label(text="Common")
@ -95,6 +95,55 @@ class BLENVY_PT_SidePanel(bpy.types.Panel):
draw_folder_browser(layout=row, label="Levels Folder", prop_origin=blenvy, target_property="export_levels_path")
row = panel.row()
draw_folder_browser(layout=row, label="Materials Folder", prop_origin=blenvy, target_property="export_materials_path")
panel.separator()
# scenes selection
section = panel
rows = 2
row = section.row()
row.label(text="main scenes")
row.prop(context.window_manager, "main_scene", text='')
row = section.row()
row.template_list("SCENE_UL_Blenvy", "level scenes", blenvy, "main_scenes", blenvy, "main_scenes_index", rows=rows)
col = row.column(align=True)
sub_row = col.row()
add_operator = sub_row.operator("scene_list.list_action", icon='ADD', text="")
add_operator.action = 'ADD'
add_operator.scene_type = 'level'
#add_operator.operator = operator
sub_row.enabled = context.window_manager.main_scene is not None
sub_row = col.row()
remove_operator = sub_row.operator("scene_list.list_action", icon='REMOVE', text="")
remove_operator.action = 'REMOVE'
remove_operator.scene_type = 'level'
col.separator()
# library scenes
row = section.row()
row.label(text="library scenes")
row.prop(context.window_manager, "library_scene", text='')
row = section.row()
row.template_list("SCENE_UL_Blenvy", "library scenes", blenvy, "library_scenes", blenvy, "library_scenes_index", rows=rows)
col = row.column(align=True)
sub_row = col.row()
add_operator = sub_row.operator("scene_list.list_action", icon='ADD', text="")
add_operator.action = 'ADD'
add_operator.scene_type = 'library'
sub_row.enabled = context.window_manager.library_scene is not None
sub_row = col.row()
remove_operator = sub_row.operator("scene_list.list_action", icon='REMOVE', text="")
remove_operator.action = 'REMOVE'
remove_operator.scene_type = 'library'
col.separator()
"""if blenvy.mode == "SETTINGS":
header, panel = layout.panel("auto_export", default_closed=False)
header.label(text="Auto Export")

View File

@ -109,10 +109,10 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
bpy.context.window_manager.auto_export_tracker.exports_total = exports_total
bpy.context.window_manager.auto_export_tracker.exports_count = exports_total
bpy.context.window_manager.exportedCollections.clear()
"""bpy.context.window_manager.exportedCollections.clear()
for blueprint in blueprints_to_export:
bla = bpy.context.window_manager.exportedCollections.add()
bla.name = blueprint.name
bla.name = blueprint.name"""
print("-------------------------------")
#print("collections: all:", collections)
#print("collections: not found on disk:", collections_not_on_disk)

View File

@ -1,22 +0,0 @@
import bpy
class SceneLink(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="") # type: ignore
scene: bpy.props.PointerProperty(type=bpy.types.Scene) # type: ignore
class SceneLinks(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="List of scenes to export", default="Unknown")
items: bpy.props.CollectionProperty(type = SceneLink) # type: ignore
class CUSTOM_PG_sceneName(bpy.types.PropertyGroup):
name: bpy.props.StringProperty() # type: ignore
display: bpy.props.BoolProperty() # type: ignore
class CollectionToExport(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="") # type: ignore
class BlueprintsToExport(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="List of collections to export", default="Unknown")
items: bpy.props.CollectionProperty(type = CollectionToExport) # type: ignore

View File

@ -1,11 +1,6 @@
import json
import bpy
from bpy.types import Operator
from bpy_extras.io_utils import ExportHelper
from bpy.props import (IntProperty, StringProperty, BoolProperty)
from ..ui.operators import OT_OpenFolderbrowser, draw_folder_browser
#from ..ui.main import GLTF_PT_auto_export_general, GLTF_PT_auto_export_main, GLTF_PT_auto_export_root
from .preferences import (AutoExportGltfAddonPreferences, AutoExportGltfPreferenceNames)
@ -54,29 +49,11 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
@classmethod
def register(cls):
bpy.types.WindowManager.main_scene = bpy.props.PointerProperty(type=bpy.types.Scene, name="main scene", description="main_scene_picker", poll=cls.is_scene_ok)
bpy.types.WindowManager.library_scene = bpy.props.PointerProperty(type=bpy.types.Scene, name="library scene", description="library_scene_picker", poll=cls.is_scene_ok)
bpy.types.WindowManager.main_scenes_list_index = IntProperty(name = "Index for main scenes list", default = 0)
bpy.types.WindowManager.library_scenes_list_index = IntProperty(name = "Index for library scenes list", default = 0)
cls.main_scenes_index = 0
cls.library_scenes_index = 0
pass
@classmethod
def unregister(cls):
del bpy.types.WindowManager.main_scene
del bpy.types.WindowManager.library_scene
del bpy.types.WindowManager.main_scenes_list_index
del bpy.types.WindowManager.library_scenes_list_index
def is_scene_ok(self, scene):
try:
operator = bpy.context.space_data.active_operator
return scene.name not in operator.main_scenes and scene.name not in operator.library_scenes
except:
return True
pass
def format_settings(self):
# find all props to save
@ -362,17 +339,7 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
if self.show_general_settings:
section = layout.box()
section.enabled = controls_enabled
draw_folder_browser(section, "Export root folder", self.export_root_path, "export_root_path")
row = section.row()
draw_folder_browser(row, "Assets Folder", self.export_root_path, "export_assets_path")
section.prop(operator, "export_scene_settings")
"""header, panel = layout.panel("my_panel_id", default_closed=False)
header.label(text="Hello World")
if panel:
panel.label(text="Success")"""
section.prop(operator, "export_scene_settings")
toggle_icon = "TRIA_DOWN" if self.show_change_detection_settings else "TRIA_RIGHT"
layout.prop(operator, "show_change_detection_settings", text="Change Detection", icon=toggle_icon)
if self.show_change_detection_settings:
@ -380,56 +347,6 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
section.enabled = controls_enabled
section.prop(operator, "export_change_detection", text="Use change detection")
# main/level scenes
toggle_icon = "TRIA_DOWN" if self.show_scene_settings else "TRIA_RIGHT"
layout.prop(operator, "show_scene_settings", text="Scenes", icon=toggle_icon)
if self.show_scene_settings:
section = layout.box()
section.enabled = controls_enabled
rows = 2
row = section.row()
row.label(text="main scenes")
row.prop(context.window_manager, "main_scene", text='')
row = section.row()
row.template_list("SCENE_UL_GLTF_auto_export", "level scenes", operator, "main_scenes", operator, "main_scenes_index", rows=rows)
col = row.column(align=True)
sub_row = col.row()
add_operator = sub_row.operator("scene_list.list_action", icon='ADD', text="")
add_operator.action = 'ADD'
add_operator.scene_type = 'level'
#add_operator.operator = operator
sub_row.enabled = context.window_manager.main_scene is not None
sub_row = col.row()
remove_operator = sub_row.operator("scene_list.list_action", icon='REMOVE', text="")
remove_operator.action = 'REMOVE'
remove_operator.scene_type = 'level'
col.separator()
# library scenes
row = section.row()
row.label(text="library scenes")
row.prop(context.window_manager, "library_scene", text='')
row = section.row()
row.template_list("SCENE_UL_GLTF_auto_export", "library scenes", operator, "library_scenes", operator, "library_scenes_index", rows=rows)
col = row.column(align=True)
sub_row = col.row()
add_operator = sub_row.operator("scene_list.list_action", icon='ADD', text="")
add_operator.action = 'ADD'
add_operator.scene_type = 'library'
sub_row.enabled = context.window_manager.library_scene is not None
sub_row = col.row()
remove_operator = sub_row.operator("scene_list.list_action", icon='REMOVE', text="")
remove_operator.action = 'REMOVE'
remove_operator.scene_type = 'library'
col.separator()
toggle_icon = "TRIA_DOWN" if self.show_blueprint_settings else "TRIA_RIGHT"
layout.prop(operator, "show_blueprint_settings", text="Blueprints", icon=toggle_icon)
if self.show_blueprint_settings:
@ -441,15 +358,10 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
section.enabled = controls_enabled and self.export_blueprints
# collections/blueprints
draw_folder_browser(section, "Blueprints folder", self.export_root_path, "export_blueprints_path")
#section.prop(operator, "export_blueprints_path")
section.prop(operator, "collection_instances_combine_mode")
section.prop(operator, "export_marked_assets")
section.separator()
draw_folder_browser(section, "Levels folder", self.export_root_path, "export_levels_path")
#section.prop(operator, "export_levels_path")
section.prop(operator, "export_separate_dynamic_and_static_objects")
section.separator()
@ -457,7 +369,6 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
section.prop(operator, "export_materials_library")
section = section.box()
section.enabled = controls_enabled and self.export_materials_library
draw_folder_browser(section, 'Materials folder', self.export_root_path, "export_materials_path")
#section.prop(operator, "export_materials_path")

View File

@ -8,8 +8,6 @@ from bpy.props import (BoolProperty,
CollectionProperty
)
from .internals import (CUSTOM_PG_sceneName)
AutoExportGltfPreferenceNames = [
'will_save_settings',
'direct_mode',# specific to main auto_export operator
@ -201,8 +199,3 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
default=True
) # type: ignore
main_scenes: CollectionProperty(name="main scenes", type=CUSTOM_PG_sceneName) # type: ignore
main_scenes_index: IntProperty(name = "Index for main scenes list", default = 0) # type: ignore
library_scenes: CollectionProperty(name="library scenes", type=CUSTOM_PG_sceneName) # type: ignore
library_scenes_index: IntProperty(name = "Index for library scenes list", default = 0) # type: ignore

View File

@ -4,12 +4,7 @@ import bpy
from bpy.types import (PropertyGroup)
from bpy.props import (PointerProperty, IntProperty, StringProperty)
from .get_blueprints_to_export import get_blueprints_to_export
from ..constants import TEMPSCENE_PREFIX
from .internals import BlueprintsToExport
from ..helpers.helpers_scenes import (get_scenes)
from .preferences import AutoExportGltfAddonPreferences
class AutoExportTracker(PropertyGroup):
@ -36,8 +31,6 @@ class AutoExportTracker(PropertyGroup):
@classmethod
def register(cls):
bpy.types.WindowManager.auto_export_tracker = PointerProperty(type=AutoExportTracker)
# register list of exportable collections
bpy.types.WindowManager.exportedCollections = bpy.props.CollectionProperty(type=BlueprintsToExport)
# setup handlers for updates & saving
#bpy.app.handlers.save_post.append(cls.save_handler)
@ -53,7 +46,6 @@ class AutoExportTracker(PropertyGroup):
bpy.app.handlers.save_post.remove(cls.save_handler)
except:pass"""
del bpy.types.WindowManager.auto_export_tracker
del bpy.types.WindowManager.exportedCollections
@classmethod
def save_handler(cls, scene, depsgraph):

View File

@ -143,92 +143,6 @@ class GLTF_PT_auto_export_change_detection(bpy.types.Panel):
layout.active = operator.auto_export
layout.prop(operator, "export_change_detection")
class GLTF_PT_auto_export_scenes(bpy.types.Panel):
bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOL_PROPS'
bl_label = "Scenes"
bl_parent_id = "GLTF_PT_auto_export_root"
@classmethod
def poll(cls, context):
sfile = context.space_data
operator = sfile.active_operator
return operator.bl_idname == "EXPORT_SCENES_OT_auto_gltf" #"EXPORT_SCENE_OT_gltf"
def draw_header(self, context):
layout = self.layout
sfile = context.space_data
operator = sfile.active_operator
#layout.label(text="export scenes")#layout.prop(operator, "export_blueprints", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
sfile = context.space_data
operator = sfile.active_operator
# scene selectors
row = layout.row()
col = row.column(align=True)
col.separator()
layout.active = operator.auto_export
source = operator
rows = 2
# main/level scenes
row = layout.row()
row.label(text="main scenes")
row.prop(context.window_manager, "main_scene", text='')
row = layout.row()
row.template_list("SCENE_UL_GLTF_auto_export", "level scenes", source, "main_scenes", source, "main_scenes_index", rows=rows)
col = row.column(align=True)
sub_row = col.row()
add_operator = sub_row.operator("scene_list.list_action", icon='ADD', text="")
add_operator.action = 'ADD'
add_operator.scene_type = 'level'
#add_operator.source = operator
sub_row.enabled = context.window_manager.main_scene is not None
sub_row = col.row()
remove_operator = sub_row.operator("scene_list.list_action", icon='REMOVE', text="")
remove_operator.action = 'REMOVE'
remove_operator.scene_type = 'level'
col.separator()
#up_operator = col.operator("scene_list.list_action", icon='TRIA_UP', text="")
#up_operator.action = 'UP'
#col.operator("scene_list.list_action", icon='TRIA_DOWN', text="").action = 'DOWN'
# library scenes
row = layout.row()
row.label(text="library scenes")
row.prop(context.window_manager, "library_scene", text='')
row = layout.row()
row.template_list("SCENE_UL_GLTF_auto_export", "library scenes", source, "library_scenes", source, "library_scenes_index", rows=rows)
col = row.column(align=True)
sub_row = col.row()
add_operator = sub_row.operator("scene_list.list_action", icon='ADD', text="")
add_operator.action = 'ADD'
add_operator.scene_type = 'library'
sub_row.enabled = context.window_manager.library_scene is not None
sub_row = col.row()
remove_operator = sub_row.operator("scene_list.list_action", icon='REMOVE', text="")
remove_operator.action = 'REMOVE'
remove_operator.scene_type = 'library'
col.separator()
class GLTF_PT_auto_export_blueprints(bpy.types.Panel):
bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOL_PROPS'
@ -268,35 +182,4 @@ class GLTF_PT_auto_export_blueprints(bpy.types.Panel):
# materials
layout.prop(operator, "export_materials_library")
layout.prop(operator, "export_materials_path")
class SCENE_UL_GLTF_auto_export(bpy.types.UIList):
# The draw_item function is called for each item of the collection that is visible in the list.
# data is the RNA object containing the collection,
# item is the current drawn item of the collection,
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
# have custom icons ID, which are not available as enum items).
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
# active item of the collection).
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
# index is index of the current item in the collection.
# flt_flag is the result of the filtering process for this item.
# Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't
# need them.
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
ob = data
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
if self.layout_type in {'DEFAULT', 'COMPACT'}:
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
# Note "data" names should never be translated!
#if ma:
# layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
#else:
# layout.label(text="", translate=False, icon_value=icon)
layout.label(text=item.name, icon_value=icon)
#layout.prop(item, "name", text="", emboss=False, icon_value=icon)
# 'GRID' layout type should be as compact as possible (typically a single icon!).
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)

View File

@ -1,181 +0,0 @@
import bpy
from bpy.types import Operator
class ASSETS_LIST_OT_actions(Operator):
"""Add / remove etc assets"""
bl_idname = "asset_list.list_action"
bl_label = "Asset Actions"
bl_description = "Move items up and down, add and remove"
bl_options = {'REGISTER'}
class SCENES_LIST_OT_actions(Operator):
"""Move items up and down, add and remove"""
bl_idname = "scene_list.list_action"
bl_label = "List Actions"
bl_description = "Move items up and down, add and remove"
bl_options = {'REGISTER'}
action: bpy.props.EnumProperty(
items=(
('UP', "Up", ""),
('DOWN', "Down", ""),
('REMOVE', "Remove", ""),
('ADD', "Add", ""))) # type: ignore
scene_type: bpy.props.StringProperty()#TODO: replace with enum
def invoke(self, context, event):
source = context.active_operator
target_name = "library_scenes"
target_index = "library_scenes_index"
if self.scene_type == "level":
target_name = "main_scenes"
target_index = "main_scenes_index"
target = getattr(source, target_name)
idx = getattr(source, target_index)
current_index = getattr(source, target_index)
try:
item = target[idx]
except IndexError:
pass
else:
if self.action == 'DOWN' and idx < len(target) - 1:
target.move(idx, idx + 1)
setattr(source, target_index, current_index +1 )
info = 'Item "%s" moved to position %d' % (item.name, current_index + 1)
self.report({'INFO'}, info)
elif self.action == 'UP' and idx >= 1:
target.move(idx, idx - 1)
setattr(source, target_index, current_index -1 )
info = 'Item "%s" moved to position %d' % (item.name, current_index + 1)
self.report({'INFO'}, info)
elif self.action == 'REMOVE':
info = 'Item "%s" removed from list' % (target[idx].name)
setattr(source, target_index, current_index -1 )
target.remove(idx)
self.report({'INFO'}, info)
if self.action == 'ADD':
new_scene_name = None
if self.scene_type == "level":
if context.window_manager.main_scene:
new_scene_name = context.window_manager.main_scene.name
else:
if context.window_manager.library_scene:
new_scene_name = context.window_manager.library_scene.name
if new_scene_name:
item = target.add()
item.name = new_scene_name#f"Rule {idx +1}"
if self.scene_type == "level":
context.window_manager.main_scene = None
else:
context.window_manager.library_scene = None
#name = f"Rule {idx +1}"
#target.append({"name": name})
setattr(source, target_index, len(target) - 1)
#source[target_index] = len(target) - 1
info = '"%s" added to list' % (item.name)
self.report({'INFO'}, info)
return {"FINISHED"}
import os
from bpy_extras.io_utils import ImportHelper
class OT_OpenFolderbrowser(Operator, ImportHelper):
"""Browse for registry json file"""
bl_idname = "generic.open_folderbrowser"
bl_label = "Select folder"
# Define this to tell 'fileselect_add' that we want a directoy
directory: bpy.props.StringProperty(
name="Outdir Path",
description="selected folder"
# subtype='DIR_PATH' is not needed to specify the selection mode.
# But this will be anyway a directory path.
) # type: ignore
# Filters folders
filter_folder: bpy.props.BoolProperty(
default=True,
options={"HIDDEN"}
) # type: ignore
target_property: bpy.props.StringProperty(
name="target_property",
options={'HIDDEN'}
) # type: ignore
def execute(self, context):
"""Do something with the selected file(s)."""
operator = context.active_operator
new_path = self.directory
target_path_name = self.target_property
# path to the current blend file
blend_file_path = bpy.data.filepath
# Get the folder
blend_file_folder_path = os.path.dirname(blend_file_path)
print("blend_file_folder_path", blend_file_folder_path)
print("new_path", self.directory, self.target_property, operator)
asset_path_names = ['export_assets_path', 'export_blueprints_path', 'export_levels_path', 'export_materials_path']
export_root_path = operator.export_root_path
export_assets_path = operator.export_assets_path
#export_root_path_absolute = os.path.join(blend_file_folder_path, export_root_path)
export_assets_path_full = os.path.join(blend_file_folder_path, export_root_path, export_assets_path)
print("export_assets_path_full", export_assets_path_full)
#new_root_path = os.path.join(blend_file_folder_path, new_path)
if target_path_name == 'export_root_path':
new_root_path_relative = os.path.relpath(new_path, blend_file_folder_path)
print("changing root new_path to", self.directory, blend_file_folder_path, new_root_path_relative)
# we need to change all other relative paths before setting the new absolute path
for path_name in asset_path_names:
# get current relative path
relative_path = getattr(operator, path_name, None)
if relative_path is not None:
# and now get absolute path of asset_path
absolute_path = os.path.join(export_assets_path_full, relative_path)
print("absolute path for", path_name, absolute_path)
relative_path = os.path.relpath(absolute_path, new_path)
setattr(operator, path_name, relative_path)
# store the root path as relative to the current blend file
setattr(operator, target_path_name, new_path)
elif target_path_name == 'export_assets_path':
pass
else:
relative_path = os.path.relpath(new_path, export_assets_path_full)
setattr(operator, target_path_name, relative_path)
#filename, extension = os.path.splitext(self.filepath)
return {'FINISHED'}
def draw_folder_browser(layout, label, value, target_property):
row = layout.row()
row.label(text=label)
'''box = row.box()
box.scale_y = 0.5
box.label(text=value)'''
col = row.column()
col.enabled = False
col.prop(bpy.context.active_operator, target_property, text="")
folder_selector = row.operator(OT_OpenFolderbrowser.bl_idname, icon="FILE_FOLDER", text="")
folder_selector.target_property = target_property #"export_root_path"