mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-12-22 15:44:11 +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 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
|
||||
- [ ] 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:
|
||||
- [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
|
||||
|
||||
# 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
|
||||
# even better, keep a list of dynamic objects per scene , updated only when needed ?
|
||||
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
|
||||
collection_name = object.instance_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
|
||||
"""for object in original_collection.objects:
|
||||
#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"""
|
||||
is_dynamic = get_bevy_component_value_by_long_name(original_collection, 'blenvy::save_load::Dynamic') is not None
|
||||
|
||||
#print("IS OBJECT DYNAMIC", object, 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
|
||||
|
||||
|
||||
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_list = getattr(propertyGroup, "with_list")
|
||||
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
|
||||
field_names = propertyGroup.field_names
|
||||
layout.enabled = enabled
|
||||
#print("")
|
||||
#print("drawing", propertyGroup, nesting, "component_name", rootName)
|
||||
if is_enum:
|
||||
@ -31,7 +32,7 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
||||
nested = getattr(nestedPropertyGroup, "nested", False)
|
||||
#print("nestedPropertyGroup", nestedPropertyGroup, fname, 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
|
||||
break
|
||||
elif is_list:
|
||||
@ -39,12 +40,13 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
||||
list_index = getattr(propertyGroup, "list_index")
|
||||
box = layout.box()
|
||||
split = box.split(factor=0.9)
|
||||
box.enabled = enabled
|
||||
list_column, buttons_column = (split.column(),split.column())
|
||||
|
||||
list_column = list_column.box()
|
||||
for index, item in enumerate(item_list):
|
||||
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'
|
||||
op = row.operator('blenvy.component_list_actions', icon=icon, text="")
|
||||
op.action = 'SELECT'
|
||||
@ -100,10 +102,10 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
||||
row = box.row()
|
||||
row.label(text="Add entry:")
|
||||
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")
|
||||
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.action = 'ADD'
|
||||
@ -119,10 +121,10 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None, item_
|
||||
|
||||
for index, item in enumerate(keys_list):
|
||||
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]
|
||||
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.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.separator()
|
||||
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:
|
||||
subrow = layout.row()
|
||||
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
|
||||
#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
|
||||
if component_name == "components_meta":
|
||||
continue
|
||||
@ -244,7 +249,9 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
||||
component_invalid = getattr(component_meta, "invalid")
|
||||
invalid_details = getattr(component_meta, "invalid_details")
|
||||
component_visible = getattr(component_meta, "visible")
|
||||
component_internal = component_name in internal_components # internal components are not editable ?
|
||||
single_field = False
|
||||
label = f"{component_name}{' (internal)' if component_internal else ''}"
|
||||
|
||||
# our whole row
|
||||
box = layout.box()
|
||||
@ -252,7 +259,8 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
||||
# "header"
|
||||
row.alert = component_invalid
|
||||
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
|
||||
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 !"
|
||||
prop_group_location.label(text=error_message)
|
||||
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 :
|
||||
row.label(text="details hidden, click on toggle to display")
|
||||
else:
|
||||
@ -293,17 +301,18 @@ def draw_component_ui(layout, object_or_collection, registry, selected_component
|
||||
op.component_name = component_name
|
||||
row.separator()
|
||||
|
||||
op = row.operator("blenvy.component_remove", text="", icon="X")
|
||||
op.component_name = component_name
|
||||
op.item_name = object_or_collection.name
|
||||
op.item_type = get_selection_type(object_or_collection)
|
||||
row.separator()
|
||||
|
||||
op = row.operator("blenvy.component_copy", text="", icon="COPYDOWN")
|
||||
op.source_component_name = component_name
|
||||
op.source_item_name = object_or_collection.name
|
||||
op.source_item_type = get_selection_type(object_or_collection)
|
||||
row.separator()
|
||||
if not component_internal:
|
||||
op = row.operator("blenvy.component_remove", text="", icon="X")
|
||||
op.component_name = component_name
|
||||
op.item_name = object_or_collection.name
|
||||
op.item_type = get_selection_type(object_or_collection)
|
||||
row.separator()
|
||||
|
||||
op = row.operator("blenvy.component_copy", text="", icon="COPYDOWN")
|
||||
op.source_component_name = component_name
|
||||
op.source_item_name = object_or_collection.name
|
||||
op.source_item_type = get_selection_type(object_or_collection)
|
||||
row.separator()
|
||||
|
||||
#if not single_field:
|
||||
toggle_icon = "TRIA_DOWN" if component_visible else "TRIA_RIGHT"
|
||||
@ -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)
|
||||
|
||||
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 = []
|
||||
|
||||
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
|
||||
component_settings = blenvy.components
|
||||
#print("watching schema file for changes")
|
||||
reloading_registry = False
|
||||
try:
|
||||
stamp = os.stat(component_settings.schema_path_full).st_mtime
|
||||
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
|
||||
bpy.app.timers.register(lambda: bpy.ops.blenvy.components_registry_reload(), first_interval=1)
|
||||
component_settings.schemaTimeStamp = stamp
|
||||
reloading_registry = True
|
||||
|
||||
if component_settings.schemaTimeStamp == "":
|
||||
component_settings.schemaTimeStamp = stamp
|
||||
except Exception as error:
|
||||
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
|
||||
|
||||
class ComponentsSettings(PropertyGroup):
|
||||
|
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import posixpath
|
||||
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):
|
||||
not_found_materials = []
|
||||
@ -79,6 +80,7 @@ def get_all_materials(collection_names, library_scenes):
|
||||
used_material_names = list(set(used_material_names))
|
||||
return (used_material_names, materials_per_object)
|
||||
|
||||
import bpy
|
||||
def add_material_info_to_objects(materials_per_object, settings):
|
||||
materials_path = getattr(settings, "materials_path")
|
||||
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)
|
||||
# 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
|
||||
#bpy.ops.blenvy.component_add(target_item_name=object.name, target_item_type="OBJECT", component_type="blenvy::blueprints::materials::MaterialInfos", component_value=component_value)
|
||||
object['MaterialInfos'] = f"({material_infos})".replace("'","")
|
||||
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("'","")
|
||||
#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)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user