public static bool addSteinerPointsAtOffset(ref Polygon _polygon, ref ClipperOffset co, float offset, int seglenBigInt) { PolyTree resPolytree = new AXClipperLib.PolyTree(); co.Execute(ref resPolytree, (double)(-offset * AXGeometryTools.Utilities.IntPointPrecision)); Paths paths = Clipper.PolyTreeToPaths(resPolytree); if (paths != null && paths.Count > 0 && paths[0] != null && paths[0].Count > 0) { foreach (Path path in paths) { if (path != null && path.Count > 0) { Path ppp = Pather.segmentPath(path, seglenBigInt); if (ppp != null && ppp.Count > 0) { foreach (IntPoint ip in ppp) { _polygon.AddSteinerPoint(new TriangulationPoint((double)ip.X / (double)AXGeometryTools.Utilities.IntPointPrecision, (double)ip.Y / (double)AXGeometryTools.Utilities.IntPointPrecision)); } } } } return(true); } return(false); }
/* bridges to poly2tri * */ public static Mesh triangulate(Path path, AXTexCoords tex, int seglen = 0) { /* Assume a single path with no holes * and return a mesh. */ if (path == null || path.Count < 3) { return(null); } if (path[path.Count - 1].X == path[0].X && path[path.Count - 1].Y == path[0].Y) { path.RemoveAt(path.Count - 1); } else if (AXGeometryTools.Utilities.IntPointsAreNear(path[0], path[path.Count - 1])) { path.RemoveAt(path.Count - 1); } //Paths tmpPaths = Clipper.SimplifyPolygon (path); //CombineInstance[] combinator = new CombineInstance[tmpPaths.Count]; //for (int i = 0; i < tmpPaths.Count; i++) { Mesh mesh = null; PolygonPoints _points; // = AXGeometryTools.Utilities.path2polygonPts (Pather.cleanPath(path)); if (seglen > 0) { _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(path), seglen)); } else { _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(path)); } Polygon _polygon = null; if (_points.Count >= 3) { _polygon = new Polygon(_points); if (_polygon != null) { try { // Testing Steiner // for (int j = -10; j<10; j++) // { // for (int k = -10; k<10; k++) // _polygon.AddSteinerPoint(new TriangulationPoint(.1f*j, k*.1f)); // } P2T.Triangulate(_polygon); //foreach (DelaunayTriangle triangle in _polygon.Triangles) mesh = polygon2mesh(_polygon, tex); } catch { Debug.Log("Can't triangulate: probably point on edge."); } } //combinator[i].mesh = mesh; //combinator [i].transform = Matrix4x4.identity; //return mesh; //} } // Mesh returnMesh = new Mesh(); // returnMesh.CombineMeshes(combinator); // return returnMesh; return(mesh); }
public static Mesh triangulatePolyNode(PolyNode node, AXTexCoords tex, int seglenBigInt = 1000000) { //Debug.Log ("D " + seglenBigInt); Polygon _polygon = null; if (seglenBigInt < 10) { seglenBigInt = 999999; } List <Mesh> meshes = new List <Mesh>(); // Contour is Solid PolygonPoints _points = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(node.Contour), seglenBigInt)); } else { _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(node.Contour)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); } //Debug.Log ("_polygon="+_points.Count); // ADD HOLES TO POLYGON foreach (PolyNode subnode in node.Childs) { PolygonPoints hpoints = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { hpoints = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(subnode.Contour), seglenBigInt)); } else { hpoints = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(subnode.Contour)); } if (hpoints.Count >= 3) { _polygon.AddHole(new Polygon(hpoints)); } } try { // STEINER POINTS ClipperOffset co = new ClipperOffset(); co.AddPath(node.Contour, AXClipperLib.JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon); //addSteinerPointsAtAllOffsets(ref _polygon, ref co, seglenBigInt/AXGeometryTools.Utilities.IntPointPrecision, seglenBigInt); addSteinerPointsAtAllOffsets(ref _polygon, ref co, (float)seglenBigInt / ((float)AXGeometryTools.Utilities.IntPointPrecision), seglenBigInt); P2T.Triangulate(_polygon); meshes.Add(polygon2mesh(_polygon, tex)); } catch { //Debug.Log ("Can't triangulate: probably point on edge."); } // Continue down the tree... /* * foreach(PolyNode cnode in node.Childs) * { * Mesh submesh = triangulatePolyNode(cnode, tex); * if (submesh != null) * meshes.Add(submesh); * } */ CombineInstance[] combine = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { combine[i].mesh = meshes[i]; combine[i].transform = Matrix4x4.identity; } Mesh mesh = new Mesh(); mesh.CombineMeshes(combine); mesh.RecalculateNormals(); return(mesh); }
public static Mesh triangulate(List <PolyNode> childs, AXTexCoords tex, int seglenBigInt = 1000000) { //Debug.Log ("C " + seglenBigInt); Polygon _polygon = null; List <Mesh> meshes = new List <Mesh>(); if (seglenBigInt < 10) { seglenBigInt = 100000; } //int count = 0; foreach (PolyNode node in childs) { // Contour is Solid // List<TriangulationPoint> tripoints = new List<TriangulationPoint>(); // // // Testing Steiner // int cells = 6; // for (int j = -cells/2; j<cells/2; j++) // { // for (int k = -cells/3; k<cells/2; k++) // if (Clipper.PointInPolygon( AXGeometryTools.Utilities.Vec2_2_IntPt(new Vector2(2f*j, k*2f)), node.Contour) > 0) // { // //Debug.Log("add steiner " + .4f*j +", " + k*.2f); // tripoints.Add(new TriangulationPoint(.4f*j, k*.2f)); // } // } PolygonPoints _points = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(node.Contour), seglenBigInt)); } else { _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(node.Contour)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); } // ADD HOLES TO POLYGON foreach (PolyNode subnode in node.Childs) { PolygonPoints hpoints = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { hpoints = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(subnode.Contour), seglenBigInt)); } else { hpoints = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(subnode.Contour)); } if (hpoints.Count >= 3) { _polygon.AddHole(new Polygon(hpoints)); } } try { // STEINER POINTS ClipperOffset co = new ClipperOffset(); co.AddPath(node.Contour, AXClipperLib.JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon); addSteinerPointsAtAllOffsets(ref _polygon, ref co, (float)seglenBigInt / ((float)AXGeometryTools.Utilities.IntPointPrecision), seglenBigInt); P2T.Triangulate(_polygon); meshes.Add(polygon2mesh(_polygon, tex)); } catch { //Debug.Log ("Can't triangulate: probably point on edge."); } // Continue down the tree... foreach (PolyNode cnode in node.Childs) { Mesh submesh = triangulate(cnode, tex); if (submesh != null) { meshes.Add(submesh); } } } CombineInstance[] combine = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { combine[i].mesh = meshes[i]; combine[i].transform = Matrix4x4.identity; } Mesh mesh = new Mesh(); mesh.CombineMeshes(combine); mesh.RecalculateNormals(); return(mesh); }