diff --git a/tools/blenvy/TODO.md b/tools/blenvy/TODO.md index 296fbfb..80e3f62 100644 --- a/tools/blenvy/TODO.md +++ b/tools/blenvy/TODO.md @@ -43,7 +43,7 @@ Blueprints: - [x] on save: write IN THE COLLECTION PROPERTIES - list of assets - export path - - [ ] blueprint selection for nested blueprints is broken + - [x] blueprint selection for nested blueprints is broken - [ ] scan & inject on load - [ ] scan & inject on save @@ -58,7 +58,7 @@ Components: - [ ] OT_rename_component - [ ] Fix_Component_Operator - [ ] add handling for core::ops::Range & other ranges - - [ ] fix is_component_valid that is used in gltf_auto_export + - [x] fix is_component_valid that is used in gltf_auto_export - Hashmap Support - [x] fix parsing of keys's type either on Bevy side (prefered) or on the Blender side - [x] fix weird issue with missing "0" property when adding new entry in empty hashmap => happens only if the values for the "setter" have never been set @@ -69,6 +69,16 @@ Components: - [x] move saveable settings out to a settings file - [x] update save & load - [x] add handling of polling frequency & enabling + - [x] move advanced tools to components tab + - [ ] remove most of the (bulk) advanced tools, too complex, too unclear (even for me !) and of limited use + - component renaming should be kept, but perhaps simplified: + - if a renaming fails because the parameters are incompatible, nuke the old parameters + - perhaps just add a display list of all NON component custom properties, so the user can find them easilly ? + - [ ] status "unregistered" is often false and misleading + -> see in registry ui "for custom_property in object.keys():" + + - [x] overhaul / improve the component selector (with built in searching, etc) + - [ ] remove select_component_name_to_replace General things to solve: @@ -124,7 +134,9 @@ General issues: - [x] remove BlueprintsList & replace is with assets list - [ ] update main docs + - [ ] rename project to Blenvy - [ ] replace all references to the old 2 add-ons with those to Blenvy - [ ] rename repo to "Blenvy" + clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py \ No newline at end of file diff --git a/tools/blenvy/__init__.py b/tools/blenvy/__init__.py index 43b6309..023962c 100644 --- a/tools/blenvy/__init__.py +++ b/tools/blenvy/__init__.py @@ -24,7 +24,6 @@ from .add_ons.bevy_components.registry.ui import (BEVY_COMPONENTS_PT_Configurati from .add_ons.bevy_components.components.metadata import (ComponentMetadata, ComponentsMeta) from .add_ons.bevy_components.components.lists import GENERIC_LIST_OT_actions, Generic_LIST_OT_AddItem, Generic_LIST_OT_RemoveItem, Generic_LIST_OT_SelectItem from .add_ons.bevy_components.components.maps import GENERIC_MAP_OT_actions -from .add_ons.bevy_components.components.definitions_list import (ComponentDefinitionsList, ClearComponentDefinitionsList) from .add_ons.bevy_components.components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel) from .add_ons.bevy_components.settings import ComponentsSettings @@ -80,9 +79,6 @@ classes = [ RenameHelper, GenerateComponent_From_custom_property_Operator, Toggle_ComponentVisibility, - - ComponentDefinitionsList, - ClearComponentDefinitionsList, ComponentMetadata, ComponentsMeta, @@ -103,6 +99,7 @@ classes = [ BEVY_COMPONENTS_PT_ComponentsPanel, BEVY_COMPONENTS_PT_AdvancedToolsPanel, #BEVY_COMPONENTS_PT_Configuration, + MISSING_TYPES_UL_List, BEVY_COMPONENTS_PT_MissingTypesPanel, diff --git a/tools/blenvy/add_ons/auto_export/common/duplicate_object.py b/tools/blenvy/add_ons/auto_export/common/duplicate_object.py index f72329b..87a2bac 100644 --- a/tools/blenvy/add_ons/auto_export/common/duplicate_object.py +++ b/tools/blenvy/add_ons/auto_export/common/duplicate_object.py @@ -1,16 +1,9 @@ import json import bpy from blenvy.core.object_makers import (make_empty) +from blenvy.add_ons.bevy_components.utils import is_component_valid_and_enabled from ..constants import custom_properties_to_filter_out -def is_component_valid_and_enabled(object, component_name): - if "components_meta" in object or hasattr(object, "components_meta"): - target_components_metadata = object.components_meta.components - component_meta = next(filter(lambda component: component["long_name"] == component_name, target_components_metadata), None) - if component_meta != None: - return component_meta.enabled and not component_meta.invalid - return True - def remove_unwanted_custom_properties(object): to_remove = [] component_names = list(object.keys()) # to avoid 'IDPropertyGroup changed size during iteration' issues diff --git a/tools/blenvy/add_ons/auto_export/common/generate_temporary_scene_and_export.py b/tools/blenvy/add_ons/auto_export/common/generate_temporary_scene_and_export.py index e4dc647..ea48f0f 100644 --- a/tools/blenvy/add_ons/auto_export/common/generate_temporary_scene_and_export.py +++ b/tools/blenvy/add_ons/auto_export/common/generate_temporary_scene_and_export.py @@ -39,14 +39,14 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out add_scene_property(temp_scene, 'assets_components', {"AllAssets": f"AllAssets({all_assets})".replace("'", '')}) # save active scene - original_scene = bpy.context.window.scene + active_scene = bpy.context.window.scene # and selected collection - original_collection = bpy.context.view_layer.active_layer_collection + active_collection = bpy.context.view_layer.active_layer_collection # and mode - original_mode = bpy.context.active_object.mode if bpy.context.active_object != None else None + active_mode = bpy.context.active_object.mode if bpy.context.active_object != None else None # we change the mode to object mode, otherwise the gltf exporter is not happy - if original_mode != None and original_mode != 'OBJECT': - print("setting to object mode", original_mode) + if active_mode != None and active_mode != 'OBJECT': + print("setting to object mode", active_mode) bpy.ops.object.mode_set(mode='OBJECT') # we set our active scene to be this one : this is needed otherwise the stand-in empties get generated in the wrong scene bpy.context.window.scene = temp_scene @@ -74,12 +74,12 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out tempScene_cleaner(temp_scene, scene_filler_data) # reset active scene - bpy.context.window.scene = original_scene + bpy.context.window.scene = active_scene # reset active collection - bpy.context.view_layer.active_layer_collection = original_collection + bpy.context.view_layer.active_layer_collection = active_collection # reset mode - if original_mode != None: - bpy.ops.object.mode_set( mode = original_mode ) + if active_mode is not None: + bpy.ops.object.mode_set( mode = active_mode ) diff --git a/tools/blenvy/add_ons/bevy_components/components/definitions_list.py b/tools/blenvy/add_ons/bevy_components/components/definitions_list.py deleted file mode 100644 index 56cfc83..0000000 --- a/tools/blenvy/add_ons/bevy_components/components/definitions_list.py +++ /dev/null @@ -1,57 +0,0 @@ -import bpy -from bpy.props import (StringProperty) - -# this one is for UI only, and its inner list contains a useable list of shortnames of components -class ComponentDefinitionsList(bpy.types.PropertyGroup): - - # FIXME: not sure, hard coded exclude list, feels wrong - exclude = ['Parent', 'Children'] - - def add_component_to_ui_list(self, context): - #print("add components to ui_list") - items = [] - type_infos = context.window_manager.components_registry.type_infos - for long_name in type_infos.keys(): - definition = type_infos[long_name] - short_name = definition["short_name"] - is_component = definition['isComponent'] if "isComponent" in definition else False - - if self.filter in short_name and is_component: - if not 'Handle' in short_name and not "Cow" in short_name and not "AssetId" in short_name and short_name not in self.exclude: # FIXME: hard coded, seems wrong - items.append((long_name, short_name, long_name)) - - items.sort(key=lambda a: a[1]) - return items - - @classmethod - def register(cls): - bpy.types.WindowManager.components_list = bpy.props.PointerProperty(type=ComponentDefinitionsList) - - @classmethod - def unregister(cls): - del bpy.types.WindowManager.components_list - - list : bpy.props.EnumProperty( - name="list", - description="list", - # items argument required to initialize, just filled with empty values - items = add_component_to_ui_list, - ) # type: ignore - filter: StringProperty( - name="component filter", - description="filter for the components list", - options={'TEXTEDIT_UPDATE'} - ) # type: ignore - - -class ClearComponentDefinitionsList(bpy.types.Operator): - ''' clear list of bpy.context.collection.component_definitions ''' - bl_label = "clear component definitions" - bl_idname = "components.clear_component_definitions" - - def execute(self, context): - # create a new item, assign its properties - bpy.context.collection.component_definitions.clear() - - return {'FINISHED'} - diff --git a/tools/blenvy/add_ons/bevy_components/components/metadata.py b/tools/blenvy/add_ons/bevy_components/components/metadata.py index 6f8da5f..8ee1757 100644 --- a/tools/blenvy/add_ons/bevy_components/components/metadata.py +++ b/tools/blenvy/add_ons/bevy_components/components/metadata.py @@ -4,6 +4,7 @@ from bpy_types import (PropertyGroup) from ..propGroups.conversions_from_prop_group import property_group_value_to_custom_property_value from ..propGroups.conversions_to_prop_group import property_group_value_from_custom_property_value +from ..utils import add_component_to_ui_list class ComponentMetadata(bpy.types.PropertyGroup): short_name : bpy.props.StringProperty( @@ -43,6 +44,8 @@ class ComponentMetadata(bpy.types.PropertyGroup): default=True ) # type: ignore + + class ComponentsMeta(PropertyGroup): infos_per_component: StringProperty( name="infos per component", @@ -50,6 +53,12 @@ class ComponentsMeta(PropertyGroup): ) # type: ignore components: bpy.props.CollectionProperty(type = ComponentMetadata) # type: ignore + # compone + component_selector: StringProperty( + search=add_component_to_ui_list + ) # type: ignore + + @classmethod def register(cls): # you can add components to both objects & collections diff --git a/tools/blenvy/add_ons/bevy_components/components/operators.py b/tools/blenvy/add_ons/bevy_components/components/operators.py index 0d12839..59609eb 100644 --- a/tools/blenvy/add_ons/bevy_components/components/operators.py +++ b/tools/blenvy/add_ons/bevy_components/components/operators.py @@ -198,7 +198,7 @@ class RemoveComponentFromAllItemsOperator(Operator): class RenameHelper(bpy.types.PropertyGroup): original_name: bpy.props.StringProperty(name="") # type: ignore - new_name: bpy.props.StringProperty(name="") # type: ignore + target_name: bpy.props.StringProperty(name="") # type: ignore #object: bpy.props.PointerProperty(type=bpy.types.Object) @classmethod @@ -217,12 +217,12 @@ class OT_rename_component(Operator): bl_options = {"UNDO"} original_name: bpy.props.StringProperty(default="") # type: ignore - new_name: StringProperty( - name="new_name", + target_name: StringProperty( + name="target_name", description="new name of component", ) # type: ignore - target_objects: bpy.props.StringProperty() # type: ignore + target_items: bpy.props.StringProperty() # type: ignore @classmethod def register(cls): @@ -237,28 +237,28 @@ class OT_rename_component(Operator): type_infos = registry.type_infos settings = context.window_manager.bevy_component_rename_helper original_name = settings.original_name if self.original_name == "" else self.original_name - new_name = self.new_name + target_name = self.target_name - print("renaming components: original name", original_name, "new_name", self.new_name, "targets", self.target_objects) - target_objects = json.loads(self.target_objects) + print("renaming components: original name", original_name, "target_name", self.target_name, "targets", self.target_items) + target_items = json.loads(self.target_items) errors = [] - total = len(target_objects) + total = len(target_items) - if original_name != '' and new_name != '' and original_name != new_name and len(target_objects) > 0: - for index, item_name in enumerate(target_objects): + if original_name != '' and target_name != '' and original_name != target_name and len(target_items) > 0: + for index, item_name in enumerate(target_items): object = bpy.data.objects[item_name] if object and original_name in get_bevy_components(object) or original_name in object: try: # attempt conversion - rename_component(object=object, original_long_name=original_name, new_long_name=new_name) + rename_component(item=object, original_long_name=original_name, new_long_name=target_name) except Exception as error: if '__disable__update' in object: del object["__disable__update"] # make sure custom properties are updateable afterwards, even in the case of failure components_metadata = getattr(object, "components_meta", None) if components_metadata: components_metadata = components_metadata.components - component_meta = next(filter(lambda component: component["long_name"] == new_name, components_metadata), None) + component_meta = next(filter(lambda component: component["long_name"] == target_name, components_metadata), None) if component_meta: component_meta.invalid = True component_meta.invalid_details = "wrong custom property value, overwrite them by changing the values in the ui or change them & regenerate" diff --git a/tools/blenvy/add_ons/bevy_components/components/ui.py b/tools/blenvy/add_ons/bevy_components/components/ui.py index ce975bf..b9d6113 100644 --- a/tools/blenvy/add_ons/bevy_components/components/ui.py +++ b/tools/blenvy/add_ons/bevy_components/components/ui.py @@ -172,7 +172,7 @@ class BEVY_COMPONENTS_PT_ComponentsPanel(bpy.types.Panel): # name = context.object.name if context.object != None else '' layout.label(text=f"Components for {name} ({target_type})") - print("object", context.object, "active", context.active_object, "objects", context.selected_objects) + #print("object", context.object, "active", context.active_object, "objects", context.selected_objects) def draw(self, context): object = next(iter(context.selected_objects), None) @@ -181,28 +181,27 @@ class BEVY_COMPONENTS_PT_ComponentsPanel(bpy.types.Panel): # we get & load our component registry registry = bpy.context.window_manager.components_registry - available_components = bpy.context.window_manager.components_list + selected_component = bpy.context.window_manager.blenvy.components.component_selector registry_has_type_infos = registry.has_type_infos() if object is not None: - draw_component_ui(layout, object, registry, available_components, registry_has_type_infos, context) + draw_component_ui(layout, object, registry, selected_component, registry_has_type_infos, context) elif collection is not None: - draw_component_ui(layout, collection, registry, available_components, registry_has_type_infos, context) + draw_component_ui(layout, collection, registry, selected_component, registry_has_type_infos, context) else: layout.label(text ="Select an object to edit its components") -def draw_component_ui(layout, object_or_collection, registry, available_components, registry_has_type_infos, context): +def draw_component_ui(layout, object_or_collection, registry, selected_component, registry_has_type_infos, context): row = layout.row(align=True) - row.prop(available_components, "list", text="Component") - row.prop(available_components, "filter",text="Filter") + row.prop(context.window_manager.blenvy.components, "component_selector", text="Component: ") # add components row = layout.row(align=True) op = row.operator(AddComponentOperator.bl_idname, text="Add", icon="ADD") - op.component_type = available_components.list - row.enabled = available_components.list != '' + op.component_type = selected_component + row.enabled = selected_component != '' layout.separator() @@ -249,7 +248,6 @@ def draw_component_ui(layout, object_or_collection, registry, available_componen # we fetch the matching ui property group root_propertyGroup_name = registry.get_propertyGroupName_from_longName(component_name) """print("root_propertyGroup_name", root_propertyGroup_name)""" - print("component_meta", component_meta, component_invalid) if root_propertyGroup_name: propertyGroup = getattr(component_meta, root_propertyGroup_name, None) @@ -299,4 +297,4 @@ def draw_component_ui(layout, object_or_collection, registry, available_componen toggle_icon = "TRIA_DOWN" if component_visible else "TRIA_RIGHT" op = row.operator(Toggle_ComponentVisibility.bl_idname, text="", icon=toggle_icon) op.component_name = component_name - #row.separator() \ No newline at end of file + #row.separator() diff --git a/tools/blenvy/add_ons/bevy_components/constants.py b/tools/blenvy/add_ons/bevy_components/constants.py new file mode 100644 index 0000000..5f2267e --- /dev/null +++ b/tools/blenvy/add_ons/bevy_components/constants.py @@ -0,0 +1,2 @@ +# FIXME: not sure, hard coded exclude list ? +HIDDEN_COMPONENTS = ['Parent', 'Children'] \ No newline at end of file diff --git a/tools/blenvy/add_ons/bevy_components/registry/ui.py b/tools/blenvy/add_ons/bevy_components/registry/ui.py index afc6091..2d61e7a 100644 --- a/tools/blenvy/add_ons/bevy_components/registry/ui.py +++ b/tools/blenvy/add_ons/bevy_components/registry/ui.py @@ -69,7 +69,7 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): @classmethod def poll(cls, context): - return context.window_manager.blenvy.mode == 'TOOLS' + return context.window_manager.blenvy.mode == 'COMPONENTS' def draw_invalid_or_unregistered_header(self, layout, items): row = layout.row() @@ -78,17 +78,13 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): col = row.column() col.label(text=item) - def draw_invalid_or_unregistered(self, layout, status, component_name, target): - available_components = bpy.context.window_manager.components_list registry = bpy.context.window_manager.components_registry registry_has_type_infos = registry.has_type_infos() + selected_component = target.components_meta.component_selector row = layout.row() - col = row.column() - col.label(text=component_name) - col = row.column() operator = col.operator("object.select", text=target.name) operator.target_name = target.name @@ -97,15 +93,21 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): col.label(text=status) col = row.column() - col.prop(available_components, "list", text="") + col.label(text=component_name) + + col = row.column() + # each components_meta has a component selector to pick components from + components_meta = target.components_meta + col.prop(components_meta, "component_selector", text="") + col = row.column() operator = col.operator("object.rename_bevy_component", text="", icon="SHADERFX") #rename - new_name = registry.type_infos[available_components.list]['long_name'] if available_components.list in registry.type_infos else "" + target_name = registry.type_infos[selected_component]['long_name'] if selected_component in registry.type_infos else "" operator.original_name = component_name - operator.target_objects = json.dumps([target.name]) - operator.new_name = new_name - col.enabled = registry_has_type_infos and component_name != "" and component_name != new_name + operator.target_items = json.dumps([target.name]) + operator.target_name = target_name + col.enabled = registry_has_type_infos and component_name != "" and component_name != target_name col = row.column() @@ -115,84 +117,100 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): operator.item_type = get_selection_type(target) - col = row.column() + """col = row.column() col = row.column() operator = col.operator("object.select_component_name_to_replace", text="", icon="EYEDROPPER") #text="select for rename", - operator.component_name = component_name + operator.component_name = component_name""" + + def draw_invalid_item_entry(self, layout, item, invalid_component_names, items_with_invalid_components): + if "components_meta" in item: + components_metadata = item.components_meta.components + object_component_names = [] + for index, component_meta in enumerate(components_metadata): + long_name = component_meta.long_name + if component_meta.invalid: + self.draw_invalid_or_unregistered(layout, "Invalid", long_name, item) + + if not item.name in items_with_invalid_components: + items_with_invalid_components.append(item.name) + + if not long_name in invalid_component_names: + invalid_component_names.append(long_name) + + + object_component_names.append(long_name) + + for custom_property in item.keys(): + # Invalid (something is wrong) + # Unregistered (not in registry) + # Upgrade Needed (Old-style component) + + status = None + if custom_property != 'components_meta' and custom_property != 'bevy_components' and custom_property not in object_component_names: + status = "Upgrade Needed" + + if status is not None: + self.draw_invalid_or_unregistered(layout, status, custom_property, item) + + if not item.name in items_with_invalid_components: + items_with_invalid_components.append(item.name) + """if not long_name in invalid_component_names: + invalid_component_names.append(custom_property)""" # FIXME def draw(self, context): layout = self.layout registry = bpy.context.window_manager.components_registry registry_has_type_infos = registry.has_type_infos() selected_object = context.selected_objects[0] if len(context.selected_objects) > 0 else None - available_components = bpy.context.window_manager.components_list + selected_component = bpy.context.window_manager.blenvy.components.component_selector row = layout.row() box= row.box() box.label(text="Invalid/ unregistered components") - objects_with_invalid_components = [] + items_with_invalid_components = [] invalid_component_names = [] - self.draw_invalid_or_unregistered_header(layout, ["Component", "Object", "Status", "Target"]) + self.draw_invalid_or_unregistered_header(layout, ["Item","Status", "Component", "Target"]) for object in bpy.data.objects: # TODO: very inneficent if len(object.keys()) > 0: - if "components_meta" in object: - components_metadata = object.components_meta.components - comp_names = [] - for index, component_meta in enumerate(components_metadata): - long_name = component_meta.long_name - if component_meta.invalid: - self.draw_invalid_or_unregistered(layout, "Invalid", long_name, object) - - if not object.name in objects_with_invalid_components: - objects_with_invalid_components.append(object.name) - - if not long_name in invalid_component_names: - invalid_component_names.append(long_name) + self.draw_invalid_item_entry(layout, object, invalid_component_names, items_with_invalid_components) + + for collection in bpy.data.collections: + if len(collection.keys()) > 0: + self.draw_invalid_item_entry(layout, collection, invalid_component_names, items_with_invalid_components) - comp_names.append(long_name) - - for custom_property in object.keys(): - if custom_property != 'components_meta' and custom_property != 'bevy_components' and custom_property not in comp_names: - self.draw_invalid_or_unregistered(layout, "Unregistered", custom_property, object) - - if not object.name in objects_with_invalid_components: - objects_with_invalid_components.append(object.name) - """if not long_name in invalid_component_names: - invalid_component_names.append(custom_property)""" # FIXME layout.separator() layout.separator() - original_name = bpy.context.window_manager.bevy_component_rename_helper.original_name + layout.label(text="------------------Bulk actions: Rename/ Upgrade -------------------") + original_name = bpy.context.window_manager.blenvy.components.source_component_selector + target_name = bpy.context.window_manager.blenvy.components.target_component_selector row = layout.row() col = row.column() - col.label(text="Original") + col.label(text="Component") col = row.column() - col.label(text="New") + col.label(text="Target") col = row.column() col.label(text="------") row = layout.row() col = row.column() - box = col.box() - box.label(text=original_name) + col.prop(bpy.context.window_manager.blenvy.components, "source_component_selector", text="") col = row.column() - col.prop(available_components, "list", text="") - #row.prop(available_components, "filter",text="Filter") + col.prop(bpy.context.window_manager.blenvy.components, "target_component_selector", text="") col = row.column() components_rename_progress = context.window_manager.components_rename_progress - + print("components_rename_progress", components_rename_progress) if components_rename_progress == -1.0: operator = col.operator(OT_rename_component.bl_idname, text="apply", icon="SHADERFX") - operator.target_objects = json.dumps(objects_with_invalid_components) - new_name = registry.type_infos[available_components.list]['short_name'] if available_components.list in registry.type_infos else "" - operator.new_name = new_name - col.enabled = registry_has_type_infos and original_name != "" and original_name != new_name + operator.target_items = json.dumps(items_with_invalid_components) + operator.target_name = target_name + col.enabled = registry_has_type_infos and original_name != "" and original_name != target_name else: if hasattr(layout,"progress") : # only for Blender > 4.0 col.progress(factor = components_rename_progress, text=f"updating {components_rename_progress * 100.0:.2f}%") @@ -208,7 +226,7 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): col.progress(factor = remove_components_progress, text=f"updating {remove_components_progress * 100.0:.2f}%") layout.separator() - layout.separator() + """layout.separator() row = layout.row() box= row.box() box.label(text="Conversions between custom properties and components & vice-versa") @@ -266,7 +284,7 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): if hasattr(layout,"progress") : # only for Blender > 4.0 layout.progress(factor = components_from_custom_properties_progress_all, text=f"updating {components_from_custom_properties_progress_all * 100.0:.2f}%") - +""" class BEVY_COMPONENTS_PT_MissingTypesPanel(bpy.types.Panel): """panel listing all the missing bevy types in the schema""" bl_idname = "BEVY_COMPONENTS_PT_MissingTypesPanel" @@ -340,3 +358,4 @@ class MISSING_TYPES_UL_List(UIList): layout.alignment = 'CENTER' row = layout.row() row.prop(item, "long_name", text="") + diff --git a/tools/blenvy/add_ons/bevy_components/settings.py b/tools/blenvy/add_ons/bevy_components/settings.py index dd2080d..60e304a 100644 --- a/tools/blenvy/add_ons/bevy_components/settings.py +++ b/tools/blenvy/add_ons/bevy_components/settings.py @@ -5,6 +5,7 @@ from bpy.props import (EnumProperty, PointerProperty, StringProperty, BoolProper from blenvy.settings import load_settings, upsert_settings, generate_complete_settings_dict from .propGroups.prop_groups import generate_propertyGroups_for_components from .components.metadata import ensure_metadata_for_all_items +from .utils import add_component_to_ui_list # list of settings we do NOT want to save settings_black_list = ['settings_save_enabled', 'watcher_active'] @@ -52,7 +53,6 @@ def watch_schema(): pass return component_settings.watcher_poll_frequency if component_settings.watcher_enabled else None - class ComponentsSettings(PropertyGroup): settings_save_path = ".blenvy_components_settings" # where to store data in bpy.texts @@ -91,6 +91,20 @@ class ComponentsSettings(PropertyGroup): )# type: ignore + component_selector: StringProperty( + search=add_component_to_ui_list + )# type: ignore + + + source_component_selector: StringProperty( + search=add_component_to_ui_list + )# type: ignore + + target_component_selector: StringProperty( + search=add_component_to_ui_list + )# type: ignore + + @classmethod def register(cls): pass diff --git a/tools/blenvy/add_ons/bevy_components/utils.py b/tools/blenvy/add_ons/bevy_components/utils.py index e85b0ec..4f71edb 100644 --- a/tools/blenvy/add_ons/bevy_components/utils.py +++ b/tools/blenvy/add_ons/bevy_components/utils.py @@ -1,4 +1,5 @@ import bpy +from .constants import HIDDEN_COMPONENTS #FIXME: does not work if object is hidden !! def get_selected_object_or_collection(context): @@ -15,4 +16,27 @@ def get_selection_type(selection): if isinstance(selection, bpy.types.Object): return 'Object' if isinstance(selection, bpy.types.Collection): - return 'Collection' \ No newline at end of file + return 'Collection' + +def add_component_to_ui_list(self, context, _): + print("add components to ui_list") + items = [] + type_infos = context.window_manager.components_registry.type_infos + for long_name in type_infos.keys(): + definition = type_infos[long_name] + short_name = definition["short_name"] + is_component = definition['isComponent'] if "isComponent" in definition else False + """if self.filter.lower() in short_name.lower() and is_component:""" + if not 'Handle' in short_name and not "Cow" in short_name and not "AssetId" in short_name and short_name not in HIDDEN_COMPONENTS: # FIXME: hard coded, seems wrong + items.append((long_name, short_name)) + items.sort(key=lambda a: a[1]) + return items + + +def is_component_valid_and_enabled(object, component_name): + if "components_meta" in object or hasattr(object, "components_meta"): + target_components_metadata = object.components_meta.components + component_meta = next(filter(lambda component: component["long_name"] == component_name, target_components_metadata), None) + if component_meta != None: + return component_meta.enabled and not component_meta.invalid + return True \ No newline at end of file