示例#1
0
        /// <summary>
        /// Constructs the geometric difference between this Polygon and the supplied Polygons.
        /// </summary>
        /// <param name="difPolys">The list of intersecting Polygons.</param>
        /// <returns>
        /// Returns a list of Polygons representing the subtraction of the supplied Polygons from this Polygon.
        /// Returns null if the area of this Polygon is entirely subtracted.
        /// Returns a list containing a representation of the perimeter of this Polygon if the two Polygons do not intersect.
        /// </returns>
        public IList <Polygon> Difference(IList <Polygon> difPolys)
        {
            var thisPath  = this.ToClipperPath();
            var polyPaths = new List <List <IntPoint> >();

            foreach (Polygon polygon in difPolys)
            {
                polyPaths.Add(polygon.ToClipperPath());
            }
            Clipper clipper = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPaths(polyPaths, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctDifference, solution);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path.Distinct().ToList()));
            }
            return(polygons);
        }
示例#2
0
        /// <summary>
        /// Constructs the geometric difference between this Polygon and the supplied Polygons.
        /// </summary>
        /// <param name="difPolys">The list of intersecting Polygons.</param>
        /// <param name="tolerance">An optional tolerance value.</param>
        /// <returns>
        /// Returns a list of Polygons representing the subtraction of the supplied Polygons from this Polygon.
        /// Returns null if the area of this Polygon is entirely subtracted.
        /// Returns a list containing a representation of the perimeter of this Polygon if the two Polygons do not intersect.
        /// </returns>
        public IList <Polygon> Difference(IList <Polygon> difPolys, double tolerance = Vector3.EPSILON)
        {
            var thisPath  = this.ToClipperPath(tolerance);
            var polyPaths = new List <List <IntPoint> >();

            foreach (Polygon polygon in difPolys)
            {
                polyPaths.Add(polygon.ToClipperPath(tolerance));
            }
            Clipper clipper = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPaths(polyPaths, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctDifference, solution);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                try
                {
                    polygons.Add(PolygonExtensions.ToPolygon(path.Distinct().ToList(), tolerance));
                }
                catch
                {
                    // swallow invalid polygons
                }
            }
            return(polygons);
        }
示例#3
0
        internal static Profile ToProfile(this PolyNode node, double tolerance = Vector3.EPSILON)
        {
            var perimeter = PolygonExtensions.ToPolygon(node.Contour, tolerance);

            if (perimeter == null)
            {
                return(null);
            }
            List <Polygon> voidCrvs = new List <Polygon>();

            if (node.ChildCount > 0)
            {
                foreach (var child in node.Childs)
                {
                    var voidCrv = PolygonExtensions.ToPolygon(child.Contour, tolerance);
                    if (voidCrv != null)
                    {
                        voidCrvs.Add(voidCrv);
                    }
                }
            }
            var profile = new Profile(perimeter, voidCrvs, Guid.NewGuid(), null);

            return(profile);
        }
示例#4
0
        /// <summary>
        /// Apply a boolean operation (Union, Difference, Intersection, or XOr) to two lists of Polygons.
        /// </summary>
        /// <param name="subjectPolygons">Polygons to clip</param>
        /// <param name="clippingPolygons">Polygons with which to clip</param>
        /// <param name="booleanMode">The operation to apply: Union, Difference, Intersection, or XOr</param>
        /// <param name="voidTreatment">Optional setting for how to process the polygons in each set: either treat polygons inside others as voids, or treat them all as solid (thereby ignoring internal polygons).</param>
        /// <param name="tolerance">Optional override of the tolerance for determining if two polygons are identical.</param>
        private static IList <Polygon> BooleanTwoSets(IList <Polygon> subjectPolygons, IList <Polygon> clippingPolygons, BooleanMode booleanMode, VoidTreatment voidTreatment = VoidTreatment.PreserveInternalVoids, double tolerance = Vector3.EPSILON)
        {
            var     subjectPaths = subjectPolygons.Select(s => s.ToClipperPath(tolerance)).ToList();
            var     clipPaths    = clippingPolygons.Select(s => s.ToClipperPath(tolerance)).ToList();
            Clipper clipper      = new Clipper();

            clipper.AddPaths(subjectPaths, PolyType.ptSubject, true);
            clipper.AddPaths(clipPaths, PolyType.ptClip, true);
            var solution      = new List <List <IntPoint> >();
            var executionMode = ClipType.ctDifference;
            var polyFillType  = PolyFillType.pftEvenOdd;

            if (voidTreatment == VoidTreatment.IgnoreInternalVoids)
            {
                polyFillType = PolyFillType.pftNonZero;
            }
            switch (booleanMode)
            {
            case BooleanMode.Difference:
                executionMode = ClipType.ctDifference;
                break;

            case BooleanMode.Union:
                executionMode = ClipType.ctUnion;
                break;

            case BooleanMode.Intersection:
                executionMode = ClipType.ctIntersection;
                break;

            case BooleanMode.XOr:
                executionMode = ClipType.ctXor;
                break;
            }
            clipper.Execute(executionMode, solution, polyFillType);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path, tolerance));
            }
            return(polygons);
        }
示例#5
0
        /// <summary>
        /// Returns Polygons representing the symmetric difference between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The intersecting polygon.</param>
        /// <param name="tolerance">An optional tolerance.</param>
        /// <returns>
        /// Returns a list of Polygons representing the symmetric difference of this Polygon and the supplied Polygon.
        /// Returns a representation of this Polygon and the supplied Polygon if the Polygons do not intersect.
        /// </returns>
        public IList <Polygon> XOR(Polygon polygon, double tolerance = Vector3.EPSILON)
        {
            var     thisPath = this.ToClipperPath(tolerance);
            var     polyPath = polygon.ToClipperPath(tolerance);
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctUnion, solution);
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path, tolerance));
            }
            return(polygons);
        }
示例#6
0
        /// <summary>
        /// Apply a boolean operation (Union, Difference, Intersection, or XOr) to two lists of Polygons.
        /// </summary>
        /// <param name="subjectPolygons">Polygons to clip</param>
        /// <param name="clippingPolygons">Polygons with which to clip</param>
        /// <param name="mode">The operation to apply: Union, Difference, Intersection, or XOr</param>
        /// <returns></returns>
        private static IList <Polygon> BooleanTwoSets(IList <Polygon> subjectPolygons, IList <Polygon> clippingPolygons, BooleanMode mode)
        {
            var     subjectPaths = subjectPolygons.Select(s => s.ToClipperPath()).ToList();
            var     clipPaths    = clippingPolygons.Select(s => s.ToClipperPath()).ToList();
            Clipper clipper      = new Clipper();

            clipper.AddPaths(subjectPaths, PolyType.ptSubject, true);
            clipper.AddPaths(clipPaths, PolyType.ptClip, true);
            var solution      = new List <List <IntPoint> >();
            var executionMode = ClipType.ctDifference;

            switch (mode)
            {
            case BooleanMode.Difference:
                executionMode = ClipType.ctDifference;
                break;

            case BooleanMode.Union:
                executionMode = ClipType.ctUnion;
                break;

            case BooleanMode.Intersection:
                executionMode = ClipType.ctIntersection;
                break;

            case BooleanMode.XOr:
                executionMode = ClipType.ctXor;
                break;
            }
            clipper.Execute(executionMode, solution);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path));
            }
            return(polygons);
        }
示例#7
0
        /// <summary>
        /// Constructs the geometric difference between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The intersecting Polygon.</param>
        /// <param name="tolerance">An optional tolerance value.</param>
        /// <returns>
        /// Returns a list of Polygons representing the subtraction of the supplied Polygon from this Polygon.
        /// Returns null if the area of this Polygon is entirely subtracted.
        /// Returns a list containing a representation of the perimeter of this Polygon if the two Polygons do not intersect.
        /// </returns>
        public IList <Polygon> Difference(Polygon polygon, double tolerance = Vector3.EPSILON)
        {
            var     thisPath = this.ToClipperPath(tolerance);
            var     polyPath = polygon.ToClipperPath(tolerance);
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctDifference, solution, PolyFillType.pftNonZero);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path, tolerance));
            }
            return(polygons);
        }
示例#8
0
        /// <summary>
        /// Constructs the Polygon intersections between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The intersecting Polygon.</param>
        /// <returns>
        /// Returns a list of Polygons representing the intersection of this Polygon with the supplied Polygon.
        /// Returns null if the two Polygons do not intersect.
        /// </returns>
        public IList <Polygon> Intersection(Polygon polygon)
        {
            var     thisPath = this.ToClipperPath();
            var     polyPath = polygon.ToClipperPath();
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctIntersection, solution);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path));
            }
            return(polygons);
        }