feat(Blenvy:Blender): fixed the most obvious issues with current implementation of materials handling

* changed blenvy.component_add operator to be useable in scripts
 * experimented with using the above to add MaterialInfos as normal components
 * cleaned up & changed info output from auto_export steps
 * minor tweaks
This commit is contained in:
kaosat.dev 2024-07-25 00:06:20 +02:00
parent b92081d06e
commit b3c87085de
6 changed files with 62 additions and 17 deletions

View File

@ -222,6 +222,10 @@ Blender side:
- [ ] materials fixes & upgrades - [ ] materials fixes & upgrades
- [x] materials do not get exported again if the files are missing, until you change a material - [x] materials do not get exported again if the files are missing, until you change a material
- [x] materials do not get exported when a material is added ? - [x] materials do not get exported when a material is added ?
- [x] add_material_info_to_objects is now called AFTER the blueprint export, making it useless, needs change !
- [ ] materials_path custom property should be ignored both in the list of fixable component AND on export
- [ ] if we want to add material_infos & others as normal components they should not be editable, so we need another attribute, and adapt the UI for that
- [ ] if material library is toggled, then changes to materials should not change the blueprints that are using them ? - [ ] if material library is toggled, then changes to materials should not change the blueprints that are using them ?
- [ ] material assets seem to be added to list regardless of whether material exports are enabled or not - [ ] material assets seem to be added to list regardless of whether material exports are enabled or not
- [ ] review & upgrade overall logic of material libraries, their names & output path - [ ] review & upgrade overall logic of material libraries, their names & output path

View File

@ -101,23 +101,24 @@ def auto_export(changes_per_scene, changes_per_collection, changes_per_material,
# backup current selections # backup current selections
old_selections = bpy.context.selected_objects old_selections = bpy.context.selected_objects
# first export any level/world scenes # deal with materials
if export_materials_library:
print("export MATERIALS")
export_materials(materials_to_export, settings, blueprints_data)
# export any level/world scenes
if len(level_scenes_to_export) > 0: if len(level_scenes_to_export) > 0:
print("export MAIN scenes") print("export LEVELS")
for scene_name in level_scenes_to_export: for scene_name in level_scenes_to_export:
print(" exporting scene:", scene_name) print(" exporting scene:", scene_name)
export_level_scene(bpy.data.scenes[scene_name], settings, blueprints_data) export_level_scene(bpy.data.scenes[scene_name], settings, blueprints_data)
# now deal with blueprints/collections # now deal with blueprints/collections
do_export_library_scene = not change_detection or changed_export_parameters or len(blueprints_to_export) > 0 do_export_blueprints = not change_detection or changed_export_parameters or len(blueprints_to_export) > 0
if do_export_library_scene: if do_export_blueprints:
print("export LIBRARY") print("export BLUEPRINTS")
export_blueprints(blueprints_to_export, settings, blueprints_data) export_blueprints(blueprints_to_export, settings, blueprints_data)
# then deal with materials
if export_materials_library:
export_materials(materials_to_export, settings, blueprints_data)#blueprints_data.blueprint_names, settings.library_scenes, settings)
# reset current scene from backup # reset current scene from backup
bpy.context.window.scene = old_current_scene bpy.context.window.scene = old_current_scene

View File

@ -15,6 +15,7 @@ from ..common.export_gltf import (generate_gltf_export_settings)
# #
def clear_material_info(collection_names, library_scenes): def clear_material_info(collection_names, library_scenes):
pass
for scene in library_scenes: for scene in library_scenes:
root_collection = scene.collection root_collection = scene.collection
for cur_collection in traverse_tree(root_collection): for cur_collection in traverse_tree(root_collection):

View File

@ -170,7 +170,11 @@ def add_metadata_to_components_without_metadata(item):
if component_name == "components_meta": if component_name == "components_meta":
continue continue
upsert_component_in_item(item, component_name, registry) upsert_component_in_item(item, component_name, registry)
# adds a component to an item (including metadata) WITHOUT a component definition
def add_component_to_item_without_registry():
pass
# adds a component to an item (including metadata) using the provided component definition & optional value # adds a component to an item (including metadata) using the provided component definition & optional value
def add_component_to_item(item, component_definition, value=None): def add_component_to_item(item, component_definition, value=None):
warnings = [] warnings = []

View File

@ -19,15 +19,42 @@ class BLENVY_OT_component_add(Operator):
description="component type to add", description="component type to add",
) # type: ignore ) # type: ignore
component_value: StringProperty(
name="component_value",
description="value of the newly added component"
) # type: ignore
target_item_name: StringProperty(
name="target item name",
description="name of the object/collection/mesh/material to add the component to",
) # type: ignore
target_item_type: EnumProperty(
name="target item type",
description="type of the object/collection/mesh/material to add the component to",
items=(
('OBJECT', "Object", ""),
('COLLECTION', "Collection", ""),
('MESH', "Mesh", ""),
('MATERIAL', "Material", ""),
),
default="OBJECT"
) # type: ignore
def execute(self, context): def execute(self, context):
target = get_selected_item(context) if self.target_item_name == "" or self.target_item_type == "":
print("adding component ", self.component_type, "to target '"+target.name+"'") target_item = get_selected_item(context)
print("adding component ", self.component_type, "to target '"+target_item.name+"'")
else:
target_item = get_item_by_type(self.target_item_type, self.target_item_name)
print("adding component ", self.component_type, "to target '"+target_item.name+"'")
has_component_type = self.component_type != "" has_component_type = self.component_type != ""
if has_component_type and target is not None: if has_component_type and target_item is not None:
type_infos = context.window_manager.components_registry.type_infos type_infos = context.window_manager.components_registry.type_infos
component_definition = type_infos[self.component_type] component_definition = type_infos[self.component_type]
add_component_to_item(target, component_definition) component_value = self.component_value if self.component_value != "" else None
add_component_to_item(target_item, component_definition, value=component_value)
return {'FINISHED'} return {'FINISHED'}

View File

@ -2,6 +2,7 @@ import os
import posixpath import posixpath
import bpy import bpy
from pathlib import Path from pathlib import Path
from ..core.helpers_collections import (traverse_tree) from ..core.helpers_collections import (traverse_tree)
def find_materials_not_on_disk(materials, materials_path_full, extension): def find_materials_not_on_disk(materials, materials_path_full, extension):
@ -65,11 +66,18 @@ def add_material_info_to_objects(materials_per_object, settings):
current_project_name = Path(bpy.context.blend_data.filepath).stem current_project_name = Path(bpy.context.blend_data.filepath).stem
materials_library_name = f"{current_project_name}_materials" materials_library_name = f"{current_project_name}_materials"
materials_exported_path = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}") materials_exported_path = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
#print("ADDING MAERIAL INFOS")
for object in materials_per_object.keys(): for object in materials_per_object.keys():
material = materials_per_object[object] material = materials_per_object[object]
# TODO: switch to using actual components ?
# problem with using actual components: you NEED the type registry/component infos, so if there is none , or it is not loaded yet, it does not work
# for a few components we could hardcode this
component_value = f'(name: "{material.name}", path: "{materials_exported_path}")'
#bpy.ops.blenvy.component_add(target_item_name=object.name, target_item_type="OBJECT", component_type="blenvy::blueprints::materials::MaterialInfo", component_value=component_value)
materials_exported_path = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}") materials_exported_path = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
object['MaterialInfo'] = f'(name: "{material.name}", path: "{materials_exported_path}")' object['MaterialInfo'] = component_value
print("adding materialInfo to object", object, "material info", component_value)
# get all the materials of all objects in a given scene # get all the materials of all objects in a given scene