mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-12-27 10:04:10 +00:00
feat(Blenvy): huge improvements to components UI:
* removed obsolete / overly complex pieces of UI * complete rework of component selections: much nicer, searchable, simpler ui * main component selector & per "error" component selectors , as well as bulk replace ones are now all independant * overhauled a lot of helpers to work with both objects & collections * reworked ui ordering for upgrade/ rename * more clearer status display for invalid components * etc etc
This commit is contained in:
parent
295c387132
commit
9cb0c6262e
@ -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<f32> & 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
|
@ -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,
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
||||
|
||||
|
||||
|
@ -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'}
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
#row.separator()
|
||||
|
2
tools/blenvy/add_ons/bevy_components/constants.py
Normal file
2
tools/blenvy/add_ons/bevy_components/constants.py
Normal file
@ -0,0 +1,2 @@
|
||||
# FIXME: not sure, hard coded exclude list ?
|
||||
HIDDEN_COMPONENTS = ['Parent', 'Children']
|
@ -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="")
|
||||
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
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
|
Loading…
Reference in New Issue
Block a user