### Specify Custom Normal Vector for 3D Tessellation in LibTessDotNet Source: https://context7.com/speps/libtessdotnet/llms.txt This C# example illustrates how to perform 3D polygon tessellation using LibTessDotNet by specifying a custom normal vector. This is useful when the polygon does not lie on the XY plane. The `Tessellate` method accepts an optional `normal` parameter, defining the projection plane for the tessellation process. The example shows a 3D contour and a custom normal, then prints the tessellation normal and element count. ```csharp using LibTessDotNet; using System; var tess = new Tess(); // 3D polygon not in XY plane var contour3D = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(1, 0, 1)), new ContourVertex(new Vec3(1, 1, 1)), new ContourVertex(new Vec3(0, 1, 0)) }; tess.AddContour(contour3D); // Specify custom normal for projection plane var normal = new Vec3(0, 1, 1); // Project along this direction tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3, null, normal); Console.WriteLine($"Tessellation normal: {tess.Normal}"); Console.WriteLine($"Triangles: {tess.ElementCount}"); ``` -------------------------------- ### Generate Polygons with N Vertices using LibTessDotNet in C# Source: https://context7.com/speps/libtessdotnet/llms.txt This C# code demonstrates how to configure LibTessDotNet to output polygons with a specified number of vertices (up to 6 in this example), rather than the default triangles. It adds a rectangular contour and then calls `Tessellate` with `ElementType.Polygons` and a specified maximum `polySize`. The code iterates through the resulting elements, printing the coordinates of each polygon. This is useful for generating more complex polygon structures directly from tessellation. ```csharp using LibTessDotNet; using System; var tess = new Tess(); // Create a simple rectangular contour var rect = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(10, 0, 0)), new ContourVertex(new Vec3(10, 5, 0)), new ContourVertex(new Vec3(0, 5, 0)) }; tess.AddContour(rect); // Tessellate into polygons with up to 6 vertices each tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 6); // Iterate through polygons int polySize = 6; for (int i = 0; i < tess.ElementCount; i++) { Console.Write($"Polygon {i}: "); for (int j = 0; j < polySize; j++) { int index = tess.Elements[i * polySize + j]; if (index == Tess.Undef) break; // Incomplete polygon var v = tess.Vertices[index].Position; Console.Write($"({v.X},{v.Y}) "); } Console.WriteLine(); } ``` -------------------------------- ### Extract Boundary Contours using LibTessDotNet Source: https://context7.com/speps/libtessdotnet/llms.txt This C# example shows how to use LibTessDotNet to extract only the boundary contours of a polygon, without performing interior tessellation. It adds multiple contours (outer and a hole) and then tessellates using `BoundaryContours`, processing the `Elements` array to retrieve vertex data for each contour. ```csharp using LibTessDotNet; using System; var tess = new Tess(); // Add multiple contours representing a complex polygon var outer = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(20, 0, 0)), new ContourVertex(new Vec3(20, 20, 0)), new ContourVertex(new Vec3(0, 20, 0)) }; tess.AddContour(outer); var hole = new ContourVertex[] { new ContourVertex(new Vec3(5, 5, 0)), new ContourVertex(new Vec3(15, 5, 0)), new ContourVertex(new Vec3(15, 15, 0)), new ContourVertex(new Vec3(5, 15, 0)) }; tess.AddContour(hole); // Extract boundary contours only tess.Tessellate(WindingRule.NonZero, ElementType.BoundaryContours, 0); // Elements contains [startIndex, count] pairs Console.WriteLine($"Found {tess.ElementCount} boundary contours"); for (int i = 0; i < tess.ElementCount; i++) { int startIndex = tess.Elements[i * 2]; int count = tess.Elements[i * 2 + 1]; Console.WriteLine($"Contour {i} ({count} vertices):"); for (int j = 0; j < count; j++) { var v = tess.Vertices[startIndex + j].Position; Console.WriteLine($" ({v.X}, {v.Y})"); } } ``` -------------------------------- ### Filter Empty Polygons during Tessellation with LibTessDotNet Source: https://context7.com/speps/libtessdotnet/llms.txt This C# snippet demonstrates how to enable filtering of zero-area polygons during tessellation in LibTessDotNet. By setting `tess.NoEmptyPolygons = true;`, the library automatically removes degenerate polygons from the output. The example shows a contour with duplicate points, and the output confirms that only non-empty triangles are counted. ```csharp using LibTessDotNet; using System; var tess = new Tess(); tess.NoEmptyPolygons = true; // Enable filtering // Contour with some degenerate/collinear points var contour = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(5, 0, 0)), new ContourVertex(new Vec3(5, 0, 0)), // Duplicate point new ContourVertex(new Vec3(10, 0, 0)), new ContourVertex(new Vec3(10, 10, 0)), new ContourVertex(new Vec3(0, 10, 0)) }; tess.AddContour(contour); tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); Console.WriteLine($"Non-empty triangles: {tess.ElementCount}"); // Zero-area triangles are automatically removed ``` -------------------------------- ### Get Connected Polygons with Neighbor Information using LibTessDotNet Source: https://context7.com/speps/libtessdotnet/llms.txt This C# snippet demonstrates how to use LibTessDotNet to tessellate a polygon and retrieve connectivity information, specifically the indices of neighboring polygons for each generated triangle. It utilizes the `ConnectedPolygons` element type and processes the `Elements` array to output vertex and neighbor indices. ```csharp using LibTessDotNet; using System; var tess = new Tess(); var contour = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(10, 0, 0)), new ContourVertex(new Vec3(10, 10, 0)), new ContourVertex(new Vec3(5, 15, 0)), new ContourVertex(new Vec3(0, 10, 0)) }; tess.AddContour(contour); // Use ConnectedPolygons to get neighbor information tess.Tessellate(WindingRule.EvenOdd, ElementType.ConnectedPolygons, 3); int polySize = 3; for (int i = 0; i < tess.ElementCount; i++) { Console.WriteLine($"Triangle {i}:"); // First 3 indices are vertex indices Console.Write(" Vertices: "); for (int j = 0; j < polySize; j++) { int vIndex = tess.Elements[i * polySize * 2 + j]; Console.Write($"{vIndex} "); } Console.WriteLine(); // Next 3 indices are neighbor polygon indices Console.Write(" Neighbors: "); for (int j = 0; j < polySize; j++) { int nIndex = tess.Elements[i * polySize * 2 + polySize + j]; if (nIndex == Tess.Undef) Console.Write("boundary "); else Console.Write($"{nIndex} "); } Console.WriteLine(); } ``` -------------------------------- ### Basic Triangle Tessellation with LibTessDotNet (C#) Source: https://context7.com/speps/libtessdotnet/llms.txt Demonstrates basic tessellation of a self-intersecting star polygon into triangles using the EvenOdd winding rule in C#. It involves defining vertices, adding contours, tessellating, and accessing the resulting triangle data. Requires the LibTessDotNet library. ```csharp using LibTessDotNet; using System; using System.Drawing; // Create tessellator instance (reusable) var tess = new Tess(); // Define a self-intersecting star polygon var inputData = new float[] { 0.0f, 3.0f, -1.0f, 0.0f, 1.6f, 1.9f, -1.6f, 1.9f, 1.0f, 0.0f }; // Build contour with vertices int numPoints = inputData.Length / 2; var contour = new ContourVertex[numPoints]; for (int i = 0; i < numPoints; i++) { contour[i].Position = new Vec3(inputData[i * 2], inputData[i * 2 + 1], 0); contour[i].Data = Color.Azure; // Optional per-vertex data } // Add contour with clockwise orientation tess.AddContour(contour, ContourOrientation.Clockwise); // Tessellate into triangles with EvenOdd winding rule tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); // Access results Console.WriteLine($"Generated {tess.ElementCount} triangles"); for (int i = 0; i < tess.ElementCount; 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($"Triangle {i}: ({v0.X},{v0.Y}) ({v1.X},{v1.Y}) ({v2.X},{v2.Y})"); } ``` -------------------------------- ### C# Polygon Tessellation with LibTessDotNet Source: https://github.com/speps/libtessdotnet/blob/master/README.md This C# code snippet demonstrates how to use the LibTessDotNet library to tessellate a self-intersecting polygon. It includes setting up contours, defining a custom vertex combination function for interpolating data (like colors), and calling the tessellation process. The output is a list of triangles representing the tessellated polygon. ```csharp using LibTessDotNet; using System; using System.Drawing; namespace TessExample { class Program { // The data array contains 4 values, it's the associated data of the vertices that resulted in an intersection. private static object VertexCombine(LibTessDotNet.Vec3 position, object[] data, float[] weights) { // Fetch the vertex data. var colors = new Color[] { (Color)data[0], (Color)data[1], (Color)data[2], (Color)data[3] }; // Interpolate with the 4 weights. var rgba = new float[] { (float)colors[0].R * weights[0] + (float)colors[1].R * weights[1] + (float)colors[2].R * weights[2] + (float)colors[3].R * weights[3], (float)colors[0].G * weights[0] + (float)colors[1].G * weights[1] + (float)colors[2].G * weights[2] + (float)colors[3].G * weights[3], (float)colors[0].B * weights[0] + (float)colors[1].B * weights[1] + (float)colors[2].B * weights[2] + (float)colors[3].B * weights[3], (float)colors[0].A * weights[0] + (float)colors[1].A * weights[1] + (float)colors[2].A * weights[2] + (float)colors[3].A * weights[3] }; // Return interpolated data for the new vertex. return Color.FromArgb((int)rgba[3], (int)rgba[0], (int)rgba[1], (int)rgba[2]); } 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(inputData[i * 2], inputData[i * 2 + 1], 0); // 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(); } } } ``` -------------------------------- ### Compare Winding Rules for Polygon Tessellation in C# Source: https://context7.com/speps/libtessdotnet/llms.txt This C# snippet illustrates the effect of different winding rules on polygon tessellation using LibTessDotNet. It defines two overlapping squares and tessellates them using `EvenOdd`, `NonZero`, `Positive`, `Negative`, and `AbsGeqTwo` winding rules. The output shows the number of triangles and vertices generated for each rule, highlighting how each rule defines what is considered the 'inside' of a polygon. No external libraries beyond `LibTessDotNet` are required. ```csharp using LibTessDotNet; using System; void TessellateWithRule(WindingRule rule) { var tess = new Tess(); // Two overlapping squares var square1 = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(3, 0, 0)), new ContourVertex(new Vec3(3, 3, 0)), new ContourVertex(new Vec3(0, 3, 0)) }; var square2 = new ContourVertex[] { new ContourVertex(new Vec3(2, 2, 0)), new ContourVertex(new Vec3(5, 2, 0)), new ContourVertex(new Vec3(5, 5, 0)), new ContourVertex(new Vec3(2, 5, 0)) }; tess.AddContour(square1); tess.AddContour(square2); tess.Tessellate(rule, ElementType.Polygons, 3); Console.WriteLine($"{rule}: {tess.ElementCount} triangles, {tess.VertexCount} vertices"); } // EvenOdd: alternating in/out based on crossing count TessellateWithRule(WindingRule.EvenOdd); // NonZero: non-zero winding number is inside (union of shapes) TessellateWithRule(WindingRule.NonZero); // Positive: only positive winding numbers TessellateWithRule(WindingRule.Positive); // Negative: only negative winding numbers TessellateWithRule(WindingRule.Negative); // AbsGeqTwo: absolute winding number >= 2 (overlapping regions only) TessellateWithRule(WindingRule.AbsGeqTwo); ``` -------------------------------- ### C# Double Precision Tessellation with LibTessDotNet Source: https://context7.com/speps/libtessdotnet/llms.txt This snippet demonstrates how to use double precision for high-accuracy tessellation with LibTessDotNet. It requires compiling with the DOUBLE define. The code initializes a Tess object, adds a contour, performs tessellation using the EvenOdd winding rule, and prints the high-precision output vertices. ```csharp using LibTessDotNet.Double; using System; // When compiled with DOUBLE define, uses System.Double instead of System.Single var tess = new Tess(); var contour = new ContourVertex[] { new ContourVertex(new Vec3(0.123456789012345, 0.987654321098765, 0)), new ContourVertex(new Vec3(1.123456789012345, 0.987654321098765, 0)), new ContourVertex(new Vec3(1.123456789012345, 1.987654321098765, 0)), new ContourVertex(new Vec3(0.123456789012345, 1.987654321098765, 0)) }; tess.AddContour(contour); tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); // High precision preserved in output vertices foreach (var vertex in tess.Vertices) { Console.WriteLine($"High precision: {vertex.Position.X:F15}, {vertex.Position.Y:F15}"); } ``` -------------------------------- ### Interpolate Custom Vertex Data with Combine Callback in C# Source: https://context7.com/speps/libtessdotnet/llms.txt This C# snippet demonstrates how to use a `VertexCombine` callback with LibTessDotNet to interpolate custom vertex attributes, such as color, when the tessellator creates new vertices at intersections. It requires the `LibTessDotNet` and `System.Drawing` namespaces. The callback takes the position, data, and weights of contributing vertices and returns the interpolated data for the new vertex. The input is a set of `ContourVertex` objects with associated `Color` data, and the output is tessellated polygons with interpolated vertex colors. ```csharp using LibTessDotNet; using System; using System.Drawing; // Callback to interpolate vertex data at intersections object VertexCombine(Vec3 position, object[] data, float[] weights) { // Interpolate color data from 4 contributing vertices var colors = new Color[] { (Color)data[0], (Color)data[1], (Color)data[2], (Color)data[3] }; var r = colors[0].R * weights[0] + colors[1].R * weights[1] + colors[2].R * weights[2] + colors[3].R * weights[3]; var g = colors[0].G * weights[0] + colors[1].G * weights[1] + colors[2].G * weights[2] + colors[3].G * weights[3]; var b = colors[0].B * weights[0] + colors[1].B * weights[1] + colors[2].B * weights[2] + colors[3].B * weights[3]; var a = colors[0].A * weights[0] + colors[1].A * weights[1] + colors[2].A * weights[2] + colors[3].A * weights[3]; return Color.FromArgb((int)a, (int)r, (int)g, (int)b); } var tess = new Tess(); // Create contour with color data var contour = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0), Color.Red), new ContourVertex(new Vec3(5, 0, 0), Color.Green), new ContourVertex(new Vec3(5, 5, 0), Color.Blue), new ContourVertex(new Vec3(0, 5, 0), Color.Yellow) }; tess.AddContour(contour); // Tessellate with combine callback for vertex data interpolation tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3, VertexCombine); // Access interpolated vertex data foreach (var vertex in tess.Vertices) { Console.WriteLine($"Position: {vertex.Position}, Color: {vertex.Data}"); } ``` -------------------------------- ### Polygon with Holes Tessellation using LibTessDotNet (C#) Source: https://context7.com/speps/libtessdotnet/llms.txt Illustrates tessellating a polygon containing holes using LibTessDotNet in C#. It involves adding an outer contour (counterclockwise) and inner hole contours (clockwise) and applying the NonZero winding rule for correct hole handling. Requires the LibTessDotNet library. ```csharp using LibTessDotNet; var tess = new Tess(); // Outer contour (counterclockwise for outer boundary) var outer = new ContourVertex[] { new ContourVertex(new Vec3(0, 0, 0)), new ContourVertex(new Vec3(10, 0, 0)), new ContourVertex(new Vec3(10, 10, 0)), new ContourVertex(new Vec3(0, 10, 0)) }; tess.AddContour(outer, ContourOrientation.CounterClockwise); // Inner hole (clockwise for holes) var hole = new ContourVertex[] { new ContourVertex(new Vec3(2, 2, 0)), new ContourVertex(new Vec3(8, 2, 0)), new ContourVertex(new Vec3(8, 8, 0)), new ContourVertex(new Vec3(2, 8, 0)) }; tess.AddContour(hole, ContourOrientation.Clockwise); // Tessellate with NonZero winding rule (handles holes correctly) tess.Tessellate(WindingRule.NonZero, ElementType.Polygons, 3); Console.WriteLine($"Vertices: {tess.VertexCount}, Triangles: {tess.ElementCount}"); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.