diff --git a/src/Aardvark.Algodat.Tests/DeleteTests.cs b/src/Aardvark.Algodat.Tests/DeleteTests.cs index 10f49db..145d0fe 100644 --- a/src/Aardvark.Algodat.Tests/DeleteTests.cs +++ b/src/Aardvark.Algodat.Tests/DeleteTests.cs @@ -42,7 +42,9 @@ public static PointSet CreateRandomPointsInUnitCube(int n, int splitLimit) .WithKey("test") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps), config); + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } public static PointSet CreateRegularPointsInUnitCube(int n, int splitLimit) @@ -59,7 +61,9 @@ public static PointSet CreateRegularPointsInUnitCube(int n, int splitLimit) .WithKey("test") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps), config); + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } public static PointSet CreateRandomClassifiedPoints(int n, int splitLimit) @@ -77,7 +81,9 @@ public static PointSet CreateRandomClassifiedPoints(int n, int splitLimit) .WithKey("testaa") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps, null, null, null, ks, null, null), config); + var chunk = new Chunk(ps, null, null, null, ks, null, null); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } [Test] diff --git a/src/Aardvark.Algodat.Tests/ImportTests.cs b/src/Aardvark.Algodat.Tests/ImportTests.cs index 3b27b5d..048d09d 100644 --- a/src/Aardvark.Algodat.Tests/ImportTests.cs +++ b/src/Aardvark.Algodat.Tests/ImportTests.cs @@ -80,7 +80,7 @@ public void CanImportChunkWithoutColor() .WithKey("test") .WithOctreeSplitLimit(10) ; - + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(chunk, config); Assert.IsTrue(pointcloud.PointCount == 100); } @@ -102,6 +102,9 @@ public void CanImportChunk_MinDist() .WithOctreeSplitLimit(10) .WithMinDist(0.5) ; + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(chunk, config); Assert.IsTrue(pointcloud.PointCount < 100); } @@ -124,6 +127,7 @@ public void CanImportChunk_Reproject() .WithOctreeSplitLimit(10) .WithReproject(xs => xs.Select(x => x += V3d.OIO).ToArray()) ; + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(chunk, config); Assert.IsTrue(pointcloud.BoundingBox == bb + V3d.OIO); } @@ -145,6 +149,7 @@ public void CanImport_WithKey() .WithMinDist(0.0) .WithReproject(null) ; + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(chunk, config); Assert.IsTrue(pointcloud.Id == "test"); } @@ -170,6 +175,7 @@ public void CanImportWithKeyAndThenLoadAgainFromStore() .WithMinDist(0.0) .WithReproject(null) ; + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(chunk, config); Assert.IsTrue(pointcloud.Id == key); @@ -195,6 +201,7 @@ public void CanImport_WithoutKey() .WithMinDist(0.0) .WithReproject(null) ; + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(chunk, config); Assert.IsTrue(pointcloud.Id != null); } @@ -217,6 +224,7 @@ public void CanImport_DuplicateKey() .WithReproject(null) ; + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); var pointcloud = PointCloud.Chunks(Array.Empty(), config); Assert.IsTrue(pointcloud.Id != null); diff --git a/src/Aardvark.Algodat.Tests/LodTests.cs b/src/Aardvark.Algodat.Tests/LodTests.cs index 7057e86..8af2cd7 100644 --- a/src/Aardvark.Algodat.Tests/LodTests.cs +++ b/src/Aardvark.Algodat.Tests/LodTests.cs @@ -35,7 +35,7 @@ public void LodCreationSetsLodPointCountCell() var cs = ps.Map(_ => C4b.White); var pointset = PointSet.Create( - storage, "test", ps.ToList(), cs.ToList(), null, null, null, null, 5000, + storage, "test", ps.ToList(), cs.ToList(), null, null, null, partIndices: 42u, 5000, generateLod: false, isTemporaryImportNode: true, ct: default ); pointset.Root.Value.ForEachNode(true, cell => @@ -64,7 +64,7 @@ public void LodPositions() var cs = ps.Map(_ => C4b.White); var pointset = PointSet.Create( - storage, "test", ps.ToList(), cs.ToList(), null, null, null, null, 5000, + storage, "test", ps.ToList(), cs.ToList(), null, null, null, partIndices: 42u, 5000, generateLod: true, isTemporaryImportNode: true, default ); pointset.Root.Value.ForEachNode(true, cell => @@ -192,7 +192,9 @@ public void HasCentroid() }; var config = ImportConfig.Default.WithStorage(storage).WithRandomKey(); - var n = PointCloud.Chunks(new Chunk(ps), config).Root.Value; + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + var n = PointCloud.Chunks(chunk, config).Root.Value; Assert.IsTrue(n.HasCentroidLocal); Assert.IsTrue(n.HasCentroidLocalStdDev); @@ -217,7 +219,9 @@ public void HasBoundingBoxExact() }; var config = ImportConfig.Default.WithStorage(storage).WithRandomKey(); - var n = PointCloud.Chunks(new Chunk(ps), config).Root.Value; + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + var n = PointCloud.Chunks(chunk, config).Root.Value; Assert.IsTrue(n.HasBoundingBoxExactLocal); Assert.IsTrue(n.BoundingBoxExactLocal == new Box3f(new V3f(-0.4f), new V3f(0.4f))); @@ -237,7 +241,9 @@ public void HasTreeDepth() var ps = new V3d[10].SetByIndex(_ => new V3d(r.NextDouble(), r.NextDouble(), r.NextDouble())); var config = ImportConfig.Default.WithStorage(storage).WithRandomKey(); - var n = PointCloud.Chunks(new Chunk(ps), config).Root.Value; + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + var n = PointCloud.Chunks(chunk, config).Root.Value; Assert.IsTrue(n.HasMinTreeDepth); Assert.IsTrue(n.HasMaxTreeDepth); @@ -255,7 +261,9 @@ public void HasTreeDepth2() var ps = new V3d[20000].SetByIndex(_ => new V3d(r.NextDouble(), r.NextDouble(), r.NextDouble())); var config = ImportConfig.Default.WithStorage(storage).WithRandomKey(); - var n = PointCloud.Chunks(new Chunk(ps), config).Root.Value; + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + var n = PointCloud.Chunks(chunk, config).Root.Value; Assert.IsTrue(n.HasMinTreeDepth); Assert.IsTrue(n.HasMaxTreeDepth); @@ -283,7 +291,9 @@ public void HasPointDistance() }; var config = ImportConfig.Default.WithStorage(storage).WithRandomKey(); - var n = PointCloud.Chunks(new Chunk(ps), config).Root.Value; + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + var n = PointCloud.Chunks(chunk, config).Root.Value; Assert.IsTrue(n.HasPointDistanceAverage); Assert.IsTrue(n.HasPointDistanceStandardDeviation); diff --git a/src/Aardvark.Algodat.Tests/PointCloudTests.cs b/src/Aardvark.Algodat.Tests/PointCloudTests.cs index 6edd70c..270a270 100644 --- a/src/Aardvark.Algodat.Tests/PointCloudTests.cs +++ b/src/Aardvark.Algodat.Tests/PointCloudTests.cs @@ -35,7 +35,9 @@ private static PointSet CreateRandomPointsInUnitCube(int n, int splitLimit) .WithKey("test") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps), config); + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } private static PointSet CreateRegularPointsInUnitCube(int n, int splitLimit) @@ -52,7 +54,9 @@ private static PointSet CreateRegularPointsInUnitCube(int n, int splitLimit) .WithKey("test") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps), config); + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } [Test] diff --git a/src/Aardvark.Algodat.Tests/Program.cs b/src/Aardvark.Algodat.Tests/Program.cs index d38b7ad..f6b849b 100644 --- a/src/Aardvark.Algodat.Tests/Program.cs +++ b/src/Aardvark.Algodat.Tests/Program.cs @@ -1750,7 +1750,8 @@ internal static void Test_Import_Regression() { var filenames = new[] { - @"W:\Datasets\Vgm\Data\structured_pointclouds\lowergetikum 20230321.e57", + @"W:\Datasets\Vgm\Data\E57\JBs_Haus.e57", + //@"W:\Datasets\Vgm\Data\structured_pointclouds\lowergetikum 20230321.e57", //@"W:\Datasets\Vgm\Data\structured_pointclouds\JB_Haus_2022_KG.e57", //@"W:\Datasets\Vgm\Data\2023-02-23_bugreport\KOE1 OG7.e57", //@"W:\Datasets\unstruk\Christchurch.laz", @@ -1806,6 +1807,7 @@ internal static void Test_Import_Regression() .WithMinDist(0) .WithNormalizePointDensityGlobal(false) //.WithProgressCallback(p => { Report.Line($"{p:0.00}"); }) + .WithEnabledPartIndices(true) ; var pcl = PointCloud @@ -2687,13 +2689,15 @@ static async Task Ranges_Test_20230802() public static async Task Main(string[] _) { + Test_Import_Regression(); + //await CreateStore( // @"T:\Kindergarten.pts", // @"W:\Aardworx\pointshare2\testdata\2023-08-01_kindergarten.store", // minDist: 0.0 // ); - await Ranges_Test_20230802(); + //await Ranges_Test_20230802(); //await ParseTest_20230730(); diff --git a/src/Aardvark.Algodat.Tests/ProgressReportingTests.cs b/src/Aardvark.Algodat.Tests/ProgressReportingTests.cs index fac82a8..7e2a2fe 100644 --- a/src/Aardvark.Algodat.Tests/ProgressReportingTests.cs +++ b/src/Aardvark.Algodat.Tests/ProgressReportingTests.cs @@ -51,7 +51,7 @@ static IEnumerable GenerateChunks(int numberOfPointsPerChunk) { var _ps = new V3d[numberOfPointsPerChunk]; for (var i = 0; i < numberOfPointsPerChunk; i++) _ps[i] = new V3d(r.NextDouble(), r.NextDouble(), r.NextDouble()); - yield return new Chunk(_ps); + yield return new Chunk(_ps).WithPartIndices(42u); } } } diff --git a/src/Aardvark.Algodat.Tests/QueryTests.cs b/src/Aardvark.Algodat.Tests/QueryTests.cs index 2fb7989..28ed5c9 100644 --- a/src/Aardvark.Algodat.Tests/QueryTests.cs +++ b/src/Aardvark.Algodat.Tests/QueryTests.cs @@ -36,7 +36,9 @@ private static PointSet CreateRandomPointsInUnitCube(int n, int splitLimit) .WithKey("test") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps), config); + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } private static PointSet CreateClusteredPointsInUnitCube(int n, int splitLimit) @@ -51,7 +53,9 @@ private static PointSet CreateClusteredPointsInUnitCube(int n, int splitLimit) .WithKey("test") .WithOctreeSplitLimit(splitLimit) ; - return PointCloud.Chunks(new Chunk(ps), config); + var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + return PointCloud.Chunks(chunk, config); } private static PointSet CreateRegularPointsInUnitCube(int n, int splitLimit) @@ -67,8 +71,9 @@ private static PointSet CreateRegularPointsInUnitCube(int n, int splitLimit) .WithStorage(PointCloud.CreateInMemoryStore(cache: default)) .WithKey("test") .WithOctreeSplitLimit(splitLimit) - ; - var pc = PointCloud.Chunks(new Chunk(ps), config); + ; var chunk = new Chunk(ps); + if (config.ParseConfig.EnabledProperties.PartIndices) chunk = chunk.WithPartIndices(42u); + var pc = PointCloud.Chunks(chunk, config); return pc; } @@ -780,7 +785,7 @@ private static PointSet InternalCreateRandomPointSetForOctreeLevelTests() var config = ImportConfig.Default.WithKey("Test").WithOctreeSplitLimit(1); return PointSet .Create( - storage, "test", ps.ToList(), cs.ToList(), null, null, null, null, 100, + storage, "test", ps.ToList(), cs.ToList(), null, null, null, partIndices: 42u, 100, generateLod: false, isTemporaryImportNode: true, default ) .GenerateLod(config) diff --git a/src/Aardvark.Data.Points.Base/PartIndexUtils.cs b/src/Aardvark.Data.Points.Base/PartIndexUtils.cs index c0b6dd4..272c76d 100644 --- a/src/Aardvark.Data.Points.Base/PartIndexUtils.cs +++ b/src/Aardvark.Data.Points.Base/PartIndexUtils.cs @@ -18,8 +18,6 @@ limitations under the License. using Aardvark.Base; using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; using System.Linq; #pragma warning disable CS1591 @@ -31,6 +29,51 @@ namespace Aardvark.Data.Points; /// public static class PartIndexUtils { + /// + /// Compacts part indices. + /// If per-point indices are all identical, then return per-cell index. + /// If max per-point index fits in a smaller type (e.g. byte), then convert to array of smaller type. + /// + public static object? Compact(object? o) + { + switch (o) + { + case null: return null; + case uint x: return 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; + } + 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.Max < 256) checked { return xs.Map(x => (byte)x); } + return xs; + } + case int[] xs: + { + 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.Max < 256) checked { return xs.Map(x => (byte)x); } + if (range.Max < 32768) checked { return xs.Map(x => (short)x); } + return xs; + } + default: + throw new Exception( + $"Unexpected type {o.GetType().FullName}. " + + $"Invariant 5b5857b3-b389-41d8-ae81-50f6ef3c133e." + ); + } + } + public static Durable.Def GetDurableDefForPartIndices(object? partIndices) => partIndices switch { null => throw new Exception("Invariant 598ae146-211f-4cee-af57-985eb26ce961."), diff --git a/src/Aardvark.Geometry.PointSet/Import/MapReduce.cs b/src/Aardvark.Geometry.PointSet/Import/MapReduce.cs index 38e59c2..d564c61 100644 --- a/src/Aardvark.Geometry.PointSet/Import/MapReduce.cs +++ b/src/Aardvark.Geometry.PointSet/Import/MapReduce.cs @@ -47,7 +47,14 @@ public static PointSet MapReduce(this IEnumerable chunks, ImportConfig co var root = builder.ToPointSetNode(config.Storage, isTemporaryImportNode: true); var id = $"Aardvark.Geometry.PointSet.{Guid.NewGuid()}.json"; var pointSet = new PointSet(config.Storage, id, root.Id, config.OctreeSplitLimit); - + +#if DEBUG + if (config.ParseConfig.EnabledProperties.PartIndices) + { + if (!chunk.HasPartIndices) throw new Exception("Invariant 04c62ea7-287b-473f-a3e9-6b5451222e27."); + } +#endif + return pointSet; }, config.MaxDegreeOfParallelism, null, config.CancellationToken diff --git a/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs b/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs index 702f5b7..9f996e0 100644 --- a/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs +++ b/src/Aardvark.Geometry.PointSet/Octrees/InMemoryPointSet.cs @@ -181,7 +181,13 @@ internal PointSetNode ToPointSetNode(Storage storage, bool isTemporaryImportNode foreach (var kv in _octree.m_data) { if (kv.Key == Durable.Octree.PositionsGlobal3d) continue; - if (kv.Key == Durable.Octree.PerCellPartIndex1ui) continue; + + if (kv.Key == Durable.Octree.PerCellPartIndex1ui) + { + attributes = attributes.Add(kv.Key, kv.Value); + continue; + } + var subset = kv.Value.Subset(_ia); attributes = attributes.Add(kv.Key, subset); } diff --git a/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs b/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs index fd67de0..ccbf256 100644 --- a/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs +++ b/src/Aardvark.Geometry.PointSet/Octrees/Lod.cs @@ -15,6 +15,7 @@ You should have received a copy of the GNU Affero General Public License using Aardvark.Data; using Aardvark.Data.Points; using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -177,6 +178,73 @@ internal static Array AggregateSubArrays(int[] counts, int splitLimit, object[] }; } + /// + /// + /// + /// Number of points to take from each subnode. + /// + /// + /// + internal static object? AggregateSubPartIndices(int[] counts, int aggregateCount, object?[] xss) + { + var result = default(object?); + var ias = new int[]?[8]; + + // special case: all subnodes have identical per-cell index +#if NOT_YET + if (xss.All(xs => xs == null || xs is uint)) + { + var perCellIndices = xss.Where(xs => xs != null).Select(xs => (uint)xs!).ToArray(); + var allIdentical = true; + for (var i = 1; i < perCellIndices.Length; i++) if (perCellIndices[i] != perCellIndices[0]) { allIdentical = false; break; } + if (allIdentical) return perCellIndices[0]; + } +#endif + + var i = 0; + for (var ci = 0; ci < 8; ci++) + { + if (counts[ci] == 0) continue; + var xs = xss[ci]!; + + var xsLength = xs switch + { + null => throw new Exception("Invariant 0a65ab38-4b69-4f6d-aa54-36536c86d8d3."), + uint => counts[ci], + byte[] ys => ys.Length, + short[] ys => ys.Length, + int[] ys => ys.Length, + _ => throw new Exception($"Unexpected type {xs.GetType().FullName}. Error 8e44dd14-b984-4d7f-8be4-c8e0d4f43189.") + }; + + if (xsLength == counts[ci]) + { + result = PartIndexUtils.ConcatIndices(result, i, xs, xsLength); + i += xsLength; + } + else if (xsLength > counts[ci]) + { + var ia = new List(); + var dj = (xsLength + 0.49) / counts[ci]; + for (var j = 0.0; j < xsLength; j += dj) ia.Add((int)j); + var subset = PartIndexUtils.Subset(xs, ia); + result = PartIndexUtils.ConcatIndices(result, i, xs, xsLength); + i += ia.Count; + } + else + { + throw new Exception( + $"Expected number of sub-indices {xsLength} to be greater or equal than {counts[ci]}. " + + $"Invariant 3a9eeb72-8e56-404a-8def-7001b02c960d." + ); + } + } + + result = PartIndexUtils.Compact(result); + + return result; + } + private static async Task GenerateLod(this PointSet self, string? key, Action callback, CancellationToken ct) { try @@ -285,6 +353,12 @@ internal static async Task GenerateLod(this PointSetNode self, var fractions = ComputeLodFractions(subcells); var aggregateCount = Math.Min(octreeSplitLimit, subcells.Sum(x => x?.PointCountCell) ?? 0); var counts = ComputeLodCounts(aggregateCount, fractions); +#if DEBUG + if (counts.Sum() != aggregateCount) throw new Exception( + $"Expected aggregate count {aggregateCount} to be the same as sum of LoD counts {counts.Sum()}. " + + $"Invariant 21033eb8-2a19-43a5-82b4-f6c398ac599f." + ); +#endif ////////////////////////////////////////////////////////////////// // generate LoD data ... @@ -322,7 +396,11 @@ bool subnodesHaveAttribute(Func check, string kind) x != Durable.Octree.Normals3f && x != Durable.Octree.Classifications1b && x != Durable.Octree.Colors4b && - x != Durable.Octree.Intensities1i + x != Durable.Octree.Intensities1i && + x != Durable.Octree.PerCellPartIndex1ui && + x != Durable.Octree.PerPointPartIndex1b && + x != Durable.Octree.PerPointPartIndex1s && + x != Durable.Octree.PerPointPartIndex1i ).ToArray(); // ... positions ... @@ -367,21 +445,28 @@ void addAttributeByRef(string kind, Durable.Def def, Func x?.PartIndices)); + if (lodQs != null) + { + upsertData = upsertData.Add(PartIndexUtils.GetDurableDefForPartIndices(lodQs), lodQs); + } + // ... classifications ... - addAttributeByRef("classifications", Durable.Octree.Classifications1bReference, n => n.HasClassifications, n => n!.Classifications!.Value); + addAttributeByRef("classifications", Durable.Octree.Classifications1bReference, n => n.HasClassifications, n => n?.Classifications?.Value); // ... colors ... - addAttributeByRef("colors", Durable.Octree.Colors4bReference, n => n.HasColors, n => n!.Colors!.Value); + addAttributeByRef("colors", Durable.Octree.Colors4bReference, n => n.HasColors, n => n?.Colors?.Value); // ... intensities ... - addAttributeByRef("intensities", Durable.Octree.Intensities1iReference, n => n.HasIntensities, n => n!.Intensities!.Value); + addAttributeByRef("intensities", Durable.Octree.Intensities1iReference, n => n.HasIntensities, n => n?.Intensities?.Value); // ... for all other attributes ... foreach (var def in lodAttributeCandidates) { try { - var lod = AggregateSubArrays(counts, octreeSplitLimit, subcells.Map(x => x?.Properties[def]!)); + var lod = AggregateSubArrays(counts, octreeSplitLimit, subcells.Map(x => x?.Properties[def]!)); if (lod.Length != lodPs.Length) throw new Exception( $"Inconsistent lod-array length {lod.Length}. Should be {lodPs.Length}. Error e3f0398a-b0ae-4e57-95ab-b5d83922ec6e." ); diff --git a/src/Aardvark.Geometry.PointSet/Queries/QueriesDirectedRay3d.cs b/src/Aardvark.Geometry.PointSet/Queries/QueriesDirectedRay3d.cs index 027420f..ce775fe 100644 --- a/src/Aardvark.Geometry.PointSet/Queries/QueriesDirectedRay3d.cs +++ b/src/Aardvark.Geometry.PointSet/Queries/QueriesDirectedRay3d.cs @@ -91,7 +91,7 @@ public static IEnumerable QueryPointsNearRay( node.Normals?.Value.Subset(ia), node.Intensities?.Value.Subset(ia), node.Classifications?.Value.Subset(ia), - node.PartIndices?.Subset(ia), + PartIndexUtils.Subset(node.PartIndices, ia), bbox: null ); } diff --git a/src/Aardvark.Geometry.PointSet/Queries/QueriesGeneric.cs b/src/Aardvark.Geometry.PointSet/Queries/QueriesGeneric.cs index 1ce7d76..91b5541 100644 --- a/src/Aardvark.Geometry.PointSet/Queries/QueriesGeneric.cs +++ b/src/Aardvark.Geometry.PointSet/Queries/QueriesGeneric.cs @@ -66,7 +66,7 @@ public static IEnumerable QueryPoints(this IPointCloudNode node, for (var i = 0; i < ps.Length; i++) if (isPositionInside(ps[i])) ia.Add(i); if (ia.Count > 0) yield return new Chunk( - ps.Subset(ia), csRaw?.Subset(ia), nsRaw?.Subset(ia), jsRaw?.Subset(ia), ksRaw?.Subset(ia), qsRaw?.Subset(ia), bbox: null + ps.Subset(ia), csRaw?.Subset(ia), nsRaw?.Subset(ia), jsRaw?.Subset(ia), ksRaw?.Subset(ia), PartIndexUtils.Subset(qsRaw, ia), bbox: null ); } } diff --git a/src/Aardvark.Geometry.PointSet/Queries/QueriesRayLine3d.cs b/src/Aardvark.Geometry.PointSet/Queries/QueriesRayLine3d.cs index e772e8b..610258b 100644 --- a/src/Aardvark.Geometry.PointSet/Queries/QueriesRayLine3d.cs +++ b/src/Aardvark.Geometry.PointSet/Queries/QueriesRayLine3d.cs @@ -167,7 +167,7 @@ public static IEnumerable QueryPointsNearLineSegment( node.Normals?.Value.Subset(ia), node.Intensities?.Value.Subset(ia), node.Classifications?.Value.Subset(ia), - parts: node.PartIndices?.Subset(ia), + parts: PartIndexUtils.Subset(node.PartIndices, ia), bbox: null); throw new NotImplementedException("PARTINDICES"); }