Skip to content

Commit

Permalink
Merge branch 'master' into Feature/ForceHiglightRendering
Browse files Browse the repository at this point in the history
  • Loading branch information
vegasten authored Nov 8, 2024
2 parents 7988a55 + 0a82343 commit 0d00d09
Show file tree
Hide file tree
Showing 50 changed files with 1,587 additions and 539 deletions.
101 changes: 101 additions & 0 deletions CadRevealComposer.Tests/Utils/MeshTools/LoosePiecesMeshToolsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
namespace CadRevealComposer.Tests.Utils.MeshTools;

using System.Numerics;
using CadRevealComposer.Utils.MeshOptimization;
using Tessellation;

public class LoosePiecesMeshToolsTests
{
[Test]
public void SplitMeshByLoosePieces_WhenGivenMeshWithTwoDistinctParts_SplitsIntoTwoMeshesWithExpectedCoordinates()
{
// No overlapping vertexes
var bb1 = new BoundingBox(Vector3.One, Vector3.One * 2);
var bb2 = new BoundingBox(Vector3.Zero, Vector3.One * 0.5f);

var mesh1 = GenerateMeshFromBoundingBox(bb1);
var mesh2 = GenerateMeshFromBoundingBox(bb2);
var joinedMeshes = JoinMeshes(new[] { mesh1, mesh2 });
var result = LoosePiecesMeshTools.SplitMeshByLoosePieces(joinedMeshes);
Assert.That(result, Has.Exactly(2).Items);
Assert.Multiple(() =>
{
Assert.That(result[0].Vertices, Is.EquivalentTo(mesh1.Vertices));
Assert.That(result[1].Vertices, Is.EquivalentTo(mesh2.Vertices));
});
}

[Test]
public void SplitMeshByLoosePieces_WhenGivenMeshWithOverlappingVertexes_DoesNotSplit()
{
// Overlaps by sharing the Vector3.One vertex.
var bb1 = new BoundingBox(Vector3.One, Vector3.One * 2);
var bb2 = new BoundingBox(Vector3.Zero, Vector3.One);

var mesh1 = GenerateMeshFromBoundingBox(bb1);
var mesh2 = GenerateMeshFromBoundingBox(bb2);
var joinedMeshes = JoinMeshes(new[] { mesh1, mesh2 });
var result = LoosePiecesMeshTools.SplitMeshByLoosePieces(joinedMeshes);
Assert.That(result, Has.Exactly(1).Items);
Assert.That(result.First(), Is.EqualTo(joinedMeshes)); // Assuming the input is returned as is.
}

[Test]
public void SplitMeshByLoosePieces_WhenGivenMeshWithOnlyOnePiece_ReturnsOriginalInputMesh()
{
// Overlaps by sharing the Vector3.One vertex.
var bb1 = new BoundingBox(Vector3.One, Vector3.One * 2);

var mesh1 = GenerateMeshFromBoundingBox(bb1);
var result = LoosePiecesMeshTools.SplitMeshByLoosePieces(mesh1);
Assert.That(result, Has.Exactly(1).Items);
Assert.That(result.First(), Is.SameAs(mesh1)); // Assuming the input is returned as is.
}

private static Mesh JoinMeshes(Mesh[] meshes)
{
var vertices = new List<Vector3>();
var indices = new List<uint>();
float error = meshes.Max(x => x.Error);

foreach (var mesh in meshes)
{
var vertexOffset = vertices.Count;
vertices.AddRange(mesh.Vertices);
indices.AddRange(mesh.Indices.Select(x => x + (uint)vertexOffset));
}

return new Mesh(vertices.ToArray(), indices.ToArray(), error);
}

private static Mesh GenerateMeshFromBoundingBox(BoundingBox bb)
{
var min = bb.Min;
var max = bb.Max;

// create vertexes and triangles for a cube using min and max vectors
var vertexes = new List<Vector3>
{
new(min.X, min.Y, min.Z), // 0
new(max.X, min.Y, min.Z), // 1
new(max.X, max.Y, min.Z), // 2
new(min.X, max.Y, min.Z), // 3
new(min.X, min.Y, max.Z), // 4
new(max.X, min.Y, max.Z), // 5
new(max.X, max.Y, max.Z), // 6
new(min.X, max.Y, max.Z) // 7
};
// csharpier-ignore -- prettier manual formatting
var triangleIndexes = new uint[]
{
0, 1, 2, 0, 2, 3, // front
1, 5, 6, 1, 6, 2, // right
5, 4, 7, 5, 7, 6, // back
4, 0, 3, 4, 3, 7, // left
3, 2, 6, 3, 6, 7, // top
4, 5, 1, 4, 1, 0 // bottom
};

return new Mesh(vertexes.ToArray(), triangleIndexes, 0);
}
}
12 changes: 4 additions & 8 deletions CadRevealComposer/ModelMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@
using System.Collections.Generic;
using System.Text.Json;

public class ModelMetadata
public class ModelMetadata(Dictionary<string, string> metadata)
{
private readonly Dictionary<string, string> _metadata;

public ModelMetadata(Dictionary<string, string> metadata)
{
this._metadata = metadata;
}
private readonly Dictionary<string, string> _metadata = metadata;
private static readonly JsonSerializerOptions JsonSerializerOptions = new() { WriteIndented = true };

public int Count()
{
Expand All @@ -28,6 +24,6 @@ public void Add(ModelMetadata modelMetadata)

public static string Serialize(ModelMetadata metadata)
{
return JsonSerializer.Serialize(metadata._metadata, new JsonSerializerOptions { WriteIndented = true });
return JsonSerializer.Serialize(metadata._metadata, JsonSerializerOptions);
}
}
23 changes: 15 additions & 8 deletions CadRevealComposer/Tessellation/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using Commons.Utils;
using ProtoBuf;
using Utils;

[ProtoContract(SkipConstructor = true)]
public class Mesh : IEquatable<Mesh>
Expand Down Expand Up @@ -88,25 +90,25 @@ public BoundingBox CalculateAxisAlignedBoundingBox(Matrix4x4? transform = null)

Vector3 min = Vector3.One * float.MaxValue;
Vector3 max = Vector3.One * float.MinValue;
if (transform is not null and { IsIdentity: false }) // Skip applying the transform if its an identity transform.
if (transform is { IsIdentity: false }) // Skip applying the transform if its an identity transform.
{
for (int i = 1; i < _vertices.Length; i++)
foreach (var vertex in _vertices)
{
var transformedVertex = Vector3.Transform(_vertices[i], transform.Value);
var transformedVertex = Vector3.Transform(vertex, transform.Value);
min = Vector3.Min(min, transformedVertex);
max = Vector3.Max(max, transformedVertex);
}
}
else
{
for (int i = 1; i < _vertices.Length; i++)
foreach (var vertex in _vertices)
{
var vertex = _vertices[i];
min = Vector3.Min(min, vertex);
max = Vector3.Max(max, vertex);
}
}

Trace.Assert(min.IsFinite() && max.IsFinite(), "min.IsFinite() && max.IsFinite()");
return new BoundingBox(min, max);
}

Expand All @@ -116,13 +118,18 @@ public BoundingBox CalculateAxisAlignedBoundingBox(Matrix4x4? transform = null)
/// <param name="matrix"></param>
public void Apply(Matrix4x4 matrix)
{
if (!matrix.IsDecomposable())
{
throw new ArgumentException("Matrix is not decomposable. Is the input data valid?", nameof(matrix));
}

for (var i = 0; i < _vertices.Length; i++)
{
var newVertex = Vector3.Transform(_vertices[i], matrix);

Debug.Assert(float.IsFinite(newVertex.X));
Debug.Assert(float.IsFinite(newVertex.Y));
Debug.Assert(float.IsFinite(newVertex.Z));
Trace.Assert(float.IsFinite(newVertex.X), "float.IsFinite(newVertex.X)");
Trace.Assert(float.IsFinite(newVertex.Y), "float.IsFinite(newVertex.Y)");
Trace.Assert(float.IsFinite(newVertex.Z), "float.IsFinite(newVertex.Z)");

_vertices[i] = newVertex;
}
Expand Down
Loading

0 comments on commit 0d00d09

Please sign in to comment.