#! python3 # shared logic for C-1 (bend radius -> KDS 24 14 21 Table 4.5-1). Pure geometry, no document edits. import math import Rhino from Rhino.Geometry import Arc, Line, Point3d, Vector3d, PolyCurve, PolylineCurve, ArcCurve, Curve, Brep, PipeCapMode from Rhino.Geometry.Intersect import Intersection BASE = r"D:\★Pier 자료\프로그램\Pier_T\검토파일" NOMINAL = {13: 12.7, 16: 15.9, 19: 19.1, 22: 22.2, 25: 25.4, 29: 28.6, 32: 31.8, 35: 34.9} def required_rc(dia): """Minimum centreline bend radius: inner diameter >= 3.5db (D19+) / 2db (<=D16), db nominal, tube d = integer dia.""" d = int("".join(ch for ch in dia if ch.isdigit())) nom = NOMINAL[d] inner_r = 1.75 * nom if d >= 19 else 1.0 * nom return math.ceil((inner_r + d / 2.0) * 100.0) / 100.0, d def _is_straight(c): if isinstance(c, PolylineCurve): return True return c.IsLinear(1e-6) def plan_curve(poly, dia): """Return (new_polycurve or None, info). info['short'] = number of short arcs, info['status'] ok|complex|unchanged.""" req, d = required_rc(dia) n = poly.SegmentCount segs = [poly.SegmentCurve(i).DuplicateCurve() for i in range(n)] short = [] for i, s in enumerate(segs): ok, arc = s.TryGetArc() if ok and not s.IsLinear() and arc.Radius < req - 1e-6 and math.degrees(arc.Angle) < 179.0: short.append(i) info = {"short": len(short), "req": req, "status": "unchanged"} if not short: return None, info # each short arc needs straight neighbours (or curve ends) and tangent continuity for i in short: for j in (i - 1, i + 1): if 0 <= j < n and not _is_straight(segs[j]): info["status"] = "complex" return None, info if 0 <= j < n and j in short: info["status"] = "complex" return None, info new = list(segs) for i in short: ok, arc = segs[i].TryGetArc() p0, p1 = arc.StartPoint, arc.EndPoint t0 = segs[i].TangentAtStart t1 = segs[i].TangentAtEnd t0.Unitize() t1.Unitize() ok2, a, b = Intersection.LineLine(Line(p0, p0 + t0 * 1e5), Line(p1 - t1 * 1e5, p1)) if not ok2: info["status"] = "complex" return None, info corner = Line(p0, p0 + t0 * 1e5).PointAt(a) theta = math.acos(max(-1.0, min(1.0, t0 * t1))) tl = req * math.tan(theta / 2.0) ns = corner - t0 * tl ne = corner + t1 * tl mid_arc = Arc(ns, t0, ne) if not mid_arc.IsValid: info["status"] = "complex" return None, info new[i] = ArcCurve(mid_arc) if i - 1 >= 0: pc = new[i - 1].DuplicateCurve() new[i - 1] = _retarget(pc, end=ns) if i + 1 < n: nc = new[i + 1].DuplicateCurve() new[i + 1] = _retarget(nc, start=ne) pc = PolyCurve() for s in new: if s is None: info["status"] = "complex" return None, info pc.Append(s) info["status"] = "ok" return pc, info def _retarget(c, start=None, end=None): if isinstance(c, PolylineCurve): pts = [c.Point(i) for i in range(c.PointCount)] if start is not None: pts[0] = start if end is not None: pts[-1] = end return PolylineCurve(pts) a = start if start is not None else c.PointAtStart b = end if end is not None else c.PointAtEnd return Rhino.Geometry.LineCurve(a, b) def make_pipe(curve, d, tol): r = d / 2.0 res = Brep.CreatePipe(curve, r, False, PipeCapMode.Flat, True, tol, Rhino.RhinoMath.ToRadians(1.0)) return res