diff --git a/src/Aardvark.Data.Points.Base/Storage.cs b/src/Aardvark.Data.Points.Base/Storage.cs
index 899780dd..84139397 100644
--- a/src/Aardvark.Data.Points.Base/Storage.cs
+++ b/src/Aardvark.Data.Points.Base/Storage.cs
@@ -46,7 +46,9 @@ public class Storage : IDisposable
/// add(key, value, create)
public readonly Action> f_add;
- ///
+ ///
+ /// Returns null if key does not exist.
+ ///
public readonly Func f_get;
///
diff --git a/src/Aardvark.Geometry.PointSet/Octrees/Export.cs b/src/Aardvark.Geometry.PointSet/Octrees/Export.cs
index 097ff4d6..f27cd7d3 100644
--- a/src/Aardvark.Geometry.PointSet/Octrees/Export.cs
+++ b/src/Aardvark.Geometry.PointSet/Octrees/Export.cs
@@ -84,8 +84,7 @@ public static ExportPointSetInfo ExportPointSet(
if (pointSet == null)
{
- var (success, root) = self.TryGetPointCloudNode(pointSetId);
- if (success)
+ if (self.TryGetPointCloudNode(pointSetId, out var root))
{
var ersatzPointSetKey = Guid.NewGuid().ToString();
Report.Warn($"Created PointSet with key '{ersatzPointSetKey}'.");
diff --git a/src/Aardvark.Geometry.PointSet/Octrees/IPointCloudNodeExtensions.cs b/src/Aardvark.Geometry.PointSet/Octrees/IPointCloudNodeExtensions.cs
index 00ae7300..51d7fc59 100644
--- a/src/Aardvark.Geometry.PointSet/Octrees/IPointCloudNodeExtensions.cs
+++ b/src/Aardvark.Geometry.PointSet/Octrees/IPointCloudNodeExtensions.cs
@@ -73,7 +73,7 @@ public static void ForEachNode(
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node)) node.ForEachNode(outOfCore, action);
+ if (n.TryGetFromCache(out var node)) node.ForEachNode(outOfCore, action);
}
}
}
@@ -148,7 +148,7 @@ public static void ForEachIntersectingNode(
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node))
+ if (n.TryGetFromCache(out var node))
{
node.ForEachIntersectingNode(outOfCore, hull, doNotTraverseSubnodesWhenFullyInside, action, ct);
}
@@ -424,7 +424,7 @@ long FastCount(Guid key)
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node)) count += node.CountNodes(outOfCore);
+ if (n.TryGetFromCache(out var node)) count += node.CountNodes(outOfCore);
}
}
}
@@ -455,7 +455,7 @@ public static long CountLeafNodes(this IPointCloudNode self, bool outOfCore)
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node)) count += node.CountLeafNodes(outOfCore);
+ if (n.TryGetFromCache(out var node)) count += node.CountLeafNodes(outOfCore);
}
}
}
@@ -489,7 +489,7 @@ public static long GetMinimumLeafPointCount(this IPointCloudNode self, bool outO
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node))
+ if (n.TryGetFromCache(out var node))
{
var x = node.GetMinimumLeafPointCount(outOfCore);
if (x < min) min = x;
@@ -528,7 +528,7 @@ public static long GetMaximumLeafPointCount(this IPointCloudNode self, bool outO
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node))
+ if (n.TryGetFromCache(out var node))
{
var x = node.GetMinimumLeafPointCount(outOfCore);
if (x > max) max = x;
@@ -576,7 +576,7 @@ public static int GetMinimumTreeDepth(this IPointCloudNode self, bool outOfCore)
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node))
+ if (n.TryGetFromCache(out var node))
{
var x = node.GetMinimumTreeDepth(outOfCore);
if (x < min) min = x;
@@ -615,7 +615,7 @@ public static int GetMaximiumTreeDepth(this IPointCloudNode self, bool outOfCore
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node))
+ if (n.TryGetFromCache(out var node))
{
var x = node.GetMaximiumTreeDepth(outOfCore);
if (x > max) max = x;
@@ -660,7 +660,7 @@ private static void GetAverageTreeDepth(this IPointCloudNode self, bool outOfCor
var n = self.Subnodes[i];
if (n != null)
{
- if (n.TryGetValue(out var node)) node.GetAverageTreeDepth(outOfCore, depth, ref sum, ref count);
+ if (n.TryGetFromCache(out var node)) node.GetAverageTreeDepth(outOfCore, depth, ref sum, ref count);
}
}
}
diff --git a/src/Aardvark.Geometry.PointSet/Octrees/Inline.cs b/src/Aardvark.Geometry.PointSet/Octrees/Inline.cs
index f63aefc8..48866103 100644
--- a/src/Aardvark.Geometry.PointSet/Octrees/Inline.cs
+++ b/src/Aardvark.Geometry.PointSet/Octrees/Inline.cs
@@ -306,7 +306,7 @@ static IEnumerable EnumerateRecImpl(IPointCloudNode node, HashSet survive
var hasColors = node.HasColors;
var hasClassifications = node.HasClassifications;
var hasIntensities = node.HasIntensities;
- var subnodes = node.Subnodes?.Map(x => x?.TryGetValue());
+ var subnodes = node.Subnodes?.Map(x => x?.Value);
var isNotLeaf = !node.IsLeaf;
var ps = default(V3f[]);
@@ -418,7 +418,7 @@ static byte[] rescaleIntensities(int[] js32)
if (config.Collapse && isNotLeaf)
{
if (subnodes == null) throw new Exception("Assertion failed. Error 42565d4a-2e91-4961-a310-095b503fe6f1.");
- var nonEmptySubNodes = subnodes.Where(x => x.HasValue && x.Value.hasValue).Select(x => x!.Value.value!).ToArray();
+ var nonEmptySubNodes = subnodes.Where(x => x != null).Select(x => x!).ToArray();
ps = nonEmptySubNodes
.SelectMany(n =>
@@ -457,9 +457,9 @@ static byte[] rescaleIntensities(int[] js32)
var guids2 = subnodes
.Map(nref =>
{
- if (nref.HasValue && nref.Value.hasValue)
+ if (nref != null)
{
- var n = nref.Value.value!;
+ var n = nref!;
return !n.IsLeaf ? n.Id : Guid.Empty;
}
else
@@ -471,7 +471,7 @@ static byte[] rescaleIntensities(int[] js32)
var isNewLeaf = guids2.All(k => k == Guid.Empty);
if (!isNewLeaf)
{
- subnodeGuids = subnodes.Map(x => x.HasValue && x.Value.hasValue ? x.Value.value!.Id : Guid.Empty);
+ subnodeGuids = subnodes.Map(x => x != null ? x.Id : Guid.Empty);
foreach (var g in nonEmptySubNodes) survive.Add(g.Id);
}
}
@@ -479,14 +479,14 @@ static byte[] rescaleIntensities(int[] js32)
{
if (isNotLeaf)
{
- subnodeGuids = subnodes.Map(x => x.HasValue && x.Value.hasValue ? x.Value.value!.Id : Guid.Empty);
+ subnodeGuids = subnodes.Map(x => x != null ? x.Id : Guid.Empty);
}
ps = node.Positions.Value!;
if (hasColors) cs = node.Colors!.Value;
if (hasClassifications) ks = node.Classifications!.Value;
if (hasIntensities) js = rescaleIntensities(node.Intensities!.Value!);
- if (isNotLeaf) subnodeGuids = subnodes.Map(x => x.HasValue && x.Value.hasValue ? x.Value.value!.Id : Guid.Empty);
+ if (isNotLeaf) subnodeGuids = subnodes.Map(x => x != null ? x.Id : Guid.Empty);
}
diff --git a/src/Aardvark.Geometry.PointSet/Octrees/PointSet.cs b/src/Aardvark.Geometry.PointSet/Octrees/PointSet.cs
index cb29f2c9..8334ca36 100644
--- a/src/Aardvark.Geometry.PointSet/Octrees/PointSet.cs
+++ b/src/Aardvark.Geometry.PointSet/Octrees/PointSet.cs
@@ -15,6 +15,7 @@ You should have received a copy of the GNU Affero General Public License
using Aardvark.Data.Points;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
@@ -95,8 +96,8 @@ public PointSet(Storage storage, string pointSetId, Guid rootCellId, int splitLi
Id = pointSetId ?? throw new ArgumentNullException(nameof(pointSetId));
SplitLimit = splitLimit;
- Root = new PersistentRef(rootCellId.ToString(), storage.GetPointCloudNode!,
- k => { var (a, b) = storage.TryGetPointCloudNode(k); return (a, b); }
+ Root = new PersistentRef(rootCellId.ToString(), storage.GetPointCloudNode,
+ storage.TryGetPointCloudNode
);
}
@@ -111,7 +112,7 @@ public PointSet(Storage storage, string key, IPointCloudNode root, int splitLimi
Id = key ?? throw new ArgumentNullException(nameof(key));
SplitLimit = splitLimit;
- Root = new PersistentRef(root.Id.ToString(), storage.GetPointCloudNode!, storage.TryGetPointCloudNode);
+ Root = new PersistentRef(root.Id.ToString(), storage.GetPointCloudNode, storage.TryGetPointCloudNode);
}
///
@@ -123,7 +124,7 @@ public PointSet(Storage storage, string key)
Id = key ?? throw new ArgumentNullException(nameof(key));
SplitLimit = 0;
- Root = new(id: "", _ => PointSetNode.Empty, _ => (true, PointSetNode.Empty));
+ Root = new(id: Guid.Empty, PointSetNode.Empty);
}
#endregion
@@ -156,8 +157,8 @@ public PointSet(Storage storage, string key)
public JsonNode ToJson() => JsonSerializer.SerializeToNode(new
{
Id,
- RootCellId = Root.Id,
- OctreeId = Root.Id, // backwards compatibility
+ OctreeId = Root.Id,
+ RootCellId = Root.Id, // backwards compatibility
SplitLimit,
PartIndexRange
})!;
@@ -168,18 +169,22 @@ public static PointSet Parse(JsonNode json, Storage storage)
{
var o = json.AsObject() ?? throw new Exception($"Expected JSON object, but found {json}.");
+ // id
+ var id = (string?)o["Id"] ?? throw new Exception("Missing id. Error 71730558-699e-4128-b0f2-130fd04672e9.");
+
+
var octreeId = (string?)o["OctreeId"] ?? (string?)o["RootCellId"];
+ if (octreeId == "" || octreeId == Guid.Empty.ToString()) octreeId = null;
+
var octreeRef = octreeId != null
- ? new PersistentRef(octreeId, storage.GetPointCloudNode!, storage.TryGetPointCloudNode)
+ ? new PersistentRef(octreeId, storage.GetPointCloudNode, storage.TryGetPointCloudNode)
: null
;
+ var octree = octreeRef?.Value;
// backwards compatibility: if split limit is not set, guess as number of points in root cell
var splitLimit = o.TryGetPropertyValue("SplitLimit", out var x) ? (int)x! : 8192;
- // id
- var id = (string?)o["Id"] ?? throw new Exception("Missing id. Error 71730558-699e-4128-b0f2-130fd04672e9.");
-
// part index range (JsonArray)
var partIndexRangeArray = (JsonArray?)o["PartIndexRange"];
var partIndexRange = partIndexRangeArray != null
@@ -187,8 +192,6 @@ public static PointSet Parse(JsonNode json, Storage storage)
: Range1i.Invalid
;
- //
- var octree = octreeRef?.Value;
return new PointSet(storage, id, octree ?? PointSetNode.Empty, splitLimit).WithPartIndexRange(partIndexRange);
}
diff --git a/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs b/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs
index 22d0e58c..f56951da 100644
--- a/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs
+++ b/src/Aardvark.Geometry.PointSet/Octrees/PointSetNode.cs
@@ -162,26 +162,26 @@ public PointSetNode(
var isId = IntensitiesId;
var ksId = ClassificationsId;
- if (psId != null) PersistentRefs[Durable.Octree.PositionsLocal3fReference] = new PersistentRef(psId.Value, storage.GetV3fArray!, storage.TryGetV3fArray);
- if (csId != null) PersistentRefs[Durable.Octree.Colors4bReference] = new PersistentRef(csId.Value, storage.GetC4bArray!, storage.TryGetC4bArray);
+ if (psId != null) PersistentRefs[Durable.Octree.PositionsLocal3fReference] = new PersistentRef(psId.Value, storage.GetV3fArray, storage.TryGetV3fArrayFromCache);
+ if (csId != null) PersistentRefs[Durable.Octree.Colors4bReference] = new PersistentRef(csId.Value, storage.GetC4bArray, storage.TryGetC4bArrayFromCache);
if (kdId != null)
{
if (isObsoleteFormat)
{
PersistentRefs[Durable.Octree.PointRkdTreeFDataReference] =
- new PersistentRef>(kdId.Value, LoadKdTreeObsolete, TryLoadKdTreeObsolete)
+ new PersistentRef>(kdId.Value, LoadKdTreeObsolete, TryLoadKdTreeObsoleteOut)
;
}
else
{
PersistentRefs[Durable.Octree.PointRkdTreeFDataReference] =
- new PersistentRef>(kdId.Value, LoadKdTree, TryLoadKdTree)
+ new PersistentRef>(kdId.Value, LoadKdTree, TryLoadKdTreeOut)
;
}
}
- if (nsId != null) PersistentRefs[Durable.Octree.Normals3fReference] = new PersistentRef(nsId.Value, storage.GetV3fArray!, storage.TryGetV3fArray);
- if (isId != null) PersistentRefs[Durable.Octree.Intensities1iReference] = new PersistentRef(isId.Value, storage.GetIntArray!, storage.TryGetIntArray);
- if (ksId != null) PersistentRefs[Durable.Octree.Classifications1bReference] = new PersistentRef(ksId.Value, storage.GetByteArray!, storage.TryGetByteArray);
+ if (nsId != null) PersistentRefs[Durable.Octree.Normals3fReference] = new PersistentRef(nsId.Value, storage.GetV3fArray, storage.TryGetV3fArrayFromCache);
+ if (isId != null) PersistentRefs[Durable.Octree.Intensities1iReference] = new PersistentRef(isId.Value, storage.GetIntArray, storage.TryGetIntArrayFromCache);
+ if (ksId != null) PersistentRefs[Durable.Octree.Classifications1bReference] = new PersistentRef(ksId.Value, storage.GetByteArray, storage.TryGetByteArrayFromCache);
#endregion
@@ -323,7 +323,7 @@ public PointSetNode(
kdId = ComputeAndStoreKdTree(Storage, Positions.Value);
Data = Data.Add(Durable.Octree.PointRkdTreeFDataReference, kdId);
PersistentRefs[Durable.Octree.PointRkdTreeFDataReference] =
- new PersistentRef>(kdId.Value, LoadKdTree, TryLoadKdTree)
+ new PersistentRef>(kdId.Value, LoadKdTree, TryLoadKdTreeOut)
;
#else
//Debugger.Break();
@@ -403,20 +403,6 @@ PointRkdTreeF LoadKdTree(string key)
);
}
- (bool, PointRkdTreeF?) TryLoadKdTree(string key)
- {
- var (ok, value) = Storage.TryGetPointRkdTreeFData(key);
- if (ok == false) return (false, default);
- var ps = Positions.Value!;
- return (true, new PointRkdTreeF(
- 3, ps.Length, ps,
- (xs, i) => xs[(int)i], (v, i) => (float)v[i],
- (a, b) => Vec.Distance(a, b), (i, a, b) => b - a,
- (a, b, c) => Vec.DistanceToLine(a, b, c), Fun.Lerp, 1e-6f,
- value
- ));
- }
-
PointRkdTreeF LoadKdTreeObsolete(string key)
{
var value = Storage.GetPointRkdTreeFDataFromD(key);
@@ -430,18 +416,76 @@ PointRkdTreeF LoadKdTreeObsolete(string key)
);
}
- (bool, PointRkdTreeF?) TryLoadKdTreeObsolete(string key)
+ //(bool, PointRkdTreeF?) TryLoadKdTree(string key)
+ //{
+ // var (ok, value) = Storage.TryGetPointRkdTreeFData(key);
+ // if (ok == false) return (false, default);
+ // var ps = Positions.Value!;
+ // return (true, new PointRkdTreeF(
+ // 3, ps.Length, ps,
+ // (xs, i) => xs[(int)i], (v, i) => (float)v[i],
+ // (a, b) => Vec.Distance(a, b), (i, a, b) => b - a,
+ // (a, b, c) => Vec.DistanceToLine(a, b, c), Fun.Lerp, 1e-6f,
+ // value
+ // ));
+ //}
+
+ //(bool, PointRkdTreeF?) TryLoadKdTreeObsolete(string key)
+ //{
+ // var (ok, value) = Storage.TryGetPointRkdTreeFDataFromD(key);
+ // if (ok == false) return (false, default);
+ // var ps = Positions.Value!;
+ // return (true, new PointRkdTreeF(
+ // 3, ps.Length, ps,
+ // (xs, i) => xs[(int)i], (v, i) => (float)v[i],
+ // (a, b) => Vec.Distance(a, b), (i, a, b) => b - a,
+ // (a, b, c) => Vec.DistanceToLine(a, b, c), Fun.Lerp, 1e-6f,
+ // value
+ // ));
+ //}
+
+ bool TryLoadKdTreeOut(string key, [NotNullWhen(true)] out PointRkdTreeF? result)
+ {
+ var (ok, value) = Storage.TryGetPointRkdTreeFData(key);
+ if (ok == false)
+ {
+ result = default;
+ return false;
+ }
+ else
+ {
+ var ps = Positions.Value!;
+ result = new PointRkdTreeF(
+ 3, ps.Length, ps,
+ (xs, i) => xs[(int)i], (v, i) => (float)v[i],
+ (a, b) => Vec.Distance(a, b), (i, a, b) => b - a,
+ (a, b, c) => Vec.DistanceToLine(a, b, c), Fun.Lerp, 1e-6f,
+ value
+ );
+ return true;
+ }
+ }
+
+ bool TryLoadKdTreeObsoleteOut(string key, [NotNullWhen(true)] out PointRkdTreeF? result)
{
var (ok, value) = Storage.TryGetPointRkdTreeFDataFromD(key);
- if (ok == false) return (false, default);
- var ps = Positions.Value!;
- return (true, new PointRkdTreeF(
- 3, ps.Length, ps,
- (xs, i) => xs[(int)i], (v, i) => (float)v[i],
- (a, b) => Vec.Distance(a, b), (i, a, b) => b - a,
- (a, b, c) => Vec.DistanceToLine(a, b, c), Fun.Lerp, 1e-6f,
- value
- ));
+ if (ok == false)
+ {
+ result = default;
+ return false;
+ }
+ else
+ {
+ var ps = Positions.Value!;
+ result = new PointRkdTreeF(
+ 3, ps.Length, ps,
+ (xs, i) => xs[(int)i], (v, i) => (float)v[i],
+ (a, b) => Vec.Distance(a, b), (i, a, b) => b - a,
+ (a, b, c) => Vec.DistanceToLine(a, b, c), Fun.Lerp, 1e-6f,
+ value
+ );
+ return true;
+ }
}
}
@@ -571,13 +615,13 @@ public PersistentRef Positions
else
{
var ps = Array.Empty();
- return new PersistentRef(Guid.Empty, _ => ps, _ => (true, ps));
+ return new PersistentRef(Guid.Empty, ps);
}
}
else if (Data.TryGetValue(Durable.Octree.PositionsLocal3f, out o))
{
var ps = (V3f[])o;
- return new PersistentRef(Guid.Empty, _ => ps, _ => (true, ps));
+ return new PersistentRef(Guid.Empty, ps);
}
else if (Data.TryGetValue(Durable.Octree.PositionsLocal3b, out o))
{
@@ -588,7 +632,7 @@ public PersistentRef Positions
var ps = new V3f[pCount];
for (int i = 0, j = 0; i < pCount; i++)
ps[i] = new V3f(qs[j++] * step - hsize, qs[j++] * step - hsize, qs[j++] * step - hsize);
- return new PersistentRef(Guid.Empty, _ => ps, _ => (true, ps));
+ return new PersistentRef(Guid.Empty, ps);
}
else if (Data.TryGetValue(Durable.Octree.PositionsLocal3us, out o))
{
@@ -599,7 +643,7 @@ public PersistentRef Positions
var ps = new V3f[pCount];
for (int i = 0, j = 0; i < pCount; i++)
ps[i] = new V3f(qs[j++] * step - hsize, qs[j++] * step - hsize, qs[j++] * step - hsize);
- return new PersistentRef(Guid.Empty, _ => ps, _ => (true, ps));
+ return new PersistentRef(Guid.Empty, ps);
}
else if (Data.TryGetValue(Durable.Octree.PositionsLocal3ui, out o))
{
@@ -610,7 +654,7 @@ public PersistentRef Positions
var ps = new V3f[pCount];
for (int i = 0, j = 0; i < pCount; i++)
ps[i] = new V3f(qs[j++] * step - hsize, qs[j++] * step - hsize, qs[j++] * step - hsize);
- return new PersistentRef(Guid.Empty, _ => ps, _ => (true, ps));
+ return new PersistentRef(Guid.Empty, ps);
}
else if (Data.TryGetValue(Durable.Octree.PositionsLocal3ul, out o))
{
@@ -621,11 +665,10 @@ public PersistentRef Positions
var ps = new V3f[pCount];
for (int i = 0, j = 0; i < pCount; i++)
ps[i] = new V3f(qs[j++] * step - hsize, qs[j++] * step - hsize, qs[j++] * step - hsize);
- return new PersistentRef(Guid.Empty, _ => ps, _ => (true, ps));
+ return new PersistentRef(Guid.Empty, ps);
}
else
return null!;
- //return new(id: "", _ => Array.Empty(), _ => (true, Array.Empty()));
}
}
@@ -710,20 +753,20 @@ public PersistentRef? Colors
else if (Data.TryGetValue(Durable.Octree.Colors4b, out o))
{
var xs = (C4b[])o;
- return new PersistentRef(Guid.Empty, _ => xs, _ => (true, xs));
+ return new PersistentRef(Guid.Empty, xs);
}
else if (PersistentRefs.TryGetValue(Durable.Octree.Colors3bReference, out o) && ((PersistentRef)o).Id != GuidEmptyString)
{
// convert on the fly ...
var pref = (PersistentRef)o;
var xs = pref.Value.Map(c => new C4b(c));
- return new PersistentRef(Guid.Empty, _ => xs, _ => (true, xs));
+ return new PersistentRef(Guid.Empty, xs);
}
else if (Data.TryGetValue(Durable.Octree.Colors3b, out o))
{
// convert on the fly
var xs = ((C3b[])o).Map(c => new C4b(c));
- return new PersistentRef(Guid.Empty, _ => xs, _ => (true, xs));
+ return new PersistentRef(Guid.Empty, xs);
}
else
{
@@ -762,7 +805,7 @@ public PersistentRef? Normals
else if (Data.TryGetValue(Durable.Octree.Normals3f, out o))
{
var xs = (V3f[])o;
- return new PersistentRef(Guid.Empty, _ => xs, _ => (true, xs));
+ return new PersistentRef(Guid.Empty, xs);
}
else
{
@@ -801,7 +844,7 @@ public PersistentRef? Intensities
else if (Data.TryGetValue(Durable.Octree.Intensities1i, out o))
{
var xs = (int[])o;
- return new PersistentRef(Guid.Empty, _ => xs, _ => (true, xs));
+ return new PersistentRef(Guid.Empty, xs);
}
else
{
@@ -840,7 +883,7 @@ public PersistentRef? Classifications
else if (Data.TryGetValue(Durable.Octree.Classifications1b, out o))
{
var xs = (byte[])o;
- return new PersistentRef(Guid.Empty, _ => xs, _ => (true, xs));
+ return new PersistentRef(Guid.Empty, xs);
}
else
{
diff --git a/src/Aardvark.Geometry.PointSet/Utils/PersistentRef.cs b/src/Aardvark.Geometry.PointSet/Utils/PersistentRef.cs
index 4858b420..77374c71 100644
--- a/src/Aardvark.Geometry.PointSet/Utils/PersistentRef.cs
+++ b/src/Aardvark.Geometry.PointSet/Utils/PersistentRef.cs
@@ -15,54 +15,67 @@ You should have received a copy of the GNU Affero General Public License
using System;
using System.Diagnostics.CodeAnalysis;
-namespace Aardvark.Geometry.Points
+namespace Aardvark.Geometry.Points;
+
+
+///
+///
+public class PersistentRef
+ where T : notnull
{
+ private readonly Func f_get;
+ private readonly TryGetFunc f_tryGetFromCache;
+
+ public delegate bool TryGetFunc(string key, [NotNullWhen(true)] out T? result);
///
///
- public class PersistentRef
- where T : notnull
+ public PersistentRef(Guid id, Func get, TryGetFunc tryGetFromCache)
+ : this(id.ToString(), get, tryGetFromCache)
{
- private readonly Func f_get;
- private readonly Func f_tryGet;
+ }
- ///
- ///
- public PersistentRef(Guid id, Func get, Func tryGet)
- : this(id.ToString(), get, tryGet)
- {
- }
+ ///
+ ///
+ public PersistentRef(string id, Func get, TryGetFunc tryGetFromCache)
+ {
+ Id = id;
+ f_get = get ?? throw new ArgumentNullException(nameof(get));
+ f_tryGetFromCache = tryGetFromCache ?? throw new ArgumentNullException(nameof(tryGetFromCache));
+ }
- ///
- ///
- public PersistentRef(string id, Func get, Func tryGet)
- {
- Id = id; //?? throw new ArgumentNullException(nameof(id));
- f_get = get ?? throw new ArgumentNullException(nameof(get));
- f_tryGet = tryGet ?? throw new ArgumentNullException(nameof(tryGet));
- }
-
- ///
- ///
- public string Id { get; }
-
- ///
- ///
- public bool TryGetValue([NotNullWhen(true)]out T? value)
+ ///
+ ///
+ public PersistentRef(Guid id, T valueInMemory)
+ : this(id.ToString(), valueInMemory)
+ {
+ }
+
+ ///
+ ///
+ public PersistentRef(string id, T valueInMemory)
+ {
+ Id = id;
+ f_get = _ => valueInMemory;
+ bool tryGetFromCache(string key, [NotNullWhen(true)] out T? result)
{
- bool isSome = false;
- T? x = default;
- (isSome, x) = f_tryGet(Id);
- value = x;
- return isSome;
+ result = valueInMemory;
+ return true;
}
+ f_tryGetFromCache = tryGetFromCache;
+ }
+
+ ///
+ ///
+ public string Id { get; }
+
+ ///
+ ///
+ public T Value => f_get(Id);
- ///
- ///
- public (bool hasValue, T? value) TryGetValue() => f_tryGet(Id);
+ ///
+ ///
+ public bool TryGetFromCache([NotNullWhen(true)] out T? value)
+ => f_tryGetFromCache(Id, out value);
- ///
- ///
- public T? Value => f_get(Id);
- }
}
diff --git a/src/Aardvark.Geometry.PointSet/Utils/StorageExtensions.cs b/src/Aardvark.Geometry.PointSet/Utils/StorageExtensions.cs
index b69c4307..c4ea6741 100644
--- a/src/Aardvark.Geometry.PointSet/Utils/StorageExtensions.cs
+++ b/src/Aardvark.Geometry.PointSet/Utils/StorageExtensions.cs
@@ -226,6 +226,25 @@ public static PointRkdTreeFData BufferToPointRkdTreeFData(byte[] buffer)
///
public static class StorageExtensions
{
+ #region Generic
+
+ ///
+ public static bool TryGetFromCache(this Storage storage, string key, [NotNullWhen(true)] out T? result)
+ {
+ if (storage.HasCache && storage.Cache.TryGetValue(key, out object o))
+ {
+ result = (T)o;
+ return true;
+ }
+ else
+ {
+ result = default;
+ return false;
+ }
+ }
+
+ #endregion
+
#region Stores
///
@@ -306,6 +325,8 @@ public static (bool, byte[]?) TryGetByteArray(this Storage storage, string key)
return (buffer != null, buffer);
}
+ public static bool TryGetByteArrayFromCache(this Storage storage, string key, [NotNullWhen(true)] out byte[]? result) => TryGetFromCache(storage, key, out result);
+
///
/// Return ungzipped buffer, or original buffer if it is not gzipped.
///
@@ -410,17 +431,7 @@ public static void Add(this Storage storage, string key, IList data)
}
///
- public static (bool, V3f[]?) TryGetV3fArray(this Storage storage, string key)
- {
- if (storage.HasCache && storage.Cache.TryGetValue(key, out object o))
- {
- return (true, (V3f[])o);
- }
- else
- {
- return (false, default);
- }
- }
+ public static bool TryGetV3fArrayFromCache(this Storage storage, string key, [NotNullWhen(true)] out V3f[]? result) => TryGetFromCache(storage, key, out result);
#endregion
@@ -461,6 +472,8 @@ public static (bool, int[]?) TryGetIntArray(this Storage storage, string key)
}
}
+ public static bool TryGetIntArrayFromCache(this Storage storage, string key, [NotNullWhen(true)] out int[]? result) => TryGetFromCache(storage, key, out result);
+
#endregion
#region C4b[]
@@ -500,6 +513,8 @@ public static (bool, C4b[]?) TryGetC4bArray(this Storage storage, string key)
}
}
+ public static bool TryGetC4bArrayFromCache(this Storage storage, string key, [NotNullWhen(true)] out C4b[]? result) => TryGetFromCache(storage, key, out result);
+
#endregion
#region PointRkdTreeDData
@@ -547,6 +562,8 @@ public static PointRkdTreeD GetKdTree(this Storage storage, string k
storage.GetPointRkdTreeDData(key)
);
+ public static bool TryGetPointRkdTreeDDataFromCache(this Storage storage, string key, [NotNullWhen(true)] out C4b[]? result) => TryGetFromCache(storage, key, out result);
+
#endregion
#region PointRkdTreeFData
@@ -602,6 +619,8 @@ public static (bool, PointRkdTreeFData?) TryGetPointRkdTreeFData(this Storage st
}
}
+ public static bool TryGetPointRkdTreeFDataFromCache(this Storage storage, string key, [NotNullWhen(true)] out C4b[]? result) => TryGetFromCache(storage, key, out result);
+
///
public static (bool, PointRkdTreeFData?) TryGetPointRkdTreeFDataFromD(this Storage storage, string key)
{
@@ -615,30 +634,7 @@ public static (bool, PointRkdTreeFData?) TryGetPointRkdTreeFDataFromD(this Stora
}
}
- /////
- /////
- //public static PointRkdTreeF GetKdTreeF(this Storage storage, string key, V3f[] positions)
- // => new PointRkdTreeF(
- // 3, positions.Length, positions,
- // (xs, i) => xs[(int)i], (v, i) => (float)v[i],
- // (a, b) => V3f.Distance(a, b), (i, a, b) => b - a,
- // (a, b, c) => VecFun.DistanceToLine(a, b, c), VecFun.Lerp, 1e-6f,
- // storage.GetPointRkdTreeFData(key)
- // );
-
- /////
- /////
- //public static (bool, PointRkdTreeF) TryGetKdTreeF(this Storage storage, string key, V3f[] positions)
- //{
- // if (storage.HasCache && storage.Cache.TryGetValue(key, out object o))
- // {
- // return (true, (PointRkdTreeF)o);
- // }
- // else
- // {
- // return (false, default);
- // }
- //}
+ public static bool TryGetPointRkdTreeFDataFromDFromCache(this Storage storage, string key, [NotNullWhen(true)] out C4b[]? result) => TryGetFromCache(storage, key, out result);
#endregion
@@ -703,26 +699,30 @@ public static void Add(this Storage storage, string key, IPointCloudNode data)
});
}
- ///
- public static IPointCloudNode? GetPointCloudNode(this Storage storage, Guid key)
+ ///
+ ///
+ public static IPointCloudNode GetPointCloudNode(this Storage storage, Guid key)
=> GetPointCloudNode(storage, key.ToString());
- ///
- public static IPointCloudNode? GetPointCloudNode(this Storage storage, string key)
+ ///
+ ///
+ public static IPointCloudNode GetPointCloudNode(this Storage storage, string key)
{
- if (key == null) return null;
-
if (storage.HasCache && storage.Cache.TryGetValue(key, out object o))
{
- //if (o == null) return null;
if (o is not IPointCloudNode r) throw new InvalidOperationException(
- $"Invariant d1cb769c-36b6-4374-8248-b8c1ca31d495. [GetPointCloudNode] Store key {key} is not IPointCloudNode."
+ $"Invariant d1cb769c-36b6-4374-8248-b8c1ca31d495. " +
+ $"[GetPointCloudNode] Store key {key} is not IPointCloudNode. " +
+ $"Error 7aebf7f1-3783-42fb-b405-47384e08f716."
);
return r;
}
var buffer = storage.f_get(key);
- if (buffer == null) return null;
+ if (buffer == null) throw new Exception(
+ $"PointCloudNode not found (id={key}). " +
+ $"Error b2ef55c1-1470-465d-80ea-034464c53638."
+ );
try
{
@@ -802,7 +802,34 @@ byte[] UnGzipBuffer(byte[] buffer)
}
}
- ///
+ ///
+ ///
+ public static bool TryGetPointCloudNode(this Storage storage, string key, [NotNullWhen(true)]out IPointCloudNode? result)
+ {
+ if (storage.HasCache && storage.Cache.TryGetValue(key, out object o))
+ {
+ result = (PointSetNode)o;
+ return true;
+ }
+ else
+ {
+ try
+ {
+ result = storage.GetPointCloudNode(key);
+ return true;
+ }
+ catch
+ {
+ result = null;
+ return false;
+ }
+ }
+ }
+
+ ///
+ ///
+
+ [Obsolete("Use TryGetPointCloudNode with out parameter instead.")]
public static (bool, IPointCloudNode?) TryGetPointCloudNode(this Storage storage, string key)
{
if (storage.HasCache && storage.Cache.TryGetValue(key, out object o))
diff --git a/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs b/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs
index e9bec598..e3fc6cf5 100644
--- a/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs
+++ b/src/Aardvark.Geometry.PointSet/Views/FilteredNode.cs
@@ -254,7 +254,7 @@ public PersistentRef[]? Subnodes
else if (n0 != null)
{
var n = new FilteredNode(id, false, n0, Filter);
- m_subnodes_cache[i] = new PersistentRef(id.ToString(), _ => n, _ => (true, n));
+ m_subnodes_cache[i] = new PersistentRef(id, n);
}
}
else
@@ -318,7 +318,7 @@ private void EnsurePositionsAndDerived()
m_cache[Octree.BoundingBoxExactLocal.Id] = bboxLocal;
var kd = psLocal.BuildKdTree();
- var pRefKd = new PersistentRef>(Guid.NewGuid().ToString(), _ => kd, _ => (true, kd));
+ var pRefKd = new PersistentRef>(Guid.NewGuid(), kd);
m_cache[Octree.PointRkdTreeFData.Id] = pRefKd;
m_ensuredPositionsAndDerived = true;
@@ -531,7 +531,7 @@ public PersistentRef> KdTree
var key = (Id + originalValue.Id).ToGuid().ToString();
var xs = originalValue.Value.Where((_, i) => m_activePoints.Contains(i)).ToArray();
- var result = new PersistentRef(key, _ => xs, _ => (true, xs));
+ var result = new PersistentRef(key, xs);
m_cache[def.Id] = result;
return result;
}