From 5efeaa0925fc7c2d8c9045e14b2951ed376cb986 Mon Sep 17 00:00:00 2001 From: Stefan Maierhofer Date: Tue, 10 Oct 2023 07:13:36 +0200 Subject: [PATCH] switch to Octree.PerCellPartIndex1i (from PerCellPartIndex1ui) --- paket.dependencies | 4 +- paket.lock | 6 +- .../ViewsTests/ViewsFilterTests.cs | 2 +- src/Aardvark.Data.Points.Base/Chunk.cs | 9 +- .../PartIndexUtils.cs | 95 +++++++++++++------ .../Octrees/InMemoryPointSet.cs | 17 ++-- src/Aardvark.Geometry.PointSet/Octrees/Lod.cs | 23 +++-- .../Octrees/PointSetNode.cs | 4 +- .../Views/FilteredNode.cs | 1 + 9 files changed, 108 insertions(+), 53 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index d245c31c..87163135 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -27,8 +27,8 @@ nuget Aardvark.Application.Slim.Vulkan ~> 5.4.0 //////////////////////////////////////////////////////////////////////// // https://github.com/aardvark-community/aardvark.data.durable.dotnet -nuget Aardvark.Data.Durable ~> 0.3.14 -nuget Aardvark.Data.Durable.Codec ~> 0.3.14 +nuget Aardvark.Data.Durable ~> 0.3.15 +nuget Aardvark.Data.Durable.Codec ~> 0.3.15 //////////////////////////////////////////////////////////////////////// // 3rd-party diff --git a/paket.lock b/paket.lock index a98bd3e0..937c5841 100644 --- a/paket.lock +++ b/paket.lock @@ -155,10 +155,10 @@ NUGET Aardvark.Base.TypeProviders (4.5.15) FSharp.Core (>= 4.2.3) Aardvark.Build (1.0.20) - Aardvark.Data.Durable (0.3.14) - Aardvark.Data.Durable.Codec (0.3.14) + Aardvark.Data.Durable (0.3.15) + Aardvark.Data.Durable.Codec (0.3.15) Aardvark.Base (>= 5.2.25 < 5.3) - Aardvark.Data.Durable (0.3.14) + Aardvark.Data.Durable (0.3.15) Aardvark.Geometry (5.2.25) Aardvark.Base (5.2.25) Aardvark.Base.FSharp (5.2.25) diff --git a/src/Aardvark.Algodat.Tests/ViewsTests/ViewsFilterTests.cs b/src/Aardvark.Algodat.Tests/ViewsTests/ViewsFilterTests.cs index 67cd9229..4ac5ae24 100644 --- a/src/Aardvark.Algodat.Tests/ViewsTests/ViewsFilterTests.cs +++ b/src/Aardvark.Algodat.Tests/ViewsTests/ViewsFilterTests.cs @@ -55,7 +55,7 @@ private static IPointCloudNode CreateNode(Storage storage, V3f[] psGlobal, int[] .Add(Durable.Octree.PointCountTreeLeafs, psLocal.LongLength) .Add(Durable.Octree.PositionsLocal3fReference, psLocalId) .Add(Durable.Octree.PointRkdTreeFDataReference, kdLocalId) - .Add(Durable.Octree.PerCellPartIndex1ui, 42u) + .Add(Durable.Octree.PerCellPartIndex1i, 42) ; if (intensities != null) diff --git a/src/Aardvark.Data.Points.Base/Chunk.cs b/src/Aardvark.Data.Points.Base/Chunk.cs index 82545d7b..3c6376c6 100644 --- a/src/Aardvark.Data.Points.Base/Chunk.cs +++ b/src/Aardvark.Data.Points.Base/Chunk.cs @@ -263,11 +263,12 @@ public Chunk( switch (parts) { - case null: break; - case uint: break; - case IList: break; + case null : break; + case int : break; + case uint : break; + case IList : break; case IList: break; - case IList: break; + case IList : break; default: throw new Exception($"Unexpected part indices type {parts.GetType().FullName}. Error fc9d196d-508e-4977-8f04-2167c71e38b0."); } IList? qs1b = null; diff --git a/src/Aardvark.Data.Points.Base/PartIndexUtils.cs b/src/Aardvark.Data.Points.Base/PartIndexUtils.cs index 272c76de..8abf9dd3 100644 --- a/src/Aardvark.Data.Points.Base/PartIndexUtils.cs +++ b/src/Aardvark.Data.Points.Base/PartIndexUtils.cs @@ -39,20 +39,21 @@ public static class PartIndexUtils switch (o) { case null: return null; - case uint x: return x; + case int x: return x; + case uint x: return (int)x; case byte[] xs: { if (xs.Length == 0) throw new Exception("Invariant fa0e5cea-c04a-4649-9018-765606529e38."); var range = new Range1b(xs); if (range.Min < 0) throw new Exception("Invariant 46a46203-2525-40c5-95ab-ff6f05f71f55."); - return range.Min == range.Max ? (uint)range.Min : xs; + return range.Min == range.Max ? (int)range.Min : xs; } case short[] xs: { if (xs.Length == 0) throw new Exception("Invariant 9d18a39b-d19c-4084-95b0-eb30c6a3e38f."); var range = new Range1s(xs); if (range.Min < 0) throw new Exception("Invariant 5d7b3558-e235-4ccc-9b10-2d4217fb8459."); - if (range.Min == range.Max) return (uint)range.Min; + if (range.Min == range.Max) return (int)range.Min; if (range.Max < 256) checked { return xs.Map(x => (byte)x); } return xs; } @@ -61,7 +62,7 @@ public static class PartIndexUtils if (xs.Length == 0) throw new Exception("Invariant f60565d1-6cea-47a0-95c2-30625bd16c1b."); var range = new Range1i(xs); if (range.Min < 0) throw new Exception("Invariant 2e002802-dd0b-402b-970b-a49a6decd987."); - if (range.Min == range.Max) return (uint)range.Min; + if (range.Min == range.Max) return (int)range.Min; if (range.Max < 256) checked { return xs.Map(x => (byte)x); } if (range.Max < 32768) checked { return xs.Map(x => (short)x); } return xs; @@ -76,30 +77,32 @@ public static class PartIndexUtils public static Durable.Def GetDurableDefForPartIndices(object? partIndices) => partIndices switch { - null => throw new Exception("Invariant 598ae146-211f-4cee-af57-985eb26ce961."), - uint => Durable.Octree.PerCellPartIndex1ui, - IReadOnlyList => Durable.Octree.PerPointPartIndex1b, + null => throw new Exception("Invariant 598ae146-211f-4cee-af57-985eb26ce961."), + int => Durable.Octree.PerCellPartIndex1i, + uint => throw new Exception($"Use PerCellPartIndex1i instead of PerCellPartIndex1ui."), //Durable.Octree.PerCellPartIndex1ui, + IReadOnlyList => Durable.Octree.PerPointPartIndex1b, IReadOnlyList => Durable.Octree.PerPointPartIndex1s, - IReadOnlyList => Durable.Octree.PerPointPartIndex1i, + IReadOnlyList => Durable.Octree.PerPointPartIndex1i, _ => throw new Exception($"Unsupported part indices type {partIndices.GetType().FullName}. Invariant 6700c73d-1842-4fe9-a6b0-28420965cecb.") }; /// /// Get intex-th part index. /// - public static uint? Get(object? o, int index) => o switch + public static int? Get(object? o, int index) => o switch { - null => null, - uint x => x, - byte[] xs => (uint)xs[index], - short[] xs => (uint)xs[index], - int[] xs => (uint)xs[index], + null => null, + int x => x, + uint x => (int)x, + byte[] xs => xs[index], + short[] xs => xs[index], + int[] xs => xs[index], _ => throw new Exception($"Unexpected type {o.GetType().FullName}. Invariant 98f41e6c-6065-4dd3-aa9e-6619cc71873d.") }; /// - /// Concatenates part indices (uint, [byte|short|int] array). + /// Concatenates part indices (int, [byte|short|int] array). /// public static object? ConcatIndices( object? first , int firstCount, @@ -114,8 +117,24 @@ public static class PartIndexUtils (null, object y) => y, (object x, null) => x, - (uint x, uint y) => (x == y) ? x : createArray1(x, firstCount, y, secondCount), + (int x, int y) => (x == y) ? x : createArray1( x, firstCount, y, secondCount), + (int x, uint y) => (x == y) ? x : createArray1( x, firstCount, (int)y, secondCount), + (uint x, int y) => (x == y) ? x : createArray1((int)x, firstCount, y, secondCount), + (uint x, uint y) => (x == y) ? x : createArray1((int)x, firstCount, (int)y, secondCount), + (int x, _ ) => second switch + { + IReadOnlyList ys when x <= byte .MaxValue => createArray2((byte )x, firstCount, ys ), + IReadOnlyList ys when x <= short.MaxValue => createArray2((short)x, firstCount, b2s(ys)), + IReadOnlyList ys when x <= int .MaxValue => createArray2( x, firstCount, b2i(ys)), + + IReadOnlyList ys when x <= short.MaxValue => createArray2((short)x, firstCount, ys ), + IReadOnlyList ys when x <= int .MaxValue => createArray2( x, firstCount, s2i(ys)), + + IReadOnlyList ys when x <= int .MaxValue => createArray2( x, firstCount, ys ), + + _ => throw new Exception("Invariant efc1aa79-06d3-4768-8302-6ed743632fe3.") + }, (uint x, _ ) => second switch { IReadOnlyList ys when x <= byte .MaxValue => createArray2((byte )x, firstCount, ys ), @@ -129,7 +148,20 @@ public static class PartIndexUtils _ => throw new Exception("Invariant 588fea29-4daa-4356-92a4-369f64ac5778.") }, + + (_ , int y) => first switch + { + IReadOnlyList xs when y <= byte .MaxValue => createArray3( xs , (byte )y, secondCount), + IReadOnlyList xs when y <= short.MaxValue => createArray3(b2s(xs), (short)y, secondCount), + IReadOnlyList xs when y <= int .MaxValue => createArray3(b2i(xs), y, secondCount), + IReadOnlyList xs when y <= short.MaxValue => createArray3( xs , (short)y, secondCount), + IReadOnlyList xs when y <= int .MaxValue => createArray3(s2i(xs), y, secondCount), + + IReadOnlyList xs when y <= int .MaxValue => createArray3(xs, (int )y, secondCount), + + _ => throw new Exception("Invariant ee1933cb-f9d9-4cea-8bd8-ab702f1a8b97.") + }, (_ , uint y) => first switch { IReadOnlyList xs when y <= byte .MaxValue => createArray3( xs , (byte )y, secondCount), @@ -160,14 +192,14 @@ public static class PartIndexUtils ) }; - object createArray1(uint first, int firstCount, uint second, int secondCount) + object createArray1(int first, int firstCount, int second, int secondCount) { var count = firstCount + secondCount; return Math.Max(first, second) switch { - uint max when max <= byte .MaxValue => create((byte )first, (byte )second), - uint max when max <= short.MaxValue => create((short)first, (short)second), - uint max when max <= int .MaxValue => create((int )first, (int )second), + int max when max <= byte .MaxValue => create((byte )first, (byte )second), + int max when max <= short.MaxValue => create((short)first, (short)second), + int max when max <= int .MaxValue => create( first, second), _ => throw new Exception("Invariant 129edb1c-066d-4ff2-8edf-8c5a67191dea.") }; @@ -217,7 +249,7 @@ object createArray4(IReadOnlyList first, IReadOnlyList second) where T } /// - /// Concatenates part indices (null, uint, [byte|short|int] array). + /// Concatenates part indices (null, int, [byte|short|int] array). /// public static object? ConcatIndices(IEnumerable<(object? indices, int count)> xs) { @@ -257,11 +289,12 @@ public static Range1i ExtendRangeBy(in Range1i range, object partIndices) /// public static object? Skip(object? partIndices, int n) => partIndices switch { - null => null, - uint x => x, - IList xs => xs.Skip(n).ToArray(), + null => null, + int x => x, + uint x => (int)x, + IList xs => xs.Skip(n).ToArray(), IList xs => xs.Skip(n).ToArray(), - IList xs => xs.Skip(n).ToArray(), + IList xs => xs.Skip(n).ToArray(), _ => throw new Exception( $"Unexpected part indices type {partIndices.GetType().FullName}. " + @@ -274,11 +307,12 @@ public static Range1i ExtendRangeBy(in Range1i range, object partIndices) /// public static object? Take(object? partIndices, int n) => partIndices switch { - null => null, - uint x => x, - IList xs => xs.Take(n).ToArray(), + null => null, + int x => x, + uint x => (int)x, + IList xs => xs.Take(n).ToArray(), IList xs => xs.Take(n).ToArray(), - IList xs => xs.Take(n).ToArray(), + IList xs => xs.Take(n).ToArray(), _ => throw new Exception( $"Unexpected part indices type {partIndices.GetType().FullName}. " + @@ -292,7 +326,8 @@ public static Range1i ExtendRangeBy(in Range1i range, object partIndices) public static object? Subset(object? partIndices, IReadOnlyList subsetIndices) => partIndices switch { null => null, - uint x => x, + int x => x, + uint x => (int)x, IList xs => subsetIndices.MapToArray(i => xs[i]), IList xs => subsetIndices.MapToArray(i => xs[i]), IList xs => subsetIndices.MapToArray(i => xs[i]), diff --git a/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs b/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs index 9f996e0f..7df6d1bd 100644 --- a/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs +++ b/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs @@ -65,14 +65,15 @@ public static InMemoryPointSet Build(IList ps, IList? cs, IList? switch (partIndices) { case null : break; - case uint xs: data = data.Add(Durable.Octree.PerCellPartIndex1ui, xs ); break; - case byte[] xs: data = data.Add(Durable.Octree.PerPointPartIndex1b, xs); break; + case int x : data = data.Add(Durable.Octree.PerCellPartIndex1i , x ); break; + case uint x : data = data.Add(Durable.Octree.PerCellPartIndex1i , (int)x ); break; + case byte[] xs: data = data.Add(Durable.Octree.PerPointPartIndex1b, xs ); break; case IList xs: data = data.Add(Durable.Octree.PerPointPartIndex1b, xs.ToArray()); break; case IEnumerable xs: data = data.Add(Durable.Octree.PerPointPartIndex1b, xs.ToArray()); break; - case short[] xs: data = data.Add(Durable.Octree.PerPointPartIndex1s, xs); break; + case short[] xs: data = data.Add(Durable.Octree.PerPointPartIndex1s, xs ); break; case IList xs: data = data.Add(Durable.Octree.PerPointPartIndex1s, xs.ToArray()); break; case IEnumerable xs: data = data.Add(Durable.Octree.PerPointPartIndex1s, xs.ToArray()); break; - case int[] xs: data = data.Add(Durable.Octree.PerPointPartIndex1i, xs); break; + case int[] xs: data = data.Add(Durable.Octree.PerPointPartIndex1i, xs ); break; case IList xs: data = data.Add(Durable.Octree.PerPointPartIndex1i, xs.ToArray()); break; case IEnumerable xs: data = data.Add(Durable.Octree.PerPointPartIndex1i, xs.ToArray()); break; @@ -93,7 +94,9 @@ private InMemoryPointSet(ImmutableDictionary data, Cell cel foreach (var kv in data) { - if (kv.Key == Durable.Octree.PerCellPartIndex1ui) continue; + if (kv.Key == Durable.Octree.PerCellPartIndex1i || + kv.Key == Durable.Octree.PerCellPartIndex1ui + ) continue; if (kv.Value is not Array) throw new ArgumentException($"Entry {kv.Key} must be array."); } @@ -182,7 +185,9 @@ internal PointSetNode ToPointSetNode(Storage storage, bool isTemporaryImportNode { if (kv.Key == Durable.Octree.PositionsGlobal3d) continue; - if (kv.Key == Durable.Octree.PerCellPartIndex1ui) + if (kv.Key == Durable.Octree.PerCellPartIndex1ui || + kv.Key == Durable.Octree.PerCellPartIndex1i + ) { attributes = attributes.Add(kv.Key, kv.Value); continue; diff --git a/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs b/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs index 78ca5dee..63675132 100644 --- a/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs +++ b/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs @@ -192,9 +192,18 @@ internal static Array AggregateSubArrays(int[] counts, int splitLimit, object[] var ias = new int[]?[8]; // special case: all subnodes have identical per-cell index - if (xss.All(xs => xs == null || xs is uint)) + if (xss.All(xs => xs is not Array)) { - var perCellIndices = xss.Where(xs => xs != null).Select(xs => (uint)xs!).ToArray(); + var perCellIndices = xss + .Where(xs => xs != null) + .Select((object? xs) => xs switch { + null => default(int?), + int x => x, + uint x => (int)x , + _ => throw new Exception($"Unexpected type {xs.GetType().FullName}. Error 41874217-05a1-482f-abb5-565cebe6a402.") + }) + .ToArray() + ; if (perCellIndices.Length == 0) return null; var allIdentical = true; for (var i = 1; i < perCellIndices.Length; i++) if (perCellIndices[i] != perCellIndices[0]) { allIdentical = false; break; } @@ -210,11 +219,12 @@ internal static Array AggregateSubArrays(int[] counts, int splitLimit, object[] var xsLength = xs switch { - null => throw new Exception("Invariant 0a65ab38-4b69-4f6d-aa54-36536c86d8d3."), - uint => counts[ci], - byte[] ys => ys.Length, + null => throw new Exception("Invariant 0a65ab38-4b69-4f6d-aa54-36536c86d8d3."), + int => counts[ci], + uint => counts[ci], + byte[] ys => ys.Length, short[] ys => ys.Length, - int[] ys => ys.Length, + int[] ys => ys.Length, _ => throw new Exception($"Unexpected type {xs.GetType().FullName}. Error 8e44dd14-b984-4d7f-8be4-c8e0d4f43189.") }; @@ -413,6 +423,7 @@ bool subnodesHaveAttribute(Func check, string kind) x != Durable.Octree.Classifications1b && x != Durable.Octree.Colors4b && x != Durable.Octree.Intensities1i && + x != Durable.Octree.PerCellPartIndex1i && x != Durable.Octree.PerCellPartIndex1ui && x != Durable.Octree.PerPointPartIndex1b && x != Durable.Octree.PerPointPartIndex1s && diff --git a/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs b/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs index f1a4e0f6..07b79436 100644 --- a/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs +++ b/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs @@ -906,6 +906,7 @@ public PersistentRef? Classifications [JsonIgnore] [MemberNotNullWhen(true, nameof(PartIndices))] public bool HasPartIndices => + Data.ContainsKey(Durable.Octree.PerCellPartIndex1i ) || Data.ContainsKey(Durable.Octree.PerCellPartIndex1ui) || Data.ContainsKey(Durable.Octree.PerPointPartIndex1b) || Data.ContainsKey(Durable.Octree.PerPointPartIndex1s) || @@ -920,7 +921,8 @@ public object? PartIndices { get { - if (Data.TryGetValue(Durable.Octree.PerCellPartIndex1ui, out var pcpi)) return pcpi; + if (Data.TryGetValue(Durable.Octree.PerCellPartIndex1i, out var pcpi)) return pcpi; + else if (Data.TryGetValue(Durable.Octree.PerCellPartIndex1ui, out var pcpui)) return pcpui; else if (Data.TryGetValue(Durable.Octree.PerPointPartIndex1b, out var pppi1b)) return pppi1b; else if (Data.TryGetValue(Durable.Octree.PerPointPartIndex1s, out var pppi1s)) return pppi1s; else if (Data.TryGetValue(Durable.Octree.PerPointPartIndex1i, out var pppi1i)) return pppi1i; diff --git a/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs b/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs index 12cc22a2..e843d357 100644 --- a/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs +++ b/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs @@ -459,6 +459,7 @@ public bool TryGetPartIndices([NotNullWhen(true)] out int[]? result) switch (qs) { case null: result = null; return false; + case int x: result = new int[PointCountCell].Set(x); return true; case uint x: checked { result = new int[PointCountCell].Set((int)x); return true; } case byte[] xs: result = xs.Map(x => (int)x); return true; case short[] xs: result = xs.Map(x => (int)x); return true;