47 lines
2.1 KiB
Python
47 lines
2.1 KiB
Python
|
|
"""Print a compact inventory of a Blender-compatible source model."""
|
||
|
|
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import bpy
|
||
|
|
from mathutils import Vector
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> None:
|
||
|
|
marker = sys.argv.index("--")
|
||
|
|
source = Path(sys.argv[marker + 1]).resolve()
|
||
|
|
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||
|
|
suffix = source.suffix.lower()
|
||
|
|
if suffix in {".glb", ".gltf"}:
|
||
|
|
bpy.ops.import_scene.gltf(filepath=str(source))
|
||
|
|
elif suffix == ".fbx":
|
||
|
|
bpy.ops.import_scene.fbx(filepath=str(source))
|
||
|
|
elif suffix == ".obj":
|
||
|
|
bpy.ops.wm.obj_import(filepath=str(source))
|
||
|
|
else:
|
||
|
|
raise SystemExit(f"unsupported source format: {suffix}")
|
||
|
|
|
||
|
|
for obj in sorted(bpy.context.scene.objects, key=lambda value: value.name):
|
||
|
|
if obj.type == "MESH":
|
||
|
|
corners = [obj.matrix_world @ Vector(corner) for corner in obj.bound_box]
|
||
|
|
lo = tuple(round(min(point[index] for point in corners), 4) for index in range(3))
|
||
|
|
hi = tuple(round(max(point[index] for point in corners), 4) for index in range(3))
|
||
|
|
parent = obj.parent.name if obj.parent else "-"
|
||
|
|
print(f"MESH {obj.name} verts={len(obj.data.vertices)} mats={len(obj.data.materials)} parent={parent} hide={obj.hide_render} bbox={lo}..{hi}")
|
||
|
|
elif obj.type == "ARMATURE":
|
||
|
|
bones = ",".join(bone.name for bone in obj.data.bones)
|
||
|
|
print(f"ARMATURE {obj.name} bones={len(obj.data.bones)} [{bones}]")
|
||
|
|
for bone in obj.data.bones:
|
||
|
|
if bone.name in {"root","DEF-hips","DEF-spine.002","DEF-spine.003","DEF-head",
|
||
|
|
"DEF-hand.L","DEF-hand.R","DEF-upper_arm.L","DEF-upper_arm.R"}:
|
||
|
|
head=tuple(round(value,4) for value in bone.head_local)
|
||
|
|
tail=tuple(round(value,4) for value in bone.tail_local)
|
||
|
|
print(f"BONE {bone.name} {head}->{tail}")
|
||
|
|
for action in sorted(bpy.data.actions, key=lambda value: value.name):
|
||
|
|
start, end = action.frame_range
|
||
|
|
print(f"ACTION {action.name} frames={start:.0f}..{end:.0f}")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|