mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-22 11:50:53 +00:00
feat(Blenvy:Blender):
* cleanups to dynamic/static object detection * filtered out MaterialInfos from "fixable" Components * will now attempt to inject actual component for materialInfos * if it fails, falls back to previous custom property logic * added ability to disable ui for certain components * added display of "internal" components * internal components such as MaterialInfos are now viewable but disabled (non editable) for more clarity * experimenting with auto_reload of registry if missing (wip) * minor tweaks
This commit is contained in:
parent
0b02a24313
commit
bd830e5ad4
17
TODO.md
17
TODO.md
@ -259,6 +259,23 @@ Blender side:
|
|||||||
- [x] make sure the "add scene" button is not available unless you have actually selected one
|
- [x] make sure the "add scene" button is not available unless you have actually selected one
|
||||||
- [x] make auto export be on by default, however bail out early by detecting if there are any level/blueprint scenes
|
- [x] make auto export be on by default, however bail out early by detecting if there are any level/blueprint scenes
|
||||||
- [x] remove custom components to filter out correctly from exported blueprints list
|
- [x] remove custom components to filter out correctly from exported blueprints list
|
||||||
|
- [ ] for built in Component types that need to be injected to be used by blueprints,
|
||||||
|
namely:
|
||||||
|
- BlueprintInfos (not 100% sure for this one)
|
||||||
|
- MaterialInfos
|
||||||
|
- the various scene Components
|
||||||
|
- BlueprintAssets (although not really needed anymore with the meta files)
|
||||||
|
|
||||||
|
- [ ] Inject real components instead of just custom properties
|
||||||
|
- [ ] add boilerplate to generate real component values from type definitions instead of hacking pseudo ron strings
|
||||||
|
- [ ] fall back to bevy_components if that fails (missing registry) or just basic custom properties
|
||||||
|
- [ ] If that fails as well ?
|
||||||
|
- [ ] auto reload registry if absent/possible
|
||||||
|
- cannot be done from UI possibly polling with increasing timeout
|
||||||
|
- bpy.ops.blenvy.components_registry_reload()
|
||||||
|
|
||||||
|
- [x] filter out MaterialInfos from list of "fixable components"
|
||||||
|
|
||||||
|
|
||||||
Bevy Side:
|
Bevy Side:
|
||||||
- [x] deprecate BlueprintName & BlueprintPath & use BlueprintInfo instead
|
- [x] deprecate BlueprintName & BlueprintPath & use BlueprintInfo instead
|
||||||
|
@ -3,7 +3,6 @@ import bpy
|
|||||||
from ...bevy_components.components.metadata import get_bevy_component_value_by_long_name
|
from ...bevy_components.components.metadata import get_bevy_component_value_by_long_name
|
||||||
|
|
||||||
# checks if an object is dynamic
|
# checks if an object is dynamic
|
||||||
# TODO: for efficiency, it might make sense to write this flag semi automatically at the root level of the object so we can skip the inner loop
|
|
||||||
# TODO: we need to recompute these on blueprint changes too
|
# TODO: we need to recompute these on blueprint changes too
|
||||||
# even better, keep a list of dynamic objects per scene , updated only when needed ?
|
# even better, keep a list of dynamic objects per scene , updated only when needed ?
|
||||||
def is_object_dynamic(object):
|
def is_object_dynamic(object):
|
||||||
@ -15,17 +14,9 @@ def is_object_dynamic(object):
|
|||||||
# get the name of the collection this is an instance of
|
# get the name of the collection this is an instance of
|
||||||
collection_name = object.instance_collection.name
|
collection_name = object.instance_collection.name
|
||||||
original_collection = bpy.data.collections[collection_name]
|
original_collection = bpy.data.collections[collection_name]
|
||||||
|
|
||||||
is_dynamic = get_bevy_component_value_by_long_name(original_collection, 'blenvy::save_load::Dynamic') is not None
|
|
||||||
# scan original collection, look for a 'Dynamic' flag
|
# scan original collection, look for a 'Dynamic' flag
|
||||||
"""for object in original_collection.objects:
|
is_dynamic = get_bevy_component_value_by_long_name(original_collection, 'blenvy::save_load::Dynamic') is not None
|
||||||
#print(" inner", object)
|
|
||||||
if object.type == 'EMPTY': #and object.name.endswith("components"):
|
|
||||||
for component_name in object.keys():
|
|
||||||
#print(" compo", component_name)
|
|
||||||
if component_name == 'Dynamic':
|
|
||||||
is_dynamic = True
|
|
||||||
break"""
|
|
||||||
#print("IS OBJECT DYNAMIC", object, is_dynamic)
|
#print("IS OBJECT DYNAMIC", object, is_dynamic)
|
||||||
|
|
||||||
return is_dynamic
|
return is_dynamic
|
||||||
|
@ -5,7 +5,7 @@ from ..utils import get_selected_item, get_selection_type
|
|||||||
from .metadata import do_item_custom_properties_have_missing_metadata, get_bevy_components
|
from .metadata import do_item_custom_properties_have_missing_metadata, get_bevy_components
|
||||||
|
|
||||||
|
|
||||||
def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_type="OBJECT", item_name=""):
|
def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_type="OBJECT", item_name="", enabled=True):
|
||||||
is_enum = getattr(propertyGroup, "with_enum")
|
is_enum = getattr(propertyGroup, "with_enum")
|
||||||
is_list = getattr(propertyGroup, "with_list")
|
is_list = getattr(propertyGroup, "with_list")
|
||||||
is_map = getattr(propertyGroup, "with_map")
|
is_map = getattr(propertyGroup, "with_map")
|
||||||
@ -13,6 +13,7 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
|||||||
|
|
||||||
# if it is an enum, the first field name is always the list of enum variants, the others are the variants
|
# if it is an enum, the first field name is always the list of enum variants, the others are the variants
|
||||||
field_names = propertyGroup.field_names
|
field_names = propertyGroup.field_names
|
||||||
|
layout.enabled = enabled
|
||||||
#print("")
|
#print("")
|
||||||
#print("drawing", propertyGroup, nesting, "component_name", rootName)
|
#print("drawing", propertyGroup, nesting, "component_name", rootName)
|
||||||
if is_enum:
|
if is_enum:
|
||||||
@ -31,7 +32,7 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
|||||||
nested = getattr(nestedPropertyGroup, "nested", False)
|
nested = getattr(nestedPropertyGroup, "nested", False)
|
||||||
#print("nestedPropertyGroup", nestedPropertyGroup, fname, nested)
|
#print("nestedPropertyGroup", nestedPropertyGroup, fname, nested)
|
||||||
if nested:
|
if nested:
|
||||||
draw_propertyGroup(nestedPropertyGroup, subrow.column(), nesting + [fname], rootName, item_type, item_name )
|
draw_propertyGroup(nestedPropertyGroup, subrow.column(), nesting + [fname], rootName, item_type, item_name, enabled=enabled )
|
||||||
# if an enum variant is not a propertyGroup
|
# if an enum variant is not a propertyGroup
|
||||||
break
|
break
|
||||||
elif is_list:
|
elif is_list:
|
||||||
@ -39,12 +40,13 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
|||||||
list_index = getattr(propertyGroup, "list_index")
|
list_index = getattr(propertyGroup, "list_index")
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
split = box.split(factor=0.9)
|
split = box.split(factor=0.9)
|
||||||
|
box.enabled = enabled
|
||||||
list_column, buttons_column = (split.column(),split.column())
|
list_column, buttons_column = (split.column(),split.column())
|
||||||
|
|
||||||
list_column = list_column.box()
|
list_column = list_column.box()
|
||||||
for index, item in enumerate(item_list):
|
for index, item in enumerate(item_list):
|
||||||
row = list_column.row()
|
row = list_column.row()
|
||||||
draw_propertyGroup(item, row, nesting, rootName, item_type)
|
draw_propertyGroup(item, row, nesting, rootName, item_type, enabled=enabled)
|
||||||
icon = 'CHECKBOX_HLT' if list_index == index else 'CHECKBOX_DEHLT'
|
icon = 'CHECKBOX_HLT' if list_index == index else 'CHECKBOX_DEHLT'
|
||||||
op = row.operator('blenvy.component_list_actions', icon=icon, text="")
|
op = row.operator('blenvy.component_list_actions', icon=icon, text="")
|
||||||
op.action = 'SELECT'
|
op.action = 'SELECT'
|
||||||
@ -100,10 +102,10 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
|||||||
row = box.row()
|
row = box.row()
|
||||||
row.label(text="Add entry:")
|
row.label(text="Add entry:")
|
||||||
keys_setter = getattr(propertyGroup, "keys_setter")
|
keys_setter = getattr(propertyGroup, "keys_setter")
|
||||||
draw_propertyGroup(keys_setter, row, nesting, rootName, item_type, item_name)
|
draw_propertyGroup(keys_setter, row, nesting, rootName, item_type, item_name, enabled=enabled)
|
||||||
|
|
||||||
values_setter = getattr(propertyGroup, "values_setter")
|
values_setter = getattr(propertyGroup, "values_setter")
|
||||||
draw_propertyGroup(values_setter, row, nesting, rootName, item_type, item_name)
|
draw_propertyGroup(values_setter, row, nesting, rootName, item_type, item_name, enabled=enabled)
|
||||||
|
|
||||||
op = row.operator('blenvy.component_map_actions', icon='ADD', text="")
|
op = row.operator('blenvy.component_map_actions', icon='ADD', text="")
|
||||||
op.action = 'ADD'
|
op.action = 'ADD'
|
||||||
@ -119,10 +121,10 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
|||||||
|
|
||||||
for index, item in enumerate(keys_list):
|
for index, item in enumerate(keys_list):
|
||||||
row = list_column.row()
|
row = list_column.row()
|
||||||
draw_propertyGroup(item, row, nesting, rootName, item_type, item_name)
|
draw_propertyGroup(item, row, nesting, rootName, item_type, item_name, enabled=enabled)
|
||||||
|
|
||||||
value = values_list[index]
|
value = values_list[index]
|
||||||
draw_propertyGroup(value, row, nesting, rootName, item_type, item_name)
|
draw_propertyGroup(value, row, nesting, rootName, item_type, item_name, enabled=enabled)
|
||||||
|
|
||||||
op = row.operator('blenvy.component_map_actions', icon='REMOVE', text="")
|
op = row.operator('blenvy.component_map_actions', icon='REMOVE', text="")
|
||||||
op.action = 'REMOVE'
|
op.action = 'REMOVE'
|
||||||
@ -151,7 +153,7 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
|||||||
layout.label(text=display_name) # this is the name of the field/sub field
|
layout.label(text=display_name) # this is the name of the field/sub field
|
||||||
layout.separator()
|
layout.separator()
|
||||||
subrow = layout.row()
|
subrow = layout.row()
|
||||||
draw_propertyGroup(nestedPropertyGroup, subrow, nesting + [fname], rootName, item_type, item_name )
|
draw_propertyGroup(nestedPropertyGroup, subrow, nesting + [fname], rootName, item_type, item_name, enabled )
|
||||||
else:
|
else:
|
||||||
subrow = layout.row()
|
subrow = layout.row()
|
||||||
subrow.prop(propertyGroup, fname, text=display_name)
|
subrow.prop(propertyGroup, fname, text=display_name)
|
||||||
@ -233,6 +235,9 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
|||||||
item_name = object_or_collection.name
|
item_name = object_or_collection.name
|
||||||
#print("components_names", dict(components_bla).keys())
|
#print("components_names", dict(components_bla).keys())
|
||||||
|
|
||||||
|
#FIXME: move out, highly inneficient
|
||||||
|
internal_components = ['BlueprintInfos', 'blenvy::blueprints::materials::MaterialInfos']
|
||||||
|
|
||||||
for component_name in sorted(get_bevy_components(object_or_collection)) : # sorted by component name, practical
|
for component_name in sorted(get_bevy_components(object_or_collection)) : # sorted by component name, practical
|
||||||
if component_name == "components_meta":
|
if component_name == "components_meta":
|
||||||
continue
|
continue
|
||||||
@ -244,7 +249,9 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
|||||||
component_invalid = getattr(component_meta, "invalid")
|
component_invalid = getattr(component_meta, "invalid")
|
||||||
invalid_details = getattr(component_meta, "invalid_details")
|
invalid_details = getattr(component_meta, "invalid_details")
|
||||||
component_visible = getattr(component_meta, "visible")
|
component_visible = getattr(component_meta, "visible")
|
||||||
|
component_internal = component_name in internal_components # internal components are not editable ?
|
||||||
single_field = False
|
single_field = False
|
||||||
|
label = f"{component_name}{' (internal)' if component_internal else ''}"
|
||||||
|
|
||||||
# our whole row
|
# our whole row
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
@ -252,7 +259,8 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
|||||||
# "header"
|
# "header"
|
||||||
row.alert = component_invalid
|
row.alert = component_invalid
|
||||||
row.prop(component_meta, "enabled", text="")
|
row.prop(component_meta, "enabled", text="")
|
||||||
row.label(text=component_name)
|
row.label(text=label)
|
||||||
|
#row.enabled = not component_internal
|
||||||
|
|
||||||
# we fetch the matching ui property group
|
# we fetch the matching ui property group
|
||||||
root_propertyGroup_name = registry.get_propertyGroupName_from_longName(component_name)
|
root_propertyGroup_name = registry.get_propertyGroupName_from_longName(component_name)
|
||||||
@ -272,7 +280,7 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
|||||||
error_message = invalid_details if component_invalid else "Missing component UI data, please reload registry !"
|
error_message = invalid_details if component_invalid else "Missing component UI data, please reload registry !"
|
||||||
prop_group_location.label(text=error_message)
|
prop_group_location.label(text=error_message)
|
||||||
else:
|
else:
|
||||||
draw_propertyGroup(propertyGroup, prop_group_location, [root_propertyGroup_name], component_name, item_type, item_name)
|
draw_propertyGroup(propertyGroup, prop_group_location, [root_propertyGroup_name], component_name, item_type, item_name, enabled=not component_internal)
|
||||||
else :
|
else :
|
||||||
row.label(text="details hidden, click on toggle to display")
|
row.label(text="details hidden, click on toggle to display")
|
||||||
else:
|
else:
|
||||||
@ -293,6 +301,7 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
|||||||
op.component_name = component_name
|
op.component_name = component_name
|
||||||
row.separator()
|
row.separator()
|
||||||
|
|
||||||
|
if not component_internal:
|
||||||
op = row.operator("blenvy.component_remove", text="", icon="X")
|
op = row.operator("blenvy.component_remove", text="", icon="X")
|
||||||
op.component_name = component_name
|
op.component_name = component_name
|
||||||
op.item_name = object_or_collection.name
|
op.item_name = object_or_collection.name
|
||||||
@ -388,7 +397,7 @@ class BLENVY_PT_component_tools_panel(bpy.types.Panel):
|
|||||||
self.draw_invalid_or_unregistered(layout, status, custom_property, item, item_type)
|
self.draw_invalid_or_unregistered(layout, status, custom_property, item, item_type)
|
||||||
|
|
||||||
def gather_invalid_item_data(self, item, invalid_component_names, items_with_invalid_components, items_with_original_components, original_name, item_type):
|
def gather_invalid_item_data(self, item, invalid_component_names, items_with_invalid_components, items_with_original_components, original_name, item_type):
|
||||||
blenvy_custom_properties = ['components_meta', 'bevy_components', 'user_assets', 'generated_assets', 'BlueprintAssets', 'export_path' ] # some of our own hard coded custom properties that should be ignored
|
blenvy_custom_properties = ['components_meta', 'bevy_components', 'user_assets', 'generated_assets', 'BlueprintAssets', 'export_path', 'MaterialInfos' ] # some of our own hard coded custom properties that should be ignored
|
||||||
upgreadable_entries = []
|
upgreadable_entries = []
|
||||||
|
|
||||||
if "components_meta" in item or hasattr(item, "components_meta"): # FIXME; wrong way of determining
|
if "components_meta" in item or hasattr(item, "components_meta"): # FIXME; wrong way of determining
|
||||||
|
@ -32,6 +32,7 @@ def watch_schema():
|
|||||||
blenvy = bpy.context.window_manager.blenvy
|
blenvy = bpy.context.window_manager.blenvy
|
||||||
component_settings = blenvy.components
|
component_settings = blenvy.components
|
||||||
#print("watching schema file for changes")
|
#print("watching schema file for changes")
|
||||||
|
reloading_registry = False
|
||||||
try:
|
try:
|
||||||
stamp = os.stat(component_settings.schema_path_full).st_mtime
|
stamp = os.stat(component_settings.schema_path_full).st_mtime
|
||||||
stamp = str(stamp)
|
stamp = str(stamp)
|
||||||
@ -47,11 +48,19 @@ def watch_schema():
|
|||||||
# we need to add an additional delay as the file might not have loaded yet
|
# we need to add an additional delay as the file might not have loaded yet
|
||||||
bpy.app.timers.register(lambda: bpy.ops.blenvy.components_registry_reload(), first_interval=1)
|
bpy.app.timers.register(lambda: bpy.ops.blenvy.components_registry_reload(), first_interval=1)
|
||||||
component_settings.schemaTimeStamp = stamp
|
component_settings.schemaTimeStamp = stamp
|
||||||
|
reloading_registry = True
|
||||||
|
|
||||||
if component_settings.schemaTimeStamp == "":
|
if component_settings.schemaTimeStamp == "":
|
||||||
component_settings.schemaTimeStamp = stamp
|
component_settings.schemaTimeStamp = stamp
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# if there is no registry loaded yet, try to load it
|
||||||
|
"""registry = bpy.context.window_manager.components_registry
|
||||||
|
if not reloading_registry and len(list(registry.type_infos.keys())) == 0:
|
||||||
|
print("reload registry here")
|
||||||
|
bpy.app.timers.register(lambda: bpy.ops.blenvy.components_registry_reload(), first_interval=1)"""
|
||||||
|
|
||||||
return component_settings.watcher_poll_frequency if component_settings.watcher_enabled else None
|
return component_settings.watcher_poll_frequency if component_settings.watcher_enabled else None
|
||||||
|
|
||||||
class ComponentsSettings(PropertyGroup):
|
class ComponentsSettings(PropertyGroup):
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import posixpath
|
import posixpath
|
||||||
from ..core.helpers_collections import (traverse_tree)
|
from ..core.helpers_collections import (traverse_tree)
|
||||||
|
from ..add_ons.bevy_components.components.metadata import apply_propertyGroup_values_to_item_customProperties_for_component, upsert_bevy_component, get_bevy_component_value_by_long_name
|
||||||
|
|
||||||
def find_materials_not_on_disk(materials, materials_path_full, extension):
|
def find_materials_not_on_disk(materials, materials_path_full, extension):
|
||||||
not_found_materials = []
|
not_found_materials = []
|
||||||
@ -79,6 +80,7 @@ def get_all_materials(collection_names, library_scenes):
|
|||||||
used_material_names = list(set(used_material_names))
|
used_material_names = list(set(used_material_names))
|
||||||
return (used_material_names, materials_per_object)
|
return (used_material_names, materials_per_object)
|
||||||
|
|
||||||
|
import bpy
|
||||||
def add_material_info_to_objects(materials_per_object, settings):
|
def add_material_info_to_objects(materials_per_object, settings):
|
||||||
materials_path = getattr(settings, "materials_path")
|
materials_path = getattr(settings, "materials_path")
|
||||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||||
@ -90,8 +92,13 @@ def add_material_info_to_objects(materials_per_object, settings):
|
|||||||
material_infos.append(material_info)
|
material_infos.append(material_info)
|
||||||
# problem with using actual components: you NEED the type registry/component infos, so if there is none , or it is not loaded yet, it does not work
|
# problem with using actual components: you NEED the type registry/component infos, so if there is none , or it is not loaded yet, it does not work
|
||||||
# for a few components we could hardcode this
|
# for a few components we could hardcode this
|
||||||
#bpy.ops.blenvy.component_add(target_item_name=object.name, target_item_type="OBJECT", component_type="blenvy::blueprints::materials::MaterialInfos", component_value=component_value)
|
component_value = f"({material_infos})".replace("'","")
|
||||||
|
try:
|
||||||
|
bpy.ops.blenvy.component_add(target_item_name=object.name, target_item_type="OBJECT", component_type="blenvy::blueprints::materials::MaterialInfos", component_value=component_value )
|
||||||
|
except:
|
||||||
object['MaterialInfos'] = f"({material_infos})".replace("'","")
|
object['MaterialInfos'] = f"({material_infos})".replace("'","")
|
||||||
|
#upsert_bevy_component(object, "blenvy::blueprints::materials::MaterialInfos", f"({material_infos})".replace("'","") )
|
||||||
|
#apply_propertyGroup_values_to_item_customProperties_for_component(object, "MaterialInfos")
|
||||||
print("adding materialInfos to object", object, "material infos", material_infos)
|
print("adding materialInfos to object", object, "material infos", material_infos)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user