mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-12-22 23:54:10 +00:00
feat(bevy_components): continued changes to base logic on long_names
This commit is contained in:
parent
185c25f7b2
commit
ca02c1df8c
@ -206,4 +206,11 @@ UI:
|
||||
- [x] delete => remove
|
||||
|
||||
- [x] clean up reloading of registry settings
|
||||
- [x] clean up file watcher
|
||||
- [x] clean up file watcher
|
||||
|
||||
|
||||
=========================================
|
||||
Restructuring of storage of components
|
||||
- [x] marking of invalid root propgroups/components should be based on long name
|
||||
- [ ] overhaul & check each prop group type's use of short names => long names
|
||||
- [ ] lists
|
@ -22,8 +22,7 @@ from .registry.registry import ComponentsRegistry,MissingBevyType
|
||||
from .registry.operators import (COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_CUSTOM_PROPERTIES_CURRENT, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_ALL, COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_CURRENT, OT_select_component_name_to_replace, OT_select_object, ReloadRegistryOperator, OT_OpenFilebrowser)
|
||||
from .registry.ui import (BEVY_COMPONENTS_PT_Configuration, BEVY_COMPONENTS_PT_AdvancedToolsPanel, BEVY_COMPONENTS_PT_MissingTypesPanel, MISSING_TYPES_UL_List)
|
||||
|
||||
from .components.metadata import (ComponentMetadata, ComponentsMeta, ensure_metadata_for_all_objects)
|
||||
from .propGroups.prop_groups import (generate_propertyGroups_for_components)
|
||||
from .components.metadata import (ComponentMetadata, ComponentsMeta)
|
||||
from .components.lists import GENERIC_LIST_OT_actions, Generic_LIST_OT_AddItem, Generic_LIST_OT_RemoveItem, Generic_LIST_OT_SelectItem
|
||||
from .components.definitions_list import (ComponentDefinitionsList, ClearComponentDefinitionsList)
|
||||
from .components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel)
|
||||
|
@ -47,12 +47,12 @@ class ComponentDefinitionsList(bpy.types.PropertyGroup):
|
||||
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):
|
||||
|
@ -10,19 +10,19 @@ class Generic_LIST_OT_AddItem(Operator):
|
||||
property_group_path: StringProperty(
|
||||
name="property group path",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
component_name: StringProperty(
|
||||
name="component name",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
print("")
|
||||
object = context.object
|
||||
# information is stored in component meta
|
||||
components_in_object = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||
|
||||
propertyGroup = component_meta
|
||||
for path_item in json.loads(self.property_group_path):
|
||||
@ -47,19 +47,19 @@ class Generic_LIST_OT_RemoveItem(Operator):
|
||||
property_group_path: StringProperty(
|
||||
name="property group path",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
component_name: StringProperty(
|
||||
name="component name",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
def execute(self, context):
|
||||
print("remove from list", context.object)
|
||||
|
||||
object = context.object
|
||||
# information is stored in component meta
|
||||
components_in_object = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||
|
||||
propertyGroup = component_meta
|
||||
for path_item in json.loads(self.property_group_path):
|
||||
@ -81,14 +81,14 @@ class Generic_LIST_OT_SelectItem(Operator):
|
||||
property_group_path: StringProperty(
|
||||
name="property group path",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
component_name: StringProperty(
|
||||
name="component name",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
selection_index: IntProperty()
|
||||
selection_index: IntProperty() # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
print("select in list", context.object)
|
||||
@ -96,7 +96,7 @@ class Generic_LIST_OT_SelectItem(Operator):
|
||||
object = context.object
|
||||
# information is stored in component meta
|
||||
components_in_object = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||
|
||||
propertyGroup = component_meta
|
||||
for path_item in json.loads(self.property_group_path):
|
||||
@ -121,23 +121,23 @@ class GENERIC_LIST_OT_actions(Operator):
|
||||
('UP', "Up", ""),
|
||||
('DOWN', "Down", ""),
|
||||
('REMOVE', "Remove", ""),
|
||||
('ADD', "Add", "")))
|
||||
('ADD', "Add", ""))) # type: ignore
|
||||
|
||||
property_group_path: StringProperty(
|
||||
name="property group path",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
component_name: StringProperty(
|
||||
name="component name",
|
||||
description="",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
def invoke(self, context, event):
|
||||
object = context.object
|
||||
# information is stored in component meta
|
||||
components_in_object = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == self.component_name, components_in_object), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
||||
|
||||
propertyGroup = component_meta
|
||||
for path_item in json.loads(self.property_group_path):
|
||||
|
@ -10,51 +10,51 @@ class ComponentMetadata(bpy.types.PropertyGroup):
|
||||
name : bpy.props.StringProperty(
|
||||
name = "name",
|
||||
default = ""
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
long_name : bpy.props.StringProperty(
|
||||
name = "long name",
|
||||
default = ""
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
type_name : bpy.props.StringProperty(
|
||||
name = "Type",
|
||||
default = ""
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
values: bpy.props.StringProperty(
|
||||
name = "Value",
|
||||
default = ""
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
enabled: BoolProperty(
|
||||
name="enabled",
|
||||
description="component enabled",
|
||||
default=True
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
invalid: BoolProperty(
|
||||
name="invalid",
|
||||
description="component is invalid, because of missing registration/ other issues",
|
||||
default=False
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
invalid_details: StringProperty(
|
||||
name="invalid details",
|
||||
description="detailed information about why the component is invalid",
|
||||
default=""
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
visible: BoolProperty( # REALLY dislike doing this for UI control, but ok hack for now
|
||||
default=True
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
class ComponentsMeta(PropertyGroup):
|
||||
infos_per_component: StringProperty(
|
||||
name="infos per component",
|
||||
description="component"
|
||||
)
|
||||
components: bpy.props.CollectionProperty(type = ComponentMetadata)
|
||||
) # type: ignore
|
||||
components: bpy.props.CollectionProperty(type = ComponentMetadata) # type: ignore
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
@ -72,7 +72,9 @@ def get_component_metadata_by_short_name(object, short_name):
|
||||
|
||||
# remove no longer valid metadata from object
|
||||
def cleanup_invalid_metadata(object):
|
||||
bevy_components = json.loads(object['bevy_components']) if 'bevy_components' in object else {}
|
||||
bevy_components = get_bevy_components(object)
|
||||
if len(bevy_components.keys()) == 0: # no components, bail out
|
||||
return
|
||||
components_metadata = object.components_meta.components
|
||||
to_remove = []
|
||||
for index, component_meta in enumerate(components_metadata):
|
||||
@ -93,6 +95,10 @@ def find_component_definition_from_short_name(short_name):
|
||||
return registry.type_infos.get(long_name, None)
|
||||
return None
|
||||
|
||||
def find_component_definition_from_long_name(long_name):
|
||||
registry = bpy.context.window_manager.components_registry
|
||||
return registry.type_infos.get(long_name, None)
|
||||
|
||||
# FIXME: feels a bit heavy duty, should only be done
|
||||
# if the components panel is active ?
|
||||
def ensure_metadata_for_all_objects():
|
||||
@ -123,31 +129,45 @@ def do_object_custom_properties_have_missing_metadata(object):
|
||||
return missing_metadata
|
||||
|
||||
|
||||
# adds metadata to object only if it is missing
|
||||
def add_metadata_to_components_without_metadata(object):
|
||||
registry = bpy.context.window_manager.components_registry
|
||||
|
||||
for component_name in dict(object) :
|
||||
if component_name == "components_meta":
|
||||
continue
|
||||
upsert_component_in_object(object, component_name, registry)
|
||||
|
||||
|
||||
import json
|
||||
def inject_component(object, long_name, value):
|
||||
def upsert_bevy_component(object, long_name, value):
|
||||
if not 'bevy_components' in object:
|
||||
object['bevy_components'] = '{}'
|
||||
previous = json.loads(object['bevy_components'])
|
||||
previous[long_name] = value
|
||||
object['bevy_components'] = json.dumps(previous)
|
||||
bevy_components = json.loads(object['bevy_components'])
|
||||
bevy_components[long_name] = value
|
||||
object['bevy_components'] = json.dumps(bevy_components)
|
||||
#object['bevy_components'][long_name] = value # Sigh, this does not work, hits Blender's 63 char length limit
|
||||
|
||||
def bla_component(object, long_name):
|
||||
def remove_bevy_component(object, long_name):
|
||||
if 'bevy_components' in object:
|
||||
current = json.loads(object['bevy_components'])
|
||||
del current[long_name]
|
||||
object['bevy_components'] = json.dumps(current)
|
||||
|
||||
def get_bevy_components(object):
|
||||
if 'bevy_components' in object:
|
||||
bevy_components = json.loads(object['bevy_components'])
|
||||
return bevy_components
|
||||
return {}
|
||||
|
||||
def get_bevy_component_value_by_long_name(object, long_name):
|
||||
bevy_components = get_bevy_components(object)
|
||||
if len(bevy_components.keys()) == 0 :
|
||||
return None
|
||||
return bevy_components.get(long_name, None)
|
||||
|
||||
def is_bevy_component_in_object(object, long_name):
|
||||
return get_bevy_component_value_by_long_name(object, long_name) is not None
|
||||
|
||||
# adds metadata to object only if it is missing
|
||||
def add_metadata_to_components_without_metadata(object):
|
||||
registry = bpy.context.window_manager.components_registry
|
||||
|
||||
for component_name in get_bevy_components(object) :
|
||||
if component_name == "components_meta":
|
||||
continue
|
||||
upsert_component_in_object(object, component_name, registry)
|
||||
|
||||
# adds a component to an object (including metadata) using the provided component definition & optional value
|
||||
def add_component_to_object(object, component_definition, value=None):
|
||||
cleanup_invalid_metadata(object)
|
||||
@ -158,7 +178,6 @@ def add_component_to_object(object, component_definition, value=None):
|
||||
if not registry.has_type_infos():
|
||||
raise Exception('registry type infos have not been loaded yet or are missing !')
|
||||
definition = registry.type_infos[long_name]
|
||||
print("HEAAAY", value)
|
||||
# now we use our pre_generated property groups to set the initial value of our custom property
|
||||
(_, propertyGroup) = upsert_component_in_object(object, long_name=long_name, registry=registry)
|
||||
if value == None:
|
||||
@ -170,7 +189,7 @@ def add_component_to_object(object, component_definition, value=None):
|
||||
|
||||
# object[short_name] = value
|
||||
print("ADDING VAALUEEE", value)
|
||||
inject_component(object, long_name, value)
|
||||
upsert_bevy_component(object, long_name, value)
|
||||
#ping_depsgraph_update(object)
|
||||
|
||||
|
||||
@ -226,14 +245,14 @@ def copy_propertyGroup_values_to_another_object(source_object, target_object, co
|
||||
if source_object == None or target_object == None or component_name == None:
|
||||
raise Exception('missing input data, cannot copy component propertryGroup')
|
||||
|
||||
component_definition = find_component_definition_from_short_name(component_name)
|
||||
short_name = component_definition["short_name"]
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
component_definition = find_component_definition_from_long_name(component_name)
|
||||
long_name = component_name
|
||||
property_group_name = registry.get_propertyGroupName_from_longName(long_name)
|
||||
|
||||
registry = bpy.context.window_manager.components_registry
|
||||
|
||||
source_components_metadata = source_object.components_meta.components
|
||||
source_componentMeta = next(filter(lambda component: component["name"] == short_name, source_components_metadata), None)
|
||||
source_componentMeta = next(filter(lambda component: component["long_name"] == long_name, source_components_metadata), None)
|
||||
# matching component means we already have this type of component
|
||||
source_propertyGroup = getattr(source_componentMeta, property_group_name)
|
||||
|
||||
@ -241,28 +260,27 @@ def copy_propertyGroup_values_to_another_object(source_object, target_object, co
|
||||
(_, target_propertyGroup) = upsert_component_in_object(target_object, component_name, registry)
|
||||
# add to object
|
||||
value = property_group_value_to_custom_property_value(target_propertyGroup, component_definition, registry, None)
|
||||
target_object[short_name] = value
|
||||
upsert_bevy_component(target_object, long_name, value)
|
||||
|
||||
# copy the values over
|
||||
for field_name in source_propertyGroup.field_names:
|
||||
if field_name in source_propertyGroup:
|
||||
target_propertyGroup[field_name] = source_propertyGroup[field_name]
|
||||
apply_propertyGroup_values_to_object_customProperties(target_object)
|
||||
ping_depsgraph_update(object)
|
||||
|
||||
|
||||
# TODO: move to propgroups ?
|
||||
def apply_propertyGroup_values_to_object_customProperties(object):
|
||||
cleanup_invalid_metadata(object)
|
||||
registry = bpy.context.window_manager.components_registry
|
||||
for component_name in dict(object) :
|
||||
if component_name == "components_meta":
|
||||
continue
|
||||
for component_name in get_bevy_components(object) :
|
||||
"""if component_name == "components_meta":
|
||||
continue"""
|
||||
(_, propertyGroup) = upsert_component_in_object(object, component_name, registry)
|
||||
component_definition = find_component_definition_from_short_name(component_name)
|
||||
component_definition = find_component_definition_from_long_name(component_name)
|
||||
if component_definition != None:
|
||||
value = property_group_value_to_custom_property_value(propertyGroup, component_definition, registry, None)
|
||||
object[component_name] = value
|
||||
upsert_bevy_component(object=object, long_name=component_name, value=value)
|
||||
|
||||
# apply component value(s) to custom property of a single component
|
||||
def apply_propertyGroup_values_to_object_customProperties_for_component(object, component_name):
|
||||
@ -304,7 +322,7 @@ def apply_customProperty_values_to_object_propertyGroups(object):
|
||||
|
||||
# removes the given component from the object: removes both the custom property and the matching metadata from the object
|
||||
def remove_component_from_object(object, component_name):
|
||||
bla_component(object, component_name)
|
||||
remove_bevy_component(object, component_name)
|
||||
|
||||
components_metadata = getattr(object, "components_meta", None)
|
||||
if components_metadata == None:
|
||||
@ -319,16 +337,14 @@ def remove_component_from_object(object, component_name):
|
||||
break
|
||||
for index in to_remove:
|
||||
components_metadata.remove(index)
|
||||
ping_depsgraph_update(object)
|
||||
return True
|
||||
|
||||
def add_component_from_custom_property(object):
|
||||
add_metadata_to_components_without_metadata(object)
|
||||
apply_customProperty_values_to_object_propertyGroups(object)
|
||||
ping_depsgraph_update(object)
|
||||
|
||||
def toggle_component(object, component_name):
|
||||
components_in_object = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == component_name, components_in_object), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == component_name, components_in_object), None)
|
||||
if component_meta != None:
|
||||
component_meta.visible = not component_meta.visible
|
||||
|
@ -4,7 +4,7 @@ import bpy
|
||||
from bpy_types import Operator
|
||||
from bpy.props import (StringProperty)
|
||||
|
||||
from .metadata import add_component_from_custom_property, add_component_to_object, add_metadata_to_components_without_metadata, apply_customProperty_values_to_object_propertyGroups, apply_propertyGroup_values_to_object_customProperties_for_component, copy_propertyGroup_values_to_another_object, find_component_definition_from_short_name, remove_component_from_object, toggle_component
|
||||
from .metadata import add_component_from_custom_property, add_component_to_object, add_metadata_to_components_without_metadata, apply_customProperty_values_to_object_propertyGroups, apply_propertyGroup_values_to_object_customProperties_for_component, copy_propertyGroup_values_to_another_object, find_component_definition_from_short_name, get_bevy_component_value_by_long_name, get_bevy_components, is_bevy_component_in_object, remove_component_from_object, toggle_component
|
||||
|
||||
class AddComponentOperator(Operator):
|
||||
"""Add Bevy component to object"""
|
||||
@ -36,7 +36,7 @@ class CopyComponentOperator(Operator):
|
||||
bl_options = {"UNDO"}
|
||||
|
||||
source_component_name: StringProperty(
|
||||
name="source component_name",
|
||||
name="source component_name (long)",
|
||||
description="name of the component to copy",
|
||||
) # type: ignore
|
||||
|
||||
@ -80,10 +80,10 @@ class PasteComponentOperator(Operator):
|
||||
self.report({"ERROR"}, "The source object to copy a component from does not exist")
|
||||
else:
|
||||
component_name = context.window_manager.copied_source_component_name
|
||||
if not component_name in source_object:
|
||||
component_value = get_bevy_component_value_by_long_name(source_object, component_name)
|
||||
if component_value is None:
|
||||
self.report({"ERROR"}, "The source component to copy from does not exist")
|
||||
else:
|
||||
component_value = source_object[component_name]
|
||||
print("pasting component to object: component name:", str(component_name), "component value:" + str(component_value))
|
||||
print (context.object)
|
||||
registry = context.window_manager.components_registry
|
||||
@ -114,10 +114,15 @@ class RemoveComponentOperator(Operator):
|
||||
else:
|
||||
object = bpy.data.objects[self.object_name]
|
||||
print("removing component ", self.component_name, "from object '"+object.name+"'")
|
||||
if object is not None and 'bevy_components' in object and self.component_name in object['bevy_components']:
|
||||
remove_component_from_object(object, self.component_name)
|
||||
|
||||
if object is not None and 'bevy_components' in object :
|
||||
component_value = get_bevy_component_value_by_long_name(object, self.component_name)
|
||||
if component_value is not None:
|
||||
remove_component_from_object(object, self.component_name)
|
||||
else :
|
||||
self.report({"ERROR"}, "The component to remove ("+ self.component_name +") does not exist")
|
||||
else:
|
||||
self.report({"ERROR"}, "The object/ component to remove ("+ self.component_name +") does not exist")
|
||||
self.report({"ERROR"}, "The object to remove ("+ self.component_name +") from does not exist")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@ -145,7 +150,7 @@ class RemoveComponentFromAllObjectsOperator(Operator):
|
||||
total = len(bpy.data.objects)
|
||||
for index, object in enumerate(bpy.data.objects):
|
||||
if len(object.keys()) > 0:
|
||||
if object is not None and self.component_name in object:
|
||||
if object is not None and is_bevy_component_in_object(object, self.component_name):
|
||||
remove_component_from_object(object, self.component_name)
|
||||
|
||||
progress = index / total
|
||||
@ -222,7 +227,7 @@ class OT_rename_component(Operator):
|
||||
components_metadata = getattr(object, "components_meta", None)
|
||||
if components_metadata:
|
||||
components_metadata = components_metadata.components
|
||||
component_meta = next(filter(lambda component: component["name"] == new_name, components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == new_name, components_metadata), None)
|
||||
if component_meta:
|
||||
component_meta.invalid = True
|
||||
component_meta.invalid_details = "unknow issue when renaming/transforming component, please remove it & add it back again"
|
||||
@ -240,7 +245,7 @@ class OT_rename_component(Operator):
|
||||
components_metadata = getattr(object, "components_meta", None)
|
||||
if components_metadata:
|
||||
components_metadata = components_metadata.components
|
||||
component_meta = next(filter(lambda component: component["name"] == new_name, components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == new_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"
|
||||
|
@ -178,12 +178,12 @@ class BEVY_COMPONENTS_PT_ComponentsPanel(bpy.types.Panel):
|
||||
|
||||
# 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)
|
||||
"""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)
|
||||
print("propertyGroup", propertyGroup)
|
||||
"""print("propertyGroup", propertyGroup)"""
|
||||
if propertyGroup:
|
||||
# if the component has only 0 or 1 field names, display inline, otherwise change layout
|
||||
single_field = len(propertyGroup.field_names) < 2
|
||||
|
@ -6,7 +6,7 @@ from . import process_tupples
|
||||
from . import process_enum
|
||||
from . import process_list
|
||||
|
||||
def process_component(registry, definition, update, extras=None, nesting = []):
|
||||
def process_component(registry, definition, update, extras=None, nesting = [], nesting_long_names = []):
|
||||
component_name = definition['title']
|
||||
short_name = definition["short_name"]
|
||||
type_info = definition["typeInfo"] if "typeInfo" in definition else None
|
||||
@ -31,21 +31,21 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
||||
|
||||
|
||||
if has_properties:
|
||||
__annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting)
|
||||
__annotations__ = __annotations__ | process_structs.process_structs(registry, definition, properties, update, nesting, nesting_long_names)
|
||||
with_properties = True
|
||||
tupple_or_struct = "struct"
|
||||
|
||||
if has_prefixItems:
|
||||
__annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting)
|
||||
__annotations__ = __annotations__ | process_tupples.process_tupples(registry, definition, prefixItems, update, nesting, nesting_long_names)
|
||||
with_items = True
|
||||
tupple_or_struct = "tupple"
|
||||
|
||||
if is_enum:
|
||||
__annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting)
|
||||
__annotations__ = __annotations__ | process_enum.process_enum(registry, definition, update, nesting, nesting_long_names)
|
||||
with_enum = True
|
||||
|
||||
if is_list:
|
||||
__annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting)
|
||||
__annotations__ = __annotations__ | process_list.process_list(registry, definition, update, nesting, nesting_long_names)
|
||||
with_list= True
|
||||
|
||||
field_names = []
|
||||
@ -56,7 +56,7 @@ def process_component(registry, definition, update, extras=None, nesting = []):
|
||||
extras = extras if extras is not None else {
|
||||
"type_name": component_name
|
||||
}
|
||||
root_component = nesting[0] if len(nesting) > 0 else component_name
|
||||
root_component = nesting_long_names[0] if len(nesting_long_names) > 0 else component_name
|
||||
# print("DONE:",short_name,"__annotations__", __annotations__)
|
||||
# print("")
|
||||
property_group_params = {
|
||||
|
@ -1,13 +1,17 @@
|
||||
from bpy.props import (StringProperty)
|
||||
from . import process_component
|
||||
|
||||
def process_enum(registry, definition, update, nesting):
|
||||
def process_enum(registry, definition, update, nesting, nesting_long_names):
|
||||
blender_property_mapping = registry.blender_property_mapping
|
||||
short_name = definition["short_name"]
|
||||
long_name = definition["title"]
|
||||
|
||||
type_def = definition["type"] if "type" in definition else None
|
||||
values = definition["oneOf"]
|
||||
|
||||
nesting = nesting + [short_name]
|
||||
nesting_long_names = nesting_long_names = [long_name]
|
||||
|
||||
__annotations__ = {}
|
||||
original_type_name = "enum"
|
||||
|
||||
@ -25,12 +29,12 @@ def process_enum(registry, definition, update, nesting):
|
||||
if "prefixItems" in item:
|
||||
#print("tupple variant in enum", short_name, item)
|
||||
registry.add_custom_type(item_short_name, item)
|
||||
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting)
|
||||
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting, nesting_long_names)
|
||||
additional_annotations[variant_name] = sub_component_group
|
||||
elif "properties" in item:
|
||||
#print("struct variant in enum", short_name, item)
|
||||
registry.add_custom_type(item_short_name, item)
|
||||
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting)
|
||||
(sub_component_group, _) = process_component.process_component(registry, item, update, {"nested": True}, nesting, nesting_long_names)
|
||||
additional_annotations[variant_name] = sub_component_group
|
||||
else: # for the cases where it's neither a tupple nor a structs: FIXME: not 100% sure of this
|
||||
#print("other variant in enum", short_name)
|
||||
|
@ -2,11 +2,12 @@ from bpy.props import (StringProperty, IntProperty, CollectionProperty)
|
||||
from .utils import generate_wrapper_propertyGroup
|
||||
from . import process_component
|
||||
|
||||
def process_list(registry, definition, update, nesting=[]):
|
||||
def process_list(registry, definition, update, nesting=[], nesting_long_names=[]):
|
||||
value_types_defaults = registry.value_types_defaults
|
||||
type_infos = registry.type_infos
|
||||
|
||||
short_name = definition["short_name"]
|
||||
long_name = definition["title"]
|
||||
ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "")
|
||||
|
||||
item_definition = type_infos[ref_name]
|
||||
@ -23,6 +24,8 @@ def process_list(registry, definition, update, nesting=[]):
|
||||
property_group_class = list_content_group_class
|
||||
|
||||
nesting = nesting+[short_name]
|
||||
nesting_long_names = nesting_long_names + [long_name]
|
||||
|
||||
item_collection = CollectionProperty(type=property_group_class)
|
||||
|
||||
item_short_name = item_short_name if not is_item_value_type else "wrapper_" + item_short_name
|
||||
|
@ -1,15 +1,17 @@
|
||||
from bpy.props import (StringProperty)
|
||||
from . import process_component
|
||||
|
||||
def process_structs(registry, definition, properties, update, nesting):
|
||||
def process_structs(registry, definition, properties, update, nesting, nesting_long_names):
|
||||
value_types_defaults = registry.value_types_defaults
|
||||
blender_property_mapping = registry.blender_property_mapping
|
||||
type_infos = registry.type_infos
|
||||
long_name = definition["title"]
|
||||
short_name = definition["short_name"]
|
||||
|
||||
__annotations__ = {}
|
||||
default_values = {}
|
||||
nesting = nesting + [short_name]
|
||||
nesting_long_names = nesting_long_names + [long_name]
|
||||
|
||||
for property_name in properties.keys():
|
||||
ref_name = properties[property_name]["type"]["$ref"].replace("#/$defs/", "")
|
||||
@ -33,7 +35,7 @@ def process_structs(registry, definition, properties, update, nesting):
|
||||
__annotations__[property_name] = blender_property
|
||||
else:
|
||||
original_long_name = original["title"]
|
||||
(sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "type_name": original_long_name}, nesting)
|
||||
(sub_component_group, _) = process_component.process_component(registry, original, update, {"nested": True, "type_name": original_long_name}, nesting, nesting_long_names)
|
||||
__annotations__[property_name] = sub_component_group
|
||||
# if there are sub fields, add an attribute "sub_fields" possibly a pointer property ? or add a standard field to the type , that is stored under "attributes" and not __annotations (better)
|
||||
else:
|
||||
@ -41,6 +43,6 @@ def process_structs(registry, definition, properties, update, nesting):
|
||||
__annotations__[property_name] = StringProperty(default="N/A")
|
||||
registry.add_missing_typeInfo(ref_name)
|
||||
# the root component also becomes invalid (in practice it is not always a component, but good enough)
|
||||
registry.add_invalid_component(nesting[0])
|
||||
registry.add_invalid_component(nesting_long_names[0])
|
||||
|
||||
return __annotations__
|
||||
|
@ -1,13 +1,15 @@
|
||||
from bpy.props import (StringProperty)
|
||||
from . import process_component
|
||||
|
||||
def process_tupples(registry, definition, prefixItems, update, nesting=[]):
|
||||
def process_tupples(registry, definition, prefixItems, update, nesting=[], nesting_long_names=[]):
|
||||
value_types_defaults = registry.value_types_defaults
|
||||
blender_property_mapping = registry.blender_property_mapping
|
||||
type_infos = registry.type_infos
|
||||
long_name = definition["title"]
|
||||
short_name = definition["short_name"]
|
||||
|
||||
nesting = nesting+[short_name]
|
||||
nesting_long_names = nesting_long_names + [long_name]
|
||||
__annotations__ = {}
|
||||
|
||||
default_values = []
|
||||
@ -46,7 +48,7 @@ def process_tupples(registry, definition, prefixItems, update, nesting=[]):
|
||||
__annotations__[property_name] = StringProperty(default="N/A")
|
||||
registry.add_missing_typeInfo(ref_name)
|
||||
# the root component also becomes invalid (in practice it is not always a component, but good enough)
|
||||
registry.add_invalid_component(nesting[0])
|
||||
registry.add_invalid_component(nesting_long_names[0])
|
||||
|
||||
|
||||
return __annotations__
|
||||
|
@ -3,6 +3,7 @@ from .conversions_from_prop_group import property_group_value_to_custom_property
|
||||
from .process_component import process_component
|
||||
from .utils import update_calback_helper
|
||||
|
||||
import json
|
||||
## main callback function, fired whenever any property changes, no matter the nesting level
|
||||
def update_component(self, context, definition, component_name):
|
||||
registry = bpy.context.window_manager.components_registry
|
||||
@ -14,12 +15,17 @@ def update_component(self, context, definition, component_name):
|
||||
print("")
|
||||
print("update in component", component_name, self, "current_object", current_object.name)
|
||||
components_in_object = current_object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == component_name, components_in_object), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == component_name, components_in_object), None)
|
||||
print("component_meta", component_meta)
|
||||
|
||||
if component_meta != None:
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(component_name)
|
||||
self = getattr(component_meta, property_group_name)
|
||||
property_group_name = registry.get_propertyGroupName_from_longName(component_name)
|
||||
property_group = getattr(component_meta, property_group_name)
|
||||
# we use our helper to set the values
|
||||
context.object[component_name] = property_group_value_to_custom_property_value(self, definition, registry, None)
|
||||
object = context.object
|
||||
previous = json.loads(object['bevy_components'])
|
||||
previous[component_name] = property_group_value_to_custom_property_value(property_group, definition, registry, None)
|
||||
object['bevy_components'] = json.dumps(previous)
|
||||
|
||||
|
||||
def generate_propertyGroups_for_components():
|
||||
@ -31,9 +37,8 @@ def generate_propertyGroups_for_components():
|
||||
|
||||
for component_name in type_infos:
|
||||
definition = type_infos[component_name]
|
||||
short_name = definition["short_name"]
|
||||
is_component = definition['isComponent'] if "isComponent" in definition else False
|
||||
root_property_name = short_name if is_component else None
|
||||
root_property_name = component_name if is_component else None
|
||||
process_component(registry, definition, update_calback_helper(definition, update_component, root_property_name), None, [])
|
||||
|
||||
# if we had to add any wrapper types on the fly, process them now
|
||||
|
@ -52,7 +52,6 @@ def generate_wrapper_propertyGroup(short_name, item_long_name, definition, regis
|
||||
'tupple_or_struct': "tupple",
|
||||
'field_names': ['0'],
|
||||
**dict(with_properties = False, with_items= True, with_enum= False, with_list= False, short_name= wrapper_name, type_name=wrapper_name),
|
||||
#'root_component': root_component
|
||||
}
|
||||
property_group_class = type(wrapper_name, (PropertyGroup,), property_group_params)
|
||||
bpy.utils.register_class(property_group_class)
|
||||
|
@ -317,6 +317,7 @@ class ComponentsRegistry(PropertyGroup):
|
||||
self.type_infos[type_name] = self.custom_types_to_add[type_name]
|
||||
self.custom_types_to_add.clear()
|
||||
|
||||
# add an invalid component to the list (long name)
|
||||
def add_invalid_component(self, component_name):
|
||||
self.invalid_components.append(component_name)
|
||||
|
||||
@ -350,7 +351,7 @@ class ComponentsRegistry(PropertyGroup):
|
||||
self.short_names_to_propgroup_names[key] = propGroupName"""
|
||||
# FIXME:
|
||||
key = str(nesting) + longName if len(nesting) > 0 else longName
|
||||
self.long_names_to_propgroup_names[longName] = propGroupName
|
||||
self.long_names_to_propgroup_names[key] = propGroupName
|
||||
return propGroupName
|
||||
|
||||
def get_propertyGroupName_from_shortName(self, shortName):
|
||||
|
@ -39,7 +39,7 @@ def test_components_should_generate_correct_custom_properties(setup_data):
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
added_components.append(component_type)
|
||||
custom_property_values[short_name] = object[short_name]
|
||||
@ -87,7 +87,7 @@ def test_components_should_generate_correct_custom_properties_with_randomized_va
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
component_values_shuffler(seed= 10, property_group=propertyGroup, definition=definition, registry=registry)
|
||||
|
||||
@ -136,7 +136,7 @@ def test_components_should_generate_correct_propertyGroup_values_from_custom_pro
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
added_components.append(component_type)
|
||||
# randomise values
|
||||
@ -195,7 +195,7 @@ def test_remove_components(setup_data):
|
||||
object = bpy.context.object
|
||||
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
# print("propertyGroup", propertyGroup, propertyGroup.field_names)
|
||||
added_components.append(component_type)
|
||||
@ -231,7 +231,7 @@ def test_copy_paste_components(setup_data):
|
||||
object = context.object
|
||||
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
setattr(propertyGroup, propertyGroup.field_names[0], 25.0)
|
||||
@ -246,7 +246,7 @@ def test_copy_paste_components(setup_data):
|
||||
# change name
|
||||
new_cube.name = "TargetCube"
|
||||
target_components_metadata = new_cube.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
|
||||
# first check that there is no component currently
|
||||
assert component_meta == None
|
||||
@ -255,7 +255,7 @@ def test_copy_paste_components(setup_data):
|
||||
paste_component_operator()
|
||||
|
||||
target_components_metadata = new_cube.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
|
||||
# now after pasting to the new object, it should have component meta
|
||||
assert component_meta != None
|
||||
|
@ -16,7 +16,7 @@ def test_blend(setup_data):
|
||||
object = bpy.context.object
|
||||
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ from .setup_data import setup_data
|
||||
# small helpers
|
||||
def get_component_metadata(object, component_name):
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == component_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == component_name, target_components_metadata), None)
|
||||
return component_meta
|
||||
|
||||
def get_component_propGroup(registry, component_name, component_meta):
|
||||
|
@ -19,7 +19,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -38,7 +38,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -57,7 +57,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -75,7 +75,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -95,7 +95,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -113,7 +113,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -130,7 +130,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
@ -148,7 +148,7 @@ def test_shuffler(setup_data):
|
||||
|
||||
property_group_name = registry.get_propertyGroupName_from_shortName(short_name)
|
||||
target_components_metadata = object.components_meta.components
|
||||
component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None)
|
||||
component_meta = next(filter(lambda component: component["long_name"] == short_name, target_components_metadata), None)
|
||||
propertyGroup = getattr(component_meta, property_group_name, None)
|
||||
|
||||
definition = type_infos[component_type]
|
||||
|
Loading…
Reference in New Issue
Block a user