"""Exterior of the Spearfish in its own frame (hatch shut, cabin left out), for sweep_check.py and clamp_check.py: checks/spearfish_points.npy every 2nd vertex, whip masts raised (as drawn: the moon pool at BOARD) checks/spearfish_points_folded.npy every 2nd vertex, whip masts folded (stowed: the carousel sweep) checks/spearfish_tris.npz all triangles, masts raised (the docking clamp) Runs in the open Blender or headless; leaves the rig as it found it.""" import bpy, numpy as np, os HERE = r"D:\HADAL - The Descent\models\tender-spearfish\build" root = bpy.data.objects["Spearfish_Root"] def collect(): V, T, NAMES, OFF, P = [], [], [], 0, [] dg = bpy.context.evaluated_depsgraph_get() for o in bpy.data.objects: if o.type == 'MESH' and o.name.startswith("SM_Spearfish") and o.name != "SM_Spearfish_Cabin": ev = o.evaluated_get(dg) me = o.data me.calc_loop_triangles() M = np.array(ev.matrix_world) co = np.empty(len(me.vertices) * 3); me.vertices.foreach_get("co", co) co = co.reshape(-1, 3) @ M[:3, :3].T + M[:3, 3] tr = np.empty(len(me.loop_triangles) * 3, np.int64); me.loop_triangles.foreach_get("vertices", tr) V.append(co); T.append(tr.reshape(-1, 3) + OFF); NAMES += [o.name] * len(me.loop_triangles); OFF += len(co) P.append(co[::2]) return V, T, NAMES, P def refresh_drivers(): """the rig's drivers can be left flagged invalid by an evaluation before their variables existed: re-set them""" for ob in bpy.data.objects: if ob.animation_data: for fc in ob.animation_data.drivers: fc.driver.expression = fc.driver.expression fc.driver.is_valid = True def pose(folded): refresh_drivers() root["masts_folded"] = 1.0 if folded else 0.0 root["hatch_open_deg"] = 0.0 root.update_tag() for ob in root.children: ob.update_tag() bpy.context.view_layer.update() keep = (root.get("masts_folded", 0.0), root.get("hatch_open_deg", 0.0)) pose(True) V, T, NAMES, P = collect() np.save(os.path.join(HERE, "checks", "spearfish_points_folded.npy"), np.concatenate(P)) pose(False) V, T, NAMES, P = collect() np.save(os.path.join(HERE, "checks", "spearfish_points.npy"), np.concatenate(P)) np.savez(os.path.join(HERE, "checks", "spearfish_tris.npz"), v=np.concatenate(V), t=np.concatenate(T), names=np.array(NAMES)) root["masts_folded"], root["hatch_open_deg"] = keep root.update_tag(); bpy.context.view_layer.update() print("DUMP", sum(len(v) for v in V), sum(len(t) for t in T))