Exemple #1
0
        /// <summary>
        /// Get 'West,East,North,South' surface side of 3d curve at middle point of curve.
        /// Returns 'None' if crv is not touch any side.
        /// </summary>
        /// <param name="srf"></param>
        /// <param name="crv">3d curve</param>
        /// <returns>surface side (iso status). None if crv is not touch any side.</returns>
        public static IsoStatus _GetCurveIsoStatus(this Surface srf, Curve crv)
        {
            var res = IsoStatus.None;

            var mid = crv._PointAtMid();
            //mid = crv.PointAt(crv.Domain.Max);
            double u, v;

            if (srf.ClosestPoint(mid, out u, out v))
            {
                var s = new SurfaceSingulars(srf);
                if (u._IsSame(s.U.T0))
                {
                    res = IsoStatus.West;
                }
                else if (u._IsSame(s.U.T1))
                {
                    res = IsoStatus.East;
                }
                else if (v._IsSame(s.V.T0))
                {
                    res = IsoStatus.South;
                }
                else if (v._IsSame(s.V.T1))
                {
                    res = IsoStatus.North;
                }
            }
            return(res);
        }
Exemple #2
0
        /* OLD CODE
         * public static void _RecreateCurves(this BrepTrim trim, Surface srf, SurfaceSingulars ssingulars, bool reverseCurveDirection, bool fixDeformedEdges, double tol_tol_fixDeformedEdges, bool recreate3dCurves, out NurbsCurve crv3d, out NurbsCurve crv2d)
         * {
         *  if (recreate3dCurves)
         *  {
         *      crv3d = trim._PullEdgeToSurface(srf, ssingulars, reverseCurveDirection, fixDeformedEdges, tol_tol_fixDeformedEdges);
         *
         *      ////DEBUG
         *      //foreach (var l in crv3d.Points)
         *      //{
         *      //    debugIndexEdge2++;
         *      //    string text = "#" + debugIndexEdge2;
         *      //    AddDebugPoint(Doc, text, l.Location, Color.Gold); //debug
         *      //}
         *
         *      //
         *      // Create 2d curve (trim) from new edge (that is already projected on surface)
         *      // High interpolation of 500 points makes mistakes almost unvisible
         *      //
         *      crv2d = srf._Convert3dCurveTo2d(crv3d, ssingulars, trim);
         *  }
         *  else
         *  {
         *      crv3d = trim.Edge._ToNurbsCurve();
         *      crv2d = trim._ToNurbsCurve();
         *
         *      if (reverseCurveDirection)
         *      {
         *          crv3d.Reverse();
         *      }
         *
         *      // Reverse 2d crv if needed
         *      var trimStartPoint = srf.PointAt(trim.PointAtStart.X, trim.PointAtStart.Y);
         *      var trimEndPoint = srf.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y);
         *      if (crv3d.PointAtStart.DistanceTo(trimStartPoint) > crv3d.PointAtStart.DistanceTo(trimEndPoint))
         *      {
         *          crv2d.Reverse();
         *      }
         *  }
         * }
         *
         * public static NurbsCurve _PullEdgeToSurface(this BrepTrim trim, Surface srf, SurfaceSingulars ssingulars, bool reverseCurveDirection, bool fixDeformedEdges, double tol_tol_fixDeformedEdges)
         * {
         *  //
         *  // Project Edge to surface, and create new Edge from control points (edge devided by 100 points)
         *  //
         *  Curve edge = trim.Edge;
         *  NurbsCurve crv3d = null;
         *
         *  if (fixDeformedEdges)
         *  {
         *      NurbsCurve newedge;
         *      if (edge._ZigZagDeformations_TryRemove_old(srf, tol_tol_fixDeformedEdges, out newedge))
         *      {
         *          //log.temp("trim #{0} had zigzag ", trimIndex+1);
         *          edge = newedge;
         *      }
         *  }
         *  int DIVIDE_BY_COUNT_I = Math.Min(Math.Max(Convert.ToInt32(edge._GetLength_ThreadSafe() / 0.01), 10), 100);
         *  if (edge.Degree == 1)
         *  {
         *      DIVIDE_BY_COUNT_I = 10;
         *  }
         *
         *  Point3d[] edgeDevidedPoints;
         *  edge.DivideByCount(DIVIDE_BY_COUNT_I, true, out edgeDevidedPoints);
         *  if (edgeDevidedPoints != null)
         *  {
         *      if (reverseCurveDirection)
         *      {
         *          edgeDevidedPoints = edgeDevidedPoints.Reverse().ToArray();
         *      }
         *      var edgeDevidedUV = srf._ClosestPoints(edgeDevidedPoints);
         *
         *
         *      //DEBUG
         *      //Logger.log("+++");
         *      //foreach (var p in edgeDevidedUV)
         *      //{
         *      //    debugIndexEdge++;
         *      //    //bool inside = trim.Brep.IsPointInside(point, 0.000001,false);
         *      //    if (debugIndexEdge < debugIndexMAX)
         *      //    {
         *      //        string text = "#" + debugIndexEdge + ":   " + String.Format("{0:0.00}", p.u) + " - " + String.Format("{0:0.00}", p.v);
         *      //        //string text = "#" + debugIndexEdge;
         *      //        AddDebugPoint(Doc, text, srf.PointAt(p.u, p.v), Color.Red); //debug
         *      //        Logger.log(text);
         *      //    }
         *      //}
         *
         *      //
         *      // Fix U or V in singularities (in case where values are indentical at start of surface (like Point3d(u, v) == Point3d(u, v+100)));
         *      //
         *      var fixedSrf = srf._FixSurfacePoints(ref edgeDevidedUV, true, ssingulars, trim);
         *
         *      //
         *      // Contruct 3d curve on surface
         *      //
         *      var points2d = edgeDevidedUV.Select(o => new Point2d(o.u, o.v)).ToList();
         *      crv3d = srf.InterpolatedCurveOnSurfaceUV(points2d, 0.0000001);
         *
         *      if (crv3d == null)
         *      {
         *          var point3d = edgeDevidedUV.Select(o => srf.PointAt(o.u, o.v)).ToList();
         *          crv3d = srf.InterpolatedCurveOnSurface(point3d, 0.0001);
         *          //crv3d = crv3d;
         *          //var doc = RhinoDoc.ActiveDoc;
         *          //foreach (var p in point3d)
         *          //{
         *          //    debugIndexEdge2++;
         *          //    string text = "#" + debugIndexEdge2;
         *          //    AddDebugPoint(doc, text, p, Color.Gold); //debug
         *          //}
         *      }
         *  }
         *
         *
         *
         *  if (crv3d == null)
         *  {
         *      //log.error(g.IssueFixer, "Can't build crv3d from 2D points");
         *      throw new Exception("Can't rebuild " + trim._GUIEdgeName());
         *  }
         *
         *  return crv3d;
         * }
         *
         * private static void AddDebugPoint(RhinoDoc doc, string text, Point3d point, Color color = default(Color))
         * {
         *  // return;
         *
         *  color = (color == default(Color))
         *      ? Color.Aqua
         *      : color;
         *
         *  //doc.Objects.AddPoint(point, new ObjectAttributes()
         *  //{
         *  //    DisplayOrder = 12,
         *  //    LayerIndex = 0,
         *  //    Name = "temp",
         *  //    //Mode = ObjectMode.Locked,
         *  //    ColorSource = ObjectColorSource.ColorFromObject,
         *  //    ObjectColor = Color.Red,
         *  //    Visible = true
         *  //    //ObjectDecoration = ObjectDecoration.BothArrowhead,
         *  //});
         *  Guid id = doc.Objects.AddTextDot(text, point, new ObjectAttributes()
         *  {
         *      DisplayOrder = 5,
         *      LayerIndex = 0,
         *      //Name = "DebugPoint " + text,
         *      Name = text,
         *      //Mode = ObjectMode.Locked,
         *      ColorSource = ObjectColorSource.ColorFromObject,
         *      ObjectColor = color,
         *      Visible = true
         *  });
         *
         *
         * }
         *
         */

        #endregion

        //


        /// <summary>
        /// Recalculated iso status.
        /// Works always compare to internal Rhino method 'srf.IsIsoparametric(trim)'
        /// </summary>
        /// <param name="trim"></param>
        /// <param name="ssingulars">provide it for speed optimization. otherwise it will be calculated automatically.</param>
        /// <returns></returns>
        public static IsoStatus _IsoStatus(this BrepTrim trim, SurfaceSingulars ssingulars = null)
        {
            // COMMENTED - just to show what is a internal Rhino method to detect isoStatus
            //return srf.IsIsoparametric(trim); - doesnt work always properly!!!

            // COMMENTED - we want to be very sure and lets recalculate isostaus always
            // Calculate ony if status is invalid
            //var trimIsoStatus = trim.IsoStatus;
            //var isValidIso = trimIsoStatus == IsoStatus.East
            //                 || trimIsoStatus == IsoStatus.North
            //                 || trimIsoStatus == IsoStatus.South
            //                 || trimIsoStatus == IsoStatus.West;
            //if (isValidIso)
            //{
            //    return trimIsoStatus;
            //}


            if (ssingulars == null)
            {
                var srf = trim._Srf();
                ssingulars = new SurfaceSingulars(srf);
            }

            var T0          = trim.PointAtStart;
            var T1          = trim.PointAtEnd;
            var T0IsoStatus = ssingulars.GetIsoStatus(T0.X, T0.Y);
            var T1IsoStatus = ssingulars.GetIsoStatus(T1.X, T1.Y);

            if (T0IsoStatus == T1IsoStatus)
            {
                return(T0IsoStatus);
            }

            //  show warnig message only both iso statuses are not 'None' - when we substitute surface with no singulars we will have such situation when all iso statuses became 'None'
            if ((T0IsoStatus != IsoStatus.None || T1IsoStatus != IsoStatus.None))
            {
                if (ssingulars.Srf.IsAtSingularity(T0.X, T0.Y, true) || ssingulars.Srf.IsAtSingularity(T1.X, T1.Y, true))
                {
                    log.wrong("_BrepTrim._IsoStatus()    Cannot detect proper IsoStatus:  T0:{0}-T1:{1}  T0=[{2:0.000},{3:0.000}]   T1=[{4:0.000},{5:0.000}]", T0IsoStatus, T1IsoStatus, T0.X, T0.Y, T1.X, T1.Y);
                }
                else
                {
                    var temp = 0;
                }
            }
            return(IsoStatus.None);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        /// <summary>
        /// Fix control points of trim
        /// </summary>
        /// <param name="trim"></param>
        /// <param name="singulars"></param>
        /// <param name="roundStart">Round value of singular axis (if surface is singular on V  - then round first value of V)</param>
        /// <param name="roundEnd">Round value of singular axis (if surface is singular on V  - then round last value of V)</param>
        /// <returns></returns>
        public static NurbsCurve _FixContorlPoints(this BrepTrim trim, SurfaceSingulars singulars = null, bool roundStart = false, bool roundEnd = false)
        {
            var srf      = trim._Srf();
            var trimNurb = trim._ToNurbsCurve();
            // v1 - full
            var res     = trimNurb._Fix2dContorlPoints(srf, singulars, trim.Edge, roundStart, roundEnd);
            var newtrim = res._ZigZagDeformations_TryRemove(srf);

            //if (newtrim != null)
            //{
            //    res = newtrim;
            //}

            // v2 - only zigzag
            //var res = trimNurb;
            //var newtrim = trimNurb._ZigZagDeformations_TryRemove(srf);
            //if (newtrim != null)
            //{
            //    res = newtrim;
            //}
            //res =  res._Fix2dContorlPoints(srf, singulars, trim.Edge, roundStart, roundEnd);

            return(res);
        }
Exemple #5
0
        //private static int Num;
        private static NurbsCurve _Simplify_NEW3(this Curve crv, Surface srf = null, bool workWithSingularSurfaces = false)
        {
            // log.temp("_Simplify_NEW   workWithSingularSurfaces = " + workWithSingularSurfaces);
            var ORIGIN       = crv._ToNurbsCurve();
            var crvDimension = crv.Dimension;

            if (crv.Degree != 3)
            {
                return(ORIGIN);
            }
            if (crvDimension != 2 && crvDimension != 3)
            {
                return(ORIGIN);
            }
            if (crvDimension == 2 && srf == null)
            {
                log.wrong("_CurveSimplify._Simplify() - 2d curve requires 'srf' parameter");
                return(ORIGIN);
            }
            if (crv._ZigZagDeformationExists(srf))
            {
                return(ORIGIN);
            }
            var numValueMIN = 0;
            var numValueMAX = Math.Min(Simplify_nums.Last(), ORIGIN.Points.Count / 2);

            if (numValueMIN > numValueMAX)
            {
                return(ORIGIN);
            }

            NurbsCurve crv2d = null;
            NurbsCurve crv3d = null;

            const bool   preserveTangents3d          = false;
            const bool   preserveTangents2d          = false;
            int          VALIDATION_SEGMENTS_COUNT3d = 20;
            int          VALIDATION_SEGMENTS_COUNT2d = 20;
            double       MAX_DEVIATION3d             = 0.001;
            const double MAX_LENGTH_DIFF3d           = 0.005; // in percent = 0.5%
            var          checkControlPoints          = false; // if control points also should be close to original curve


            SurfaceSingulars ssingular = null;

            if (crvDimension == 2)
            {
                ssingular = new SurfaceSingulars(srf);
                if (ssingular.HasSingulars)
                {
                    if (!workWithSingularSurfaces)
                    {
                        return(ORIGIN);
                    }
                    if (srf._PointsAreCloseSingularity_HighJump(ORIGIN.Points._SurfacePoints(), ssingular))
                    {
                        MAX_DEVIATION3d = 0.0001;
                    }
                    checkControlPoints = true;
                }

                crv2d = ORIGIN;// set only for dimension == 2
            }
            else
            {
                crv3d = ORIGIN;// set only for dimension == 3
            }
            var crv3dLen = ORIGIN._Get3dLength(srf);

            if (crv3dLen._IsZero())
            {
                return(ORIGIN);
            }


            Point3d[] crv2d_3dPoints = null;
            Point3d[] crv3dPoints    = null;
            VALIDATION_SEGMENTS_COUNT3d = Math.Max(VALIDATION_SEGMENTS_COUNT3d, Convert.ToInt32(Math.Min(1000, crv3dLen / 0.5)));
            VALIDATION_SEGMENTS_COUNT2d = Math.Max(VALIDATION_SEGMENTS_COUNT2d, Convert.ToInt32(Math.Min(1000, crv3dLen / 0.5)));
            if (crvDimension == 2)
            {
                if (crv2d == null)
                {
                    return(ORIGIN);
                }
                Point3d[] crv2dPoints = null;
                crv2d._DivideByCount_ThreadSafe(VALIDATION_SEGMENTS_COUNT2d, true, out crv2dPoints);
                if (crv2dPoints == null)
                {
                    return(ORIGIN);
                }
                crv2d_3dPoints = crv2dPoints.Select(o => srf.PointAt(o.X, o.Y)).ToArray();
            }
            else
            {
                crv3d._DivideByCount_ThreadSafe(VALIDATION_SEGMENTS_COUNT3d, true, out crv3dPoints);
                if (crv3dPoints == null)
                {
                    return(ORIGIN);
                }
            }

            foreach (var num in Simplify_nums)
            {
                if (num < numValueMIN || num > numValueMAX)
                {
                    continue;
                }
                if (num == 2 && srf != null)
                {
                    if (srf.Degree(0) != 1 && srf.Degree(1) != 1)
                    {
                        continue;                                           // one degree has to be linear
                    }
                }
                //
                // Rebuild
                //
                NurbsCurve simple3d = null;
                NurbsCurve simple2d = null;
                if (crvDimension == 2 && crv2d != null)
                {
                    simple2d = (num == 2)
                                 ? new LineCurve(new Point2d(crv2d.PointAtStart.X, crv2d.PointAtStart.Y), new Point2d(crv2d.PointAtEnd.X, crv2d.PointAtEnd.Y))._ToNurbsCurve()
                                 : crv2d.Rebuild(num, 3, false);
                    if (simple2d == null)
                    {
                        continue;
                    }

                    if (simple2d._ZigZagDeformationExists(srf))
                    {
                        //var crv2dNorm = crv2d._2dNormalize(srf);
                        //var simple2dNorm = crv2dNorm.Rebuild(num, 3, false);
                        //simple2d = simple2dNorm._2dUnnormalize(srf);
                        if (crv3d == null)
                        {
                            crv3d = crv2d._2dTo3d(srf);
                        }
                        if (crv3d == null)
                        {
                            continue;                                                              // lazy initialization of crv3d
                        }
                        simple3d = crv3d.Rebuild(num, 3, preserveTangents3d);
                        if (simple3d == null)
                        {
                            continue;
                        }
                        simple2d = srf._Convert3dCurveTo2d_WithoutRebuildAndSimplify(simple3d, null, crv, crv3d);
                        if (simple2d == null)
                        {
                            continue;
                        }
                        simple2d = simple2d._Fix2dContorlPoints(srf, ssingular);
                        if (simple2d._ZigZagDeformationExists(srf))
                        {
                            //return simple2d;
                            continue;
                        }
                    }


                    simple2d.SetStartPoint(crv2d.PointAtStart);
                    simple2d.SetEndPoint(crv2d.PointAtEnd);

                    // Compare with original

                    // Simplification near to singularity must very very strict!!!
                    // Control poins must be very close to original curve  - its guarantee that method '_Curve._Fix2dContorlPoints()' wont change any control point, and issue 'TrimControlPointsNotCorrectInSingularity' will be fixed
                    if (checkControlPoints)
                    {
                        if (crv3d == null)
                        {
                            crv3d = crv2d._2dTo3d(srf);
                        }
                        if (crv3d == null)
                        {
                            continue;                                                               // lazy initialization of crv3d
                        }
                        if (!_Simplify_IsSimplifiedControlPointsCloseToOrigin(simple2d, srf, MAX_DEVIATION3d, crv3d))
                        {
                            continue;
                        }
                    }
                    // Compare with original
                    if (!_Simplify_IsSimplifiedCloseToOrigin_NEW3(simple2d, srf, MAX_DEVIATION3d, crv2d_3dPoints))
                    {
                        continue;
                    }
                }
                else if (crvDimension == 3 && crv3d != null)
                {
                    simple3d = (num == 2)
                                 ? new LineCurve(crv3d.PointAtStart, crv3d.PointAtEnd)._ToNurbsCurve()
                                 : crv3d.Rebuild(num, 3, preserveTangents3d);
                    if (simple3d == null)
                    {
                        continue;
                    }
                    // Compare with original
                    if (!_Simplify_IsSimplifiedCloseToOrigin(simple3d, srf, preserveTangents3d,
                                                             crv3d, crv3dLen, crv3dPoints,
                                                             MAX_LENGTH_DIFF3d, MAX_DEVIATION3d))
                    {
                        continue;
                    }
                }

                // Return new simplified curve
                if (crvDimension == 2)
                {
                    //Layers.Debug.AddCurve(simple3d, "trim 3d", Color.Purple);
                    //var z3d = simple3d._ZigZagDeformationExists(srf);
                    //var z2d = simple2d._ZigZagDeformationExists(srf);
                    var res = simple2d._Fix2dContorlPoints(srf, ssingular);
                    //Layers.Debug.AddCurve(crv3d, "crv3d", Color.PeachPuff);
                    //Layers.Debug.AddCurveControlPoints(res, srf, Color.Orchid);
                    //Layers.Debug.AddCurve(simple3d, "simple3d", Color.Orchid);
                    //var z2ds = res._ZigZagDeformationExists(srf);
                    //Layers.Debug.AddCurve(simple3d, "simple3d", Color.Aqua);
                    return(res);
                }
                else
                {
                    return(simple3d);
                }
            }

            // we fail - return origin curve
            return(ORIGIN);
        }
        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);
        }
Exemple #7
0
        public static NurbsCurve _Convert3dCurveTo2d_WithoutRebuildAndSimplify(this Surface srf, NurbsCurve crv3d
                                                                               , SurfaceSingulars ssingulars = null, Curve trim = null, Curve edge = null)
        {
            if (ssingulars == null)
            {
                ssingulars = new SurfaceSingulars(srf);
            }

            if (edge == null)
            {
                edge = crv3d;
            }

            //// version 1 - bad since it uses method Curve.CreateControlPointCurve) and is a little bit incorrect
            //crv3d.DivideByCount(DIVIDE_BY_COUNT_I * 5, true, out edgeDevidedPoints);
            //crv3d.DivideByCount(DIVIDE_BY_COUNT_I, true, out edgeDevidedPoints);
            //var edgeDevidedPointsProjectedUV = new List<Point3d>();
            //foreach (var point in edgeDevidedPoints)
            //{
            //    debugIndexTrim++;
            //    if (debugIndexTrim < debugIndexMAX) AddDebugPoint(Doc, debugIndexTrim.ToString(), point, Color.Red);//debug
            //    double u, v;
            //    if (srf.ClosestPoint(point, out u, out v))
            //    {
            //        if (debugIndexTrim < debugIndexMAX)
            //        {
            //            //string text = debugIndexTrim + " - " + Convert.ToInt32(Math.Round(u)) + " - " + Convert.ToInt32(Math.Round(v));
            //            //AddDebugPoint(Doc, text, srf.PointAt(u, v), Color.Purple);//debug
            //            //AddDebugPoint(Doc, debugIndexTrim.ToString(), srf.PointAt(u, v), Color.Purple);//debug
            //            //Logger.log(text);
            //        }
            //        var point2d = new Point3d(u, v, 0);
            //        edgeDevidedPointsProjectedUV.Add(point2d);
            //    }
            //    else
            //    {
            //        int i = 0;
            //    }
            //}

            //var crv2d = Curve.CreateControlPointCurve(edgeDevidedPointsProjectedUV, 2);
            ////crv2d = crv2d.Rebuild(10, crv3dUV.Degree, false);

            //// version 2
            //var crv2d = srf.InterpolatedCurveOnSurfaceUV(edgeDevidedPointsProjectedUV, 0.0000001);

            //// version 3 -  bad since control points can be not enough to keep good precision
            var crv2d        = new NurbsCurve(2, crv3d.IsRational, crv3d.Degree + 1, crv3d.Points.Count);
            var crv2dPoints  = new List <SurfacePoint>(crv3d.Points.Count);
            var crv2dWeights = new List <double>(crv3d.Points.Count);

            //var points3d = crv3d.Points.Select(o => o.Location).ToArray();

            //log.temp("crv3d.Points.Count = " + crv3d.Points.Count);
            foreach (var point3d in crv3d.Points)
            {
                double u, v;
                if (srf.ClosestPoint(point3d.Location, out u, out v))
                {
                    //AddDebugPoint(Doc, "", srf.PointAt(u, v), Color.Red); //debug
                    crv2dPoints.Add(new SurfacePoint(u, v));
                    crv2dWeights.Add(point3d.Weight);
                }
            }

            var fixedSrf = srf._FixSurfacePoints(ref crv2dPoints, false, ssingulars, trim, edge);
            var index    = 0;

            foreach (var p in crv2dPoints)
            {
                crv2d.Points.SetPoint(index, p.u, p.v, 0, crv2dWeights[index]);
                index++;
            }

            index = 0;
            foreach (var knot in crv3d.Knots)
            {
                crv2d.Knots[index] = knot;
                index++;
            }

            //// version 4
            //var crv2d = new NurbsCurve(2, edgeDevidedPointsProjectedUV.Count);
            //var index = 0;
            //foreach (var srfPoint in edgeDevidedPointsProjectedUV)
            //{
            //    crv2d.Points.SetPoint(index, srfPoint.X, srfPoint.Y, 0, 1);
            //    index++;
            //}
            //index = 0;
            //foreach (var knot in crv3d.Knots)
            //{
            //    crv2d.Knots[index] = knot;
            //    index++;
            //}


            return(crv2d);
        }