mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-12-22 15:44:11 +00:00
feat(Blenvy:Blender): numerous minor tweaks & fixes (mostly materials related)
* now correctly handling multi material meshes that have more materials in their slots as there are actual materials applied * per-blueprint materials are now correctly inserted/updated even when there are no material changes (ie cases where the ordering of slots etc is changed on a mesh) * conditions for trigerring exports of levels & materials are more coherent and exports are now trigerred on export setting changes (as they should have been !) * minor cleanups
This commit is contained in:
parent
ab7a0cab65
commit
94fe3f6d3c
2
TODO.md
2
TODO.md
@ -226,6 +226,8 @@ Blender side:
|
||||
- [ ] 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
|
||||
|
||||
- [x] injection of materials_infos should be done outside of export_materials as it should run even if materials do not need exporting
|
||||
|
||||
- [x] if material library is toggled, then changes to materials should not change the blueprints that are using them => not really: as the name & co might change
|
||||
- [ ] material assets seem to be added to list regardless of whether material exports are enabled or not
|
||||
- [x] review & upgrade overall logic of material libraries, their names & output path
|
||||
|
@ -2,6 +2,7 @@ import os
|
||||
import bpy
|
||||
from blenvy.assets.assets_scan import get_blueprint_asset_tree
|
||||
from blenvy.assets.generate_asset_file import write_ron_assets_file
|
||||
from ....materials.materials_helpers import add_material_info_to_objects, get_blueprint_materials
|
||||
from ..constants import TEMPSCENE_PREFIX
|
||||
from ..common.generate_temporary_scene_and_export import generate_temporary_scene_and_export, copy_hollowed_collection_into, clear_hollow_scene
|
||||
from ..common.export_gltf import generate_gltf_export_settings
|
||||
@ -26,7 +27,11 @@ def export_blueprints(blueprints, settings, blueprints_data):
|
||||
if export_materials_library:
|
||||
gltf_export_settings['export_materials'] = 'PLACEHOLDER'
|
||||
|
||||
# inject blueprint asset data
|
||||
upsert_blueprint_assets(blueprint, blueprints_data=blueprints_data, settings=settings)
|
||||
# upsert material infos if needed
|
||||
(_, materials_per_object) = get_blueprint_materials(blueprint)
|
||||
add_material_info_to_objects(materials_per_object, settings)
|
||||
|
||||
# do the actual export
|
||||
generate_temporary_scene_and_export(
|
||||
|
@ -26,7 +26,7 @@ def auto_export(changes_per_scene, changes_per_collection, changes_per_material,
|
||||
#should we use change detection or not
|
||||
change_detection = getattr(settings.auto_export, "change_detection")
|
||||
export_scene_settings = getattr(settings.auto_export, "export_scene_settings")
|
||||
do_export_blueprints = getattr(settings.auto_export, "export_blueprints")
|
||||
export_blueprints_enabled = getattr(settings.auto_export, "export_blueprints")
|
||||
export_materials_library = getattr(settings.auto_export, "export_materials_library")
|
||||
|
||||
# standard gltf export settings are stored differently
|
||||
@ -62,7 +62,7 @@ def auto_export(changes_per_scene, changes_per_collection, changes_per_material,
|
||||
light['BlenderLightShadows'] = f"(enabled: {enabled}, buffer_bias: {light.shadow_buffer_bias})"
|
||||
|
||||
# export
|
||||
if do_export_blueprints:
|
||||
if export_blueprints_enabled:
|
||||
print("EXPORTING")
|
||||
# get blueprints/collections infos
|
||||
(blueprints_to_export) = get_blueprints_to_export(changes_per_scene, changes_per_collection, changed_export_parameters, blueprints_data, settings)
|
||||
@ -100,22 +100,21 @@ def auto_export(changes_per_scene, changes_per_collection, changes_per_material,
|
||||
old_current_scene = bpy.context.scene
|
||||
# backup current selections
|
||||
old_selections = bpy.context.selected_objects
|
||||
|
||||
|
||||
# deal with materials
|
||||
if export_materials_library and len(materials_to_export) > 0:
|
||||
if export_materials_library and (not change_detection or changed_export_parameters or len(materials_to_export) > 0) :
|
||||
print("export MATERIALS")
|
||||
export_materials(materials_to_export, settings, blueprints_data)
|
||||
|
||||
# export any level/world scenes
|
||||
if len(level_scenes_to_export) > 0:
|
||||
if not change_detection or changed_export_parameters or len(level_scenes_to_export) > 0:
|
||||
print("export LEVELS")
|
||||
for scene_name in level_scenes_to_export:
|
||||
print(" exporting scene:", scene_name)
|
||||
export_level_scene(bpy.data.scenes[scene_name], settings, blueprints_data)
|
||||
|
||||
# now deal with blueprints/collections
|
||||
do_export_blueprints = not change_detection or changed_export_parameters or len(blueprints_to_export) > 0
|
||||
if do_export_blueprints:
|
||||
if not change_detection or changed_export_parameters or len(blueprints_to_export) > 0:
|
||||
print("export BLUEPRINTS")
|
||||
export_blueprints(blueprints_to_export, settings, blueprints_data)
|
||||
|
||||
|
@ -74,34 +74,30 @@ def clear_materials_scene(temp_scene):
|
||||
# exports the materials used inside the current project:
|
||||
# the name of the output path is <materials_folder>/<name_of_your_blend_file>_materials_library.gltf/glb
|
||||
def export_materials(materials_to_export, settings, blueprints_data):
|
||||
if len(materials_to_export) > 0:
|
||||
gltf_export_settings = generate_gltf_export_settings(settings)
|
||||
materials_path_full = getattr(settings,"materials_path_full")
|
||||
gltf_export_settings = generate_gltf_export_settings(settings)
|
||||
materials_path_full = getattr(settings,"materials_path_full")
|
||||
|
||||
(used_material_names, materials_per_object) = get_all_materials(blueprints_data.blueprint_names, settings.library_scenes)
|
||||
add_material_info_to_objects(materials_per_object, settings)
|
||||
gltf_export_settings = { **gltf_export_settings,
|
||||
'use_active_scene': True,
|
||||
'use_active_collection':True,
|
||||
'use_active_collection_with_nested':True,
|
||||
'use_visible': False,
|
||||
'use_renderable': False,
|
||||
'export_apply':True
|
||||
}
|
||||
|
||||
gltf_export_settings = { **gltf_export_settings,
|
||||
'use_active_scene': True,
|
||||
'use_active_collection':True,
|
||||
'use_active_collection_with_nested':True,
|
||||
'use_visible': False,
|
||||
'use_renderable': False,
|
||||
'export_apply':True
|
||||
}
|
||||
for material in materials_to_export:
|
||||
print("exporting material", material.name)
|
||||
gltf_output_path = os.path.join(materials_path_full, material.name)
|
||||
|
||||
for material in materials_to_export:
|
||||
print("exporting material", material.name)
|
||||
gltf_output_path = os.path.join(materials_path_full, material.name)
|
||||
|
||||
generate_temporary_scene_and_export(
|
||||
settings=settings,
|
||||
gltf_export_settings=gltf_export_settings,
|
||||
temp_scene_name="__materials_scene",
|
||||
gltf_output_path=gltf_output_path,
|
||||
tempScene_filler= lambda temp_collection: generate_material_scene_content(temp_collection, material.name),
|
||||
tempScene_cleaner= lambda temp_scene, params: clear_materials_scene(temp_scene=temp_scene)
|
||||
)
|
||||
generate_temporary_scene_and_export(
|
||||
settings=settings,
|
||||
gltf_export_settings=gltf_export_settings,
|
||||
temp_scene_name="__materials_scene",
|
||||
gltf_output_path=gltf_output_path,
|
||||
tempScene_filler= lambda temp_collection: generate_material_scene_content(temp_collection, material.name),
|
||||
tempScene_cleaner= lambda temp_scene, params: clear_materials_scene(temp_scene=temp_scene)
|
||||
)
|
||||
|
||||
|
||||
def cleanup_materials(collections, library_scenes):
|
||||
|
@ -17,19 +17,50 @@ def check_if_material_on_disk(scene_name, folder_path, extension):
|
||||
found = os.path.exists(gltf_output_path) and os.path.isfile(gltf_output_path)
|
||||
return found
|
||||
|
||||
|
||||
# get materials per object, and injects the materialInfo component
|
||||
def get_materials(object, materials_per_object):
|
||||
material_slots = object.material_slots
|
||||
used_materials_names = []
|
||||
|
||||
if not hasattr(object, "data"):
|
||||
return used_materials_names
|
||||
if not hasattr(object.data,"materials"):
|
||||
return used_materials_names
|
||||
if len(object.data.materials) == 0:
|
||||
return used_materials_names
|
||||
|
||||
# since we are scanning polygons to get the actually used materials, we do not get them in the correct order
|
||||
materials_per_object_unordered = []
|
||||
|
||||
"""materials_count = len(material_slots)
|
||||
print("materials_count", materials_count)
|
||||
material_indices = np.empty(materials_count, dtype=np.int64)
|
||||
object.data.polygons.foreach_get("material_index", material_indices)
|
||||
#for material_index in object.data.polygons.foreach_get("material_index", storage):
|
||||
print("polygon material_indices", material_indices)"""
|
||||
# TODO: perhaps optimise it using foreach_get
|
||||
for polygon in object.data.polygons:
|
||||
slot = material_slots[polygon.material_index]
|
||||
material = slot.material
|
||||
if not material.name in used_materials_names:
|
||||
used_materials_names.append(material.name)
|
||||
materials_per_object_unordered.append((material, polygon.material_index))
|
||||
|
||||
if len(used_materials_names) == len(material_slots): # we found all materials, bail out
|
||||
break
|
||||
|
||||
# now re-order the materials as per the object's material slots
|
||||
sorted_materials = sorted(materials_per_object_unordered, key=lambda tup: tup[1])
|
||||
|
||||
# and add them
|
||||
if not object in materials_per_object:
|
||||
materials_per_object[object] = []
|
||||
materials_per_object[object] = [material[0] for material in sorted_materials]#.append(material)
|
||||
|
||||
"""for m in material_slots:
|
||||
material = m.material"""
|
||||
|
||||
for m in material_slots:
|
||||
material = m.material
|
||||
# print(" slot", m, "material", material)
|
||||
used_materials_names.append(material.name)
|
||||
# TODO:, also respect slots & export multiple materials if applicable !
|
||||
if not object in materials_per_object:
|
||||
materials_per_object[object] = []
|
||||
materials_per_object[object].append(material)
|
||||
return used_materials_names
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user