Scene Manager: named LODs

{lod} in SCENE_MANAGER_LOD_COLLECTION now matches any name (COL_bob_LODhigh
as well as COL_bob_LOD0). SCENE_MANAGER_LODS (high, mid, low) sets the
button order and the LOD shown on load; unlisted LODs follow, numbers in
order, then names A-Z. It replaces SCENE_MANAGER_DEFAULT_LOD. The LOD of
Selected buttons get their own line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
NDemaerschalkandClaude Opus 5.5 committed 2026-10-27 16:46:36 +01:00
1 parent bac7a6f5da
commit 6ec2b228ae
8 files changed
+80 -61

No files matched your search

+25 -14
View File
@@ -177,12 +177,24 @@ def add_instance(scene, view_layer, library, parent=None):
# --------------------------------------------------------------------------- #
def _lod_pattern(asset_name):
before, _, after = config.SCENE_MANAGER_LOD_COLLECTION.partition("{lod}")
return re.compile(re.escape(before.format(asset=asset_name)) + r"(\d+)" + re.escape(after.format(asset=asset_name)) + "$")
return re.compile(
re.escape(before.format(asset=asset_name)) + r"(.+?)" + re.escape(after.format(asset=asset_name)) + r"(?:\.\d{3,})?$"
)
def lod_order(name):
"""Sort key of a LOD name: config SCENE_MANAGER_LODS order, then numbers, then names A-Z."""
listed = [str(n) for n in config.SCENE_MANAGER_LODS]
if name in listed:
return (0, listed.index(name), "")
if name.isdigit():
return (1, int(name), "")
return (2, 0, name.lower())
def lods(library, instance):
"""{LOD number: collection}: the LOD child collections of the asset collection, linked
for a collection instance, their overrides for an override."""
"""{LOD name: collection} in config order: the LOD child collections of the asset
collection, linked for a collection instance, their overrides for an override."""
root = linked_collection(library) if isinstance(instance, bpy.types.Object) else instance
if root is None:
return {}
@@ -193,8 +205,8 @@ def lods(library, instance):
name = child.override_library.reference.name if child.override_library else child.name
match = pattern.match(name)
if match:
found[int(match.group(1))] = child
return dict(sorted(found.items()))
found[match.group(1)] = child
return {name: found[name] for name in sorted(found, key=lod_order)}
def current_lod(library, instance):
@@ -211,7 +223,7 @@ def set_lod(library, instance, lod):
they are not evaluated), a collection instance instances the LOD collection."""
found = lods(library, instance)
if lod not in found:
available = ", ".join(str(n) for n in found) or "none"
available = ", ".join(found) or "none"
raise LoadError(f"{instance.name}: no LOD {lod} (LODs in the file: {available})")
if isinstance(instance, bpy.types.Object):
root = linked_collection(library)
@@ -223,23 +235,22 @@ def set_lod(library, instance, lod):
)
instance.instance_collection = found[lod]
return
for number, collection in found.items():
collection.hide_viewport = collection.hide_render = number != lod
for name, collection in found.items():
collection.hide_viewport = collection.hide_render = name != lod
def apply_default_lod(library, instance):
"""After a load or an update: show config SCENE_MANAGER_DEFAULT_LOD (else the lowest LOD)
when the instance shows no single LOD. An instance of a LOD the file no longer has goes
back to the whole asset collection first."""
"""After a load or an update: show the first LOD in config order when the instance shows
no single LOD. An instance of a LOD the file no longer has goes back to the whole asset
collection first."""
found = lods(library, instance)
root = linked_collection(library)
if isinstance(instance, bpy.types.Object) and root and instance.instance_collection not in (root, *found.values()):
instance.instance_collection = root
default = config.SCENE_MANAGER_DEFAULT_LOD
if not found or default is None or current_lod(library, instance) is not None:
if not found or current_lod(library, instance) is not None:
return
try:
set_lod(library, instance, default if default in found else min(found))
set_lod(library, instance, next(iter(found)))
except LoadError:
pass # a collection instance with content outside its LODs keeps the whole collection