feat(Blenvy:blender):

* fixed handling of colors according to changes in v0.14
 * fixed issues with hashmaps having enums as values
This commit is contained in:
kaosat.dev 2024-06-26 14:34:44 +02:00
parent 959951bca4
commit f25829f8cd
9 changed files with 72 additions and 29 deletions

View File

@ -166,12 +166,26 @@ Blender side:
- export split dynamic/static: YES - export split dynamic/static: YES
- export merge mode : YES - export merge mode : YES
- materials: YES - materials: YES
- [x] blenvy tooling not appearing in library scenes ?? (edit: was actually , it was not appearing in anything but object mode)
- [x] find a solution for the new color handling
- [x] in theory, srgba, linearrgba , and hsva should be able to be represented visually
- [x] bevy_render::color::Color => bevy_color::color::Color
- [x] fix weird issue with hashmaps with enums as values
- [ ] prevent attempting to add unexisting components to targets (ie when using the component search)
- [ ] inject_export_path_into_internal_blueprints should be called on every asset/blueprint scan !! Not just on export - [ ] inject_export_path_into_internal_blueprints should be called on every asset/blueprint scan !! Not just on export
- [ ] undo after a save removes any saved "serialized scene" data ? DIG into this - [ ] undo after a save removes any saved "serialized scene" data ? DIG into this
- [ ] handle scene renames between saves (breaks diffing) => very hard to achieve - [ ] handle scene renames between saves (breaks diffing) => very hard to achieve
- [ ] add tests for disabled components - [ ] add tests for
- [ ] find a solution for the new color handling - [ ] disabled components
- [ ] hidden objects/collections not respected at export !!! - [ ] blueprint instances as children of blueprint instances
- [ ] blueprint instances as children of empties
- [ ] hidden objects/collections not respected at export !!!?
- [ ] verify based on gltf settings
- [ ] add "hidden" component otherwise ?
https://devtalk.blender.org/t/how-to-get-render-visibility-for-object/23717
- [ ] add option to 'split out' meshes from blueprints ? - [ ] add option to 'split out' meshes from blueprints ?
- [ ] ie considering meshletts etc , it would make sense to keep blueprints seperate from purely mesh gltfs - [ ] ie considering meshletts etc , it would make sense to keep blueprints seperate from purely mesh gltfs
- [ ] persist exported materials path in blueprints so that it can be read from library file users - [ ] persist exported materials path in blueprints so that it can be read from library file users

View File

@ -332,9 +332,12 @@ def serialize_scene(settings):
custom_properties = custom_properties_hash(scene) if len(scene.keys()) > 0 else None custom_properties = custom_properties_hash(scene) if len(scene.keys()) > 0 else None
eevee_settings = generic_fields_hasher_evolved(scene.eevee, fields_to_ignore=fields_to_ignore_generic) # TODO: ignore most of the fields eevee_settings = generic_fields_hasher_evolved(scene.eevee, fields_to_ignore=fields_to_ignore_generic) # TODO: ignore most of the fields
view_settings = generic_fields_hasher_evolved(scene.view_settings, fields_to_ignore=fields_to_ignore_generic)
scene_field_hashes = { scene_field_hashes = {
"custom_properties": custom_properties, "custom_properties": custom_properties,
"eevee": eevee_settings "eevee": eevee_settings,
"view_settings": view_settings,
} }
#generic_fields_hasher_evolved(scene.eevee, fields_to_ignore=fields_to_ignore_generic) #generic_fields_hasher_evolved(scene.eevee, fields_to_ignore=fields_to_ignore_generic)
# FIXME: how to deal with this cleanly # FIXME: how to deal with this cleanly

View File

@ -88,19 +88,17 @@ class BLENVY_OT_component_map_actions(Operator):
propertyGroup.values_index = min(max(0, index - 1), len(keys_list) - 1) propertyGroup.values_index = min(max(0, index - 1), len(keys_list) - 1)
if self.action == 'ADD': if self.action == 'ADD':
print("keys_list", keys_list)
# first we gather all key/value pairs # first we gather all key/value pairs
hashmap = {} hashmap = {}
for index, key in enumerate(keys_list): for index, key in enumerate(keys_list):
print("key", key)
key_entry = {} key_entry = {}
for field_name in key.field_names: for field_name in key.field_names:
key_entry[field_name] = getattr(key, field_name, None) key_entry[field_name] = getattr(key, field_name, None)
value_entry = {} """value_entry = {}
for field_name in values_list[index].field_names: for field_name in values_list[index].field_names:
value_entry[field_name] = values_list[index][field_name] value_entry[field_name] = values_list[index][field_name]"""
hashmap[json.dumps(key_entry)] = index hashmap[json.dumps(key_entry)] = index
print("hashmap", hashmap )
# then we need to find the index of a specific value if it exists # then we need to find the index of a specific value if it exists
key_entry = {} key_entry = {}
@ -108,10 +106,9 @@ class BLENVY_OT_component_map_actions(Operator):
key_entry[field_name] = getattr(key_setter, field_name, None) key_entry[field_name] = getattr(key_setter, field_name, None)
key_to_add = json.dumps(key_entry) key_to_add = json.dumps(key_entry)
existing_index = hashmap.get(key_to_add, None) existing_index = hashmap.get(key_to_add, None)
print("existing_index", existing_index)
if existing_index is None: if existing_index is None:
print("adding new value") #print("adding new value", "key field names", key_setter.field_names, "value_setter", value_setter, "field names", value_setter.field_names)
key = keys_list.add() key = keys_list.add()
# copy the values over # copy the values over
for field_name in key_setter.field_names: for field_name in key_setter.field_names:
@ -122,16 +119,28 @@ class BLENVY_OT_component_map_actions(Operator):
value = values_list.add() value = values_list.add()
# copy the values over # copy the values over
for field_name in value_setter.field_names: is_enum = getattr(value_setter, "with_enum", False)
if not is_enum:
for field_name in list(value_setter.field_names):
val = getattr(value_setter, field_name, None) val = getattr(value_setter, field_name, None)
if val is not None: if val is not None:
value[field_name] = val value[field_name] = val
# TODO: add error handling else:
selection = getattr(value_setter, "selection", None)
setattr(value, 'selection', selection)
selector = "variant_" + selection
try:
val = getattr(value_setter, selector, None)
for field_name in val.field_names:
source = getattr(val, field_name)
setattr(getattr(value, selector), field_name, source)
except Exception as inst:
print("EROOR", inst)
# TODO: add error handling
propertyGroup.list_index = index + 1 # we use this to force the change detection propertyGroup.list_index = index + 1 # we use this to force the change detection
propertyGroup.values_index = index + 1 # we use this to force the change detection propertyGroup.values_index = index + 1 # we use this to force the change detection
else: else:
print("overriding value")
for field_name in value_setter.field_names: for field_name in value_setter.field_names:
values_list[existing_index][field_name] = value_setter[field_name] values_list[existing_index][field_name] = value_setter[field_name]

View File

@ -22,7 +22,9 @@ conversion_tables = {
"glam::Quat": lambda value: "Quat(x:"+str(value[0])+ ", y:"+str(value[1])+ ", z:"+str(value[2])+ ", w:"+str(value[3])+")", "glam::Quat": lambda value: "Quat(x:"+str(value[0])+ ", y:"+str(value[1])+ ", z:"+str(value[2])+ ", w:"+str(value[3])+")",
"bevy_render::color::Color": lambda value: "Rgba(red:"+str(value[0])+ ", green:"+str(value[1])+ ", blue:"+str(value[2])+ ", alpha:"+str(value[3])+ ")", "bevy_color::srgba::Srgba": lambda value: "Srgba(red:"+str(value[0])+ ", green:"+str(value[1])+ ", blue:"+str(value[2])+ ", alpha:"+str(value[3])+ ")",
"bevy_color::linear_rgba::LinearRgba": lambda value: "LinearRgba(red:"+str(value[0])+ ", green:"+str(value[1])+ ", blue:"+str(value[2])+ ", alpha:"+str(value[3])+ ")",
"bevy_color::hsva::Hsva": lambda value: "Hsva(hue:"+str(value[0])+ ", saturation:"+str(value[1])+ ", value:"+str(value[2])+ ", alpha:"+str(value[3])+ ")",
} }
#converts the value of a property group(no matter its complexity) into a single custom property value #converts the value of a property group(no matter its complexity) into a single custom property value

View File

@ -118,10 +118,14 @@ def parse_vec4(value, caster, typeName):
parsed = parse_struct_string(value.replace(typeName,"").replace("(", "").replace(")","") ) parsed = parse_struct_string(value.replace(typeName,"").replace("(", "").replace(")","") )
return [caster(parsed['x']), caster(parsed['y']), caster(parsed['z']), caster(parsed['w'])] return [caster(parsed['x']), caster(parsed['y']), caster(parsed['z']), caster(parsed['w'])]
def parse_color(value, caster, typeName): def parse_color_rgba(value, caster, typeName):
parsed = parse_struct_string(value.replace(typeName,"").replace("(", "").replace(")","") ) parsed = parse_struct_string(value.replace(typeName,"").replace("(", "").replace(")","") )
return [caster(parsed['red']), caster(parsed['green']), caster(parsed['blue']), caster(parsed['alpha'])] return [caster(parsed['red']), caster(parsed['green']), caster(parsed['blue']), caster(parsed['alpha'])]
def parse_color_hsva(value, caster, typeName):
parsed = parse_struct_string(value.replace(typeName,"").replace("(", "").replace(")","") )
return [caster(parsed['hue']), caster(parsed['saturation']), caster(parsed['value']), caster(parsed['alpha'])]
def to_int(input): def to_int(input):
return int(float(input)) return int(float(input))
@ -163,7 +167,11 @@ type_mappings = {
'alloc::string::String': lambda value: str(value.replace('"', "")), 'alloc::string::String': lambda value: str(value.replace('"', "")),
'alloc::borrow::Cow<str>': lambda value: str(value.replace('"', "")), 'alloc::borrow::Cow<str>': lambda value: str(value.replace('"', "")),
'bevy_render::color::Color': lambda value: parse_color(value, float, "Rgba"), "bevy_color::srgba::Srgba": lambda value: parse_color_rgba(value, float, "Srgba"),
"bevy_color::linear_rgba::LinearRgba": lambda value: parse_color_rgba(value, float, "LinearRgba"),
"bevy_color::hsva::Hsva": lambda value: parse_color_hsva(value, float, "Hsva"),
'bevy_ecs::entity::Entity': lambda value: int(value), 'bevy_ecs::entity::Entity': lambda value: int(value),
} }

View File

@ -43,10 +43,14 @@ def process_map(registry, definition, update, nesting_long_names=[]):
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName ! #if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
if is_value_value_type: if is_value_value_type:
print("WRAPPPER, property group", definition["short_name"])
values_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_values", original_long_name, definition_link, registry, update, nesting_long_names) values_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_values", original_long_name, definition_link, registry, update, nesting_long_names)
else: else:
(_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "long_name": original_long_name}, nesting_long_names) (_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "long_name": original_long_name}, nesting_long_names)
values_property_group_class = list_content_group_class values_property_group_class = list_content_group_class
print("COMPONENT, property group", definition["short_name"], values_property_group_class)
values_collection = CollectionProperty(type=values_property_group_class) values_collection = CollectionProperty(type=values_property_group_class)
values_property_group_pointer = PointerProperty(type=values_property_group_class) values_property_group_pointer = PointerProperty(type=values_property_group_class)

View File

@ -79,22 +79,21 @@ class ComponentsRegistry(PropertyGroup):
"glam::Quat": {"type": FloatVectorProperty, "presets": {"size":4} }, "glam::Quat": {"type": FloatVectorProperty, "presets": {"size":4} },
"bevy_render::color::Color": dict(type = FloatVectorProperty, presets=dict(subtype='COLOR', size=4)), "bevy_color::srgba::Srgba": dict(type = FloatVectorProperty, presets=dict(subtype='COLOR', size=4)),
"bevy_color::linear_rgba::LinearRgba": dict(type = FloatVectorProperty, presets=dict(subtype='COLOR', size=4)),
"bevy_color::hsva::Hsva": dict(type = FloatVectorProperty, presets=dict(subtype='COLOR', size=4)),
"char": dict(type=StringProperty, presets=dict()), "char": dict(type=StringProperty, presets=dict()),
"str": dict(type=StringProperty, presets=dict()), "str": dict(type=StringProperty, presets=dict()),
"alloc::string::String": dict(type=StringProperty, presets=dict()), "alloc::string::String": dict(type=StringProperty, presets=dict()),
"alloc::borrow::Cow<str>": dict(type=StringProperty, presets=dict()), "alloc::borrow::Cow<str>": dict(type=StringProperty, presets=dict()),
"enum": dict(type=EnumProperty, presets=dict()), "enum": dict(type=EnumProperty, presets=dict()),
'bevy_ecs::entity::Entity': {"type": IntProperty, "presets": {"min":0} }, 'bevy_ecs::entity::Entity': {"type": IntProperty, "presets": {"min":0} },
'bevy_utils::Uuid': dict(type=StringProperty, presets=dict()), 'bevy_utils::Uuid': dict(type=StringProperty, presets=dict()),
} }
value_types_defaults = { value_types_defaults = {
"string":" ", "string":" ",
"boolean": True, "boolean": True,
@ -141,7 +140,9 @@ class ComponentsRegistry(PropertyGroup):
"glam::Quat": [0.0, 0.0, 0.0, 0.0], "glam::Quat": [0.0, 0.0, 0.0, 0.0],
"bevy_render::color::Color": [1.0, 1.0, 0.0, 1.0], "bevy_color::srgba::Srgba": [1.0, 1.0, 0.0, 1.0],
"bevy_color::linear_rgba::LinearRgba": [1.0, 1.0, 0.0, 1.0],
"bevy_color::hsva::Hsva": [1.0, 1.0, 0.0, 1.0],
'bevy_ecs::entity::Entity': 0,#4294967295, # this is the same as Bevy's Entity::Placeholder, too big for Blender..sigh 'bevy_ecs::entity::Entity': 0,#4294967295, # this is the same as Bevy's Entity::Placeholder, too big for Blender..sigh
'bevy_utils::Uuid': '"'+str(uuid.uuid4())+'"' 'bevy_utils::Uuid': '"'+str(uuid.uuid4())+'"'

View File

@ -27,8 +27,7 @@ class BLENVY_PT_SidePanel(bpy.types.Panel):
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Bevy" bl_category = "Bevy"
bl_context = "objectmode" #bl_context = "objectmode"
def draw_header(self, context): def draw_header(self, context):
layout = self.layout layout = self.layout

View File

@ -61,7 +61,10 @@ type_mappings = {
"glam::Quat": lambda : random_vec(4, 'float'), "glam::Quat": lambda : random_vec(4, 'float'),
'bevy_render::color::Color': lambda : random_vec(4, 'float'), 'bevy_color::srgba::Srgba': lambda : random_vec(4, 'float'),
'bevy_color::linear_rgba::LinearRgba': lambda : random_vec(4, 'float'),
'bevy_color::hsva::Hsva': lambda : random_vec(4, 'float'),
'alloc::string::String': lambda : random_word(8), 'alloc::string::String': lambda : random_word(8),
'alloc::borrow::Cow<str>': lambda : random_word(8), 'alloc::borrow::Cow<str>': lambda : random_word(8),