Ejemplo n.º 1
0
        public static List <Polyline> Boolean(ClipType clipType, IEnumerable <Polyline> polyA, IEnumerable <Polyline> polyB,
                                              Plane pln, double tolerance, bool evenOddFilling)
        {
            var clipper      = new Clipper();
            var polyfilltype = PolyFillType.pftEvenOdd;

            if (!evenOddFilling)
            {
                polyfilltype = PolyFillType.pftNonZero;
            }

            foreach (var plA in polyA)
            {
                clipper.AddPath(plA.ToPath2D(pln, tolerance), PolyType.ptSubject, plA.IsClosed);
            }

            foreach (var plB in polyB)
            {
                clipper.AddPath(plB.ToPath2D(pln, tolerance), PolyType.ptClip, true);
            }

            var polytree = new PolyTree();

            clipper.Execute(clipType, polytree, polyfilltype, polyfilltype);

            var output = new List <Polyline>();

            // ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var pn in polytree.Iterate())
            {
                if (pn.Contour.Count > 1)
                {
                    output.Add(pn.Contour.ToPolyline(pln, tolerance, !pn.IsOpen));
                }
            }

            return(output);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Offsets the specified polylines.
        /// </summary>
        /// <param name="polylines">A list of polylines</param>
        /// <param name="openFilletType">Optional: line endtype (Butt, Square, Round)</param>
        /// <param name="closedFilltetType">Optional: join type: Round, Miter (uses miter parameter) or Square</param>
        /// <param name="plane">Plane to project the polylines to</param>
        /// <param name="tolerance">Tolerance: Cutoff point. Eg. point {1.245; 9.244351; 19.3214} with precision {0.1} will be cut
        /// off to {1.2; 9.2; 19.3}.</param>
        /// <param name="distance">Distances to offset set of shapes.</param>
        /// <param name="miter">Miter deterimines how long narrow spikes can become before they are cut off: A miter setting of 2
        /// means not longer than 2 times the offset distance. A miter of 25 will give big spikes.</param>
        /// <param name="arcTolerance">The arc tolerance.</param>
        /// <param name="outContour">The out contour.</param>
        /// <param name="outHoles">The out holes.</param>
        public static void Offset(IEnumerable <Polyline> polylines, List <OpenFilletType> openFilletType,
                                  List <ClosedFilletType> closedFilltetType, Plane plane, double tolerance, IEnumerable <double> distance,
                                  double miter, double arcTolerance, out List <List <Polyline> > outContour, out List <List <Polyline> > outHoles, EndType endType = default)
        {
            outContour = new List <List <Polyline> >();
            outHoles   = new List <List <Polyline> >();

            /*
             * iEndType: How to handle open ended polygons.
             * Open				Closed
             * etOpenSquare		etClosedLine    (fill inside & outside)
             * etOpenRound			etClosedPolygon (fill outside only)
             * etOpenButt
             *
             * See: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/EndType.htm
             */

            /*
             * jtJoinType
             * How to fill angles of closed polygons
             * jtRound: Round
             * jtMiter: Square with variable distance
             * jtSquare: Square with fixed distance (jtMiter = 1)
             */

            var cOffset = new ClipperOffset(miter, arcTolerance);
            var i       = 0;

            foreach (var pl in polylines)
            {
                var et = EndType.etOpenButt;
                var jt = JoinType.jtSquare;
                if (pl.IsClosed)
                {
                    et = EndType.etClosedLine;
                }
                else if (openFilletType.Count != 0)
                {
                    var oft = IndexOrLast(openFilletType, i);
                    switch (oft)
                    {
                    case OpenFilletType.Butt:
                        et = EndType.etOpenButt;
                        break;

                    case OpenFilletType.Round:
                        et = EndType.etOpenRound;
                        break;

                    case OpenFilletType.Square:
                        et = EndType.etOpenSquare;
                        break;
                    }
                }
                else
                {
                    et = EndType.etOpenButt;
                }

                if (closedFilltetType.Count != 0)
                {
                    var cft = IndexOrLast(closedFilltetType, i);
                    switch (cft)
                    {
                    case ClosedFilletType.Miter:
                        jt = JoinType.jtMiter;
                        break;

                    case ClosedFilletType.Round:
                        jt = JoinType.jtRound;
                        break;

                    case ClosedFilletType.Square:
                        jt = JoinType.jtSquare;
                        break;
                    }
                }
                else
                {
                    jt = JoinType.jtSquare;
                }
                if (endType != default)
                {
                    et = endType;
                }
                cOffset.AddPath(pl.ToPath2D(plane, tolerance), jt, et);
                i++;
            }

            foreach (var offsetDistance in distance)
            {
                var tree = new PolyTree();
                cOffset.Execute(ref tree, offsetDistance / tolerance);

                var holes    = new List <Polyline>();
                var contours = new List <Polyline>();
                foreach (var path in tree.Iterate())
                {
                    if (path.Contour.Count == 0)
                    {
                        continue;
                    }
                    Polyline polyline = path.Contour.ToPolyline(plane, tolerance, !path.IsOpen);
                    if (path.IsHole)
                    {
                        holes.Add(polyline);
                    }
                    else
                    {
                        contours.Add(polyline);
                    }
                }

                outContour.Add(contours);
                outHoles.Add(holes);
            }
        }