Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of priority sectors #240

Merged
merged 42 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2e8f0d0
Start implementing
vegasten Sep 3, 2024
f6f13e9
Create highlight sectors
vegasten Sep 4, 2024
1bedb64
Actually create highlight sectors
vegasten Sep 4, 2024
5da67da
Refactor
vegasten Sep 4, 2024
7b0b940
Insert prioritized sectors in db
vegasten Sep 5, 2024
910131f
Rename to prioritized
vegasten Sep 5, 2024
8fc92d8
Cleanup
vegasten Sep 9, 2024
e32ab1f
Leftover renaming from highlight to priority
vegasten Sep 9, 2024
b0ceb24
Add a todo for protobuf of new aprimitive properties
vegasten Sep 9, 2024
014a281
Modify budget
vegasten Sep 9, 2024
78aad92
Add a todo for renaming sectors
vegasten Sep 9, 2024
aeb9989
Fix formatting
vegasten Sep 10, 2024
dd07bdf
Reorganize Sector Id code
Strepto Oct 14, 2024
abd0ced
Add System.Diagnostics
Strepto Oct 14, 2024
443df34
Change treeIndexes to uint
Strepto Oct 14, 2024
414bc92
Add better types to TreeIndex to SectorId map
Strepto Oct 14, 2024
02fa36b
Renaming
Strepto Oct 14, 2024
bb69bbd
Refactor splitting stuff
Strepto Oct 14, 2024
0bb0523
Refactoring
stigrus Sep 17, 2024
8b23154
Refactor splitting
stigrus Oct 15, 2024
fc9fa10
Order nodes by treeindex only once
stigrus Oct 15, 2024
263bfed
Remove StidTagMapper stuff (Moving it to a its own branch)
stigrus Oct 15, 2024
bb4adcd
Simplify SequentialIdGenerator
Strepto Oct 15, 2024
b9017f3
Refactoring
Strepto Oct 15, 2024
8dfd64b
Update tests
Strepto Oct 15, 2024
a15d306
More test
Strepto Oct 15, 2024
155895e
Expand to max id 2^24 for real
Strepto Oct 15, 2024
57bb38e
Simplify TreeIndexGenerator
Strepto Oct 15, 2024
ae9d9b0
Add more comments
Strepto Oct 15, 2024
15959c1
Rename dict and move logigng
Strepto Oct 15, 2024
4e6e696
Update casing
Strepto Oct 15, 2024
5d1e3d9
Update comment
Strepto Oct 15, 2024
18840d2
Adding tests for PrioritySectorSplitter
stigrus Oct 24, 2024
6127303
Add priority and discipline to protobuf
vegasten Oct 24, 2024
dca742b
Add tests for PrioritySplittingUtils
stigrus Oct 25, 2024
3950910
Fix small issue in CameraPositioningTests
stigrus Oct 25, 2024
4dd1a75
Renaming
vegasten Oct 28, 2024
90c46e5
Rename filename used for prioritized sectors
stigrus Oct 30, 2024
700d5e0
Add/fix a couple of comments
stigrus Oct 30, 2024
8afa288
Log how many primitives was considered outliers
stigrus Nov 4, 2024
7988a55
Remove TODO and create story + create a method for post process db ma…
vegasten Nov 5, 2024
0d00d09
Merge branch 'master' into Feature/ForceHiglightRendering
vegasten Nov 8, 2024
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
19 changes: 0 additions & 19 deletions CadRevealComposer.Tests/NodeIdProviderTests.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ public void InitialCameraPositionLongestAxisY()
}

private record TestPrimitiveWithBoundingBox(Vector3 Min, Vector3 Max)
: APrimitive(int.MaxValue, Color.Red, new BoundingBox(Min, Max));
: APrimitive(int.MaxValue, Color.Red, new BoundingBox(Min, Max), 0, null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void ExteriorTest()
/// <summary>
/// The exterior splitter uses axis aligned bounding box for Box primitive. All other data is irrelevant.
/// </summary>
private static Box CreateBoxCenteredInOrigin(ulong treeIndex, float boxSize)
private static Box CreateBoxCenteredInOrigin(uint treeIndex, float boxSize)
{
return new Box(
Matrix4x4.Identity,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
namespace CadRevealComposer.Tests.Operations.Splitting;

using System.Drawing;
using System.Numerics;
using CadRevealComposer.Operations.SectorSplitting;
using IdProviders;
using Primitives;

[TestFixture]
public class PrioritySectorSplitterTests
{
const string DisciplinePipe = "PIPE";
const string DisciplineCable = "CABLE";

[Test]
public void OnePipeAndOneCablePrimitive_SplitIntoSectors_ShouldResultInRootSectorAndOneSectorForEachDiscipline()
{
APrimitive[] primitives = [CreatePrimitive(0f, 0, DisciplinePipe), CreatePrimitive(2f, 1, DisciplineCable)];

var splitter = new PrioritySectorSplitter();
var sectors = splitter.SplitIntoSectors(primitives, new SequentialIdGenerator()).ToArray();

Assert.That(sectors, Has.Length.EqualTo(3));
}

[Test]
public void FivePrimitivesWhereTwoAreFarAway_SplitIntoSectors_ShouldResultInRootSectorAndOneSectorWithThree()
{
var primitives = PositionsToPrimitives([-40f, -10f, 0f, 10f, 40f]);

var splitter = new PrioritySectorSplitter();
var sectors = splitter.SplitIntoSectors(primitives, new SequentialIdGenerator()).ToArray();

Assert.That(sectors, Has.Length.EqualTo(2));
Assert.That(sectors[1].Geometries, Has.Length.EqualTo(3));
}

[Test]
public void ManyPrimitivesToExceedByteSizeBudget_SplitIntoSectors_ShouldResultMoreThanOneNonRootSectors()
{
const int count = 1000;
var positions = Enumerable
.Range(0, count + 1)
.Select(i =>
{
var factor = i / (double)count;
var value = (-1 + 2 * factor) * 10;

return (float)(Math.Sign(value) * Math.Pow(value, 2));
});

var primitives = PositionsToPrimitives(positions);

var splitter = new PrioritySectorSplitter();
var sectors = splitter.SplitIntoSectors(primitives, new SequentialIdGenerator()).ToArray();

Assert.Multiple(() =>
{
Assert.That(sectors, Has.Length.EqualTo(3));
Assert.That(sectors[1].Geometries, Has.Length.EqualTo(569));
Assert.That(sectors[2].Geometries, Has.Length.EqualTo(432));
});
}

private static APrimitive[] PositionsToPrimitives(IEnumerable<float> positions) =>
positions
.Select((position, index) => CreatePrimitive(position, (uint)index, DisciplinePipe))
.ToArray<APrimitive>();

private static Box CreatePrimitive(float xPosition, uint treeIndex, string discipline)
{
var position = new Vector3(xPosition, 0, 0);

return new Box(
Matrix4x4.CreateTranslation(xPosition + 0.5f, 0, 0),
treeIndex,
Color.Black,
new BoundingBox(position, position + Vector3.One)
)
{
Discipline = discipline
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#nullable enable
namespace CadRevealComposer.Tests.Operations.Splitting;

using System.Drawing;
using System.Numerics;
using CadRevealComposer.Operations.SectorSplitting;
using Primitives;

[TestFixture]
public class PrioritySplittingUtilsTests
{
const string DisciplinePipe = "PIPE";
const string DisciplineCable = "CABLE";

[Test]
public void CadRevealNodesWithVariousConfigurations_SetPriorityForHighlightSplittingWithMutation_VerifyCorrectlyMutated()
vegasten marked this conversation as resolved.
Show resolved Hide resolved
{
const uint treeIndexDisciplinePipeWithTag = 0;
const uint treeIndexDisciplinePipeMissingTag = 1;
const uint treeIndexDisciplineCableWithTag = 2;
const uint treeIndexDisciplineCableMissingTag = 3;

CadRevealNode[] nodes =
[
CreateCadRevealNode(treeIndexDisciplinePipeWithTag, DisciplinePipe, true),
CreateCadRevealNode(treeIndexDisciplinePipeMissingTag, DisciplinePipe, false),
CreateCadRevealNode(treeIndexDisciplineCableWithTag, DisciplineCable, true),
CreateCadRevealNode(treeIndexDisciplineCableMissingTag, DisciplineCable, false),
];

PrioritySplittingUtils.SetPriorityForHighlightSplittingWithMutation(nodes);

AssertDisciplineAndPriority(nodes[treeIndexDisciplinePipeWithTag].Geometries[0], DisciplinePipe, 1);
AssertDisciplineAndPriority(nodes[treeIndexDisciplinePipeMissingTag].Geometries[0], DisciplinePipe, 0);
AssertDisciplineAndPriority(nodes[treeIndexDisciplineCableWithTag].Geometries[0], null, 0);
AssertDisciplineAndPriority(nodes[treeIndexDisciplineCableMissingTag].Geometries[0], null, 0);
return;

void AssertDisciplineAndPriority(APrimitive primitive, string? expectedDiscipline, int expectedPriority)
{
Assert.Multiple(() =>
{
Assert.That(primitive.Discipline, Is.EqualTo(expectedDiscipline));
Assert.That(primitive.Priority, Is.EqualTo(expectedPriority));
});
}
}

[Test]
public void ThreePrimitiveGroupsWithDifferentCombinationsOfSizes_ConvertPrimitiveGroupsToNodes_ShouldReturnNodesWithCorrectNumberOfPrimitives()
{
const float smallPrimitiveSize = 0.01f;
const float largePrimitiveSize = 1.0f;
const uint treeIndexOneLargeOneSmallPrimitive = 0;
const uint treeIndexTwoSmallPrimitives = 1;
const uint treeIndexTwoLargePrimitives = 2;

APrimitive[] primitives =
[
CreatePrimitive(smallPrimitiveSize, treeIndexOneLargeOneSmallPrimitive, DisciplinePipe),
CreatePrimitive(largePrimitiveSize, treeIndexOneLargeOneSmallPrimitive, DisciplinePipe),
CreatePrimitive(smallPrimitiveSize, treeIndexTwoSmallPrimitives, DisciplinePipe),
CreatePrimitive(smallPrimitiveSize, treeIndexTwoSmallPrimitives, DisciplinePipe),
CreatePrimitive(largePrimitiveSize, treeIndexTwoLargePrimitives, DisciplinePipe),
CreatePrimitive(largePrimitiveSize, treeIndexTwoLargePrimitives, DisciplinePipe),
];

var geometryGroups = primitives.GroupBy(primitive => primitive.TreeIndex);

var result = PrioritySplittingUtils.ConvertPrimitiveGroupsToNodes(geometryGroups);

Assert.That(result, Has.Length.EqualTo(3));
Assert.Multiple(() =>
{
Assert.That(result[treeIndexOneLargeOneSmallPrimitive].Geometries, Has.Length.EqualTo(1));
Assert.That(result[treeIndexTwoSmallPrimitives].Geometries, Has.Length.EqualTo(2));
Assert.That(result[treeIndexTwoLargePrimitives].Geometries, Has.Length.EqualTo(2));
});
}

private static Box CreatePrimitive(float size, uint treeIndex, string? discipline = null)
{
return new Box(Matrix4x4.Identity, treeIndex, Color.Black, new BoundingBox(Vector3.Zero, size * Vector3.One))
{
Discipline = discipline
};
}

private static CadRevealNode CreateCadRevealNode(uint treeIndex, string discipline, bool hasTagAttribute)
{
const string dummyName = "dummyName";

return new CadRevealNode
{
Attributes = hasTagAttribute
? new Dictionary<string, string> { ["Discipline"] = discipline, ["Tag"] = "tag" }
: new Dictionary<string, string> { ["Discipline"] = discipline },
Geometries = [CreatePrimitive(1.0f, treeIndex)],
TreeIndex = treeIndex,
Name = dummyName,
Parent = null
};
}
}
33 changes: 33 additions & 0 deletions CadRevealComposer.Tests/SequentialIdGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace CadRevealComposer.Tests;

using IdProviders;

[TestFixture]
public class SequentialIdGeneratorTests
{
[TestCase(0u)]
[TestCase(10u)]
public void GetNodeId_ForFirstId_ReturnsSameAsStartingId(uint firstIdReturned)
{
// This test tests N random values. It should never fail.
var sequentialIdGenerator = new SequentialIdGenerator(firstIdReturned);
uint nextId = sequentialIdGenerator.GetNextId();
Assert.That(nextId, Is.EqualTo(firstIdReturned));
var expectedNextIdFromPeekNextBeforeGetNextId = sequentialIdGenerator.PeekNextId;
var nextId2 = sequentialIdGenerator.GetNextId();
Assert.That(nextId2, Is.EqualTo(firstIdReturned + 1));
Assert.That(nextId2, Is.EqualTo(expectedNextIdFromPeekNextBeforeGetNextId));
}

[Test]
public void GetNextId_WhenIdIsAboveFloatMaxInt_ThrowsException()
{
// This test tests N random values. It should never fail.
var sequentialIdGenerator = new SequentialIdGenerator((uint)Math.Pow(2, 24));
_ = sequentialIdGenerator.GetNextId(); // Should not throw yet.
Assert.That(
() => sequentialIdGenerator.GetNextId(),
Throws.Exception.With.Message.EqualTo("Too many ids generated")
);
}
}
22 changes: 0 additions & 22 deletions CadRevealComposer.Tests/Utils/HierarchyComposerConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,4 @@ public void ConvertToHierarchyNodes_GivenRevealNodes_ConvertsWithoutCrashing()
);
Assert.That(firstNode.OptionalDiagnosticInfo, Is.EqualTo(arrangedJson));
}

[Test]
public void ConvertToHierarchyNodes_GivenRevealNodes_CrashesIfTreeIndexIsOutOfRange()
{
var node1 = new CadRevealNode()
{
TreeIndex = uint.MaxValue + 1L,
Children = Array.Empty<CadRevealNode>(),
BoundingBoxAxisAligned = new BoundingBox(-Vector3.One, Vector3.One),
Name = "RootNode",
Attributes = { { "RefNo", "=123/321" }, { "Tag", "23L0001" } },
Parent = null,
Geometries = Array.Empty<APrimitive>()
};

var nodes = new[] { node1 };

Assert.That(
() => HierarchyComposerConverter.ConvertToHierarchyNodes(nodes),
Throws.Exception.Message.StartsWith("input was higher than the max uint32 value")
);
}
}
Loading
Loading