Skip to content

Commit

Permalink
[builder] add build logic for yet more cases
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanmaierhofer committed Mar 15, 2024
1 parent 2b6421e commit 2cb5679
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 60 deletions.
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 0.5.8
- [builder] add build logic for yet more cases

### 0.5.7
- fix Sample.PositionsWithBounds (dict trygetvalue fails when key does not exist, probably due to uninitialized tuple)

Expand Down
89 changes: 36 additions & 53 deletions src/Aardvark.Geometry.Quadtree/Builder.fs
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,13 @@ module Builder =

| 0 ->

//printfn "[00000] %d" rootCell.Exponent

if config.Verbose then
printfn "[build''] ZERO patches"

NoNode

| 1 ->

//printfn "[11111] %d" rootCell.Exponent

if config.Verbose then
printfn "[build''] SINGLE patch (%A)" patches[0].SampleWindow

Expand All @@ -146,8 +142,6 @@ module Builder =

| 2 ->

//printfn "[22222] %d" rootCell.Exponent

if config.Verbose then
printfn "[build''] TWO patches (%A, %A)" patches[0].SampleWindow patches[1].SampleWindow

Expand All @@ -158,52 +152,37 @@ module Builder =

| n -> // n patches

//printfn "[nnnnn] %d" rootCell.Exponent

if config.Verbose then
printfn "[build''] MULTIPLE patches (n=%d)" patches.Length

let ebb = patches |> Seq.map (fun patch -> patch.BoundingBox) |> Box2d

invariantm (config.SplitLimitPowerOfTwo >= 0)
(fun () -> sprintf "Expected config.SplitLimitPowerOfTwo to be non-negative, but found %d." config.SplitLimitPowerOfTwo)
"95c43529-9649-42d6-9b47-c6f8fb6da301"

let mutable forceFlatten = false
//let tileSize = 1 <<< config.SplitLimitPowerOfTwo

// bounds of root cell at level of highest-resolution patch
// exact bounding box in global space
let ebb = patches |> Seq.map (fun patch -> patch.BoundingBox) |> Box2d
// bounds of root cell in sample space (at sample level of highest-resolution patch)
let rootBounds = getBoundsForExponent minSampleExponent rootCell

// if all remaining patches have the same resolution, then we can flatten all layers
// (because there can be no troubles with overlapping samples of different sizes)
if (patches |> Seq.distinctBy (fun p -> p.SampleExponent) |> Seq.tryExactlyOne).IsSome then
forceFlatten <- true
let allRemainingPatchesHaveSameResolution =
(patches |> Seq.distinctBy (fun p -> p.SampleExponent) |> Seq.tryExactlyOne).IsSome

if config.Verbose then
if allRemainingPatchesHaveSameResolution then
printfn "[build''] FLATTEN all %d patches, because they have same resolution" patches.Length
else
printfn "[build''] DO NOT FLATTEN %d patches, because different resolutions" patches.Length


let patchesWithMinExp = patches |> Array.filter (fun p -> p.SampleExponent = minSampleExponent)
if patchesWithMinExp |> Array.exists (fun p -> p.SampleWindow.Contains(rootBounds)) then
forceFlatten <- true

//let patchesPerQuadrant =
// rootCell.Children
// |> Array.map (fun subCell ->
// let subPatches =
// patches
// |> Array.choose (fun patch ->
// let bbQuadrant = subCell.GetBoundsForExponent(patch.SampleExponent)
// let r = patch.WithWindow bbQuadrant
// //if config.Verbose && r.IsSome then
// // printfn "[build''] | subCell=%A patch.Window=%A bbQuadrant=%A" subCell patch.SampleWindow r.Value.SampleWindow
// r
// )
// (subCell, subPatches)
// )

//let patchesPerQuadrantCounts = patchesPerQuadrant |> Array.map (fun (_, ps) -> ps.Length)
//let canMakeProgress = patchesPerQuadrantCounts |> Array.forall (fun count -> count < n)

//if rootBounds.Size.X <= tileSize && rootBounds.Size.Y <= tileSize then
if rootCell.Exponent = minSampleExponent || forceFlatten (*&& rootBounds.Size.X <= tileSize && rootBounds.Size.Y <= tileSize*) then
let forceFlatten = patchesWithMinExp |> Array.exists (fun p -> p.SampleWindow.Contains(rootBounds))

let stopRecursion = rootCell.Exponent = minSampleExponent || forceFlatten || (allRemainingPatchesHaveSameResolution && rootCell.Exponent < minSampleExponent + config.SplitLimitPowerOfTwo)

if stopRecursion then

// current tile size has reached the split limit:
// 1. sort all patches from fine to coarse (from small to large sample exponents)
Expand All @@ -213,7 +192,10 @@ module Builder =
// -> a mask indicates non-defined samples

if config.Verbose then
printfn "[build''] MERGE %d patches; because reached split limit" n
if forceFlatten then
printfn "[build''] MERGE %d patches (forceFlatten = true)" n
else
printfn "[build''] MERGE %d patches; because reached split limit" n

//if debugOutput then
// let bbWindow = patches |> Seq.map (fun patch -> patch.SampleWindow) |> Box2l
Expand All @@ -228,24 +210,25 @@ module Builder =

let mutable rootCell = rootCell

if requiredRootCellExponent <> rootCell.Exponent then
if not forceFlatten then
if requiredRootCellExponent <> rootCell.Exponent then

invariantm (rootCell.Exponent < requiredRootCellExponent)
(fun () -> sprintf "Expected root cell exponent %d to be smaller than requiredRootCellExponent %d." rootCell.Exponent requiredRootCellExponent)
"4911adf3-7b87-4234-9bcc-bc3076df846e"
invariantm (rootCell.Exponent < requiredRootCellExponent)
(fun () -> sprintf "Expected root cell exponent %d to be smaller than requiredRootCellExponent %d." rootCell.Exponent requiredRootCellExponent)
"4911adf3-7b87-4234-9bcc-bc3076df846e"

if config.Verbose then
printfn "[build''] | must adjust root cell %A exponent to %d ..." rootCell requiredRootCellExponent
if config.Verbose then
printfn "[build''] | must adjust root cell %A exponent to %d ..." rootCell requiredRootCellExponent

while rootCell.Exponent < requiredRootCellExponent do rootCell <- rootCell.Parent
while rootCell.Exponent < requiredRootCellExponent do rootCell <- rootCell.Parent

if config.Verbose then
printfn "[build''] | adjusted root cell is %A" rootCell
if config.Verbose then
printfn "[build''] | adjusted root cell is %A" rootCell

else
else

if config.Verbose then
printfn "[build''] | root cell %A already has requiredRootCellExponent %d" rootCell requiredRootCellExponent
if config.Verbose then
printfn "[build''] | root cell %A already has requiredRootCellExponent %d" rootCell requiredRootCellExponent

let flattended = LayerSet.Flatten config.Verbose patches

Expand Down
35 changes: 28 additions & 7 deletions src/Scratch/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1480,21 +1480,42 @@ let cp_20240311_quadtree_exception () =
printfn "reloaded from file, %d patches" (x.GetPatches() |> Seq.length)

let sw = Stopwatch.StartNew()
let buildConfig = { BuildConfig.Default with Verbose = false; SplitLimitPowerOfTwo = 8 }
let buildConfig = { BuildConfig.Default with Verbose = true; SplitLimitPowerOfTwo = 8 }
let maybeQuadtree = x.Build2 buildConfig
sw.Stop()
printfn "[TIMING] build: %A" sw.Elapsed

match maybeQuadtree with
| None -> failwith ""
| None -> failwith "build failed"
| Some qtree ->

let pos = V2d(66077.6476628291, 270082.243676802)
match Sample.Position Query.Config.Default pos qtree with
| None -> failwith "foo"
| Some x -> printfn "sample is: %A" x
let makeReturnValOfQueryResults (resultChunk : seq<Query.Result>) (def : Aardvark.Data.Durable.Def) =

let samples =
resultChunk
|> Seq.collect (fun chunk -> chunk.GetSamples<V4f> def)
|> Seq.toList

()
samples

let sw = Stopwatch.StartNew()
let config = Query.Config.Default //{ Query.Config.Default with Verbose = true }
let resultCells = qtree |> Query.All config |> Seq.toArray
let samples = makeReturnValOfQueryResults resultCells Defs.HeightsBilinear4f
let samplesLength = samples.Length
sw.Stop()
printfn "[TIMING] query all samples: %A" sw.Elapsed

printfn("SAMPLES: count=%d") samplesLength
let gs = samples
|> List.groupBy (fun (c, v) -> c.Exponent)
|> List.map (fun (e, xs) ->
let countNaN = xs |> Seq.filter(fun (_, x) -> x.IsNaN) |> Seq.length
(e, xs.Length, countNaN)
)
for (e, c, cNaN) in gs do
printfn(" e=%d; count=%d; count NaN=%d") e c cNaN


()

Expand Down

0 comments on commit 2cb5679

Please sign in to comment.