public Tessellate ( WindingRule windingRule, ElementType elementType, int polySize ) : void | ||
windingRule | WindingRule | |
elementType | ElementType | |
polySize | int | |
Результат | void |
public static void GenerateTestData() { foreach (var name in _loader.AssetNames) { var pset = _loader.GetAsset(name).Polygons; var lines = new List<string>(); var indices = new List<int>(); foreach (WindingRule winding in Enum.GetValues(typeof(WindingRule))) { var tess = new Tess(); PolyConvert.ToTess(pset, tess); tess.Tessellate(winding, ElementType.Polygons, 3); lines.Add(string.Format("{0} {1}", winding, 3)); for (int i = 0; i < tess.ElementCount; i++) { indices.Clear(); for (int j = 0; j < 3; j++) { int index = tess.Elements[i * 3 + j]; indices.Add(index); } lines.Add(string.Join(" ", indices)); } lines.Add(""); } File.WriteAllLines(Path.Combine(TestDataPath, name + ".testdat"), lines); } }
/// <summary> /// Creates a triangulation of the vertices given, and gives you the indices of it. /// </summary> /// <param name="aPoints">A list of points to triangulate.</param> /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param> /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param> /// <returns>A magical list of indices describing the triangulation!</returns> public static List <int> GetIndices(ref List <Vector2> aPoints, bool aTreatAsPath, bool aInvert) { Vector4 bounds = GetBounds(aPoints); LibTessDotNet.Tess tess = new LibTessDotNet.Tess(); LibTessDotNet.ContourVertex[] verts = new LibTessDotNet.ContourVertex[aPoints.Count]; for (int i = 0; i < aPoints.Count; i++) { verts[i] = new LibTessDotNet.ContourVertex(); verts[i].Position = new LibTessDotNet.Vec3(); verts[i].Position.X = aPoints[i].x; verts[i].Position.Y = aPoints[i].y; verts[i].Position.Z = 0; } tess.AddContour(verts, LibTessDotNet.ContourOrientation.Original); if (aInvert) { aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 4 aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 3 aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 2 aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 1 LibTessDotNet.ContourVertex[] outer = new LibTessDotNet.ContourVertex[4]; for (int i = 0; i < 4; i++) { outer[i] = new LibTessDotNet.ContourVertex(); outer[i].Position = new LibTessDotNet.Vec3(); outer[i].Position.X = aPoints[(aPoints.Count - 4) + i].x; outer[i].Position.Y = aPoints[(aPoints.Count - 4) + i].y; outer[i].Position.Z = 0; } tess.AddContour(outer, aInvert ? LibTessDotNet.ContourOrientation.CounterClockwise : LibTessDotNet.ContourOrientation.Clockwise); } tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); List <int> result = new List <int>(); for (int i = 0; i < tess.Elements.Length; i += 3) { for (int t = 0; t < 3; t++) { if (tess.Elements[i + t] == -1) { continue; } for (int v = 0; v < aPoints.Count; v++) { if (aPoints[v].x == tess.Vertices[tess.Elements[i + t]].Position.X && aPoints[v].y == tess.Vertices[tess.Elements[i + t]].Position.Y) { result.Add(v); break; } } } } return(result); }
/// <summary> /// Creates a triangulation of the vertices given, and gives you the indices of it. /// </summary> /// <param name="aPoints">A list of points to triangulate.</param> /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param> /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param> /// <returns>A magical list of indices describing the triangulation!</returns> public static List<int> GetIndices(ref List<Vector2> aPoints, bool aTreatAsPath, bool aInvert) { Vector4 bounds = GetBounds(aPoints); LibTessDotNet.Tess tess = new LibTessDotNet.Tess(); LibTessDotNet.ContourVertex[] verts = new LibTessDotNet.ContourVertex[aPoints.Count]; for (int i = 0; i < aPoints.Count; i++) { verts[i] = new LibTessDotNet.ContourVertex(); verts[i].Position = new LibTessDotNet.Vec3(); verts[i].Position.X = aPoints[i].x; verts[i].Position.Y = aPoints[i].y; verts[i].Position.Z = 0; } tess.AddContour(verts, LibTessDotNet.ContourOrientation.Original); if (aInvert) { aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 4 aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 3 aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 2 aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 1 LibTessDotNet.ContourVertex[] outer = new LibTessDotNet.ContourVertex[4]; for (int i = 0; i < 4; i++) { outer[i] = new LibTessDotNet.ContourVertex(); outer[i].Position = new LibTessDotNet.Vec3(); outer[i].Position.X = aPoints[(aPoints.Count - 4) + i].x; outer[i].Position.Y = aPoints[(aPoints.Count - 4) + i].y; outer[i].Position.Z = 0; } tess.AddContour(outer, aInvert ? LibTessDotNet.ContourOrientation.CounterClockwise : LibTessDotNet.ContourOrientation.Clockwise); } tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); List<int> result = new List<int>(); for (int i = 0; i < tess.Elements.Length; i += 3) { for (int t = 0; t < 3; t++) { if (tess.Elements[i + t] == -1) { continue; } for (int v = 0; v < aPoints.Count; v++) { if (aPoints[v].x == tess.Vertices[tess.Elements[i + t]].Position.X && aPoints[v].y == tess.Vertices[tess.Elements[i + t]].Position.Y) { result.Add(v); break; } } } } return result; }
public static Cad2D.Polygon Tesselate(List <Cad2D.Polygon> Polygons) { // Create an instance of the tessellator. Can be reused. var tess = new LibTessDotNet.Tess(); // Construct the contours from input polygons // A polygon can be composed of multiple contours which are all tessellated at the same time. foreach (Cad2D.Polygon poly in Polygons) { int numPoints = poly.Vertices.Count; var contour = new LibTessDotNet.ContourVertex[numPoints]; for (int i = 0; i < numPoints; i++) { // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important. contour[i].Position = new LibTessDotNet.Vec3 { X = poly.Vertices[i].X, Y = poly.Vertices[i].Y, Z = 0.0f }; // Data can contain any per-vertex data, here a constant color. contour[i].Data = Color.Azure; } // Add the contour with a specific orientation, use "Original" if you want to keep the input orientation. tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise); } // Tessellate! // The winding rule determines how the different contours are combined together. // See http://www.glprogramming.com/red/chapter11.html (section "Winding Numbers and Winding Rules") for more information. // If you want triangles as output, you need to use "Polygons" type as output and 3 vertices per polygon. tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine); // Same call but the last callback is optional. Data will be null because no interpolated data would have been generated. //tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); // Some vertices will have null Data in this case. Cad2D.Polygon result = new Cad2D.Polygon(); int numTriangles = tess.ElementCount; result.Triangles = new List <Cad2D.Triangle>(); for (int i = 0; i < numTriangles; i++) { var v0 = tess.Vertices[tess.Elements[i * 3]].Position; var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position; var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position; result.Triangles.Add(new Cad2D.Triangle(v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y)); } return(result); }
static void Main(string[] args) { // Example input data in the form of a star that intersects itself. var inputData = new float[] { 0.0f, 3.0f, -1.0f, 0.0f, 1.6f, 1.9f, -1.6f, 1.9f, 1.0f, 0.0f }; // Create an instance of the tessellator. Can be reused. var tess = new LibTessDotNet.Tess(); // Construct the contour from inputData. // A polygon can be composed of multiple contours which are all tessellated at the same time. int numPoints = inputData.Length / 2; var contour = new LibTessDotNet.ContourVertex[numPoints]; for (int i = 0; i < numPoints; i++) { // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important. contour[i].Position = new LibTessDotNet.Vec3 { X = inputData[i * 2], Y = inputData[i * 2 + 1], Z = 0.0f }; // Data can contain any per-vertex data, here a constant color. contour[i].Data = Color.Azure; } // Add the contour with a specific orientation, use "Original" if you want to keep the input orientation. tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise); // Tessellate! // The winding rule determines how the different contours are combined together. // See http://www.glprogramming.com/red/chapter11.html (section "Winding Numbers and Winding Rules") for more information. // If you want triangles as output, you need to use "Polygons" type as output and 3 vertices per polygon. tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine); // Same call but the last callback is optional. Data will be null because no interpolated data would have been generated. //tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); // Some vertices will have null Data in this case. Console.WriteLine("Output triangles:"); int numTriangles = tess.ElementCount; for (int i = 0; i < numTriangles; i++) { var v0 = tess.Vertices[tess.Elements[i * 3]].Position; var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position; var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position; Console.WriteLine("#{0} ({1:F1},{2:F1}) ({3:F1},{4:F1}) ({5:F1},{6:F1})", i, v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y); } Console.ReadLine(); }
static void Main(string[] args) { // Example input data in the form of a star that intersects itself. var inputData = new float[] { 0.0f, 3.0f, -1.0f, 0.0f, 1.6f, 1.9f, -1.6f, 1.9f, 1.0f, 0.0f }; // Create an instance of the tessellator. Can be reused. var tess = new LibTessDotNet.Tess(); // Construct the contour from inputData. // A polygon can be composed of multiple contours which are all tessellated at the same time. int numPoints = inputData.Length / 2; var contour = new LibTessDotNet.ContourVertex[numPoints]; for (int i = 0; i < numPoints; i++) { // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important. contour[i].Position = new LibTessDotNet.Vec3 { X = inputData[i * 2], Y = inputData[i * 2 + 1], Z = 0.0f }; // Data can contain any per-vertex data, here a constant color. contour[i].Data = Color.Azure; } // Add the contour with a specific orientation, use "Original" if you want to keep the input orientation. tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise); // Tessellate! // The winding rule determines how the different contours are combined together. // See http://www.glprogramming.com/red/chapter11.html (section "Winding Numbers and Winding Rules") for more information. // If you want triangles as output, you need to use "Polygons" type as output and 3 vertices per polygon. tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine); // Same call but the last callback is optional. Data will be null because no interpolated data would have been generated. //tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); // Some vertices will have null Data in this case. Console.WriteLine("Output triangles:"); int numTriangles = tess.ElementCount; for (int i = 0; i < numTriangles; i++) { var v0 = tess.Vertices[tess.Elements[i * 3]].Position; var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position; var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position; Console.WriteLine("#{0} ({1:F1},{2:F1}) ({3:F1},{4:F1}) ({5:F1},{6:F1})", i, v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y); } Console.ReadLine(); }
static void Main(string[] args) { if (args.Length >= 1) { if (string.Equals(args[0], "gentestdat", StringComparison.OrdinalIgnoreCase)) { UnitTests.GenerateTestData(); } if (args.Length == 2 && string.Equals(args[0], "profile", StringComparison.OrdinalIgnoreCase)) { int count = 0; if (!int.TryParse(args[1], out count)) { return; } var stopwatch = new Stopwatch(); var loader = new DataLoader(); for (int i = 0; i < count; i++) { foreach (var name in loader.AssetNames) { var pset = loader.GetAsset(name).Polygons; foreach (WindingRule winding in Enum.GetValues(typeof(WindingRule))) { var tess = new Tess(); PolyConvert.ToTess(pset, tess); stopwatch.Start(); tess.Tessellate(winding, ElementType.Polygons, 3); stopwatch.Stop(); } } } Console.WriteLine("{0:F3}ms", stopwatch.Elapsed.TotalMilliseconds); } return; } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); }
private void adaptate() { if (!this.aad.isRectangular() && this.aad.getInfluenceArea() != null) { this.transform.localScale = new Vector3(1, 1, 1); Mesh mesh = new Mesh(); List <Vector3> vertices = new List <Vector3>(); Tess tess = new LibTessDotNet.Tess(); ContourVertex[] contour = new ContourVertex[aad.getPoints().Count]; int i = 0; float minx = float.MaxValue, miny = float.MaxValue, maxx = 0, maxy = 0; foreach (Vector2 v in this.aad.getPoints()) { if (v.x < minx) { minx = v.x; } if (v.x > maxx) { maxx = v.x; } if (v.y < miny) { miny = v.y; } if (v.y > maxy) { maxy = v.y; } } minx = (minx + (maxx - minx) / 2) / 10; miny = 60 - (miny + (maxy - miny) / 2) / 10; foreach (Vector2 v in this.aad.getPoints()) { contour[i].Position = new LibTessDotNet.Vec3 { X = v.x / 10f - minx, Y = 60 - v.y / 10f - miny, Z = this.transform.position.z }; i++; } tess.AddContour(contour, LibTessDotNet.ContourOrientation.CounterClockwise); tess.Tessellate(WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); List <int> triangles = new List <int>(); int numTriangles = tess.ElementCount; for (i = 0; i < numTriangles; i++) { vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3]].Position)); vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 1]].Position)); vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 2]].Position)); triangles.AddRange(new int[] { i * 3, i * 3 + 1, i * 3 + 2 }); } mesh.SetVertices(vertices); mesh.SetTriangles(triangles, 0); this.GetComponent <MeshFilter>().sharedMesh = mesh; this.GetComponent <MeshCollider>().sharedMesh = mesh; } }
public void Tessellate_WithAsset_ReturnsExpectedTriangulation(TestCaseData data) { var pset = _loader.GetAsset(data.AssetName).Polygons; var tess = new Tess(); PolyConvert.ToTess(pset, tess); tess.Tessellate(data.Winding, ElementType.Polygons, data.ElementSize); var resourceName = Assembly.GetExecutingAssembly().GetName().Name + ".TestData." + data.AssetName + ".testdat"; var testData = ParseTestData(data.Winding, data.ElementSize, Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)); Assert.IsNotNull(testData); Assert.AreEqual(testData.ElementSize, data.ElementSize); var indices = new List<int>(); for (int i = 0; i < tess.ElementCount; i++) { for (int j = 0; j < data.ElementSize; j++) { int index = tess.Elements[i * data.ElementSize + j]; indices.Add(index); } } Assert.AreEqual(testData.Indices, indices.ToArray()); }
public void Tesselate_WithThinQuad_DoesNotCrash() { string data = "9.5,7.5,-0.5\n9.5,2,-0.5\n9.5,2,-0.4999999701976776123\n9.5,7.5,-0.4999999701976776123"; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data))) { var pset = DataLoader.LoadDat(stream); var tess = new Tess(); PolyConvert.ToTess(pset, tess); tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); } }
public void Tesselate_WithSingleTriangle_ProducesSameTriangle() { string data = "0,0,0\n0,1,0\n1,1,0"; var indices = new List<int>(); var expectedIndices = new int[] { 0, 1, 2 }; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data))) { var pset = DataLoader.LoadDat(stream); var tess = new Tess(); PolyConvert.ToTess(pset, tess); tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); indices.Clear(); for (int i = 0; i < tess.ElementCount; i++) { for (int j = 0; j < 3; j++) { int index = tess.Elements[i * 3 + j]; indices.Add(index); } } Assert.AreEqual(expectedIndices, indices.ToArray()); } }
public void Tesselate_WithNoEmptyPolygonsTrue_RemovesEmptyPolygons() { string data = "2,0,4\n2,0,2\n4,0,2\n4,0,0\n0,0,0\n0,0,4"; var indices = new List<int>(); var expectedIndices = new int[] { 0, 1, 2, 2, 3, 4, 3, 1, 5 }; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data))) { var pset = DataLoader.LoadDat(stream); var tess = new Tess(); PolyConvert.ToTess(pset, tess); tess.NoEmptyPolygons = true; tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); indices.Clear(); for (int i = 0; i < tess.ElementCount; i++) { for (int j = 0; j < 3; j++) { int index = tess.Elements[i * 3 + j]; indices.Add(index); } } Assert.AreEqual(expectedIndices, indices.ToArray()); } }
public void Tesselate_WithIssue1Quad_ReturnsSameResultAsLibtess2() { string data = "50,50\n300,50\n300,200\n50,200"; var indices = new List<int>(); var expectedIndices = new int[] { 0, 1, 2, 1, 0, 3 }; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data))) { var pset = DataLoader.LoadDat(stream); var tess = new Tess(); PolyConvert.ToTess(pset, tess); tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); indices.Clear(); for (int i = 0; i < tess.ElementCount; i++) { for (int j = 0; j < 3; j++) { int index = tess.Elements[i * 3 + j]; indices.Add(index); } } Assert.AreEqual(expectedIndices, indices.ToArray()); } }
private void adaptate() { if (!this.aad.isRectangular() && this.aad.getInfluenceArea () != null) { this.transform.localScale = new Vector3 (1, 1, 1); Mesh mesh = new Mesh (); List<Vector3> vertices = new List<Vector3> (); List<Vector2> vertices2 = new List<Vector2> (); Tess tess = new LibTessDotNet.Tess(); ContourVertex[] contour = new ContourVertex[aad.getPoints().Count]; int i = 0; float minx = float.MaxValue, miny = float.MaxValue, maxx = 0, maxy = 0; foreach (Vector2 v in this.aad.getPoints()) { if (v.x < minx) minx = v.x; if (v.x > maxx) maxx = v.x; if (v.y < miny) miny = v.y; if (v.y > maxy) maxy = v.y; } minx = (minx + (maxx - minx) / 2 ) / 10; miny = 60 - (miny + (maxy - miny) / 2 ) / 10; foreach (Vector2 v in this.aad.getPoints()) { contour[i].Position = new LibTessDotNet.Vec3 { X = v.x / 10f - minx, Y = 60 - v.y / 10f - miny, Z = this.transform.position.z }; i++; } tess.AddContour(contour, LibTessDotNet.ContourOrientation.CounterClockwise); tess.Tessellate(WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons,3); Debug.Log("Output triangles:"); List<int> triangles = new List<int> (); int numTriangles = tess.ElementCount; for (i = 0; i < numTriangles; i++){ vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3]].Position)); vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 1]].Position)); vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 2]].Position)); triangles.AddRange(new int[] { i * 3, i * 3+1, i * 3+2 }); } mesh.SetVertices (vertices); mesh.SetTriangles (triangles,0); this.GetComponent<MeshFilter> ().sharedMesh = mesh; this.GetComponent<MeshCollider> ().sharedMesh = mesh; } }
public void DrawPath(Path path, VBO vbo) { List <List <Vector2> > shapes = new List <List <Vector2> >(); List <Vector2> positions = new List <Vector2>(); List <Vector2> tesselated = new List <Vector2>(); Point position = new Point(); foreach (var op in path.Operations) { var mt = op as MoveTo; if (mt != null) { shapes.Add(positions); positions = new List <Vector2>(); positions.Add(Vec2(mt.Point)); position = mt.Point; continue; } var lt = op as LineTo; if (lt != null) { positions.Add(Vec2(lt.Point)); position = lt.Point; continue; } var at = op as ArcTo; if (at != null) { var p = nsvg.nsvg__pathArcTo((Vector2d)Vec2(position), at); positions.AddRange(p); position = at.Point; continue; } var ct = op as CurveTo; if (ct != null) { if (double.IsNaN(ct.Control1.X) && double.IsNaN(ct.Control1.Y)) { BezierCurveQuadric b = new BezierCurveQuadric(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control2)); Vector2 old = b.CalculatePoint(0f); positions.Add(old); var precision = 0.05f; for (float i = precision; i < 1f + precision; i += precision) { Vector2 j = b.CalculatePoint(i); positions.Add(j); old = j; } } else { BezierCurveCubic b = new BezierCurveCubic(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control1), Vec2(ct.Control2)); Vector2 old = b.CalculatePoint(0f); positions.Add(old); var precision = 0.05f; for (float i = precision; i < 1f + precision; i += precision) { Vector2 j = b.CalculatePoint(i); positions.Add(j); } } position = ct.EndPoint; } var cp = op as ClosePath; if (cp != null) { if (positions.Count > 0) { positions.Add(positions[0]); shapes.Add(positions); } positions = new List <Vector2>(); position = new Point(); continue; } } shapes.Add(positions); brushcheck(path.Brush); LibTessDotNet.Tess t = new LibTessDotNet.Tess(); List <Vec3> vertices = new List <Vec3>(); foreach (var s in shapes) { ContourVertex[] cv = new ContourVertex[s.Count]; for (int i = 0; i < s.Count; i++) { var v = s[i]; cv[i] = new ContourVertex() { Position = new Vec3() { X = v.X, Y = v.Y } }; } t.AddContour(cv); } var rule = LibTessDotNet.WindingRule.NonZero; if (path.Brush != null) { rule = path.Brush.FillMode == FillMode.EvenOdd ? LibTessDotNet.WindingRule.EvenOdd : LibTessDotNet.WindingRule.NonZero; } t.Tessellate(rule, LibTessDotNet.ElementType.Polygons, 3); for (var i = 0; i < t.ElementCount; i++) { for (var tri = 0; tri < 3; tri++) { vertices.Add(t.Vertices[t.Elements[(i * 3) + tri]].Position); } } for (int i = 0; i < vertices.Count; i++) { tesselated.Add(new Vector2(vertices[i].X, vertices[i].Y)); } var lineshapes = new List <List <Vector2> >(); foreach (var s in shapes) { if (s.Count == 0) { continue; } List <Vector2> add = new List <Vector2>(); for (int i = 0; i < s.Count; i++) { add.Add(new Vector2(s[i].X, s[i].Y)); } lineshapes.Add(add); } if (path.Brush is SolidBrush || path.Pen != null) { if (path.Brush is SolidBrush) { var sb = path.Brush as SolidBrush; for (int i = 0; i < tesselated.Count; i++) { vbo.AddVertex(new Vertex(tesselated[i], color(sb.Color))); } } if (path.Pen != null) { foreach (var list in lineshapes) { foreach (var v in TesselateLines(list, path.Pen)) { vbo.AddVertex(v); } } } } }
private List <Vertex> TesselateLines(List <Vector2> points, Pen p) { List <ContourVertex> vecs = new List <ContourVertex>(); List <Vertex> ret = new List <Vertex>(); if (points.Count < 2) { return(ret); } var co = color(p.Color); MatterHackers.Agg.VertexSource.PathStorage ps = new MatterHackers.Agg.VertexSource.PathStorage(); ps.remove_all(); ps.MoveTo(points[0].X, points[0].Y); for (int i = 1; i < points.Count; i++) { ps.LineTo(points[i].X, points[i].Y); } ps.end_poly(); MatterHackers.Agg.VertexSource.Stroke str = new MatterHackers.Agg.VertexSource.Stroke(ps, p.Width); switch (p.Join) { case LineJoin.Round: str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Round); str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Round); break; case LineJoin.Miter: str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Miter); str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Miter); str.inner_miter_limit(p.MiterLimit); str.miter_limit(p.MiterLimit); break; } switch (p.Cap) { case LineCaps.Butt: str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Butt); break; case LineCaps.Round: str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Round); break; case LineCaps.Square: str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Square); break; } str.rewind(0); double x, y; LibTessDotNet.Tess t = new LibTessDotNet.Tess(); ShapePath.FlagsAndCommand cmd; do { cmd = str.vertex(out x, out y); if (ShapePath.is_vertex(cmd)) { vecs.Add(new ContourVertex() { Position = new Vec3() { X = (float)x, Y = (float)y } }); } if (ShapePath.is_end_poly(cmd)) { t.AddContour(vecs.ToArray()); vecs.Clear(); } } while (!ShapePath.is_stop(cmd)); /* * foreach (var v in vertices) * { * if (!ShapePath.is_close(v.command) && !ShapePath.is_stop(v.command)) * vecs.Add(new Vector2((float)v.position.x, (float)v.position.y)); * }*/ if (vecs.Count != 0) { t.AddContour(vecs.ToArray()); } t.Tessellate(LibTessDotNet.WindingRule.NonZero, LibTessDotNet.ElementType.Polygons, 3); for (var i = 0; i < t.ElementCount; i++) { for (var tri = 0; tri < 3; tri++) { var v = t.Vertices[t.Elements[(i * 3) + tri]].Position; ret.Add(new Vertex(v.X, v.Y, co)); } } return(ret); }
void StartOld() { OsmBuilding building = Data.Instance.buildings [buildingId]; //float[] points = building.getPolygon (); Vector3[] points = building.getPolygonAsVector3 (); var tess = new LibTessDotNet.Tess(); //Debug.Log ("-" + buildingId); var contour = new LibTessDotNet.ContourVertex[points.Length]; for (int i = 0; i < points.Length; i++) { // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important. contour[i].Position = new LibTessDotNet.Vec3 { X = points[i].x, Y = points[i].y, Z = points[i].z }; // Data can contain any per-vertex data, here a constant color. contour[i].Data = Color.cyan; if (i != points.Length-1) { Debug.DrawLine(points [i], points [i + 1],Color.red,2000f); } } tess.AddContour(contour, LibTessDotNet.ContourOrientation.Original); tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine); //gameObject.AddComponent<MeshFilter>(); //gameObject.AddComponent<MeshRenderer>(); Mesh mesh = new Mesh (); mesh.Clear(); mesh.name = "Building"; mesh.vertices = points; mesh.RecalculateNormals(); mesh.RecalculateBounds(); Vector2[] uvs = new Vector2[points.Length]; Bounds bounds = mesh.bounds; for(int i = 0; i < points.Length; i++) { uvs[i] = new Vector2(points[i].x / bounds.size.x, points[i].z / bounds.size.x); } mesh.uv = uvs; mesh.triangles = tess.Elements; GameObject meshObject = new GameObject (); meshObject.AddComponent<MeshFilter> ().mesh = mesh; Renderer renderer = meshObject.AddComponent<MeshRenderer> (); meshObject.transform.parent = this.transform; //meshObject.transform.position = new Vector3(-mesh.bounds.center.x, -mesh.bounds.center.y, -mesh.bounds.center.z); //gameObject.transform.position = new Vector3(-mesh.bounds.center.x, -mesh.bounds.center.y, -mesh.bounds.center.z); //GetComponent<MeshRenderer> ().material = Resources.Load<Material> ("Source/Red"); }
public List <Triangle> TrianglateGlyph(Glyph g) { var re = new List <Triangle>(); var tess = new LibTessDotNet.Tess(); var c = 0; var last = 0; var vecs = new List <Vec3>(); for (var i = 0; i < g.Points.Count; i++) { var glyphPointA = g.Points[i]; vecs.Add(new Vec3() { X = glyphPointA["x"], Y = glyphPointA["y"], Z = 0 }); if (i == g.ContourEnds[c]) { c += 1; var contour = new LibTessDotNet.ContourVertex[vecs.Count]; for (var index = 0; index < vecs.Count; index++) { contour[index].Position = vecs[index]; contour[index].Data = Color.Black; } tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise); vecs.Clear(); } } tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); Console.WriteLine("Output triangles:"); int numTriangles = tess.ElementCount; for (int i = 0; i < numTriangles; i++) { var v0 = tess.Vertices[tess.Elements[i * 3]].Position; var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position; var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position; re.Add(new Triangle(new Point((int)v0.X, (int)v0.Y), new Point((int)v1.X, (int)v1.Y), new Point((int)v2.X, (int)v2.Y))); } return(re); }