GetFirst() public method

public GetFirst ( ) : PolyNode
return PolyNode
Esempio n. 1
0
        public List<DelaunayTriangle> TriangulateComplex(
         PolyTree polyTree,
         bool ignoreFills = false, bool ignoreHoles = true)
        {
            PolyNode rootNode;
             if (polyTree.Total == 0) {
            Console.WriteLine(0);
            rootNode = new PolyNode();
             } else {
            rootNode = polyTree.GetFirst().Parent;
             }

             // Equivalent to rootNode.Contour = bounds;
             var contourField = rootNode.GetType().GetField("m_polygon", BindingFlags.Instance | BindingFlags.NonPublic);
             if (contourField == null) {
            throw new Exception("Could not find field contour backing field.");
             }
             contourField.SetValue(rootNode, kTriangulatorBounds);

             var result = new List<DelaunayTriangle>();
             int i = 0;
             for (var currentNode = rootNode; currentNode != null; currentNode = currentNode.GetNext()) {
            if ((ignoreHoles && currentNode.IsHole) || (ignoreFills && !currentNode.IsHole)) continue;
            var polyline = DownscalePolygon(currentNode.Contour);
            var finalPolygon = new Polygon(polyline);
            foreach (var child in currentNode.Childs) {
               var shrunkContour = EdgeShrink(child.Contour);
               var holePoints = DownscalePolygon(shrunkContour);
               var holePoly = new Polygon(holePoints);
               finalPolygon.AddHole(holePoly);
            }
            P2T.Triangulate(finalPolygon);
            result.AddRange(finalPolygon.Triangles);
             }
             return result;
        }
Esempio n. 2
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();
        }
Esempio n. 3
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;
 }
Esempio n. 4
0
 private PolyTree Punch(PolyTree input, PolyTree hole)
 {
     var subtractClipper = new Clipper(Clipper.ioStrictlySimple);
      for (var it = input.GetFirst(); it != null; it = it.GetNext()) {
     subtractClipper.AddPath(it.Contour, PolyType.ptSubject, true);
      }
      for (var it = hole.GetFirst(); it != null; it = it.GetNext()) {
     subtractClipper.AddPath(it.Contour, PolyType.ptClip, true);
      }
      var result = new PolyTree();
      subtractClipper.Execute(ClipType.ctDifference, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
      return result;
 }
Esempio n. 5
0
 private PolyTree Offset(PolyTree input, double delta)
 {
     var clipperOffset = new ClipperOffset();
      for (var currentNode = input.GetFirst(); currentNode != null; currentNode = currentNode.GetNext()) {
     clipperOffset.AddPath(currentNode.Contour, JoinType.jtMiter, EndType.etClosedPolygon);
      }
      var result = new PolyTree();
      clipperOffset.Execute(ref result, delta);
      return result;
 }
Esempio n. 6
0
 private static void DrawPolyTree(PolyTree inputUnionTree)
 {
     var bitmap = new Bitmap(200, 200);
      using (var g = Graphics.FromImage(bitmap)) {
     const double kScale = kInverseClipperScaleFactor * 10;
     g.SmoothingMode = SmoothingMode.AntiAlias;
     for (var current = inputUnionTree.GetFirst(); current != null; current = current.GetNext()) {
        Console.WriteLine("Current Is Hole: " + current.IsHole);
        Console.WriteLine("Current Contour Count: " + current.Contour.Count);
        Console.WriteLine("Current Child Count: " + current.Childs.Count);
        for (var i = 0; i < current.Contour.Count; i++) {
           foreach (var child in current.Childs) {
              for (var j = 0; j < child.Contour.Count - 1; j++) {
                 for (var k = j + 1; k < child.Contour.Count; k++) {
                    var a = child.Contour[j];
                    var b = child.Contour[k];
                    g.DrawLine(Pens.Red, (float)(a.X * kScale), (float)(a.Y * kScale), (float)(b.X * kScale), (float)(b.Y * kScale));
                 }
              }
           }
           {
              var a = current.Contour[i];
              var b = current.Contour[(i + 1) % current.Contour.Count];
              g.DrawLine(Pens.Cyan, (float)(a.X * kScale), (float)(a.Y * kScale), (float)(b.X * kScale), (float)(b.Y * kScale));
           }
        }
     }
      }
      NaviUtil.ShowBitmap(bitmap);
 }