예제 #1
0
        /// <summary>
        /// Remove kinks if possible.
        /// Works only for 3d curves.
        /// </summary>
        /// <param name="curve">3d curve</param>
        /// <param name="kinks">kinks provided by a method '_FindKinksAtEnds'</param>
        /// <param name="failReason">if a method failed - this string will have fail reason</param>
        /// <returns></returns>
        private static Curve _Kinks_TryRemove_Simple(Curve curve, List <CurveKinkData> kinks, int DIVBY_FIX, int DIVBY_MIN, out string failReason)
        {
            failReason = "";
            Percent cutPercents = 1.0 / DIVBY_FIX;
            var     crv         = new CurveNormalized(curve);

            // Div crv by small segments
            var divby = curve._GetDivBy(null, 0.01, DIVBY_MIN);

            Point3d[] points;
            double[]  ts;
            if (!curve._TryDivideByCount(divby, out points, out ts, out failReason))
            {
                return(null);
            }

            // Construct copy indexes (we will remove 5% from start and end, where the kinks found)
            var tMin = crv.Domain.T0 - 1;
            var tMax = crv.Domain.T1 + 1;

            foreach (var kink in kinks)
            {
                switch (kink.CrvEnd)
                {
                case CurveEnd.Start:
                    tMin = crv.T(0 + cutPercents);     // cut 5% from start
                    break;

                case CurveEnd.End:
                    tMax = crv.T(1 - cutPercents);     // cut 5% from end
                    break;
                }
            }


            // Copy points excluding kink diapasons
            var iadded = new List <int>();

            if (kinks.Exists(o => o.CrvEnd == CurveEnd.Start))
            {
                iadded.Add(0); // add start point anyway, since we need it and it will be removed by condition 'tMin <= ts[i]'
            }
            for (int i = 0; i < points.Length; i++)
            {
                if (tMin <= ts[i] && ts[i] <= tMax)
                {
                    iadded.Add(i);
                }
            }
            if (kinks.Exists(o => o.CrvEnd == CurveEnd.End))
            {
                iadded.Add(points.Length - 1); // add end point anyway, since we need it and it will be removed by condition 'ts[i] <= tMax'
            }
            var validPoints = iadded.Select(o => points[o]).ToList();

            //
            // Construct new curve
            //
            var newCuve = Curve.CreateControlPointCurve(validPoints, 3);

            //var newCuve = Curve.CreateInterpolatedCurve(validPoints, 3); - makes zigzag - so we cant use it here

            if (DEBUG)
            {
                Layers.Debug.AddCurve(newCuve);
                for (var i = 0; i < validPoints.Count; i++)
                {
                    var p = validPoints[i];
                    Layers.Debug.AddPoint(p);
                    //                    Layers.Debug.AddTextPoint("" + tsadded[i]._ToStringX(2), p);
                }
            }

            if (newCuve == null)
            {
                failReason = "failed to create curve from 3d points";
                return(null);
            }
            newCuve = newCuve._Simplify(); //simplify crv after constructing if from many points
            return(newCuve);
        }