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); }
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()); }
/// <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); }
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); }
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(); } }
public virtual void GetFistChildInEmptyPolyTreeTest() { PolyTree tree = new PolyTree(); NUnit.Framework.Assert.IsNull(tree.GetFirst()); }
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; }
//------------------------------------------------------------------------------ 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(); }