#!/usr/bin/env python3 import sys import re import numpy as np import matplotlib.pyplot as plt from matplotlib.collections import PolyCollection # ---- Option A: paste your data directly here ---- RAW = """ 0.010 , 0.000 , 0.000 0.009 , -0.000 , 0.000 0.009 , 0.001 , 0.000 -0.010 , 0.000 , 0.000 -0.010 , 0.001 , 0.000 -0.009 , 0.001 , 0.000 -0.010 , 0.000 , 0.000 -0.009 , 0.001 , 0.000 -0.009 , 0.000 , 0.000 0.010 , 0.000 , 0.000 0.009 , -0.000 , 0.000 0.010 , -0.000 , 0.000 -0.001 , 0.000 , 0.000 0.001 , 0.001 , 0.000 -0.001 , 0.001 , 0.000 0.003 , -0.000 , 0.000 0.001 , -0.000 , 0.000 0.003 , 0.001 , 0.000 -0.006 , 0.001 , 0.000 -0.006 , 0.000 , 0.000 -0.008 , 0.001 , 0.000 -0.001 , 0.000 , 0.000 0.001 , 0.001 , 0.000 0.001 , -0.000 , 0.000 -0.005 , 0.000 , 0.000 -0.003 , 0.000 , 0.000 -0.003 , 0.001 , 0.000 -0.005 , 0.000 , 0.000 -0.006 , 0.001 , 0.000 -0.006 , 0.000 , 0.000 -0.009 , 0.001 , 0.000 -0.009 , 0.000 , 0.000 -0.009 , 0.000 , 0.000 -0.005 , 0.000 , 0.000 -0.006 , 0.001 , 0.000 -0.005 , 0.001 , 0.000 -0.009 , 0.001 , 0.000 -0.009 , 0.001 , 0.000 -0.009 , 0.000 , 0.000 -0.008 , 0.001 , 0.000 -0.009 , 0.000 , 0.000 -0.008 , 0.000 , 0.000 -0.005 , 0.000 , 0.000 -0.003 , 0.001 , 0.000 -0.005 , 0.001 , 0.000 -0.009 , 0.001 , 0.000 -0.008 , 0.001 , 0.000 -0.009 , 0.000 , 0.000 -0.006 , 0.000 , 0.000 -0.008 , 0.001 , 0.000 -0.008 , 0.000 , 0.000 0.001 , 0.001 , 0.000 0.001 , -0.000 , 0.000 0.003 , 0.001 , 0.000 -0.001 , 0.001 , 0.000 -0.003 , 0.000 , 0.000 -0.003 , 0.001 , 0.000 0.008 , -0.000 , 0.000 0.006 , 0.001 , 0.000 0.008 , 0.001 , 0.000 0.009 , 0.001 , 0.000 0.008 , -0.000 , 0.000 0.008 , 0.001 , 0.000 0.006 , -0.000 , 0.000 0.005 , -0.000 , 0.000 0.005 , 0.001 , 0.000 0.005 , -0.000 , 0.000 0.005 , 0.001 , 0.000 0.003 , -0.000 , 0.000 0.009 , 0.001 , 0.000 0.009 , -0.000 , 0.000 0.009 , 0.001 , 0.000 -0.001 , 0.000 , 0.000 -0.001 , 0.001 , 0.000 -0.003 , 0.000 , 0.000 0.006 , -0.000 , 0.000 0.008 , -0.000 , 0.000 0.006 , 0.001 , 0.000 0.009 , -0.000 , 0.000 0.009 , 0.001 , 0.000 0.008 , -0.000 , 0.000 0.006 , -0.000 , 0.000 0.005 , 0.001 , 0.000 0.006 , 0.001 , 0.000 0.005 , 0.001 , 0.000 0.003 , -0.000 , 0.000 0.003 , 0.001 , 0.000 0.009 , -0.000 , 0.000 0.009 , 0.001 , 0.000 0.009 , -0.000 , 0.000 """.strip() #!/usr/bin/env python3 import sys import re import numpy as np import matplotlib.pyplot as plt from matplotlib.collections import PolyCollection if len(sys.argv) > 1: with open(sys.argv[1], "r") as f: RAW = f.read().strip() def parse_points(text): pts = [] for line in text.splitlines(): line = line.strip() if not line: continue nums = re.split(r"[,\s]+", line) nums = [n for n in nums if n] if len(nums) < 3: continue try: x, y, z = map(float, nums[:3]) pts.append([x, y, z]) except ValueError: pass return np.array(pts, dtype=float) pts = parse_points(RAW) if pts.size == 0 or pts.shape[0] % 3 != 0: raise SystemExit(f"Parsed {pts.shape[0]} points; not a multiple of 3.") tris = pts.reshape(-1, 3, 3) n_tris = tris.shape[0] print(f"Number of triangles: {n_tris}") # --- Check for duplicates --- def canonical_triangle(tri): # round to 6 decimals to avoid tiny float noise verts = [tuple(np.round(v, 6)) for v in tri] # sort vertices lexicographically to remove ordering ambiguity verts_sorted = tuple(sorted(verts)) return verts_sorted seen = {} duplicates = [] for i, tri in enumerate(tris): key = canonical_triangle(tri) if key in seen: duplicates.append((i, seen[key])) else: seen[key] = i if duplicates: print(f"Found {len(duplicates)} duplicate triangles:") for i, j in duplicates: print(f" Triangle {i} is a duplicate of {j}") else: print("No duplicate triangles found.") # --- Plot 2D view --- xy_polys = [tri[:, :2] for tri in tris] fig, ax = plt.subplots(figsize=(6, 6)) pc = PolyCollection(xy_polys, closed=True, linewidths=0.8, edgecolors="k", facecolors="none") ax.add_collection(pc) all_xy = np.vstack(xy_polys) xmin, ymin = all_xy.min(axis=0) xmax, ymax = all_xy.max(axis=0) pad = 0.05 * max(xmax - xmin, ymax - ymin, 1e-12) ax.set_xlim(xmin - pad, xmax + pad) ax.set_ylim(ymin - pad, ymax + pad) ax.set_aspect("equal", adjustable="box") ax.set_title(f"Triangles (N = {n_tris})") plt.show()