switched from trianglenet to libtessdotnet (#559)

This commit is contained in:
kekesidavid
2025-02-04 16:09:47 +01:00
committed by GitHub
parent a70a894089
commit a2b01c0bbb
10 changed files with 100 additions and 121 deletions
@@ -325,8 +325,8 @@
"speckle.common.meshtriangulation": {
"type": "Project",
"dependencies": {
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Triangle": "[1.0.0, )"
"LibTessDotNet": "[1.1.15, )",
"Speckle.DoubleNumerics": "[4.1.0, )"
}
},
"speckle.connectors.common": {
@@ -374,6 +374,12 @@
"Speckle.Objects": "[3.1.0-dev.251, )"
}
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -435,12 +441,6 @@
"requested": "[3.1.0-dev.251, )",
"resolved": "3.1.0-dev.251",
"contentHash": "M8MNH+yeIkEmhnb4GxrKyewCotaP+MZ+FUbkuHDaMbnG7xbJ0Y83nDA7v77v2v/UczCFmdVqroFnV4i6OQew7g=="
},
"Speckle.Triangle": {
"type": "CentralTransitive",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "3fWYy5IG9EpkxvqSkRWtgWraYg7ylkg8Ea3WesIqAodjOySYzv+ntdcCP7EW7a5NB3nUhlp27woMAwyKFEF5XQ=="
}
}
}
@@ -406,8 +406,8 @@
"speckle.common.meshtriangulation": {
"type": "Project",
"dependencies": {
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Triangle": "[1.0.0, )"
"LibTessDotNet": "[1.1.15, )",
"Speckle.DoubleNumerics": "[4.1.0, )"
}
},
"speckle.connectors.common": {
@@ -455,6 +455,12 @@
"Speckle.Objects": "[3.1.0-dev.251, )"
}
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -516,12 +522,6 @@
"requested": "[3.1.0-dev.251, )",
"resolved": "3.1.0-dev.251",
"contentHash": "M8MNH+yeIkEmhnb4GxrKyewCotaP+MZ+FUbkuHDaMbnG7xbJ0Y83nDA7v77v2v/UczCFmdVqroFnV4i6OQew7g=="
},
"Speckle.Triangle": {
"type": "CentralTransitive",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "3fWYy5IG9EpkxvqSkRWtgWraYg7ylkg8Ea3WesIqAodjOySYzv+ntdcCP7EW7a5NB3nUhlp27woMAwyKFEF5XQ=="
}
}
}
@@ -294,8 +294,8 @@
"speckle.common.meshtriangulation": {
"type": "Project",
"dependencies": {
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Triangle": "[1.0.0, )"
"LibTessDotNet": "[1.1.15, )",
"Speckle.DoubleNumerics": "[4.1.0, )"
}
},
"speckle.converters.common": {
@@ -305,6 +305,12 @@
"Speckle.Objects": "[3.1.0-dev.251, )"
}
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -361,12 +367,6 @@
"resolved": "3.1.0-dev.251",
"contentHash": "M8MNH+yeIkEmhnb4GxrKyewCotaP+MZ+FUbkuHDaMbnG7xbJ0Y83nDA7v77v2v/UczCFmdVqroFnV4i6OQew7g=="
},
"Speckle.Triangle": {
"type": "CentralTransitive",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "3fWYy5IG9EpkxvqSkRWtgWraYg7ylkg8Ea3WesIqAodjOySYzv+ntdcCP7EW7a5NB3nUhlp27woMAwyKFEF5XQ=="
},
"Tekla.Structures.Dialog": {
"type": "CentralTransitive",
"requested": "[2024.0.4, )",
@@ -335,8 +335,8 @@
"speckle.common.meshtriangulation": {
"type": "Project",
"dependencies": {
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Triangle": "[1.0.0, )"
"LibTessDotNet": "[1.1.15, )",
"Speckle.DoubleNumerics": "[4.1.0, )"
}
},
"speckle.converters.common": {
@@ -346,6 +346,12 @@
"Speckle.Objects": "[3.1.0-dev.251, )"
}
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -402,12 +408,6 @@
"resolved": "3.1.0-dev.251",
"contentHash": "M8MNH+yeIkEmhnb4GxrKyewCotaP+MZ+FUbkuHDaMbnG7xbJ0Y83nDA7v77v2v/UczCFmdVqroFnV4i6OQew7g=="
},
"Speckle.Triangle": {
"type": "CentralTransitive",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "3fWYy5IG9EpkxvqSkRWtgWraYg7ylkg8Ea3WesIqAodjOySYzv+ntdcCP7EW7a5NB3nUhlp27woMAwyKFEF5XQ=="
},
"Tekla.Structures.Plugins": {
"type": "CentralTransitive",
"requested": "[2024.0.4, )",
@@ -96,7 +96,7 @@ public class SolidToSpeckleConverter : ITypedConverter<TSM.Solid, SOG.Mesh>
private SOG.Mesh ExtrudeFromPolygons(List<Poly3> face1, List<Poly3> face2)
{
var point = face2[0].Vertices[0];
var generator = new MeshGenerator(new BaseTransformer(), new TriangleNetTriangulator());
var generator = new MeshGenerator(new BaseTransformer(), new LibTessTriangulator());
var mesh3 = generator.ExtrudeMesh(face1, point);
return Mesh3ToSpeckleMesh(mesh3);
+1
View File
@@ -10,6 +10,7 @@
<PackageVersion Include="FluentAssertions" Version="6.12.1" />
<PackageVersion Include="Glob" Version="1.1.9" />
<PackageVersion Include="ILRepack.FullAuto" Version="1.6.0" />
<PackageVersion Include="LibTessDotNet" Version="1.1.15" />
<PackageVersion Include="Moq" Version="4.20.70" />
<PackageVersion Include="Microsoft.Build" Version="17.11.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
@@ -0,0 +1,53 @@
using Speckle.DoubleNumerics;
namespace Speckle.Common.MeshTriangulation;
public class LibTessTriangulator : ITriangulator
{
public Mesh2 Triangulate(IReadOnlyList<Poly2> polygons)
{
var tess = new LibTessDotNet.Tess();
for (int polygonIndex = 0; polygonIndex < polygons.Count; polygonIndex++)
{
var numPoints = polygons[polygonIndex].Vertices.Count;
var contour = new LibTessDotNet.ContourVertex[numPoints];
for (int vertexIndex = 0; vertexIndex < numPoints; vertexIndex++)
{
var v = polygons[polygonIndex].Vertices[vertexIndex];
contour[vertexIndex].Position = new LibTessDotNet.Vec3((float)v.X, (float)v.Y, 0);
}
// the outer contour has to be in clockwise order
var orientation =
polygonIndex == 0
? LibTessDotNet.ContourOrientation.Clockwise
: LibTessDotNet.ContourOrientation.CounterClockwise;
tess.AddContour(contour, orientation);
}
tess.Tessellate();
var vertices = new List<Vector2>();
var triangles = new List<int>();
int tc = 0;
int numTriangles = tess.ElementCount;
for (int i = 0; i < numTriangles; i++)
{
var v1 = tess.Vertices[tess.Elements[i * 3]].Position;
var v2 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
var v3 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;
vertices.Add(new Vector2(v1.X, v1.Y));
vertices.Add(new Vector2(v2.X, v2.Y));
vertices.Add(new Vector2(v3.X, v3.Y));
triangles.Add(tc++);
triangles.Add(tc++);
triangles.Add(tc++);
}
return new Mesh2(vertices, triangles);
}
}
@@ -5,8 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibTessDotNet" />
<PackageReference Include="Speckle.DoubleNumerics" />
<PackageReference Include="Speckle.Triangle" />
</ItemGroup>
</Project>
@@ -1,75 +0,0 @@
using Speckle.DoubleNumerics;
using TriangleNet.Geometry;
namespace Speckle.Common.MeshTriangulation;
public class TriangleNetTriangulator : ITriangulator
{
public Mesh2 Triangulate(IReadOnlyList<Poly2> polygons)
{
var poly = new Polygon();
AddContour(poly, polygons[0]);
for (int i = 1; i < polygons.Count; i++)
{
AddHole(poly, polygons[i]);
}
var mesh = poly.Triangulate();
var vertices = new List<Vector2>();
var triangles = new List<int>();
int tc = 0;
foreach (var triangle in mesh.Triangles)
{
var v1 = triangle.GetVertex(0);
var v2 = triangle.GetVertex(1);
var v3 = triangle.GetVertex(2);
vertices.Add(new Vector2(v1.X, v1.Y));
vertices.Add(new Vector2(v2.X, v2.Y));
vertices.Add(new Vector2(v3.X, v3.Y));
triangles.Add(tc++);
triangles.Add(tc++);
triangles.Add(tc++);
}
return new Mesh2(vertices, triangles);
}
private void AddContour(Polygon p, Poly2 poly2)
{
var verts = new List<Vertex>();
foreach (var v in poly2.Vertices)
{
verts.Add(new Vertex(v.X, v.Y, 1));
}
p.Add(new TriangleNet.Geometry.Contour(verts, 1));
}
private void AddHole(Polygon p, Poly2 poly2)
{
var verts = new List<Vertex>();
foreach (var v in poly2.Vertices)
{
verts.Add(new Vertex(v.X, v.Y, 2));
}
// we need a point inside the hole to add it
var pointInHole = GetRightPointOfEdge(poly2.Vertices[0], poly2.Vertices[1]);
p.Add(new TriangleNet.Geometry.Contour(verts, 2), new Point(pointInHole.X, pointInHole.Y));
}
// picks a point on the right side of the given edge
private Vector2 GetRightPointOfEdge(Vector2 a, Vector2 b)
{
Vector2 ab = b - a;
var normal = Vector2.Normalize(new Vector2(-ab.Y, ab.X));
var right = -0.01 * normal;
var midPoint = Vector2.Lerp(a, b, 0.5f);
return midPoint + right;
}
}
@@ -2,6 +2,12 @@
"version": 2,
"dependencies": {
".NETStandard,Version=v2.0": {
"LibTessDotNet": {
"type": "Direct",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.0.3, )",
@@ -48,12 +54,6 @@
"resolved": "0.9.6",
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
},
"Speckle.Triangle": {
"type": "Direct",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "3fWYy5IG9EpkxvqSkRWtgWraYg7ylkg8Ea3WesIqAodjOySYzv+ntdcCP7EW7a5NB3nUhlp27woMAwyKFEF5XQ=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
@@ -76,6 +76,12 @@
}
},
"net8.0": {
"LibTessDotNet": {
"type": "Direct",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.0.3, )",
@@ -113,12 +119,6 @@
"resolved": "0.9.6",
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
},
"Speckle.Triangle": {
"type": "Direct",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "3fWYy5IG9EpkxvqSkRWtgWraYg7ylkg8Ea3WesIqAodjOySYzv+ntdcCP7EW7a5NB3nUhlp27woMAwyKFEF5XQ=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",