Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MeshDecimatorCore/MeshDecimatorCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Nullable>disable</Nullable>
</PropertyGroup>

</Project>
8 changes: 7 additions & 1 deletion Obj2Gltf/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,13 @@ private List<Primitive> AddVertexAttributes(GltfModel gltfModel,
var hasColors = objModel.Colors.Count == objModel.Vertices.Count;

var materialIndex = GetMaterialIndexOrDefault(gltfModel, objModel, f.MatName);
var material = materialIndex < objModel.Materials.Count ? objModel.Materials[materialIndex] : null;
// Fix Issue #36: look up the OBJ material by name instead of relying
// on the gltfModel index, which can diverge from objModel.Materials
// when the default material is inserted at index 0.
var material = !string.IsNullOrEmpty(f.MatName)
? objModel.Materials.FirstOrDefault(m => m.Name == f.MatName)
?? (materialIndex < objModel.Materials.Count ? objModel.Materials[materialIndex] : null)
: objModel.Materials.FirstOrDefault();
var materialHasTexture = material?.DiffuseTextureFile != null;

// every primitive needs their own vertex indices(v,t,n)
Expand Down
2 changes: 1 addition & 1 deletion Obj2Gltf/WaveFront/ObjParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public ObjModel Parse(string objFilePath, bool removeDegenerateFaces = false, En

using (_reader)
{
model.Materials.Add(new Material() { Ambient = new Reflectivity(new FactorColor(1)) });
model.Materials.Add(new Material() { Name = "default", Ambient = new Reflectivity(new FactorColor(1)) });
var currentMaterialName = "default";
var currentGeometries = model.GetOrAddGeometries("default");
Face currentFace = null;
Expand Down
22 changes: 11 additions & 11 deletions Obj2Tiles.Common/CommonUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static bool FilesAreEqual(FileInfo first, FileInfo second)
return true;
}

public static TValue SafeGetValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
public static TValue? SafeGetValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
return !dictionary.TryGetValue(key, out var value) ? default : value;
}
Expand All @@ -74,7 +74,7 @@ public static TValue SafeGetValue<TKey, TValue>(this IDictionary<TKey, TValue> d
}

/// <summary>
/// Ensures that the sqlite database folder exists
/// Ensures that the sqlite database folder exists
/// </summary>
/// <param name="connstr"></param>
public static void EnsureFolderCreated(string connstr)
Expand All @@ -93,7 +93,7 @@ public static void EnsureFolderCreated(string connstr)

if (folder != null)
Directory.CreateDirectory(folder);
}
}
}
}

Expand Down Expand Up @@ -125,7 +125,7 @@ public static string ComputeFileHash(string filePath)

private static string ConvertBytesToString(byte[] bytes)
{
// Convert byte array to a string
// Convert byte array to a string
var builder = new StringBuilder();
foreach (var t in bytes)
builder.Append(t.ToString("x2"));
Expand Down Expand Up @@ -202,7 +202,7 @@ public static bool SafeDelete(string path)
return false;
}
}

public static bool SafeCopy(string source, string dest, bool overwrite = true)
{
try
Expand Down Expand Up @@ -316,7 +316,7 @@ public static string[] SafeTreeDelete(string baseTempFolder, int rounds = 3, int
}
}

if (!entries.Any())
if (!entries.Any())
return [];

Thread.Sleep(delay);
Expand Down Expand Up @@ -363,7 +363,7 @@ public static string[] SafeTreeDelete(string baseTempFolder, int rounds = 3, int

// Credit https://stackoverflow.com/a/11124118
/// <summary>
/// Returns the human-readable file size for an arbitrary, 64-bit file size
/// Returns the human-readable file size for an arbitrary, 64-bit file size
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
Expand Down Expand Up @@ -420,7 +420,7 @@ public static bool Validate<T>(T obj, out ICollection<ValidationResult> results)
{
results = new List<ValidationResult>();

return Validator.TryValidateObject(obj, new ValidationContext(obj), results, true);
return Validator.TryValidateObject(obj!, new ValidationContext(obj!), results, true);
}

public static string ToErrorString(this IEnumerable<ValidationResult> results)
Expand Down Expand Up @@ -448,7 +448,7 @@ public static async Task<FileStream> WaitForFile(string fullPath, FileMode mode,
int hops = 15, int baseDelay = 10, int incrementDelay = 2)
{
int delay = baseDelay;

for (var hop = 0; hop < hops; hops++)
{
FileStream fs = null;
Expand All @@ -472,13 +472,13 @@ public static async Task<FileStream> WaitForFile(string fullPath, FileMode mode,
return null;
}*/

public static async Task<FileStream> WaitForFile(string fullPath, FileMode mode, FileAccess access,
public static async Task<FileStream?> WaitForFile(string fullPath, FileMode mode, FileAccess access,
FileShare share,
int delay = 50, int retries = 1200)
{
for (var numTries = 0; numTries < retries; numTries++)
{
FileStream fs = null;
FileStream? fs = null;
try
{
fs = new FileStream(fullPath, mode, access, share);
Expand Down
2 changes: 1 addition & 1 deletion Obj2Tiles.Common/TestArea.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public TestArea(string name)

}

public TestArea() : this(new StackFrame(1).GetMethod()?.Name)
public TestArea() : this(new StackFrame(1).GetMethod()?.Name ?? "Unknown")
{
//
}
Expand Down
2 changes: 1 addition & 1 deletion Obj2Tiles.Common/TestFS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class TestFS : IDisposable
/// </summary>
public string BaseTestFolder { get; }

private readonly string _oldCurrentDirectory = null;
private readonly string? _oldCurrentDirectory = null;

/// <summary>
/// Creates a new instance of TestFS
Expand Down
146 changes: 146 additions & 0 deletions Obj2Tiles.Library.Test/BoundsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System.IO;
using NUnit.Framework;
using Obj2Tiles.Library.Geometry;
using Shouldly;

namespace Obj2Tiles.Library.Test;

/// <summary>
/// Tests for Box3 bounding box and mesh Bounds calculation.
/// </summary>
public class BoundsTests
{
private const string TestDataPath = "TestData";

[Test]
public void Bounds_Triangle_Correct()
{
var mesh = MeshUtils.LoadMesh(Path.Combine(TestDataPath, "triangle.obj"));
var bounds = mesh.Bounds;

bounds.Min.X.ShouldBe(0.0);
bounds.Min.Y.ShouldBe(0.0);
bounds.Min.Z.ShouldBe(0.0);
bounds.Max.X.ShouldBe(1.0);
bounds.Max.Y.ShouldBe(1.0);
bounds.Max.Z.ShouldBe(0.0);
}

[Test]
public void Bounds_Cube3D_SymmetricAroundOrigin()
{
var mesh = MeshUtils.LoadMesh(Path.Combine(TestDataPath, "cube-3d.obj"));
var bounds = mesh.Bounds;

bounds.Min.X.ShouldBe(-1.0);
bounds.Min.Y.ShouldBe(-1.0);
bounds.Min.Z.ShouldBe(-1.0);
bounds.Max.X.ShouldBe(1.0);
bounds.Max.Y.ShouldBe(1.0);
bounds.Max.Z.ShouldBe(1.0);

bounds.Width.ShouldBe(2.0);
bounds.Height.ShouldBe(2.0);
bounds.Depth.ShouldBe(2.0);
}

[Test]
public void Bounds_Center_IsCorrect()
{
var mesh = MeshUtils.LoadMesh(Path.Combine(TestDataPath, "cube-3d.obj"));
var center = mesh.Bounds.Center;

center.X.ShouldBe(0.0);
center.Y.ShouldBe(0.0);
center.Z.ShouldBe(0.0);
}

[Test]
public void Bounds_AfterSplit_SubsetsOfOriginal()
{
var mesh = MeshUtils.LoadMesh(Path.Combine(TestDataPath, "cube-3d.obj"));
var originalBounds = mesh.Bounds;
var xutils = new VertexUtilsX();

mesh.Split(xutils, 0.0, out var left, out var right);

var lb = left.Bounds;
lb.Min.X.ShouldBeGreaterThanOrEqualTo(originalBounds.Min.X - 1e-9);
lb.Max.X.ShouldBeLessThanOrEqualTo(0.0 + 1e-9);

var rb = right.Bounds;
rb.Min.X.ShouldBeGreaterThanOrEqualTo(0.0 - 1e-9);
rb.Max.X.ShouldBeLessThanOrEqualTo(originalBounds.Max.X + 1e-9);
}

// --- Box3 Split ---

[Test]
public void Box3_SplitX_CoversFull()
{
var box = new Box3(-1, -1, -1, 1, 1, 1);
var halves = box.Split(Axis.X);

halves.Length.ShouldBe(2);
halves[0].Min.X.ShouldBe(-1.0);
halves[0].Max.X.ShouldBe(0.0);
halves[1].Min.X.ShouldBe(0.0);
halves[1].Max.X.ShouldBe(1.0);

// Y and Z unchanged
halves[0].Min.Y.ShouldBe(-1.0);
halves[0].Max.Y.ShouldBe(1.0);
}

[Test]
public void Box3_SplitY_CoversFull()
{
var box = new Box3(-1, -1, -1, 1, 1, 1);
var halves = box.Split(Axis.Y);

halves[0].Max.Y.ShouldBe(0.0);
halves[1].Min.Y.ShouldBe(0.0);
}

[Test]
public void Box3_SplitZ_CoversFull()
{
var box = new Box3(-1, -1, -1, 1, 1, 1);
var halves = box.Split(Axis.Z);

halves[0].Max.Z.ShouldBe(0.0);
halves[1].Min.Z.ShouldBe(0.0);
}

[Test]
public void Box3_SplitAtPosition_Correct()
{
var box = new Box3(0, 0, 0, 10, 10, 10);
var halves = box.Split(Axis.X, 3.0);

halves[0].Max.X.ShouldBe(3.0);
halves[1].Min.X.ShouldBe(3.0);
}

[Test]
public void Box3_Center_Calculation()
{
var box = new Box3(2, 4, 6, 8, 10, 12);
var center = box.Center;

center.X.ShouldBe(5.0);
center.Y.ShouldBe(7.0);
center.Z.ShouldBe(9.0);
}

[Test]
public void Box3_Equality()
{
var a = new Box3(0, 0, 0, 1, 1, 1);
var b = new Box3(0, 0, 0, 1, 1, 1);
var c = new Box3(0, 0, 0, 2, 1, 1);

(a == b).ShouldBeTrue();
(a != c).ShouldBeTrue();
}
}
Loading