"""Study only: every ship object (not the layout) near the well, and the coaming's build.""" import collections import json import os import bmesh import bpy from mathutils import Vector HERE = os.path.dirname(os.path.abspath(__file__)) BOX = ((-5.0, 11.0), (-9.4, 0.5), (-4.6, -2.9)) layout = set(o.name for o in bpy.data.collections["10 INTERIOR | Season 2 layout"].all_objects) rows = [] for ob in bpy.data.objects: if ob.type != "MESH" or ob.name in layout or ob.library is not None: continue if not ob.users_collection: continue pts = [ob.matrix_world @ Vector(c) for c in ob.bound_box] lo = [min(p[i] for p in pts) for i in range(3)] hi = [max(p[i] for p in pts) for i in range(3)] if all(hi[i] >= BOX[i][0] and lo[i] <= BOX[i][1] for i in range(3)): rows.append({"object": ob.name, "collections": [c.name for c in ob.users_collection], "faces": len(ob.data.polygons), "min": [round(v, 2) for v in lo], "max": [round(v, 2) for v in hi], "materials": [s.material.name if s.material else None for s in ob.material_slots], "modifiers": [(m.name, m.type) for m in ob.modifiers], "parent": ob.parent.name if ob.parent else None, "hide": [ob.hide_viewport, ob.hide_render]}) out = {"near_well": rows} ob = bpy.data.objects.get("Moonpool | rounded trapezoid silver coaming") if ob: cu = ob.data rec = {"type": ob.type, "collections": [c.name for c in ob.users_collection], "parent": ob.parent.name if ob.parent else None, "location": [round(v, 3) for v in ob.location], "rotation": [round(v, 4) for v in ob.rotation_euler], "scale": [round(v, 3) for v in ob.scale], "custom": {k: str(ob[k])[:160] for k in ob.keys()}, "materials": [s.material.name if s.material else None for s in ob.material_slots], "modifiers": [(m.name, m.type) for m in ob.modifiers], "dimensions": cu.dimensions, "bevel_mode": cu.bevel_mode, "bevel_depth": cu.bevel_depth, "bevel_resolution": cu.bevel_resolution, "bevel_object": cu.bevel_object.name if cu.bevel_object else None, "extrude": cu.extrude, "offset": cu.offset, "fill_mode": cu.fill_mode, "resolution_u": cu.resolution_u, "use_fill_caps": cu.use_fill_caps, "taper": cu.taper_object.name if cu.taper_object else None, "twist_mode": cu.twist_mode, "splines": []} for sp in cu.splines: srec = {"type": sp.type, "cyclic": sp.use_cyclic_u, "order": sp.order_u, "res": sp.resolution_u, "n_points": len(sp.points), "n_bezier": len(sp.bezier_points)} if sp.type == "BEZIER": srec["bezier"] = [[[round(c, 4) for c in (ob.matrix_world @ bp.co)], [round(c, 4) for c in (ob.matrix_world @ bp.handle_left)], [round(c, 4) for c in (ob.matrix_world @ bp.handle_right)], bp.handle_left_type, round(bp.tilt, 4), round(bp.radius, 4)] for bp in sp.bezier_points] else: srec["points"] = [[round(c, 4) for c in (ob.matrix_world @ p.co.xyz)] + [round(p.co.w, 3), round(p.tilt, 4), round(p.radius, 4)] for p in sp.points] rec["splines"].append(srec) if cu.bevel_object: bo = cu.bevel_object rec["bevel_object_splines"] = [[[round(c, 4) for c in p.co.xyz] for p in sp.points] or [[round(c, 4) for c in bp.co] for bp in sp.bezier_points] for sp in bo.data.splines] rec["bevel_object_cyclic"] = [sp.use_cyclic_u for sp in bo.data.splines] rec["bevel_object_scale"] = [round(v, 4) for v in bo.scale] dg = bpy.context.evaluated_depsgraph_get() ev = ob.evaluated_get(dg) me = ev.to_mesh() mw = ob.matrix_world vs = [mw @ v.co for v in me.vertices] rec["eval_verts"] = len(vs) rec["eval_faces"] = len(me.polygons) rec["eval_bounds"] = [[round(min(v[i] for v in vs), 3) for i in range(3)], [round(max(v[i] for v in vs), 3) for i in range(3)]] rec["eval_section_x3"] = sorted([[round(v.y, 3), round(v.z, 3)] for v in vs if abs(v.x - 3.05) < 0.06]) ev.to_mesh_clear() out["coaming"] = rec with open(os.path.join(HERE, "study_deck4.json"), "w", encoding="utf-8") as f: json.dump(out, f, indent=1) print("STUDY written")