"""Study only: the deck's two contours in order (well and outer), and how its quads run.""" import json import math import os import bmesh import bpy HERE = os.path.dirname(os.path.abspath(__file__)) ob = bpy.data.objects["Moonpool | deck around open well"] bm = bmesh.new() bm.from_mesh(ob.data) bm.transform(ob.matrix_world) bm.verts.ensure_lookup_table() bm.faces.ensure_lookup_table() ztop = max(v.co.z for v in bm.verts) top_faces = [f for f in bm.faces if f.normal.z > 0.9] # edges of the top sheet that belong to one top face only = the two contours cnt = {} for f in top_faces: for e in f.edges: cnt[e.index] = cnt.get(e.index, 0) + 1 bm.edges.ensure_lookup_table() border = [bm.edges[i] for i, c in cnt.items() if c == 1] adj = {} for e in border: a, b = e.verts adj.setdefault(a.index, []).append(b.index) adj.setdefault(b.index, []).append(a.index) loops = [] seen = set() for start in adj: if start in seen: continue loop = [start] seen.add(start) cur, prev = start, None while True: nxt = [n for n in adj[cur] if n != prev and n not in seen] if not nxt: break prev, cur = cur, nxt[0] loop.append(cur) seen.add(cur) loops.append(loop) loops.sort(key=lambda l: max(abs(bm.verts[i].co.y) for i in l)) inner, outer = loops[0], loops[-1] uv = bm.loops.layers.uv["UV0"] uv1 = bm.loops.layers.uv["UV1_Lightmap"] rec = {"n_loops": len(loops), "inner_n": len(inner), "outer_n": len(outer), "ztop": ztop, "inner": [[round(bm.verts[i].co.x, 4), round(bm.verts[i].co.y, 4)] for i in inner], "outer": [[round(bm.verts[i].co.x, 4), round(bm.verts[i].co.y, 4)] for i in outer]} # pairing: each top quad has two inner and two outer verts iset, oset = set(inner), set(outer) pairs = {} for f in top_faces: vi = [v.index for v in f.verts if v.index in iset] vo = [v.index for v in f.verts if v.index in oset] for e in f.edges: a, b = e.verts[0].index, e.verts[1].index if (a in iset) != (b in iset): pairs[a if a in iset else b] = b if a in iset else a rec["pairs"] = [[inner.index(i), outer.index(o)] for i, o in pairs.items()] f = top_faces[0] rec["uv0_face"] = [[[round(l.vert.co.x, 3), round(l.vert.co.y, 3)], [round(l[uv].uv.x, 4), round(l[uv].uv.y, 4)], [round(l[uv1].uv.x, 4), round(l[uv1].uv.y, 4)]] for l in f.loops] side = [f for f in bm.faces if abs(f.normal.z) < 0.5][:2] rec["uv0_side"] = [[[[round(l.vert.co.x, 3), round(l.vert.co.y, 3), round(l.vert.co.z, 3)], [round(l[uv].uv.x, 4), round(l[uv].uv.y, 4)]] for l in f.loops] for f in side] rec["sharp_edges"] = sum(1 for e in bm.edges if not e.smooth) rec["custom"] = {k: (list(ob[k]) if hasattr(ob[k], "__len__") and not isinstance(ob[k], str) else ob[k]) for k in ob.keys()} with open(os.path.join(HERE, "study_deck2.json"), "w", encoding="utf-8") as fh: json.dump(rec, fh, default=str) print("STUDY written")