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:
1 parent
bac7a6f5da
commit
6ec2b228ae
8 files changed
+80
-61
No files matched your search
+25
-14
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user