public void AddSeam(Surface srf, Color color = default(Color)) { if (!IS_ENABLED) { return; } if (color == default(Color)) { color = Color.Crimson; } var ss = new SurfaceSeams(srf); if (ss.HasSeams) { var uT0 = ss.U.Domain.T0; var uT1 = ss.U.Domain.T1; var vT0 = ss.V.Domain.T0; var vT1 = ss.V.Domain.T1; if (ss.U.IsAtT0 && ss.U.IsAtT1) { AddCurve(srf._GetVCurve(ss.U.T0), "Seam on U at {0:0.00} & {1:0.00}"._Format(uT0, uT1), color); } if (ss.V.IsAtT0 && ss.V.IsAtT1) { AddCurve(srf._GetUCurve(ss.V.T0), "Seam on V at {0:0.00} & {1:0.00}"._Format(vT0, vT1), color); } } }
public static NurbsCurve _Convert3dCurveTo2d(this Surface srf, NurbsCurve crv3d , SurfaceSingulars ssingulars = null, Curve trim = null, Curve edge = null, double pullback_tol = 0.001) { var seam = new SurfaceSeams(srf); if (seam.HasSeams) { log.wrong("Dangerous convertion of 3d curve to 2d in method _Curve._Convert3dCurveTo2d(). Remove seam before use such convertions."); } // Try internal method first - it is faster, but may be incorrect var newCrv2d = srf.Pullback(crv3d, pullback_tol); Point3d[] point3d; if (newCrv2d != null && newCrv2d._TryDivideByCount(5, out point3d)) { //var sps = newCrv2d.Points._SurfacePoints(); var sps = point3d.Select(o => new SurfacePoint(o)).ToList(); var isSPSFixed = srf._FixSurfacePoints(ref sps, false, null, null, crv3d); if (!isSPSFixed) // if there is no need in fixing points - we have good 2d curve - lets return result { return(newCrv2d._ToNurbsCurve()); } } // Lets use our method - slow but very precise // Rebuild 3d curve for better precision pulling to 2d surface. var divby = crv3d._GetDivBy(null, 0.01, 100); NurbsCurve Crv3dRebuilded = crv3d.Rebuild(divby, 3, false) ?? crv3d; Crv3dRebuilded = Crv3dRebuilded._SetDimension(3); newCrv2d = srf._Convert3dCurveTo2d_WithoutRebuildAndSimplify(Crv3dRebuilded, ssingulars, trim, edge); var res = newCrv2d._Simplify(srf); return(res); }
public static List <SurfaceKinkData> _Kinks_Find(this Surface srf) { if (srf.IsClosed(0) || srf.IsClosed(1)) { return(null); } if (srf.IsPeriodic(0) || srf.IsPeriodic(1)) { return(null); } if (srf.IsCone()) { return(null); } if (srf.IsCylinder()) { return(null); } if (srf.IsSphere()) { return(null); } if (srf.IsTorus()) { return(null); } var ss = new SurfaceSeams(srf); if (ss.HasSeams) { return(null); } var sss = new SurfaceSingulars(srf); if (sss.HasSingulars) { return(null); } var srfNurb = srf._IncreaseSurfaceDensity().ToNurbsSurface(); if (srfNurb.Points.CountU < MIN_CONTORL_POINTS_COUNT && srfNurb.Points.CountV < MIN_CONTORL_POINTS_COUNT) { return(null); } //var srfBound = srf._GetMinMaxUV(); //var faceBound = face._GetMinMaxUV(); var uv0 = 0; var uv1 = 1; if (srfNurb.Points.CountU < MIN_CONTORL_POINTS_COUNT) { uv0 = 1; // exclude checking on u if not enought control points } if (srfNurb.Points.CountV < MIN_CONTORL_POINTS_COUNT) { uv1 = 0; // exclude checking on v if not enought control points } string failReason = ""; double deviation = 0; List <SurfaceKinkData> res = null; for (int uv = uv0; uv <= uv1; uv++) { var crv = srf._TryGetIsoCurve_Mid(uv, true, out failReason, out deviation); if (crv == null) { log.wrong("srf._TryGetIsoCurve_Mid failed: " + failReason); continue; } if (DEBUG) { Layers.Debug.AddTangent(crv, "" + uv, Color.Red); RhinoDoc.ActiveDoc.Objects.AddCurve(crv); } var crvEnds = new[] { CurveEnd.Start, CurveEnd.End }; var srfEnds = (uv == 0) ? new[] { IsoStatus.West, IsoStatus.East } : new[] { IsoStatus.South, IsoStatus.North }; for (int istartend = 0; istartend <= 1; istartend++) { // // Angle // var angle = GetAngle(srf, crv, uv, istartend); if (Math.Abs(90 - angle) > 3) { log.wrong("_SurfaceKinks._Kinks_Find: Math.Abs(90 - angle) > 10"); continue; } // // Angle Extended // var crvEnd = crvEnds[istartend]; var srfEnd = srfEnds[istartend]; var srfExtended = srf._ExtendSurfaceByPercent(srfEnd, 100 * EXTEND_BY_PERCENT); var crvExtended = srfExtended._TryGetIsoCurve_Mid(uv, true, out failReason, out deviation); if (crvExtended == null) { log.wrong("srfExtended._TryGetIsoCurve_Mid failed: " + failReason); continue; } var angleExtended = GetAngle(srfExtended, crvExtended, uv, istartend); if (Math.Abs(90 - angleExtended) > 3) { log.wrong("_SurfaceKinks._Kinks_Find: Math.Abs(90 - angleExtended) > 10"); continue; } // // Angle between 'extended IsoCurve1' to 'IsoCurve2' // var crvIso1Extended = crv.Extend(crvEnd, crv._GetLength_ThreadSafe() * EXTEND_BY_PERCENT, CurveExtensionStyle.Arc); if (crvIso1Extended == null) { log.wrong("crv.Extend failed"); continue; } var angleCrvs = Vector3d.VectorAngle(crvExtended._Tangent(crvEnd), crvIso1Extended._Tangent(crvEnd))._RadianToDegree(); if (angleCrvs > 10) { var kink = new SurfaceKinkData { AngleDeviation = angleCrvs, SrfEnd = srfEnd, }; if (res == null) { res = new List <SurfaceKinkData>(2); } res.Add(kink); } //if (DEBUG) //{ // //RhinoDoc.ActiveDoc.Objects.AddSurface(srfExtended); // RhinoDoc.ActiveDoc.Objects.AddCurve(crvExtended); //} } } return(res); }