Exemplo n.º 1
0
        public static List <List <Vector2> > SimplifyPolygon(List <Vector2> polygon, PolyFillType polyFillType = PolyFillType.pftNonZero)
        {
            if (polygon == null || polygon.Count == 0)
            {
                return(null);
            }

            List <IntPoint> polygonInt = ConvertFloatToInt(polygon);

            List <List <IntPoint> > polygonsInt = Clipper.SimplifyPolygon(polygonInt, polyFillType);
            int polygonsIntCount = polygonsInt.Count, i;            //, j, polygonCount;
            List <List <Vector2> > polygons = new List <List <Vector2> >(polygonsIntCount);

            for (i = 0; i < polygonsIntCount; i++)
            {
                //polygonCount = polygonsInt [i].Count;
                polygons.Add(ConvertIntToFloat(polygonsInt [i]));
            }

            if (polygons == null || polygons.Count == 0)
            {
                return(null);
            }

            return(polygons);
        }
Exemplo n.º 2
0
        public override bool Read(GH_IO.Serialization.GH_IReader reader)
        {
            Operation = (ClipType)reader.GetInt32("Operation");
            FillType  = (PolyFillType)reader.GetInt32("FillType");

            return(base.Read(reader));
        }
Exemplo n.º 3
0
        public static List<List<Vector2>> SimplifyPolygons(List<List<Vector2>> polygon, PolyFillType polyFillType = PolyFillType.pftNonZero)
        {
            if (polygon == null || polygon.Count == 0)
                return null;

            List<List<IntPoint>> polygonsInt = new List<List<IntPoint>>();
            int i;//, j, polygonCount;
            for(i = 0; i < polygon.Count; i++)
            {
                polygonsInt.Add(ConvertFloatToInt(polygon[i]));
            }

            polygonsInt = Clipper.SimplifyPolygons(polygonsInt, polyFillType);
            int polygonsIntCount = polygonsInt.Count;
            List<List<Vector2>> polygons = new List<List<Vector2>>(polygonsIntCount);
            for (i = 0; i < polygonsIntCount; i++)
            {
                polygons.Add(ConvertIntToFloat(polygonsInt [i]));
            }
            
            if (polygons == null || polygons.Count == 0)
                return null;
            
            return polygons;
        }
        /**
         * Note: this method will close all unclosed subpaths of the passed path.
         *
         * @param fillingRule If the subpath is contour, pass any value.
         */
        protected internal Path FilterFillPath(Path path, Matrix ctm, int fillingRule)
        {
            path.CloseAllSubpaths();

            Clipper clipper = new Clipper();

            AddPath(clipper, path);

            foreach (Rectangle rectangle in rectangles)
            {
                Point2D[] transfRectVertices = TransformPoints(ctm, true, GetVertices(rectangle));
                AddRect(clipper, transfRectVertices, PolyType.ptClip);
            }

            PolyFillType fillType = PolyFillType.pftNonZero;

            if (fillingRule == PathPaintingRenderInfo.EVEN_ODD_RULE)
            {
                fillType = PolyFillType.pftEvenOdd;
            }

            PolyTree resultTree = new PolyTree();

            clipper.Execute(ClipType.ctDifference, resultTree, fillType, PolyFillType.pftNonZero);

            return(ConvertToPath(resultTree));
        }
Exemplo n.º 5
0
 protected override void AppendAdditionalComponentMenuItems(System.Windows.Forms.ToolStripDropDown menu)
 {
     Menu_AppendItem(menu, "Even-Odd", (s, e) => { FillType = PolyFillType.pftEvenOdd; ExpireSolution(true); }, true, FillType == PolyFillType.pftEvenOdd);
     Menu_AppendItem(menu, "Non-Zero", (s, e) => { FillType = PolyFillType.pftNonZero; ExpireSolution(true); }, true, FillType == PolyFillType.pftNonZero);
     Menu_AppendItem(menu, "Positive", (s, e) => { FillType = PolyFillType.pftPositive; ExpireSolution(true); }, true, FillType == PolyFillType.pftPositive);
     Menu_AppendItem(menu, "Negative", (s, e) => { FillType = PolyFillType.pftNegative; ExpireSolution(true); }, true, FillType == PolyFillType.pftNegative);
 }
Exemplo n.º 6
0
 protected override void AppendAdditionalComponentMenuItems(System.Windows.Forms.ToolStripDropDown menu)
 {
     Menu_AppendItem(menu, "Even-Odd", (s, e) => { FillType = PolyFillType.pftEvenOdd; ExpireSolution(true); }, true, FillType == PolyFillType.pftEvenOdd);
     Menu_AppendItem(menu, "Non-Zero", (s, e) => { FillType = PolyFillType.pftNonZero; ExpireSolution(true); }, true, FillType == PolyFillType.pftNonZero);
     Menu_AppendItem(menu, "Positive", (s, e) => { FillType = PolyFillType.pftPositive; ExpireSolution(true); }, true, FillType == PolyFillType.pftPositive);
     Menu_AppendItem(menu, "Negative", (s, e) => { FillType = PolyFillType.pftNegative; ExpireSolution(true); }, true, FillType == PolyFillType.pftNegative);
 }
Exemplo n.º 7
0
 private void Init(IEnumerable <LineStrip> lines, Plane plane, PolyFillType pft = PolyFillType.pftEvenOdd)
 {
     transform        = plane.CreateMatrix();
     transform        = Matrix4.Mult(transform, Matrix4.CreateScale(scale));
     inverseTransform = Matrix4.Invert(transform);
     this.plane       = plane;
     polyTree         = GetPolyTree(lines, pft);
 }
Exemplo n.º 8
0
        /// <summary>
        /// Performs the clipping operation.
        /// Can be called multiple times without reassigning subject and clip polygons
        /// (ie when different clipping operations are required on the same polygon sets).
        /// </summary>
        /// <param name="clipType"> Type of the clipping operation. </param>
        /// <param name="output"> The List that will receive the result of the clipping operation. </param>
        /// <param name="subjectFillType"> Fill rule that will be applied to the subject paths. </param>
        /// <param name="clipFillType"> Fill rule that will be applied to the clip paths. </param>
        /// <returns> True if the operation was successful, false otherwise. </returns>
        public bool Clip(ClipType clipType, ref List <List <Vector2> > output, PolyFillType subjectFillType, PolyFillType clipFillType)
        {
            var  intOutput = new List <List <IntPoint> >();
            bool succeeded = clipper.Execute(clipType, intOutput, subjectFillType, clipFillType);

            ClipperUtility.ToVector2Paths(intOutput, ref output);
            return(succeeded);
        }
Exemplo n.º 9
0
        public void SimplifyPolygon(IEnumerable <Point2d> poly, List <Point2d> solution,
                                    PolyFillType fillType = PolyFillType.pftEvenOdd)
        {
            List <IntPoint> _poly = poly.Select(p => this.converter.ToIntPoint(p)).ToList();

            Clipper.SimplifyPolygon(_poly, fillType);
            solution.AddRange(_poly.Select(p => this.converter.FromIntPoint(p)));
        }
Exemplo n.º 10
0
 public StyleInfo() 
 {
     pft = PolyFillType.pftNonZero;
     brushClr = Color.AntiqueWhite;
     dashArray = null;
     penClr = Color.Black;
     penWidth = 0.8;
     showCoords = false;
 }
Exemplo n.º 11
0
        public void SimplifyPolygons <TPoly>(IEnumerable <TPoly> polys, List <List <Point2d> > solution,
                                             PolyFillType fillType = PolyFillType.pftEvenOdd)
            where TPoly : IEnumerable <Point2d>
        {
            List <List <IntPoint> > _polys = polys.Select(poly => poly.Select(p => this.converter.ToIntPoint(p)).ToList()).ToList();

            Clipper.SimplifyPolygons(_polys, fillType);
            solution.AddRange(_polys.Select(poly => poly.Select(p => this.converter.FromIntPoint(p)).ToList()));
        }
Exemplo n.º 12
0
 public StyleInfo()
 {
     pft        = PolyFillType.pftNonZero;
     brushClr   = Color.AntiqueWhite;
     dashArray  = null;
     penClr     = Color.Black;
     penWidth   = 0.8;
     showCoords = false;
 }
Exemplo n.º 13
0
        /// <summary>
        /// Converts iText filling rule constant into the corresponding constant
        /// of the Clipper library.
        /// </summary>
        /// <param name="fillingRule">
        /// Either
        /// <see cref="iText.Kernel.Pdf.Canvas.PdfCanvasConstants.FillingRule.NONZERO_WINDING"/>
        /// or
        /// <see cref="iText.Kernel.Pdf.Canvas.PdfCanvasConstants.FillingRule.EVEN_ODD"/>.
        /// </param>
        /// <returns>Clipper fill type constant.</returns>
        public static PolyFillType GetFillType(int fillingRule)
        {
            PolyFillType fillType = PolyFillType.NON_ZERO;

            if (fillingRule == PdfCanvasConstants.FillingRule.EVEN_ODD)
            {
                fillType = PolyFillType.EVEN_ODD;
            }
            return(fillType);
        }
Exemplo n.º 14
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));
        }
Exemplo n.º 15
0
        public bool Execute(ClipType clipType, List <List <Point2d> > solution,
                            PolyFillType subjFillType,
                            PolyFillType clipFillType)
        {
            List <List <IntPoint> > _solution = new List <List <IntPoint> >();
            bool ret = this.clipper.Execute(clipType, _solution, subjFillType, clipFillType);

            if (!ret)
            {
                Debug.WriteLine("Error in clipper.Execute");
            }
            solution.AddRange(_solution.Select(poly => poly.Select(p => this.converter.FromIntPoint(p)).ToList()));
            return(ret);
        }
Exemplo n.º 16
0
        /// <summary>
        ///     Joins all the polygones.
        ///     ClipType: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm
        ///     PolyFillType: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm
        /// </summary>
        /// <param name="sList">The s list.</param>
        /// <param name="cType">Type of the c.</param>
        /// <param name="pType">Type of the p.</param>
        /// <param name="pFType1">The p f type1.</param>
        /// <param name="pFType2">The p f type2.</param>
        /// <returns></returns>
        public static List <Polygon> JoinPolygons(
            this List <Polygon> sList,
            ClipType cType,
            PolyType pType       = PolyType.ptClip,
            PolyFillType pFType1 = PolyFillType.pftNonZero,
            PolyFillType pFType2 = PolyFillType.pftNonZero)
        {
            var p     = ClipPolygons(sList);
            var tList = new List <List <IntPoint> >();

            var c = new Clipper();

            c.AddPaths(p, pType, true);
            c.Execute(cType, tList, pFType1, pFType2);

            return(ToPolygons(tList));
        }
Exemplo n.º 17
0
        //---------------------------------------------------------------------

        private void bSave_Click(object sender, EventArgs e)
        {
            //save to SVG ...
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                PolyFillType pft = GetPolyFillType();
                SVGBuilder   svg = new SVGBuilder();
                svg.style.brushClr = Color.FromArgb(0x10, 0, 0, 0x9c);
                svg.style.penClr   = Color.FromArgb(0xd3, 0xd3, 0xda);
                svg.AddPolygons(subjects);
                svg.style.brushClr = Color.FromArgb(0x10, 0x9c, 0, 0);
                svg.style.penClr   = Color.FromArgb(0xff, 0xa0, 0x7a);
                svg.AddPolygons(clips);
                svg.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
                svg.style.penClr   = Color.FromArgb(0, 0x33, 0);
                svg.AddPolygons(solution);
                svg.SaveToFile(saveFileDialog1.FileName, 1.0 / scale);
            }
        }
Exemplo n.º 18
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);
        }
Exemplo n.º 19
0
        public static List <Polyline> Boolean(ClipType clipType, IEnumerable <Polyline> polyA, IEnumerable <Polyline> polyB, Plane pln, double tolerance, bool evenOddFilling)
        {
            Clipper      clipper      = new Clipper(0);
            PolyFillType polyfilltype = PolyFillType.pftEvenOdd;

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

            List <List <IntPoint> > PathsA = new List <List <IntPoint> >();
            List <List <IntPoint> > PathsB = new List <List <IntPoint> >();

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

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

            PolyTree OutputTree = new PolyTree();

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

            List <Polyline> Output = new List <Polyline> ();

            foreach (PolyNode pn in OutputTree.Iterate())
            {
                if (pn.Contour.Count > 1)
                {
                    Output.Add(pn.Contour.ToPolyline(pln, tolerance, !pn.IsOpen));
                }
            }

            return(Output);
        }
Exemplo n.º 20
0
        /// <summary>Note: this method will close all unclosed subpaths of the passed path.</summary>
        /// <param name="fillingRule">If the subpath is contour, pass any value.</param>
        protected internal virtual Path FilterFillPath(Path path, Matrix ctm, int fillingRule)
        {
            path.CloseAllSubpaths();
            Clipper clipper = new Clipper();

            ClipperBridge.AddPath(clipper, path, PolyType.SUBJECT);
            foreach (Rectangle rectangle in regions)
            {
                Point[] transfRectVertices = TransformPoints(ctm, true, GetRectangleVertices(rectangle));
                ClipperBridge.AddRectToClipper(clipper, transfRectVertices, PolyType.CLIP);
            }
            PolyFillType fillType = PolyFillType.NON_ZERO;

            if (fillingRule == PdfCanvasConstants.FillingRule.EVEN_ODD)
            {
                fillType = PolyFillType.EVEN_ODD;
            }
            PolyTree resultTree = new PolyTree();

            clipper.Execute(ClipType.DIFFERENCE, resultTree, fillType, PolyFillType.NON_ZERO);
            return(ClipperBridge.ConvertToPath(resultTree));
        }
Exemplo n.º 21
0
        public static List <Polyline> Boolean(ClipType clipType, IEnumerable <Polyline> polyA, IEnumerable <Polyline> polyB,
                                              Plane pln, double tolerance, bool evenOddFilling)
        {
            NGonsCore.Clipper642.Clipper clipper = new NGonsCore.Clipper642.Clipper();
            PolyFillType polyfilltype            = PolyFillType.pftEvenOdd;

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

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

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

            PolyTree polytree = new PolyTree();

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

            List <Polyline> output = new List <Polyline>();

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

            return(output);
        }
Exemplo n.º 22
0
        public static Mesh CreatePolygon(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh)
        {
            antialiasingMesh = null;
            if (inputShapes == null || inputShapes.Count == 0)
            {
                return(null);
            }

            List <List <Vector2> > simplifiedShapes = new List <List <Vector2> >();

            PolyFillType fillType = PolyFillType.pftNonZero;

            if (paintable.fillRule == SVGFillRule.EvenOdd)
            {
                fillType = PolyFillType.pftEvenOdd;
            }

            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if (simplifiedShapes == null || simplifiedShapes.Count == 0)
            {
                return(null);
            }

            AddInputShape(simplifiedShapes);

            Rect bounds = GetRect(simplifiedShapes);

            switch (paintable.GetPaintType())
            {
            case SVGPaintMethod.SolidGradientFill:
            {
                Color        color     = Color.black;
                SVGColorType colorType = paintable.fillColor.Value.colorType;
                if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                {
                    color.a          *= paintable.fillOpacity;
                    paintable.svgFill = new SVGFill(color);
                }
                else
                {
                    color             = paintable.fillColor.Value.color;
                    color.a          *= paintable.fillOpacity;
                    paintable.svgFill = new SVGFill(color);
                }

                paintable.svgFill.fillType = FILL_TYPE.SOLID;
                if (color.a == 1)
                {
                    paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                }
                else
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
            }
            break;

            case SVGPaintMethod.LinearGradientFill:
            {
                SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix);
                paintable.svgFill = linearGradBrush.fill;
            }
            break;

            case SVGPaintMethod.RadialGradientFill:
            {
                SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix);
                paintable.svgFill = radialGradBrush.fill;
            }
            break;

            case SVGPaintMethod.ConicalGradientFill:
            {
                SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix);
                paintable.svgFill = conicalGradBrush.fill;
            }
            break;

            case SVGPaintMethod.PathDraw:
            {
                Color        color     = Color.black;
                SVGColorType colorType = paintable.fillColor.Value.colorType;
                if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                {
                    color.a          *= paintable.strokeOpacity;
                    paintable.svgFill = new SVGFill(color);
                }
                else
                {
                    color             = paintable.fillColor.Value.color;
                    color.a          *= paintable.strokeOpacity;
                    paintable.svgFill = new SVGFill(color);
                }

                paintable.svgFill.fillType = FILL_TYPE.SOLID;
                if (color.a == 1)
                {
                    paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                }
                else
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
            }
            break;

            default:
                break;
            }

            LibTessDotNet.Tess            tesselation = new LibTessDotNet.Tess();
            LibTessDotNet.ContourVertex[] path;
            int pathLength;

            for (int i = 0; i < simplifiedShapes.Count; i++)
            {
                if (simplifiedShapes[i] == null)
                {
                    continue;
                }

                pathLength = simplifiedShapes[i].Count;
                path       = new LibTessDotNet.ContourVertex[pathLength];
                Vector2 position;
                for (int j = 0; j < pathLength; j++)
                {
                    position         = simplifiedShapes[i][j];
                    path[j].Position = new LibTessDotNet.Vec3 {
                        X = position.x, Y = position.y, Z = 0f
                    };
                }
                tesselation.AddContour(path);
            }

            tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

            Mesh mesh            = new Mesh();
            int  meshVertexCount = tesselation.Vertices.Length;

            Vector3[] vertices = new Vector3[meshVertexCount];
            Vector2[] uv       = null;
            Vector2[] uv2      = null;

            for (int i = 0; i < meshVertexCount; i++)
            {
                vertices[i] = new Vector3(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y, 0f);
            }

            int numTriangles = tesselation.ElementCount;

            int[] triangles = new int[numTriangles * 3];
            for (int i = 0; i < numTriangles; i++)
            {
                triangles[i * 3]     = tesselation.Elements[i * 3];
                triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
            }

            SVGFill svgFill   = paintable.svgFill;
            Color32 fillColor = Color.white;

            if (svgFill.fillType != FILL_TYPE.GRADIENT && svgFill.gradientColors == null)
            {
                fillColor = svgFill.color;
            }

            antialiasingMesh = CreateAntialiasing(simplifiedShapes, fillColor, -SVGAssetImport.antialiasingWidth, false, SVGImporter.Utils.ClosePathRule.ALWAYS);

            Color32[] colors32 = new Color32[meshVertexCount];

            for (int i = 0; i < meshVertexCount; i++)
            {
                colors32 [i].r = fillColor.r;
                colors32 [i].g = fillColor.g;
                colors32 [i].b = fillColor.b;
                colors32 [i].a = fillColor.a;
            }

            if (antialiasingMesh != null)
            {
                Vector3[] antialiasingVertices = antialiasingMesh.vertices;
                Vector2[] antialiasingUV       = antialiasingMesh.uv;
                Vector2[] antialiasingUV2      = antialiasingMesh.uv2;
                WriteUVGradientCoordinates(ref antialiasingUV, antialiasingVertices, paintable, bounds);
                WriteUVGradientIndexType(ref antialiasingUV2, antialiasingVertices.Length, paintable);
                antialiasingMesh.uv  = antialiasingUV;
                antialiasingMesh.uv2 = antialiasingUV2;
            }

            WriteUVGradientCoordinates(ref uv, vertices, paintable, bounds);
            WriteUVGradientIndexType(ref uv2, meshVertexCount, paintable);

            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            if (colors32 != null)
            {
                mesh.colors32 = colors32;
            }
            if (uv != null)
            {
                mesh.uv = uv;
            }
            if (uv2 != null)
            {
                mesh.uv2 = uv2;
            }

            return(mesh);
        }
Exemplo n.º 23
0
 private void Init(IEnumerable<LineStrip> lines, Plane plane, PolyFillType pft = PolyFillType.pftEvenOdd)
 {
     transform = plane.CreateMatrix();
     transform = Matrix4.Mult(transform, Matrix4.CreateScale(scale));
     inverseTransform = Matrix4.Invert(transform);
     this.plane = plane;
     polyTree = GetPolyTree(lines, pft);
 }
Exemplo n.º 24
0
        public static IEnumerable <Rhino.Geometry.Curve> Boolean(ClipType operation, PolyFillType fillType, IEnumerable <Rhino.Geometry.Curve> curvesA, IEnumerable <Rhino.Geometry.Curve> curvesB, Plane?plane)
        {
            var closedA = curvesA.Where(o => o.IsClosed);
            var closedB = curvesB.Where(o => o.IsClosed);

            if (!plane.HasValue)
            {
                foreach (var curve in closedA)
                {
                    var curvePlane = default(Plane);

                    if (!curve.TryGetPlane(out curvePlane))
                    {
                        continue;
                    }

                    plane = curvePlane;
                }
            }

            if (!plane.HasValue)
            {
                plane = Plane.WorldXY;
            }


            var polylinesA = new List <List <Point2d> >();
            var polylinesB = new List <List <Point2d> >();

            foreach (var curve in closedA)
            {
                var polyline = default(Polyline);

                if (!curve.TryGetPolyline(out polyline))
                {
                    continue;
                }

                polylinesA.Add(polyline.Select(o => o.Map2D(plane.Value)).ToList());
            }

            foreach (var curve in closedB)
            {
                var polyline = default(Polyline);

                if (!curve.TryGetPolyline(out polyline))
                {
                    continue;
                }

                polylinesB.Add(polyline.Select(o => o.Map2D(plane.Value)).ToList());
            }


            var minX = polylinesA.Union(polylinesB).SelectMany(o => o).Min(o => o.X);
            var minY = polylinesA.Union(polylinesB).SelectMany(o => o).Min(o => o.Y);
            var maxX = polylinesA.Union(polylinesB).SelectMany(o => o).Max(o => o.X);
            var maxY = polylinesA.Union(polylinesB).SelectMany(o => o).Max(o => o.Y);

            var unit = Math.Max(maxX - minX, maxY - minY) / (2 * 4.6e+18);

            var midX = (minX + maxX) / 2.0;
            var midY = (minY + maxY) / 2.0;


            var polygonsA = polylinesA.Select(o => o.Select(p => new IntPoint((p.X - midX) / unit, (p.Y - midY) / unit)).ToList())
                            .ToList();

            var polygonsB = polylinesB.Select(o => o.Select(p => new IntPoint((p.X - midX) / unit, (p.Y - midY) / unit)).ToList())
                            .ToList();


            var clipper = new Clipper();

            clipper.AddPaths(polygonsA, PolyType.ptSubject, true);
            clipper.AddPaths(polygonsB, PolyType.ptClip, true);

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

            clipper.Execute(operation, solution, fillType, fillType);


            return(solution.Select(o =>
            {
                var points = o.Select(p => plane.Value.Origin + (p.X * unit + midX) * plane.Value.XAxis + (p.Y * unit + midY) * plane.Value.YAxis)
                             .ToList();

                if (points.Count > 0 && points.First() != points.Last())
                {
                    points.Add(points[0]);
                }

                return new PolylineCurve(points);
            }));
        }
Exemplo n.º 25
0
      //------------------------------------------------------------------------------

      public static Paths SimplifyPolygons(Paths polys,
          PolyFillType fillType = PolyFillType.pftEvenOdd)
      {
          Paths result = new Paths();
          Clipper c = new Clipper();
          c.StrictlySimple = true;
          c.AddPaths(polys, PolyType.ptSubject, true);
          c.Execute(ClipType.ctUnion, result, fillType, fillType);
          return result;
      }
Exemplo n.º 26
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;
        }
Exemplo n.º 27
0
        private static Polygons CombinePolygons(this Polygons aPolys, Polygons bPolys, ClipType clipType, PolyFillType fillType = PolyFillType.pftEvenOdd)
        {
            var clipper = new Clipper();

            clipper.AddPaths(aPolys, PolyType.ptSubject, true);
            clipper.AddPaths(bPolys, PolyType.ptClip, true);

            var outputPolys = new Polygons();

            clipper.Execute(clipType, outputPolys, fillType);
            return(outputPolys);
        }
Exemplo n.º 28
0
 private void AppendFillTypeMenuItem(System.Windows.Forms.ToolStripDropDown menu, string text, PolyFillType fillType)
 {
     Menu_AppendItem(menu, text, (s, e) => { RecordUndoEvent("FillType"); FillType = fillType; ExpireSolution(true); }, true, FillType == fillType);
 }
Exemplo n.º 29
0
        /// <summary>
        /// Performs the Boolean Operations from the Clipper Library
        /// </summary>
        /// <param name="clipType"></param>
        /// <param name="subject"></param>
        /// <param name="clip"></param>
        /// <param name="simplifyPriorToBooleanOperation"></param>
        /// <param name="scale"></param>
        /// <param name="fillMethod"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private static List <Polygon> BooleanViaClipper(PolyFillType fillMethod, ClipType clipType, IEnumerable <Polygon> subject,
                                                        IEnumerable <Polygon> clip = null, bool subjectIsClosed = true, bool clipIsClosed = true)
        {
            //Remove any polygons that are only a line.
            //subject = subject.Where(p => p.Count > 2);
            //clip = clip?.Where(p => p.Count > 2);
            var simplifyPriorToBooleanOperation = true;

            if (simplifyPriorToBooleanOperation)
            {
                //subject = subject.Select(p=>SimplifyFuzzy(p));
                subject = subject.Select(p => Simplify(p, 0.0000003));
            }
            if (simplifyPriorToBooleanOperation)
            {
                //If not null
                //clip = clip?.Select(p => SimplifyFuzzy(p));
                clip = clip?.Select(p => Simplify(p, 0.0000003));
            }
            if (!subject.Any())
            {
                if (clip == null || !clip.Any())
                {
                    return(new List <Polygon>());
                }
                //Use the clip as the subject if this is a union operation and the clip is not null.
                if (clipType == ClipType.ctUnion)
                {
                    subject = clip;
                    clip    = null;
                }
            }
            var subjectAll = subject.SelectMany(p => p.AllPolygons).ToList();

            var clipperSolution = new List <List <IntPoint> >();
            //Convert Points (TVGL) to IntPoints (Clipper)
            var clipperSubject =
                subjectAll.Select(loop => loop.Vertices.Select(point => new IntPoint(point.X * scale, point.Y * scale)).ToList()).ToList();

            //Setup Clipper
            var clipper = new ClipperLib.Clipper()
            {
                StrictlySimple = true
            };

            clipper.AddPaths(clipperSubject, PolyType.ptSubject, subjectIsClosed);

            if (clip != null)
            {
                var clipAll = clip.SelectMany(p => p.AllPolygons).ToList();

                var clipperClip =
                    clipAll.Select(loop => loop.Vertices.Select(point => new IntPoint(point.X * scale, point.Y * scale)).ToList()).ToList();
                clipper.AddPaths(clipperClip, PolyType.ptClip, clipIsClosed);
            }

            //Begin an evaluation
            var result = clipper.Execute(clipType, clipperSolution, fillMethod, fillMethod);

            if (!result)
            {
                throw new Exception("Clipper Union Failed");
            }

            //Convert back to points and return solution
            var solution = clipperSolution.Select(clipperPath => new Polygon(clipperPath.Select(point => new Vector2(point.X / scale, point.Y / scale))));

            return(solution.CreateShallowPolygonTrees(true));
        }
Exemplo n.º 30
0
        //------------------------------------------------------------------------------

        private void BmpUpdateNeeded()
        {
            const int textOffset = 20;

            if (bmpGraphics == null)
            {
                return;
            }
            FillMode fm = (mEvenOdd.Checked ? FillMode.Alternate : FillMode.Winding);

            bmpGraphics.Clear(Color.White);

            //draw the subject and clip paths ...
            Paths openPaths   = new Paths();
            Paths closedPaths = new Paths();
            Paths clipPaths   = new Paths();

            //sort the paths into open and closed subjects and (closed) clips ...
            foreach (MultiPath mp2 in allPaths)
            {
                if (mp2.RefID == CLIP)
                {
                    clipPaths.Add(mp2.Flatten());
                }
                else if (mp2.IsClosed)
                {
                    closedPaths.Add(mp2.Flatten());
                }
                else
                {
                    openPaths.Add(mp2.Flatten());
                }
            }

            DrawPath(bmpGraphics, openPaths, false, 0x0, 0xFFAAAAAA, fm, 1.0);
            DrawPath(bmpGraphics, closedPaths, true, 0x0, 0xFFAAAAAA, fm, 1.0);
            DrawPath(bmpGraphics, clipPaths, true, 0x10FF6600, 0x99FF6600, fm, 1.0);

            if (cbShowCoords.Checked)
            {
                Font       fnt   = new Font("Arial", 8);
                SolidBrush brush = new SolidBrush(Color.Navy);
                foreach (MultiPath mp2 in allPaths)
                {
                    foreach (MultiPathSegment mps in mp2)
                    {
                        foreach (IntPoint ip in mps)
                        {
                            IntPoint ip2    = new IntPoint(ip.X / scale, ip.Y / scale);
                            string   coords = ip2.X.ToString() + "," + ip2.Y.ToString();
                            bmpGraphics.DrawString(coords, fnt, brush, ip2.X - textOffset, ip2.Y - textOffset, null);
                        }
                    }
                }
                fnt.Dispose();
                brush.Dispose();
            }

            //for the active path, draw control buttons and control lines too ...
            MultiPath activePath = GetActivePath();

            if (activePath != null && activePath.Count > 0)
            {
                foreach (MultiPathSegment mps in activePath)
                {
                    CurveType pt = mps.curvetype;
                    if (pt == CurveType.CubicBezier)
                    {
                        DrawBezierCtrlLines(bmpGraphics, mps, 0xFFEEEEEE);
                    }
                    else if (pt == CurveType.QuadBezier)
                    {
                        DrawBezierCtrlLines(bmpGraphics, mps, 0xFFEEEEEE);
                    }
                }

                DrawButtons(bmpGraphics, activePath);

                //display the coords of a moving button ...
                if (MovingButtonIdx >= 0)
                {
                    Font       f  = new Font("Arial", 8);
                    SolidBrush b  = new SolidBrush(Color.Navy);
                    IntPoint   ip = MovingButtonSeg[MovingButtonIdx];
                    ip.X = (int)(ip.X / scale); ip.Y = (int)(ip.Y / scale);
                    string coords = ip.X.ToString() + "," + ip.Y.ToString();
                    bmpGraphics.DrawString(coords, f, b, ip.X - textOffset, ip.Y - textOffset, null);
                    f.Dispose();
                    b.Dispose();
                }
            }

            //if there's any clipping to be done, do it here ...
            if (!mNone.Checked && GetCurrentSubjMultiPath() != null && GetCurrentClipMultiPath() != null)
            {
                PolyFillType pft = (mEvenOdd.Checked ? PolyFillType.pftEvenOdd : PolyFillType.pftNonZero);
                ClipType     ct;
                if (mUnion.Checked)
                {
                    ct = ClipType.ctUnion;
                }
                else if (mDifference.Checked)
                {
                    ct = ClipType.ctDifference;
                }
                else if (mXor.Checked)
                {
                    ct = ClipType.ctXor;
                }
                else
                {
                    ct = ClipType.ctIntersection;
                }

                //CLIPPING DONE HERE ...
                Clipper c = new Clipper();
                c.ZFillFunction = MultiPaths.ClipCallback; //set the callback function (called at intersections)
                if (openPaths.Count > 0)
                {
                    c.AddPaths(openPaths, PolyType.ptSubject, false);
                }
                if (closedPaths.Count > 0)
                {
                    c.AddPaths(closedPaths, PolyType.ptSubject, true);
                }
                c.AddPaths(clipPaths, PolyType.ptClip, true);
                PolyTree polytree = new PolyTree();

                Paths solution;
                c.Execute(ct, polytree, pft, pft); //EXECUTE CLIP !!!!!!!!!!!!!!!!!!!!!!
                solution = Clipper.ClosedPathsFromPolyTree(polytree);
                if (!cbReconstCurve.Checked)
                {
                    DrawPath(bmpGraphics, solution, true, 0x2033AA00, 0xFF33AA00, fm, 2.0);
                }
                solution = Clipper.OpenPathsFromPolyTree(polytree);
                if (!cbReconstCurve.Checked)
                {
                    DrawPath(bmpGraphics, solution, false, 0x0, 0xFF33AA00, fm, 2.0);
                }

                //now to demonstrate reconstructing beziers & arcs ...
                if (cbReconstCurve.Checked)
                {
                    PolyNode pn = polytree.GetFirst();
                    while (pn != null)
                    {
                        if (pn.IsHole || pn.Contour.Count < 2)
                        {
                            pn = pn.GetNext();
                            continue;
                        }

                        if (pn.ChildCount > 0)
                        {
                            throw new Exception("Sorry, this demo doesn't currently handle holes");
                        }

                        //and reconstruct each curve ...
                        MultiPath reconstructedMultiPath = allPaths.Reconstruct(pn.Contour);

                        if (cbShowCtrls.Enabled && cbShowCtrls.Checked)
                        {
                            //show (small) buttons on the red reconstructed path too ...
                            DrawButtons(bmpGraphics, reconstructedMultiPath, true);
                        }

                        //now to show how accurate these reconstructed (control) paths are,
                        //we flatten them (drawing them red) so we can compare them with
                        //the original flattened paths (light gray) ...
                        Paths paths = new Paths();
                        paths.Add(reconstructedMultiPath.Flatten());
                        DrawPath(bmpGraphics, paths, !pn.IsOpen, 0x18FF0000, 0xFFFF0000, fm, 2.0);

                        pn = pn.GetNext();
                    }
                }
                //else //shows just how many vertices there are in flattened paths ...
                //{
                //  solution = Clipper.PolyTreeToPaths(polytree);
                //  MultiPath flatMultiPath = new MultiPath(null, 0, false);
                //  foreach (Path p in solution)
                //    flatMultiPath.NewMultiPathSegment(PathType.Line, p);
                //  DrawButtons(bmpGraphics, flatMultiPath, true);
                //}
            }

            string s = "  ";

            if (mIntersection.Checked)
            {
                s += "INTERSECTION";
            }
            else if (mUnion.Checked)
            {
                s += "UNION";
            }
            else if (mDifference.Checked)
            {
                s += "DIFFERENCE";
            }
            else if (mXor.Checked)
            {
                s += "XOR";
            }
            else
            {
                s += "NO CLIPPING";
            }
            s += " with ";
            if (mEvenOdd.Checked)
            {
                s += "EVENODD fill.";
            }
            else
            {
                s += "NONZERO fill.";
            }
            toolStripStatusLabel2.Text = s;
            displayPanel.Invalidate();
        }
Exemplo n.º 31
0
        public static void TesselateStroke(List <List <Vector2> > inputShapes, Color32 color, out List <List <Vector2> > simplifiedShapes, out Vector3[] vertices, out int[] triangles, out Color32[] colors32)
        {
            simplifiedShapes = null;
            vertices         = null;
            triangles        = null;
            colors32         = null;

            if (inputShapes == null || inputShapes.Count == 0)
            {
                return;
            }

            int i, j;

            simplifiedShapes = new List <List <Vector2> >();

            PolyFillType fillType = PolyFillType.pftNonZero;

            for (i = 0; i < inputShapes.Count; i++)
            {
                if (inputShapes[i] == null || inputShapes.Count == 0)
                {
                    continue;
                }

                List <List <Vector2> > output = SVGGeom.SimplifyPolygon(inputShapes[i], fillType);
                if (output == null || output.Count == 0)
                {
                    simplifiedShapes.Add(inputShapes[i]);
                }
                else
                {
                    simplifiedShapes.AddRange(output);
                }
            }

            LibTessDotNet.Tess tesselation = new LibTessDotNet.Tess();

            LibTessDotNet.ContourVertex[] path;
            for (i = 0; i < simplifiedShapes.Count; i++)
            {
                if (simplifiedShapes[i] == null || simplifiedShapes[i].Count < 2)
                {
                    continue;
                }

                path = new LibTessDotNet.ContourVertex[simplifiedShapes[i].Count];
                for (j = 0; j < simplifiedShapes[i].Count; j++)
                {
                    path[j].Position = new LibTessDotNet.Vec3 {
                        X = simplifiedShapes[i][j].x, Y = simplifiedShapes[i][j].y, Z = 0f
                    };
                }
                tesselation.AddContour(path);
            }

            tesselation.Tessellate(LibTessDotNet.WindingRule.Positive, LibTessDotNet.ElementType.Polygons, 3);
            if (tesselation.Vertices == null || tesselation.Vertices.Length == 0)
            {
                return;
            }

            int numVertices  = tesselation.Vertices.Length;
            int numTriangles = tesselation.ElementCount * 3;

            triangles = new int[numTriangles];
            vertices  = new Vector3[numVertices];
            colors32  = new Color32[numVertices];

            for (i = 0; i < numVertices; i++)
            {
                vertices[i] = new Vector3(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y, 0f);
                colors32[i] = color;
            }
            for (i = 0; i < numTriangles; i += 3)
            {
                triangles[i]     = tesselation.Elements[i];
                triangles[i + 1] = tesselation.Elements[i + 1];
                triangles[i + 2] = tesselation.Elements[i + 2];
            }
        }
Exemplo n.º 32
0
        public static bool CreatePolygon(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, out SVGLayer layer, bool isStroke = false)
        {
            layer = new SVGLayer();
            if (inputShapes == null || inputShapes.Count == 0)
            {
                return(false);
            }

            List <List <Vector2> > simplifiedShapes = new List <List <Vector2> >();
            PolyFillType           fillType         = PolyFillType.pftNonZero;

            if (paintable.fillRule == SVGFillRule.EvenOdd)
            {
                fillType = PolyFillType.pftEvenOdd;
            }
            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if (simplifiedShapes == null || simplifiedShapes.Count == 0)
            {
                return(false);
            }

            AddInputShape(simplifiedShapes);

            Rect bounds   = GetRect(simplifiedShapes);
            Rect viewport = paintable.viewport;

            if (!isStroke)
            {
                switch (paintable.GetPaintType())
                {
                case SVGPaintMethod.SolidFill:
                {
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                case SVGPaintMethod.LinearGradientFill:
                {
                    SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = linearGradBrush.fill;
                }
                break;

                case SVGPaintMethod.RadialGradientFill:
                {
                    SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = radialGradBrush.fill;
                }
                break;

                case SVGPaintMethod.ConicalGradientFill:
                {
                    SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = conicalGradBrush.fill;
                }
                break;

                case SVGPaintMethod.PathDraw:
                {
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                default:
                    break;
                }
            }
            else
            {
                Color color = paintable.strokeColor.Value.color;
                color.a          *= paintable.strokeOpacity;
                paintable.svgFill = new SVGFill(color, FILL_BLEND.OPAQUE, FILL_TYPE.SOLID);
                if (color.a != 1f)
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
                paintable.svgFill.color = color;
            }

            LibTessDotNet.Tess            tesselation = new LibTessDotNet.Tess();
            LibTessDotNet.ContourVertex[] path;
            int pathLength;

            for (int i = 0; i < simplifiedShapes.Count; i++)
            {
                if (simplifiedShapes[i] == null)
                {
                    continue;
                }

                pathLength = simplifiedShapes[i].Count;
                path       = new LibTessDotNet.ContourVertex[pathLength];
                Vector2 position;
                for (int j = 0; j < pathLength; j++)
                {
                    position         = simplifiedShapes[i][j];
                    path[j].Position = new LibTessDotNet.Vec3 {
                        X = position.x, Y = position.y, Z = 0f
                    };
                }
                tesselation.AddContour(path, SVGImporter.LibTessDotNet.ContourOrientation.Clockwise);
            }

            tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

            int meshVertexCount = tesselation.Vertices.Length;

            layer.vertices = new Vector2[meshVertexCount];

            for (int i = 0; i < meshVertexCount; i++)
            {
                layer.vertices[i] = new Vector2(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y) * SVGAssetImport.meshScale;
            }

            int numTriangles = tesselation.ElementCount;

            layer.triangles = new int[numTriangles * 3];
            for (int i = 0; i < numTriangles; i++)
            {
                layer.triangles[i * 3]     = tesselation.Elements[i * 3];
                layer.triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                layer.triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
            }

            layer.fill         = paintable.svgFill;
            layer.fill.opacity = paintable.opacity;
            if (layer.fill.opacity < 1f && layer.fill.blend == FILL_BLEND.OPAQUE)
            {
                layer.fill.blend = FILL_BLEND.ALPHA_BLENDED;
            }

            if (layer.fill.fillType == FILL_TYPE.GRADIENT && layer.fill.gradientColors != null)
            {
                layer.fill.color = Color.white;
            }
            else if (layer.fill.fillType == FILL_TYPE.TEXTURE)
            {
                layer.fill.color = Color.white;
            }

            viewport.x         *= SVGAssetImport.meshScale;
            viewport.y         *= SVGAssetImport.meshScale;
            viewport.size      *= SVGAssetImport.meshScale;
            layer.fill.viewport = viewport;

            if (layer.fill.transform != null)
            {
                SVGMatrix scaleMatrix = SVGMatrix.Identity().Scale(SVGAssetImport.meshScale);
                layer.fill.transform = scaleMatrix.Multiply(layer.fill.transform);
                layer.fill.transform = layer.fill.transform.Multiply(scaleMatrix.Inverse());
            }

            Vector2 boundsMin = bounds.min * SVGAssetImport.meshScale;
            Vector2 boundsMax = bounds.max * SVGAssetImport.meshScale;

            layer.bounds = new Rect(boundsMin.x,
                                    boundsMin.y,
                                    boundsMax.x - boundsMin.x,
                                    boundsMax.y - boundsMin.y);

            return(true);
        }
Exemplo n.º 33
0
        //------------------------------------------------------------------------------

        public bool Execute(ClipType clipType, PolyTree polytree,
            PolyFillType subjFillType, PolyFillType clipFillType)
        {
            if (m_ExecuteLocked) return false;
            m_ExecuteLocked = true;
            m_SubjFillType = subjFillType;
            m_ClipFillType = clipFillType;
            m_ClipType = clipType;
            m_UsingPolyTree = true;
            bool succeeded = ExecuteInternal();
            //build the return polygons ...
            if (succeeded) BuildResult2(polytree);
            m_ExecuteLocked = false;
            return succeeded;
        }
Exemplo n.º 34
0
 //------------------------------------------------------------------------------
 public static List<List<IntPoint>> SimplifyPolygons(List<List<IntPoint>> polys,
     PolyFillType fillType = PolyFillType.pftEvenOdd)
 {
     List<List<IntPoint>> result = new List<List<IntPoint>>();
     Clipper c = new Clipper();
     c.StrictlySimple = true;
     c.AddPaths(polys, PolyType.ptSubject, true);
     c.Execute(ClipType.ctUnion, result, fillType, fillType);
     return result;
 }
Exemplo n.º 35
0
        public static bool CreatePolygon(List <List <Vector2> > inputShapes, SVGPaintable paintable, SVGMatrix matrix, out SVGShape layer, out SVGShape antialiasingLayer, bool isStroke = false, bool antialiasing = false)
        {
            layer             = new SVGShape();
            antialiasingLayer = new SVGShape();

            if (inputShapes == null || inputShapes.Count == 0)
            {
                return(false);
            }

            List <List <Vector2> > simplifiedShapes = new List <List <Vector2> >();
            PolyFillType           fillType         = PolyFillType.pftNonZero;

            if (paintable.fillRule == SVGFillRule.EvenOdd)
            {
                fillType = PolyFillType.pftEvenOdd;
            }
            simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType);
            if (simplifiedShapes == null || simplifiedShapes.Count == 0)
            {
                return(false);
            }

            AddInputShape(simplifiedShapes);

            Rect bounds   = GetRect(simplifiedShapes);
            Rect viewport = paintable.viewport;

            if (!isStroke)
            {
                switch (paintable.GetPaintType())
                {
                case SVGPaintMethod.SolidFill:
                {
                    layer.type = SVGShapeType.FILL;
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.fillOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                case SVGPaintMethod.LinearGradientFill:
                {
                    layer.type = SVGShapeType.FILL;
                    SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = linearGradBrush.fill;
                }
                break;

                case SVGPaintMethod.RadialGradientFill:
                {
                    layer.type = SVGShapeType.FILL;
                    SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = radialGradBrush.fill;
                }
                break;

                case SVGPaintMethod.ConicalGradientFill:
                {
                    layer.type = SVGShapeType.FILL;
                    SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix, viewport);
                    paintable.svgFill = conicalGradBrush.fill;
                }
                break;

                case SVGPaintMethod.PathDraw:
                {
                    layer.type = SVGShapeType.STROKE;
                    Color        color     = Color.black;
                    SVGColorType colorType = paintable.fillColor.Value.colorType;
                    if (colorType == SVGColorType.Unknown || colorType == SVGColorType.None)
                    {
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }
                    else
                    {
                        color             = paintable.fillColor.Value.color;
                        color.a          *= paintable.strokeOpacity;
                        paintable.svgFill = new SVGFill(color);
                    }

                    paintable.svgFill.fillType = FILL_TYPE.SOLID;
                    if (color.a == 1)
                    {
                        paintable.svgFill.blend = FILL_BLEND.OPAQUE;
                    }
                    else
                    {
                        paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                    }
                }
                break;

                default:
                    break;
                }
            }
            else
            {
                layer.type = SVGShapeType.STROKE;
                Color color = paintable.strokeColor.Value.color;
                color.a          *= paintable.strokeOpacity;
                paintable.svgFill = new SVGFill(color, FILL_BLEND.OPAQUE, FILL_TYPE.SOLID);
                if (color.a != 1f)
                {
                    paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
                paintable.svgFill.color = color;
            }

            // Use LibTessDotNet
            if (true)
            {
                LibTessDotNet.Tess            tesselation = new LibTessDotNet.Tess();
                LibTessDotNet.ContourVertex[] path;
                int pathLength;
                for (int i = 0; i < simplifiedShapes.Count; i++)
                {
                    if (simplifiedShapes[i] == null)
                    {
                        continue;
                    }

                    pathLength = simplifiedShapes[i].Count;
                    path       = new LibTessDotNet.ContourVertex[pathLength];
                    Vector2 position;
                    for (int j = 0; j < pathLength; j++)
                    {
                        position         = simplifiedShapes[i][j];
                        path[j].Position = new LibTessDotNet.Vec3 {
                            X = position.x, Y = position.y, Z = 0f
                        };
                    }
                    tesselation.AddContour(path, SVGImporter.LibTessDotNet.ContourOrientation.Clockwise);
                }

                tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);
                int meshVertexCount = tesselation.Vertices.Length;
                if (meshVertexCount == 0)
                {
                    return(false);
                }

                int numTriangles = tesselation.ElementCount;
                layer.triangles = new int[numTriangles * 3];
                layer.vertices  = new Vector2[meshVertexCount];

                for (int i = 0; i < numTriangles; i++)
                {
                    layer.triangles[i * 3]     = tesselation.Elements[i * 3];
                    layer.triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1];
                    layer.triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2];
                }

                for (int i = 0; i < meshVertexCount; i++)
                {
                    layer.vertices[i] = new Vector2(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y) * SVGAssetImport.meshScale;
                }
            }

            /*
             * else {
             *  // Use Triangle.net library
             *  SVGImporter.TriangleNet.Mesh triangleMesh = new SVGImporter.TriangleNet.Mesh();
             *  SVGImporter.TriangleNet.Geometry.InputGeometry triangleInput = new SVGImporter.TriangleNet.Geometry.InputGeometry();
             *
             *  int pathLength, m = 0;
             *  for(int i = 0; i < simplifiedShapes.Count; i++)
             *  {
             *      if(simplifiedShapes[i] == null)
             *          continue;
             *
             *      pathLength = simplifiedShapes[i].Count;
             *      Vector2 position;
             *      for(int j = 0; j < pathLength; j++)
             *      {
             *          triangleInput.AddPoint(simplifiedShapes[i][j].x, simplifiedShapes[i][j].y);
             *      }
             *  }
             *
             *  triangleMesh.Triangulate(triangleInput);
             *
             *  int totalVertices = triangleMesh.vertices.Count;
             *  layer.vertices = new Vector2[totalVertices];
             *  for(int i = 0; i < totalVertices; i++)
             *  {
             *      layer.vertices[i].x = (float)triangleMesh.vertices[i].x * SVGAssetImport.meshScale;
             *      layer.vertices[i].y = (float)triangleMesh.vertices[i].y * SVGAssetImport.meshScale;
             *  }
             *
             *  int totalTriangles = triangleMesh.triangles.Count;
             *  layer.triangles = new int[totalTriangles * 3];
             *  int ti = 0;
             *  for(int i = 0; i < totalTriangles; i++)
             *  {
             *      ti = i * 3;
             *      layer.triangles[ti] = triangleMesh.triangles[i].P0;
             *      layer.triangles[ti + 1] = triangleMesh.triangles[i].P1;
             *      layer.triangles[ti + 2] = triangleMesh.triangles[i].P2;
             *  }
             * }
             */

            layer.fill         = paintable.svgFill;
            layer.fill.opacity = paintable.opacity;
            if (layer.fill.opacity < 1f && layer.fill.blend == FILL_BLEND.OPAQUE)
            {
                layer.fill.blend = FILL_BLEND.ALPHA_BLENDED;
            }

            if (layer.fill.fillType == FILL_TYPE.GRADIENT && layer.fill.gradientColors != null)
            {
                layer.fill.color = Color.white;
            }
            else if (layer.fill.fillType == FILL_TYPE.TEXTURE)
            {
                layer.fill.color = Color.white;
            }

            viewport.x         *= SVGAssetImport.meshScale;
            viewport.y         *= SVGAssetImport.meshScale;
            viewport.size      *= SVGAssetImport.meshScale;
            layer.fill.viewport = viewport;

            SVGMatrix scaleMatrix = SVGMatrix.identity.Scale(SVGAssetImport.meshScale);

            layer.fill.transform = scaleMatrix.Multiply(layer.fill.transform);
            layer.fill.transform = layer.fill.transform.Multiply(scaleMatrix.Inverse());

            Vector2 boundsMin = bounds.min * SVGAssetImport.meshScale;
            Vector2 boundsMax = bounds.max * SVGAssetImport.meshScale;

            layer.bounds = new Rect(boundsMin.x,
                                    boundsMin.y,
                                    boundsMax.x - boundsMin.x,
                                    boundsMax.y - boundsMin.y);

            if (antialiasing)
            {
                if (CreateAntialiasing(simplifiedShapes, out antialiasingLayer, Color.white, -1f, ClosePathRule.ALWAYS))
                {
                    int verticesLength = antialiasingLayer.vertices.Length;
                    for (int i = 0; i < verticesLength; i++)
                    {
                        antialiasingLayer.vertices[i] *= SVGAssetImport.meshScale;
                    }
                    antialiasingLayer.type = SVGShapeType.ANTIALIASING;
                    antialiasingLayer.RecalculateBounds();
                    antialiasingLayer.fill       = layer.fill.Clone();
                    antialiasingLayer.fill.blend = FILL_BLEND.ALPHA_BLENDED;
                }
            }

            return(true);
        }
Exemplo n.º 36
0
 public static Polygons Union(this Polygons polygons, Polygons other, PolyFillType fillType = PolyFillType.pftEvenOdd)
 {
     return(polygons.CombinePolygons(other, ClipType.ctUnion, fillType));
 }
Exemplo n.º 37
0
 //------------------------------------------------------------------------------
 public bool Execute(ClipType clipType, PolyTree polytree,
     PolyFillType FillType = PolyFillType.pftEvenOdd)
 {
     return Execute(clipType, polytree, FillType, FillType);
 }
Exemplo n.º 38
0
 public bool Execute(ClipType clipType, List <List <Point2d> > solution,
                     PolyFillType fillType = PolyFillType.pftEvenOdd)
 {
     return(this.Execute(clipType, solution, fillType, fillType));
 }
Exemplo n.º 39
0
      //------------------------------------------------------------------------------

      public bool Execute(ClipType clipType, Paths solution,
          PolyFillType subjFillType, PolyFillType clipFillType)
      {
          if (m_ExecuteLocked) return false;
          if (m_HasOpenPaths) throw 
            new ClipperException("Error: PolyTree struct is need for open path clipping.");

        m_ExecuteLocked = true;
          solution.Clear();
          m_SubjFillType = subjFillType;
          m_ClipFillType = clipFillType;
          m_ClipType = clipType;
          m_UsingPolyTree = false;
          bool succeeded = ExecuteInternal();
          //build the return polygons ...
          if (succeeded) BuildResult(solution);
          m_ExecuteLocked = false;
          return succeeded;
      }
Exemplo n.º 40
0
        //------------------------------------------------------------------------------

        //------------------------------------------------------------------------------
        // SimplifyPolygon functions ...
        // Convert self-intersecting polygons into simple polygons
        //------------------------------------------------------------------------------

        public static PolygonsClp SimplifyPolygon(PolygonClp poly,
              PolyFillType fillType = PolyFillType.pftEvenOdd)
        {
            PolygonsClp result = new PolygonsClp();
            Clipper c = new Clipper();
            c.ForceSimple = true;
            c.AddPolygon(poly, PolyType.ptSubject);
            c.Execute(ClipType.ctUnion, result, fillType, fillType);
            return result;
        }
Exemplo n.º 41
0
        ////////////////////////////////////////////////

        static void Main(string[] args)
        {
            ////quick test with random polygons ...
            //Polygons ss = new Polygons(1), cc = new Polygons(1), sss = new Polygons();
            //Random r = new Random((int)DateTime.Now.Ticks);
            //int scale = 1000000000; //tests 128bit math
            //ss.Add(MakeRandomPolygon(r, 400, 350, 9, scale));
            //cc.Add(MakeRandomPolygon(r, 400, 350, 9, scale));
            //Clipper cpr = new Clipper();
            //cpr.AddPolygons(ss, PolyType.ptSubject);
            //cpr.AddPolygons(cc, PolyType.ptClip);
            //cpr.Execute(ClipType.ctUnion, sss, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
            //sss = Clipper.OffsetPolygons(sss, -5.0*scale, JoinType.jtMiter, 4);
            //SVGBuilder svg1 = new SVGBuilder();
            //svg1.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c);
            //svg1.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda);
            //svg1.AddPolygons(ss);
            //svg1.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0);
            //svg1.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a);
            //svg1.AddPolygons(cc);
            //svg1.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
            //svg1.style.penClr = Color.FromArgb(0, 0x33, 0);
            //svg1.AddPolygons(sss);
            //svg1.SaveToFile("solution.svg", 1.0/scale);
            //return;

            if (args.Length < 5)
            {
                string appname = System.Environment.GetCommandLineArgs()[0];
                appname = Path.GetFileName(appname);
                Console.WriteLine("");
                Console.WriteLine("Usage:");
                Console.WriteLine("  {0} CLIPTYPE s_file c_file INPUT_DEC_PLACES SVG_SCALE [S_FILL, C_FILL]", appname);
                Console.WriteLine("  where ...");
                Console.WriteLine("  CLIPTYPE = INTERSECTION|UNION|DIFFERENCE|XOR");
                Console.WriteLine("  FILLMODE = NONZERO|EVENODD");
                Console.WriteLine("  INPUT_DEC_PLACES = signific. decimal places for subject & clip coords.");
                Console.WriteLine("  SVG_SCALE = scale of SVG image as power of 10. (Fractions are accepted.)");
                Console.WriteLine("  both S_FILL and C_FILL are optional. The default is EVENODD.");
                Console.WriteLine("Example:");
                Console.WriteLine("  Intersect polygons, rnd to 4 dec places, SVG is 1/100 normal size ...");
                Console.WriteLine("  {0} INTERSECTION subj.txt clip.txt 0 0 NONZERO NONZERO", appname);
                return;
            }

            ClipType ct;

            switch (args[0].ToUpper())
            {
            case "INTERSECTION": ct = ClipType.ctIntersection; break;

            case "UNION": ct = ClipType.ctUnion; break;

            case "DIFFERENCE": ct = ClipType.ctDifference; break;

            case "XOR": ct = ClipType.ctXor; break;

            default: Console.WriteLine("Error: invalid operation - {0}", args[0]); return;
            }

            string subjFilename = args[1];
            string clipFilename = args[2];

            if (!File.Exists(subjFilename))
            {
                Console.WriteLine("Error: file - {0} - does not exist.", subjFilename);
                return;
            }
            if (!File.Exists(clipFilename))
            {
                Console.WriteLine("Error: file - {0} - does not exist.", clipFilename);
                return;
            }

            int decimal_places = 0;

            if (!Int32.TryParse(args[3], out decimal_places))
            {
                Console.WriteLine("Error: invalid number of decimal places - {0}", args[3]);
                return;
            }
            if (decimal_places > 8)
            {
                decimal_places = 8;
            }
            else if (decimal_places < 0)
            {
                decimal_places = 0;
            }

            double svg_scale = 0;

            if (!double.TryParse(args[4], out svg_scale))
            {
                Console.WriteLine("Error: invalid value for SVG_SCALE - {0}", args[4]);
                return;
            }
            if (svg_scale < -18)
            {
                svg_scale = -18;
            }
            else if (svg_scale > 18)
            {
                svg_scale = 18;
            }
            svg_scale = Math.Pow(10, svg_scale - decimal_places);//nb: also compensate for decimal places


            PolyFillType pftSubj = PolyFillType.pftEvenOdd;
            PolyFillType pftClip = PolyFillType.pftEvenOdd;

            if (args.Length > 6)
            {
                switch (args[5].ToUpper())
                {
                case "EVENODD": pftSubj = PolyFillType.pftEvenOdd; break;

                case "NONZERO": pftSubj = PolyFillType.pftNonZero; break;

                default: Console.WriteLine("Error: invalid cliptype - {0}", args[5]); return;
                }
                switch (args[6].ToUpper())
                {
                case "EVENODD": pftClip = PolyFillType.pftEvenOdd; break;

                case "NONZERO": pftClip = PolyFillType.pftNonZero; break;

                default: Console.WriteLine("Error: invalid cliptype - {0}", args[6]); return;
                }
            }

            Polygons subjs = new Polygons();
            Polygons clips = new Polygons();

            if (!LoadFromFile(subjFilename, subjs, decimal_places))
            {
                Console.WriteLine("Error processing subject polygons file - {0} ", subjFilename);
                OutputFileFormat();
                return;
            }
            if (!LoadFromFile(clipFilename, clips, decimal_places))
            {
                Console.WriteLine("Error processing clip polygons file - {0} ", clipFilename);
                OutputFileFormat();
                return;
            }

            Console.WriteLine("wait ...");
            Clipper cp = new Clipper();

            cp.AddPolygons(subjs, PolyType.ptSubject);
            cp.AddPolygons(clips, PolyType.ptClip);

            Polygons solution = new Polygons();

            //Polygons solution = new Polygons();
            if (cp.Execute(ct, solution, pftSubj, pftClip))
            {
                SaveToFile("solution.txt", solution, decimal_places);

                //solution = Clipper.OffsetPolygons(solution, -4, JoinType.jtRound);

                SVGBuilder svg = new SVGBuilder();
                svg.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c);
                svg.style.penClr   = Color.FromArgb(0xd3, 0xd3, 0xda);
                svg.AddPolygons(subjs);
                svg.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0);
                svg.style.penClr   = Color.FromArgb(0xff, 0xa0, 0x7a);
                svg.AddPolygons(clips);
                svg.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
                svg.style.penClr   = Color.FromArgb(0, 0x33, 0);
                svg.AddPolygons(solution);
                svg.SaveToFile("solution.svg", svg_scale);

                Console.WriteLine("finished!");
            }
            else
            {
                Console.WriteLine("failed!");
            }
        }
Exemplo n.º 42
0
        //------------------------------------------------------------------------------
        public bool Execute(ClipType clipType, Polygons solution,
            PolyFillType subjFillType, PolyFillType clipFillType)
        {
            if( m_ExecuteLocked ) return false;
              bool succeeded;
              try {
            m_ExecuteLocked = true;
            solution.Clear();
            if ( !Reset() )
            {
              m_ExecuteLocked = false;
              return false;
            }
            m_SubjFillType = subjFillType;
            m_ClipFillType = clipFillType;
            m_ClipType = clipType;

            int botY = PopScanbeam();
            do {
              InsertLocalMinimaIntoAEL(botY);
              m_HorizJoins.Clear();
              ProcessHorizontals();
              int topY = PopScanbeam();
              succeeded = ProcessIntersections(topY);
              if (succeeded) ProcessEdgesAtTopOfScanbeam(topY);
              botY = topY;
            } while( succeeded && m_Scanbeam != null );

            //build the return polygons ...
            if (succeeded) BuildResult(solution);
              }
              catch {
              m_Joins.Clear();
              m_HorizJoins.Clear();
              solution.Clear();
              succeeded = false;
              }
              m_Joins.Clear();
              m_HorizJoins.Clear();
              DisposeAllPolyPts();
              m_ExecuteLocked = false;
              return succeeded;
        }
Exemplo n.º 43
0
 //------------------------------------------------------------------------------
 public bool Execute(ClipType clipType, List<List<IntPoint>> solution,
     PolyFillType FillType = PolyFillType.pftEvenOdd)
 {
     return Execute(clipType, solution, FillType, FillType);
 }
Exemplo n.º 44
0
        //------------------------------------------------------------------------------

        public static Polygons SimplifyPolygons(Polygons polys,
            PolyFillType fillType = PolyFillType.pftEvenOdd)
        {
            Polygons result = new Polygons();
            Clipper c = new Clipper();
            c.AddPolygons(polys, PolyType.ptSubject);
            c.Execute(ClipType.ctUnion, result, fillType, fillType);
            return result;
        }
Exemplo n.º 45
0
        public bool Execute(ClipType clipType, PolyTree polytree, PolyFillType subjFillType = PolyFillType.EvenOdd, PolyFillType clipFillType = PolyFillType.EvenOdd)
        {
            if (_executeLocked)
                return false;
            _executeLocked = true;

            _subjFillType = subjFillType;
            _clipFillType = clipFillType;
            _clipType = clipType;
            _usingPolyTree = true;
            var succeeded = ExecuteInternal();

            //build the return polygons ...
            if (succeeded)
                BuildResultPolytree(polytree);

            _executeLocked = false;
            return succeeded;
        }
Exemplo n.º 46
0
        public override bool Read(GH_IO.Serialization.GH_IReader reader)
        {
            Operation = (ClipType)reader.GetInt32("Operation");
            FillType = (PolyFillType)reader.GetInt32("FillType");

            return base.Read(reader);
        }
Exemplo n.º 47
0
        // RAIL

        public void genrateRail()
        {
            // generate a rail for all three: difference, intersection, union


            if (inputs.Count == 0)
            {
                return;
            }


            PolyFillType subjPolyFillType = PolyFillType.pftNonZero;
            //if (hasHoles)
            //subjPolyFillType = PolyFillType.pftPositive;


            //* organize by solids, holes (from SOLID designation) and clippers (from VOID designation)
            Paths subjPaths = new Paths();
            Paths clipPaths = new Paths();

            AXParameter inp = null;
            AXParameter src = null;


            Paths segments = new Paths();
            Path  tmp      = null;


            for (int i = 0; i < inputs.Count; i++)
            {
                inp = inputs [i];
                src = inp.DependsOn;

                if (src == null)
                {
                    continue;
                }

                Paths srcPaths = src.getPaths();

                if (srcPaths == null)
                {
                    continue;
                }

                if (inp.polyType == PolyType.ptSubject)
                {
                    subjPaths.AddRange(srcPaths);


                    foreach (Path sp in srcPaths)
                    {
                        // When clipping open shapes, don't add a closingsegment:
                        int ender = (inp.shapeState == ShapeState.Open) ? sp.Count - 1 : sp.Count;

                        for (int j = 0; j < ender; j++)
                        {
                            int next_j = (j == sp.Count - 1) ? 0 : j + 1;
                            tmp = new Path();
                            tmp.Add(sp[j]);
                            tmp.Add(sp[next_j]);
                            segments.Add(tmp);
                        }
                    }

                    //subjPaths.AddRange (src.getTransformedHolePaths());
                }
                else if (inp.polyType == PolyType.ptClip)
                {
                    clipPaths.AddRange(srcPaths);
                    //clipPaths.AddRange (src.getTransformedHolePaths());
                }
                else
                {
                    continue;
                }
            }


            // turn subjs and holes into segments to be clipped
//			foreach(Path sp in subjPaths)
//			{
//				// each path
//				//int ender =
//				for(int i=0; i<sp.Count-1; i++)
//				{
//					int next_i = (i == sp.Count-1) ? 0 : i+1;
//					tmp = new Path();
//					tmp.Add (sp[i]);
//					tmp.Add (sp[next_i]);
//					segments.Add(tmp);
//				}
//			}

            //Debug.Log ("segments");
            //Archimatix.printPaths(segments);

            Clipper railc = new Clipper(Clipper.ioPreserveCollinear);

            if (segments != null)
            {
                railc.AddPaths(segments, PolyType.ptSubject, false);
            }

            if (clipPaths != null)
            {
                railc.AddPaths(clipPaths, PolyType.ptClip, true);
            }

            AXClipperLib.PolyTree solutionRail = new AXClipperLib.PolyTree();



            // DIFFERENCE_RAIL
            if ((differenceRail.Dependents != null && differenceRail.Dependents.Count > 0) || combineType == CombineType.DifferenceRail)
            {
                railc.Execute(ClipType.ctDifference, solutionRail, subjPolyFillType, PolyFillType.pftNonZero);

                differenceRail.polyTree = null;

                differenceRail.paths = assembleRailPathsFromClippedSegments(solutionRail);
                if (differenceRail.paths.Count == 0)
                {
                    differenceRail.paths = subjPaths;
                }

                alignPathsDirestionsWithSource(ref differenceRail.paths, ref segments);

                thickenAndOffset(ref differenceRail, differenceRail);
            }

            // INTERSECTION RAIL
            if ((intersectionRail.Dependents != null && intersectionRail.Dependents.Count > 0) || combineType == CombineType.IntersectionRail)
            {
                //railc.Execute(ClipType.ctIntersection, solutionRail, subjPolyFillType, PolyFillType.pftNonZero);
                railc.Execute(ClipType.ctIntersection, solutionRail, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

                intersectionRail.polyTree = null;

                intersectionRail.paths = assembleRailPathsFromClippedSegments(solutionRail);
                if (intersectionRail.paths.Count == 0)
                {
                    AXGeometryTools.Utilities.reversePaths(ref intersectionRail.paths);
                }

                alignPathsDirestionsWithSource(ref intersectionRail.paths, ref segments);

                thickenAndOffset(ref intersectionRail, intersectionRail);
            }
        }
Exemplo n.º 48
0
        /// <summary>
        ///     Joins all the polygones.
        ///     ClipType: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm
        ///     PolyFillType: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm
        /// </summary>
        /// <param name="sList">The s list.</param>
        /// <param name="cType">Type of the c.</param>
        /// <param name="pType">Type of the p.</param>
        /// <param name="pFType1">The p f type1.</param>
        /// <param name="pFType2">The p f type2.</param>
        /// <returns></returns>
        public static List<Polygon> ELJoinPolygons(this List<Polygon> sList, ClipType cType,
            PolyType pType = PolyType.ptClip, PolyFillType pFType1 = PolyFillType.pftNonZero,
            PolyFillType pFType2 = PolyFillType.pftNonZero)
        {
            var p = ELClipPolygons(sList);
            var tList = new List<List<IntPoint>>();

            var c = new Clipper();
            c.AddPaths(p, pType, true);
            c.Execute(cType, tList, pFType1, pFType2);

            return ToPolygons(tList);
        }
Exemplo n.º 49
0
        /// <summary>
        /// Convert self intersecting polygons into simple polygons
        /// </summary>
        /// <param name="polys"></param>
        /// <param name="fillType"></param>
        /// <returns></returns>
        public static List<List<IntPoint>> SimplifyPolygons(IEnumerable<List<IntPoint>> polys, PolyFillType fillType = PolyFillType.EvenOdd)
        {
            Contract.Requires(polys != null);
            Contract.Requires(Contract.ForAll(polys, a => a != null));
            Contract.Ensures(Contract.Result<List<List<IntPoint>>>() != null);

            var result = new List<List<IntPoint>>();
            var c = new Clipper { ForceSimple = true };
            c.AddPolygons(polys, PolyType.Subject);
            c.Execute(ClipType.Union, result, fillType, fillType);
            return result;
        }
 //------------------------------------------------------------------------------
 public bool Execute(ClipType clipType, ExPolygons solution,
     PolyFillType subjFillType, PolyFillType clipFillType)
 {
     if (m_ExecuteLocked) return false;
     m_ExecuteLocked = true;
     solution.Clear();
     m_SubjFillType = subjFillType;
     m_ClipFillType = clipFillType;
     m_ClipType = clipType;
     bool succeeded = ExecuteInternal(true);
     //build the return polygons ...
     if (succeeded) BuildResultEx(solution);
     m_ExecuteLocked = false;
     return succeeded;
 }
Exemplo n.º 51
0
        public bool Execute(ClipType clipType, List<List<IntPoint>> solution, PolyFillType subjFillType = PolyFillType.EvenOdd, PolyFillType clipFillType = PolyFillType.EvenOdd)
        {
            Contract.Requires(solution != null);

            if (_executeLocked)
                return false;
            _executeLocked = true;

            solution.Clear();
            _subjFillType = subjFillType;
            _clipFillType = clipFillType;
            _clipType = clipType;
            _usingPolyTree = false;
            var succeeded = ExecuteInternal();

            //build the return polygons ...
            if (succeeded)
                BuildResultPointList(solution);

            _executeLocked = false;
            return succeeded;
        }