示例#1
0
    private List <DelaunayTriangle> GenerateTriangles()
    {
        List <DelaunayTriangle> triangles = new List <DelaunayTriangle>();

        Dictionary <PolyNode, Polygon> dict = new Dictionary <PolyNode, Polygon>();
        PolyNode curt = m_polyTree.GetFirst();

        while (curt != null)
        {
            var polygon = Convert(curt.Contour);
            dict.Add(curt, polygon);

            if (curt.IsHole && curt.Parent != null)
            {
                dict[curt.Parent].AddHole(polygon);
            }

            curt = curt.GetNext();
        }

        foreach (var pair in dict)
        {
            var node = pair.Key;
            var poly = pair.Value;

            if (node.IsHole == false)
            {
                P2T.Triangulate(poly);
                triangles.AddRange(poly.Triangles);
            }
        }

        return(triangles);
    }
示例#2
0
        public virtual void GetFistChildInPolyTreeTest()
        {
            PolyTree tree        = new PolyTree();
            PolyNode firstChild  = new PolyNode();
            PolyNode secondChild = new PolyNode();

            tree.AddChild(firstChild);
            tree.AddChild(secondChild);
            NUnit.Framework.Assert.AreSame(firstChild, tree.GetFirst());
        }
示例#3
0
        /// <summary>
        /// Converts Clipper library
        /// <see cref="PolyTree"/>
        /// abstraction into iText
        /// <see cref="iText.Kernel.Geom.Path"/>
        /// object.
        /// </summary>
        public static Path ConvertToPath(PolyTree result)
        {
            Path     path = new Path();
            PolyNode node = result.GetFirst();

            while (node != null)
            {
                AddContour(path, node.Contour, !node.IsOpen);
                node = node.GetNext();
            }
            return(path);
        }
示例#4
0
        private Paths PolyTreeToPolygons(PolyTree tree)
        {
            Paths    p = new Paths();
            PolyNode n = tree.GetFirst();

            while (null != n)
            {
                p.Add(n.Contour);
                n = n.GetNext();
            }
            return(p);
        }
        public List <PointF[]> Triangulate(PolyTree solution)
        {
            List <PointF[]> list = new List <PointF[]>();
            Tess            tess = new Tess();

            tess.NoEmptyPolygons = true;
            Func <IntPoint, ContourVertex> selector = delegate(IntPoint p)
            {
                ContourVertex result = default(ContourVertex);
                result.Position = new Vec3
                {
                    X = (float)p.X,
                    Y = (float)p.Y,
                    Z = 0f
                };
                return(result);
            };

            for (PolyNode polyNode = solution.GetFirst(); polyNode != null; polyNode = polyNode.GetNext())
            {
                if (!polyNode.IsOpen)
                {
                    ContourVertex[] vertices = polyNode.Contour.Select(selector).ToArray();
                    tess.AddContour(vertices);
                }
            }
            tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
            int elementCount = tess.ElementCount;

            for (int i = 0; i < elementCount; i++)
            {
                Vec3          position  = tess.Vertices[tess.Elements[i * 3 + 0]].Position;
                Vec3          position2 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
                Vec3          position3 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;
                List <PointF> list2     = new List <PointF>
                {
                    new PointF(position.X, position.Y),
                    new PointF(position2.X, position2.Y),
                    new PointF(position3.X, position3.Y)
                };
                if (Math.Cross(list2[0], list2[1], list2[2]) > 0f)
                {
                    list2.Reverse();
                }
                list.Add(list2.ToArray());
            }
            return(list);
        }
示例#6
0
        public IEnumerable <LineStrip> GetLines(LineType type)
        {
            PolyNode n = polyTree.GetFirst();

            while (null != n)
            {
                bool hole = n.IsHole;
                if (type == LineType.All || (hole && type == LineType.Hole) || (!hole && type == LineType.Outside))
                {
                    yield return(LineStripFromPolygon(n.Contour));
                }
                n = n.GetNext();
            }
        }
示例#7
0
        public virtual void GetFistChildInEmptyPolyTreeTest()
        {
            PolyTree tree = new PolyTree();

            NUnit.Framework.Assert.IsNull(tree.GetFirst());
        }
示例#8
0
        private static Path ConvertToPath(PolyTree result) {
            Path path = new Path();
            PolyNode node = result.GetFirst();

            while (node != null) {
                AddContour(path, node.Contour, !node.IsOpen);
                node = node.GetNext();
            }

            return path;
        }
示例#9
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();
        }