import sys, math, collections, json sys.path.insert(0, 'pylib') import rhino3dm M = r"D:\★Pier 자료\심수석님 검토 파일\검토_옥성교P1\옥성교P1_G5.3dm" m3 = rhino3dm.File3dm.Read(M) lay = {l.Index: l.FullPath for l in m3.Layers} def V(p): return (p.X, p.Y, p.Z) def sub(a, b): return (a[0]-b[0], a[1]-b[1], a[2]-b[2]) def dot(a, b): return a[0]*b[0]+a[1]*b[1]+a[2]*b[2] def nrm(a): return math.sqrt(dot(a, a)) def segs_of(g): if isinstance(g, rhino3dm.PolyCurve): return [g.SegmentCurve(i) for i in range(g.SegmentCount)] return [g] def is_line(s): return type(s).__name__ in ("LineCurve", "PolylineCurve") bars = collections.defaultdict(dict) for o in m3.Objects: L = lay.get(o.Attributes.LayerIndex, "") g = o.Geometry; nm = o.Attributes.Name or "" if isinstance(g, rhino3dm.Brep): us = dict(o.Attributes.GetUserStrings()) if us.get("mark"): bars[us["mark"]].setdefault(us.get("occurrence"), {}).update(us=us, layer=L) elif nm.startswith("P1-RC-"): p = nm.split("-") bars[p[2]].setdefault("-".join(p[3:]), {})["g"] = g out = {} for mk, dd in sorted(bars.items()): items = [b for b in dd.values() if "us" in b and "g" in b] if not items: print(mk, 'no items'); continue # pick shortest and longest by design length items.sort(key=lambda b: float(b["us"].get("design_length", 0))) for tag, b in (("min", items[0]), ("max", items[-1])): g = b["g"] segs = segs_of(g) desc = [] for s in segs: t = type(s).__name__ if is_line(s): desc.append("L%.0f" % nrm(sub(V(s.PointAtEnd), V(s.PointAtStart)))) elif t == "ArcCurve": desc.append("A r%.1f a%.1f" % (s.Arc.Radius, s.Arc.AngleDegrees)) else: desc.append(t) print(mk, tag, b["us"].get("shape"), b["us"].get("dia"), "dl", b["us"].get("design_length"), b["us"].get("coupler_length"), "|", " ".join(desc)) print(" src:", b["us"].get("src")) print("=========== CORNER SEQ") def addv(a, b, t): return (a[0]+b[0]*t, a[1]+b[1]*t, a[2]+b[2]*t) def isect(p1, d1, p2, d2): w = sub(p1, p2); a = dot(d1, d1); b = dot(d1, d2); c = dot(d2, d2); d = dot(d1, w); e = dot(d2, w) den = a*c - b*b if abs(den) < 1e-9: return None return addv(p1, d1, (b*e - c*d)/den) def cseq(g): lines = [(V(s.PointAtStart), V(s.PointAtEnd)) for s in segs_of(g) if is_line(s)] if len(lines) < 2: return [round(nrm(sub(lines[0][1], lines[0][0])))] if lines else [] pts = [] for i in range(len(lines)-1): p1, q1 = lines[i]; p2, q2 = lines[i+1] pts.append(isect(p1, sub(q1, p1), p2, sub(q2, p2))) seq = [lines[0][0]] + pts + [lines[-1][1]] return [round(nrm(sub(seq[i+1], seq[i]))) for i in range(len(seq)-1)] for mk, dd in sorted(bars.items()): items = [b for b in dd.values() if "us" in b and "g" in b] seqs = collections.Counter(tuple(cseq(b["g"])) for b in items) print(mk, len(items), "distinct", len(seqs)) for s, c in sorted(seqs.items())[:3] + sorted(seqs.items())[-2:]: print(" ", c, s)