switched from trianglenet to libtessdotnet (#559)
This commit is contained in:
@@ -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, )",
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user