private List <List <IntPoint> > ClipToRooms(List <IntPoint> roomFootprint, bool allowSplit)
        {
            _clipper.Clear();
            _clipper.AddPath(roomFootprint, PolyType.ptSubject, true);
            _clipper.AddPaths(_rooms.Select(r => r.OuterFootprint.Select(ToPoint).ToList()).ToList(), PolyType.ptClip, true);

            var solution = new PolyTree();

            _clipper.Execute(ClipType.ctDifference, solution);

            //Rooms with holes are not supported
            if (HasHole(solution))
            {
                //Rooms with holes are not supported (issue #166 - Will Not Fix)
                return(new List <List <IntPoint> >());
            }

            var shapes = Clipper.ClosedPathsFromPolyTree(solution);

            if (shapes.Count > 1 && !allowSplit)
            {
                return(new List <List <IntPoint> >());
            }

            return(shapes);
        }
        public List <DTPolygon> Subtract(DTPolygon subject, DTPolygon clippingPolygon)
        {
            if (!DTUtility.BoundsCheck(subject.Contour, clippingPolygon.Contour))
            {
                // There is no overlap at all, so output a copy of the subject polygon
                return(new List <DTPolygon>()
                {
                    new DTPolygon(new List <Vector2>(subject.Contour))
                });
            }

            clipper.Clear();

            // Add subject polygon paths
            clipper.AddPath(subject.Contour.ToIntPointList(), PolyType.ptSubject, true);
            foreach (var hole in subject.Holes)
            {
                clipper.AddPath(hole.ToIntPointList(), PolyType.ptSubject, true);
            }

            // Add clipping polygon paths
            clipper.AddPath(clippingPolygon.Contour.ToIntPointList(), PolyType.ptClip, true);
            foreach (var hole in clippingPolygon.Holes)
            {
                clipper.AddPath(hole.ToIntPointList(), PolyType.ptClip, true);
            }

            // Execute subtraction and store result in a PolyTree so that we can easily identify holes
            PolyTree clipperOutput = new PolyTree();

            clipper.Execute(ClipType.ctDifference, clipperOutput, PolyFillType.pftEvenOdd, PolyFillType.pftNonZero);

            // Convert Polytree into list of DTPolygons
            return(clipperOutput.ToDTPolygons());
        }
        /// <summary>
        /// Clean up a proposed corridor shape (primarily removing holes, which are invalid in a floorplan)
        /// </summary>
        /// <param name="clipper"></param>
        /// <param name="outline"></param>
        /// <param name="corridor"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        public static List <List <IntPoint> > CleanCorridorPolygon(Clipper clipper, List <IntPoint> outline, IEnumerable <Vector2> corridor, float width)
        {
            //Clean up after the previous run, just in case
            clipper.Clear();

            //Clip this spanning tree to the footprint of the floorplan (to create a polytree)
            var result = new List <List <IntPoint> >();

            clipper.AddPath(outline, PolyType.ptClip, true);
            clipper.AddPath(corridor.Select(ToPoint).ToList(), PolyType.ptSubject, true);
            clipper.Execute(ClipType.ctIntersection, result);

            //Clean up after self, to be polite
            clipper.Clear();

            //Keep simplifying, and removing holes until nothing happens
            do
            {
                //merge together vertices which are very close
                result = Clipper.CleanPolygons(result, width / 8);

                //Remove holes from the result
                var holes = result.RemoveAll(r => !Clipper.Orientation(r));

                //Once we have one single polygon, or removing holes did nothing we've finished!
                if (result.Count == 1 || holes == 0)
                {
                    return(result);
                }
            } while (result.Count > 0);

            //This shouldn't ever happen unless we simplify away to nothing
            return(result);
        }
Esempio n. 4
0
        public static List <List <Vector2> > Simplify(List <Vector2> polygon, FillMode fillMode, out PolyTree tree)
        {
            Clipper.Clear();
            Clipper.AddPath(polygon, PolyType.ptSubject, true);
            Clipper.AddPath(polygon, PolyType.ptClip, true);

            tree = new PolyTree();
            PolyFillType fillType = fillMode.ToPolyFillType();

            Clipper.Execute(ClipType.ctUnion, tree, fillType, fillType);
            return(Clipper.ClosedPathsFromPolyTree(tree));
        }
        private static IReadOnlyList <IReadOnlyList <Vector2> > CalculateCorners(IReadOnlyList <Vector2> outer, float width, IReadOnlyList <Section> sections)
        {
            const float TOLERANCE = 0.01f;

            //Reform inner boundary, but slightly larger than it should be (that's our error tolerance);
            var inner = outer.Shrink(width - TOLERANCE, 1);

            //Reform outer boundary, but slightly smaller than it should be (more error tolerance)
            var outerAdjusted = outer.Shrink(TOLERANCE, 1000);

            var clipper = new Clipper();

            //Create a ring shape which is all the outer walls of this room (outer - inner)
            clipper.AddPath(outerAdjusted.Select(ToPoint).ToList(), PolyType.ptSubject, true);
            clipper.AddPath(inner.Select(ToPoint).ToList(), PolyType.ptClip, true);
            var ringResult = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctDifference, ringResult);

            //Now subtract all the wall sections
            clipper.Clear();
            clipper.AddPaths(ringResult, PolyType.ptSubject, true);
            foreach (var section in sections)
            {
                clipper.AddPath(new List <IntPoint> {
                    ToPoint(section.Inner1), ToPoint(section.Inner2), ToPoint(section.Outer1), ToPoint(section.Outer2)
                }, PolyType.ptClip, true);
            }
            var result = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctDifference, result);

            //Convert back to vectors
            return(result.Select(a => a.Select(ToVector).ToArray()).ToArray());
        }
Esempio n. 6
0
 internal void Reset()
 {
     _aPolys.Clear();
     _bPolys.Clear();
     _intersectedPolys.Clear();
     _clipper.Clear();
 }
Esempio n. 7
0
        private List <IntPoint> CreateVoronoiRegion(Site primary)
        {
            Clipper c = new Clipper();

            var solution = new List <List <IntPoint> >();

            List <IntPoint> currentList = null;

            foreach (var site in Sites)
            {
                if (primary.Equals(site))
                {
                    continue;
                }

                var region = NearestRegion(primary, site);
                if (currentList == null)
                {
                    currentList = region;
                }
                else
                {
                    c.Clear();
                    c.AddPath(currentList, PolyType.ptSubject, true);
                    c.AddPath(region, PolyType.ptClip, true);
                    //c.AddPolygon(currentList, PolyType.ptSubject);
                    //c.AddPolygon(region, PolyType.ptClip);
                    c.Execute(ClipType.ctIntersection, solution);

                    currentList = solution[0];
                }
            }

            return(currentList);
        }
Esempio n. 8
0
        private static Ngons MSumFull(Ngon pattern, Ngons subject, bool flip_pattern)
        {
            Clipper clipper = new Clipper();

            Ngons full = new Ngons();

            long scale = flip_pattern ? -1 : 1;

            for (int i = 0; i < pattern.Count; i++)
            {
                clipper.AddPaths(subject.Clone(scale * pattern[i].X, scale * pattern[i].Y), PolyType.ptSubject, true);
            }

            clipper.Execute(ClipType.ctUnion, full, PolyFillType.pftNonZero);
            clipper.Clear();

            clipper.AddPaths(full, PolyType.ptSubject, true);
            clipper.AddPaths(MinkowskiSumBoundary(pattern, subject, flip_pattern), PolyType.ptSubject, true);

            Ngons res = new Ngons();

            clipper.Execute(ClipType.ctUnion, res, PolyFillType.pftNonZero);

            return(res);
        }
Esempio n. 9
0
        /// <summary>
        /// Applies the damage to affected chunks.
        /// </summary>
        /// <param name="damage">Damage.</param>
        private void ApplyDamage(List <IntPoint> damage)
        {
            long minX = long.MaxValue, minY = long.MaxValue,
                 maxX = long.MinValue, maxY = long.MinValue;

            for (int i = 0; i < damage.Count; ++i)
            {
                if (damage[i].X < minX)
                {
                    minX = damage[i].X;
                }
                if (damage[i].X > maxX)
                {
                    maxX = damage[i].X;
                }

                if (damage[i].Y < minY)
                {
                    minY = damage[i].Y;
                }
                if (damage[i].Y > maxY)
                {
                    maxY = damage[i].Y;
                }
            }

            minX = Helper.NegDivision(minX, Chunk.SIZE);
            maxX = Helper.NegDivision(maxX, Chunk.SIZE);
            minY = Helper.NegDivision(minY, Chunk.SIZE);
            maxY = Helper.NegDivision(maxY, Chunk.SIZE);

            var clipper = new Clipper();

            for (int y = (int)minY; y <= maxY; ++y)
            {
                for (int x = (int)minX; x <= maxX; ++x)
                {
                    var chunk = GetChunk(TerrainHelper.PackCoordinates(x, y));

                    clipper.Clear();
                    clipper.AddPolygon(new List <IntPoint>()
                    {
                        new IntPoint(chunk.Left, chunk.Top),
                        new IntPoint(chunk.Left + Chunk.SIZE, chunk.Top),
                        new IntPoint(chunk.Left + Chunk.SIZE, chunk.Top + Chunk.SIZE),
                        new IntPoint(chunk.Left, chunk.Top + Chunk.SIZE)
                    }, PolyType.ptSubject);
                    clipper.AddPolygon(damage, PolyType.ptClip);
                    clipper.AddPolygons(chunk.Damage, PolyType.ptClip);
                    clipper.Execute(ClipType.ctIntersection, chunk.Damage,
                                    PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    chunk.Recalculate = true;
                    if (ActiveChunks.Contains(chunk))
                    {
                        Task.Run(() => { PlaceChunk(chunk); });
                    }
                }
            }
        }
Esempio n. 10
0
        public void RemoveHoles(float maxPerimiter)
        {
            Paths    keep = new Paths();
            PolyNode node = polyTree.GetFirst();

            while (node != null)
            {
                if (node.IsHole && node.ChildCount == 0)
                {
                    var   line   = LineStripFromPolygon(node.Contour);
                    float length = line.Length(LineStrip.Type.Closed);
                    if (length < maxPerimiter)
                    {
                        // Remove it
                    }
                    else
                    {
                        keep.Add(node.Contour);
                    }
                }
                else
                {
                    keep.Add(node.Contour);
                }
                node = node.GetNext();
            }
            Clipper c = new Clipper();

            c.Clear();
            c.AddPaths(keep, PolyType.ptSubject, true);
            polyTree = new PolyTree();
            c.Execute(ClipType.ctUnion, polyTree);
        }
Esempio n. 11
0
        IEnumerator RemoveHexagons(IAdminEntity[] entities)
        {
            Clipper clipper = new Clipper();

            Cell[] cells = _map.cells;
            for (int j = 0; j < cells.Length; j++)
            {
                if (j % 100 == 0)
                {
                    if (hexifyContext.progress != null)
                    {
                        if (hexifyContext.progress((float)j / cells.Length, hexifyContext.title, "Pass 5/6: removing cells from neighbours..."))
                        {
                            cancelled = true;
                            hexifyContext.finish(true);
                            yield break;
                        }
                    }
                    yield return(null);
                }

                int entityIndex = procCells [j].entityIndex;
                if (entityIndex < 0)
                {
                    continue;
                }

                RegionCell   regionCell = procCells [j];
                IAdminEntity entity     = entities [entityIndex];

                // Substract cell region from any other entity
                List <Region> otherRegions;
                if (entity is Country)
                {
                    otherRegions = _map.GetCountryRegionsOverlap(regionCell.cellRegion);
                }
                else
                {
                    otherRegions = _map.GetProvinceRegionsOverlap(regionCell.cellRegion);
                }
                int orCount = otherRegions.Count;
                for (int o = 0; o < orCount; o++)
                {
                    Region       otherRegion = otherRegions [o];
                    IAdminEntity otherEntity = otherRegion.entity;
                    if (otherEntity == entity)
                    {
                        continue;
                    }
                    clipper.Clear();
                    clipper.AddPath(otherRegion, PolyType.ptSubject);
                    clipper.AddPath(regionCell.cellRegion, PolyType.ptClip);
                    clipper.Execute(ClipType.ctDifference, otherEntity);
                }
            }
        }
Esempio n. 12
0
        private PolyTree PolygonsToPolyTree(Paths polygons)
        {
            var     tree = new PolyTree();
            Clipper c    = new Clipper();

            c.Clear();
            c.AddPaths(polygons, PolyType.ptSubject, true);
            c.Execute(ClipType.ctUnion, tree);
            return(tree);
        }
Esempio n. 13
0
        public void Union(Slice other)
        {
            Clipper c = new Clipper();

            c.Clear();
            c.AddPaths(Clipper.PolyTreeToPaths(polyTree), PolyType.ptSubject, true);
            c.AddPaths(Clipper.PolyTreeToPaths(other.polyTree), PolyType.ptClip, true);

            polyTree = new PolyTree();
            c.Execute(ClipType.ctUnion, polyTree);
        }
Esempio n. 14
0
        public static PolyTree Combine(List <List <ControlPoint> > polygons)
        {
            Clipper.Clear();
            Clipper.AddPaths(polygons, PolyType.ptSubject, true);
            Clipper.AddPaths(polygons, PolyType.ptClip, true);

            var tree = new PolyTree();

            Clipper.Execute(ClipType.ctUnion, tree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
            return(tree);
        }
Esempio n. 15
0
        public void SubtractFrom(Slice other)
        {
            Clipper c = new Clipper();

            c.Clear();
            c.AddPaths(PolyTreeToPolygons(other.polyTree), PolyType.ptSubject, true);
            c.AddPaths(PolyTreeToPolygons(polyTree), PolyType.ptClip, true);

            polyTree = new PolyTree();
            c.Execute(ClipType.ctDifference, polyTree);
        }
Esempio n. 16
0
    void UpdateFrontPolygon(Polygon surface, Polygon tunnel)
    {
        frontPolygons.Clear();

        //Lets generate the polygons which represent the landscape.
        //Clipper c = new Clipper();
        clipper.AddPolygon(surface, PolyType.Subject);
        clipper.AddPolygon(tunnel, PolyType.Clip);
        bool result = clipper.Execute(ClipType.Difference, frontPolygons,
                                      PolyFillType.EvenOdd, PolyFillType.EvenOdd);

        clipper.Clear();
    }
Esempio n. 17
0
        private void BuildBackground(Path clipRect)
        {
            _clipper.AddPath(clipRect, PolyType.ptSubject, true);

            _clipper.AddPaths(_carRoads.Shape, PolyType.ptClip, true);
            _clipper.AddPaths(_walkRoads.Shape, PolyType.ptClip, true);
            _clipper.AddPaths(_water.Shape, PolyType.ptClip, true);
            _clipper.AddPaths(_surfaces.SelectMany(r => r.Shape), PolyType.ptClip, true);
            var solution = new Paths();

            _clipper.Execute(ClipType.ctDifference, solution, PolyFillType.pftPositive,
                             PolyFillType.pftPositive);
            _clipper.Clear();

            _background = new MeshCanvas.Region()
            {
                Shape = solution
            };
        }
Esempio n. 18
0
        /// <summary>
        /// Calculate the intersection of all given shapes
        /// </summary>
        /// <param name="clipper"></param>
        /// <param name="shapes"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        public static IEnumerable <IEnumerable <Vector2> > IntersectAll(this Clipper clipper, IEnumerable <IEnumerable <Vector2> > shapes, int scale = 1000)
        {
            //Just in case someone else made a mess, clean up before we start
            clipper.Clear();

            //First shape is taken as the first "previous"
            var previous = new List <List <IntPoint> > {
                shapes.First().Select(a => new IntPoint(a.X * scale, a.Y * scale)).ToList()
            };

            //Loop through each shape (except the first) intersecting reuslts of all previous intersections with this shape
            foreach (var shape in shapes.Skip(1))
            {
                clipper.AddPaths(previous, PolyType.ptSubject, true);
                clipper.AddPath(shape.Select(a => new IntPoint(a.X * scale, a.Y * scale)).ToList(), PolyType.ptClip, true);

                clipper.Execute(ClipType.ctIntersection, previous);
                clipper.Clear();
            }

            //Convert back into normal scale
            return(previous.Select(s => s.Select(v => new Vector2((float)v.X / scale, (float)v.Y / scale))));
        }
Esempio n. 19
0
        private Paths ClipByRectangle(Path clipRect, Paths subjects)
        {
            Clipper clipper = _objectPool.NewObject <Clipper>();

            clipper.AddPath(clipRect, PolyType.ptClip, true);
            clipper.AddPaths(subjects, PolyType.ptSubject, true);
            var solution = new Paths();

            clipper.Execute(ClipType.ctIntersection, solution);

            clipper.Clear();
            _objectPool.StoreObject(clipper);
            return(solution);
        }
Esempio n. 20
0
        IEnumerator AddHexagons(IAdminEntity[] entities)
        {
            Cell[]  cells   = _map.cells;
            Clipper clipper = new Clipper();

            for (int j = 0; j < cells.Length; j++)
            {
                if (j % 100 == 0)
                {
                    if (hexifyContext.progress != null)
                    {
                        if (hexifyContext.progress((float)j / cells.Length, hexifyContext.title, "Pass 3/6: adding hexagons to frontiers..."))
                        {
                            cancelled = true;
                            hexifyContext.finish(true);
                            yield break;
                        }
                    }
                    yield return(null);
                }

                int entityIndex = procCells [j].entityIndex;
                if (entityIndex < 0)
                {
                    continue;
                }
                Cell cell = cells [j];

                // Create a region for the cell
                IAdminEntity entity    = entities [entityIndex];
                Vector2[]    newPoints = new Vector2[6];
                for (int k = 0; k < 6; k++)
                {
                    newPoints [k].x = hexagonPoints [k].x + cell.center.x;
                    newPoints [k].y = hexagonPoints [k].y + cell.center.y;
                }
                procCells [j].cellRegion = new Region(entity, entity.regions.Count);
                procCells [j].cellRegion.UpdatePointsAndRect(newPoints);

                // Add region to target entity's polygon - only if the entity is touching or crossing target entity frontier
                Region targetRegion = procCells [j].entityRegion;
                clipper.Clear();
                clipper.AddPath(targetRegion, PolyType.ptSubject);
                clipper.AddPath(procCells [j].cellRegion, PolyType.ptClip);
                clipper.Execute(ClipType.ctUnion);
            }
        }
Esempio n. 21
0
        private static Polygon ClipPolygon(Polygon subject, Polygon clip, ClipType operation)
        {
            Paths clprResult = new Paths();
            // Convert to library structure
            Paths clprSubject = PolygonToClprPaths(subject);
            Paths clprClip    = PolygonToClprPaths(clip);

            // Execute clip action
            lock (ClipperEngine) {
                ClipperEngine.Clear();
                ClipperEngine.AddPaths(clprSubject, PolyType.ptSubject, true);
                ClipperEngine.AddPaths(clprClip, PolyType.ptClip, true);
                ClipperEngine.Execute(operation, clprResult);
            }
            // Convert back to common polygon
            return(ClprPathsToPolygon(clprResult));
        }
Esempio n. 22
0
        /// <summary>
        /// Inverts the selection.
        /// </summary>
        /// <param name="surface">
        /// Surface for the selection path.
        /// </param>
        /// <param name='imageSize'>
        /// The size of the document.
        /// </param>
        public void Invert(Surface surface, Gdk.Size imageSize)
        {
            List <List <IntPoint> > resultingPolygons = new List <List <IntPoint> > ();

            var documentPolygon = CreateRectanglePolygon(new Rectangle(0, 0, imageSize.Width, imageSize.Height));

            // Create a rectangle that is the size of the entire image,
            // and subtract all of the polygons in the current selection from it.
            SelectionClipper.AddPolygon(documentPolygon, PolyType.ptSubject);
            SelectionClipper.AddPolygons(SelectionPolygons, PolyType.ptClip);
            SelectionClipper.Execute(ClipType.ctDifference, resultingPolygons);

            SelectionClipper.Clear();

            SelectionPolygons = resultingPolygons;
            MarkDirty();
        }
Esempio n. 23
0
        /// <summary>
        /// 使用Clipper将阻挡裁剪出来
        /// </summary>
        private static List <List <IntPoint> > ClipPolygons(List <List <IntPoint> > walkablePolygons, List <List <IntPoint> > blockedPolygons)
        {
            //合并可走区域
            List <List <IntPoint> > result = new List <List <IntPoint> >();
            Clipper clipper = new Clipper();

            clipper.AddPolygons(walkablePolygons, PolyType.ptClip);
            clipper.Execute(ClipType.ctUnion, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            clipper.Clear();

            //去掉不可走区域
            clipper.AddPolygons(result, PolyType.ptSubject);
            clipper.AddPolygons(blockedPolygons, PolyType.ptClip);
            clipper.Execute(ClipType.ctDifference, result);

            return(result);
        }
Esempio n. 24
0
        private PolyTree GetPolyTree(IEnumerable <LineStrip> lines, PolyFillType pft)
        {
            Paths   polygons = new Paths();
            Clipper c        = new Clipper();

            c.Clear();

            foreach (var line in lines)
            {
                polygons.Add(LineStripToPolygon(line));
            }

            polygons = Clipper.SimplifyPolygons(polygons, pft);
            c.AddPaths(polygons, PolyType.ptSubject, true);
            PolyTree tree = new PolyTree();

            c.Execute(ClipType.ctUnion, tree);
            return(tree);
        }
Esempio n. 25
0
        public static Ngons MinkowskiSumBoundary(Ngon pattern, Ngons path, bool flip_pattern)
        {
            Clipper clipper = new Clipper();

            Ngons full = new Ngons();

            for (int i = 0; i < path.Count; i++)
            {
                Ngons seg = MinkowskiSumBoundary(pattern, path[i], flip_pattern);
                clipper.AddPaths(full, PolyType.ptSubject, true);
                clipper.AddPaths(seg, PolyType.ptSubject, true);

                Ngons res = new Ngons();
                clipper.Execute(ClipType.ctUnion, res, PolyFillType.pftNonZero);
                full = res;
                clipper.Clear();
            }

            return(full);
        }
Esempio n. 26
0
        public bool Contains(Slice other)
        {
            // To contain another slice:
            // 1. Area of the union must be the same
            // 2. Area of this - other must be less



            float thisArea = this.Area();

            Paths   otherPolygons = Clipper.PolyTreeToPaths(other.polyTree);
            Paths   thesePolygons = Clipper.PolyTreeToPaths(polyTree);
            Slice   s             = new Slice(this);
            Clipper c             = new Clipper();

            c.Clear();
            c.AddPaths(thesePolygons, PolyType.ptSubject, true);
            c.AddPaths(otherPolygons, PolyType.ptClip, true);
            s.polyTree = new PolyTree();
            c.Execute(ClipType.ctUnion, s.polyTree);
            float area_union = s.Area();

            if (area_union > thisArea)
            {
                return(false);
            }
            return(true);
            //c.Clear();
            //c.AddPaths(thesePolygons, PolyType.ptSubject, true);
            //c.AddPaths(otherPolygons, PolyType.ptClip, true);
            //s.polyTree = new PolyTree();
            //c.Execute(ClipType.ctDifference, s.polyTree);
            //float area_difference = s.Area();
            //if (area_difference < thisArea)
            //{
            //    return true;
            //}
            //return false;
        }
Esempio n. 27
0
        private bool Intersects(Tile tile, GeoReference elem)
        {
            var element = FindGeoElement(elem);

            // do the clipping
            var tb         = GM.TileBounds(tile.TileTms, tile.Zoom);
            var tilePoints = AdaptToClipper(new List <Vector2d> {
                tb.Min,
                tb.Min + new Vector2d(tb.Width, 0),
                tb.Min + new Vector2d(tb.Width, tb.Height),
                tb.Min + new Vector2d(0, tb.Height)
            }.ConvertAll(p => GM.MetersToLatLon(p)));
            var geoPoints = AdaptToClipper(element.Geometry.Points);

            var solution = new List <List <IntPoint> >();

            clipper.Clear();
            clipper.AddPath(tilePoints, PolyType.ptSubject, true);
            clipper.AddPath(geoPoints, PolyType.ptSubject, true);

            return(clipper.Execute(ClipType.ctIntersection, solution) && solution.Count > 0);
        }
Esempio n. 28
0
        PushPolygonToArray(List <List <IntPoint> > subjects, List <List <IntPoint> > clips)
        {
            Polygons nextClip              = new Polygons();
            Polygons currentSubject        = new Polygons();
            Polygons currentClip           = new Polygons();
            Polygons currentArrayDraw      = new Polygons();
            Polygons currentArrayInvisible = new Polygons();
            Clipper  cTupleDraw            = new Clipper();
            Clipper  cTupleInvisible       = new Clipper();

            //find polygons to be drawn
            currentSubject.Clear();
            currentClip.Clear();
            currentSubject = subjects;
            currentClip    = clips;
            cTupleDraw.Clear();
            cTupleDraw.AddPaths(currentSubject, PolyType.ptSubject, true);
            cTupleDraw.AddPaths(currentClip, PolyType.ptClip, true);
            currentArrayDraw.Clear();
            bool succeededDraw = cTupleDraw.Execute(ClipType.ctDifference, currentArrayDraw,
                                                    PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            //find next clipped polygon
            nextClip.Clear();
            bool succeededNextClip = cTupleDraw.Execute(ClipType.ctUnion, nextClip,
                                                        PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            //find invisible polygons
            cTupleInvisible.Clear();
            cTupleInvisible.AddPaths(currentSubject, PolyType.ptSubject, true);
            cTupleInvisible.AddPaths(currentClip, PolyType.ptClip, true);
            currentArrayInvisible.Clear();
            bool succeededInvisible = cTupleInvisible.Execute(ClipType.ctIntersection, currentArrayInvisible,
                                                              PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            return(new Tuple <List <List <IntPoint> >, List <List <IntPoint> >, List <List <IntPoint> > >
                       (currentArrayDraw, currentArrayInvisible, nextClip));
        }
Esempio n. 29
0
        public void Calculate()
        {
            Debug.Log("Calculate");

            c.Clear();
            subj[0].Clear();
            clip[0].Clear();
            solution.Clear();

            for (int i = listSolutionPolygon.Count - 1; i >= 0; --i)
            {
                Destroy(listSolutionPolygon[i]);
            }
            listSolutionPolygon.Clear();

            var roomShapeSubject = listPolygon[0].GetComponent <RoomShape> ();

            foreach (var pointData in roomShapeSubject.Points)
            {
                subj[0].Add(new IntPoint(pointData.point.vec.x, pointData.point.vec.y));
            }

            var roomShapeClip = listPolygon[1].GetComponent <RoomShape> ();

            foreach (var pointData in roomShapeClip.Points)
            {
                clip[0].Add(new IntPoint(pointData.point.vec.x, pointData.point.vec.y));
            }

            c.AddPaths(subj, PolyType.ptSubject, true);
            c.AddPaths(clip, PolyType.ptClip, true);
            c.Execute(clipType, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

            Debug.Log("solution count:" + solution.Count + " points count: " + (solution.Count > 0 ? solution[0].Count.ToString() : "0"));

            DrawPolygons(solution, "0xFF00009A".hexToColor(), "0xFF00669A".hexToColor(), true);
        }
Esempio n. 30
0
        internal static void ClipGeometry(VectorUtils.Geometry geom)
        {
            UnityEngine.Profiling.Profiler.BeginSample("ClipGeometry");

            var clipper = new Clipper();

            foreach (var clipperPaths in m_ClipStack)
            {
                var vertices = new List <Vector2>(geom.Vertices.Length);
                var indices  = new List <UInt16>(geom.Indices.Length);
                var paths    = BuildTriangleClipPaths(geom);
                var result   = new List <List <IntPoint> >();

                UInt16 maxIndex = 0;

                foreach (var path in paths)
                {
                    clipper.AddPaths(clipperPaths, PolyType.ptClip, true);
                    clipper.AddPath(path, PolyType.ptSubject, true);
                    clipper.Execute(ClipType.ctIntersection, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    if (result.Count > 0)
                    {
                        BuildGeometryFromClipPaths(geom, result, vertices, indices, ref maxIndex);
                    }

                    clipper.Clear();
                    result.Clear();
                }

                geom.Vertices = vertices.ToArray();
                geom.Indices  = indices.ToArray();
            }

            UnityEngine.Profiling.Profiler.EndSample();
        }