# Which image datablocks exist, and which ones the body material actually SAMPLES. # blender --background --python 16b_images.py -- [ ...] import bpy, sys import numpy as np for BLEND in sys.argv[sys.argv.index("--") + 1:]: bpy.ops.wm.open_mainfile(filepath=BLEND) print(f"\n===== {BLEND} =====") ob = max([o for o in bpy.data.objects if o.type == 'MESH'], key=lambda o: len(o.data.vertices)) print(f"body '{ob.name}' {len(ob.data.vertices)}v materials=" f"{[ms.material.name if ms.material else None for ms in ob.material_slots]}") for i in bpy.data.images: b = np.empty(i.size[0] * i.size[1] * 4, dtype=np.float32) try: i.pixels.foreach_get(b) m = b.reshape(-1, 4)[:, :3] stat = f"mean {m.mean(axis=0).round(4)} std {m.std(axis=0).round(4)}" except Exception as e: stat = f"(no pixels: {e})" print(f" IMG '{i.name}' {i.size[0]}x{i.size[1]} packed={bool(i.packed_file)} " f"file='{i.filepath}' {stat}") for ms in ob.material_slots: mat = ms.material if not mat or not mat.node_tree: continue print(f" MAT '{mat.name}':") bsdf = next((n for n in mat.node_tree.nodes if n.type == 'BSDF_PRINCIPLED'), None) for n in mat.node_tree.nodes: if n.type == 'TEX_IMAGE': tgt = [] for o in n.outputs: for lk in o.links: tgt.append(f"{lk.to_node.name}.{lk.to_socket.name}") print(f" TEX_IMAGE node '{n.name}' image='{n.image.name if n.image else None}'" f" -> {tgt if tgt else 'UNCONNECTED'}") if bsdf: for sock in ("Base Color", "Normal", "Roughness", "Metallic"): if sock in bsdf.inputs: lk = bsdf.inputs[sock].links src = lk[0].from_node.name if lk else "(unlinked)" if lk and lk[0].from_node.type == 'TEX_IMAGE': src += f" image='{lk[0].from_node.image.name if lk[0].from_node.image else None}'" print(f" BSDF.{sock} <- {src}") print("IMAGES_DONE")