# Critique round 2 (read-only): decal faces that lie on top of each other (two markings' pads copying the same hull face) import bpy, json, os, collections ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) o = bpy.data.objects["SM_Grouper_Decals"]; me = o.data; M = o.matrix_world uv = me.uv_layers["UVMap"].data tiles = json.load(open(os.path.join(ROOT, "build", "decals.json")))["tiles"] def tile_of(p): u = sum(uv[li].uv.x for li in range(p.loop_start, p.loop_start + p.loop_total)) / p.loop_total v = sum(uv[li].uv.y for li in range(p.loop_start, p.loop_start + p.loop_total)) / p.loop_total for k, t in tiles.items(): if t["uv"][0] <= u <= t["uv"][2] and t["uv"][1] <= v <= t["uv"][3]: return k return "?" groups = collections.defaultdict(list) for p in me.polygons: c = M @ p.center groups[(round(c.x, 4), round(c.y, 4), round(c.z, 4))].append(tile_of(p)) dup = {k: v for k, v in groups.items() if len(v) > 1} pairs = collections.Counter(tuple(sorted(v)) for v in dup.values()) res = dict(faces=len(me.polygons), positions_shared=len(dup), pairs=[[list(k), n] for k, n in pairs.items()], examples=[[list(k), v] for k, v in list(dup.items())[:6]]) json.dump(res, open(os.path.join(ROOT, "critique", "round2", "decal_dupes.json"), "w"), indent=1) print("CR2 DUPES", json.dumps(res))