Skip to content

Commit 7eb89f5

Browse files
sync
1 parent 9d408c2 commit 7eb89f5

File tree

2 files changed

+161
-69
lines changed

2 files changed

+161
-69
lines changed

src/Aardvark.Geometry.Quadtree/Builder.fs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,7 @@ module Builder =
207207
if config.Verbose then
208208
printfn "[build''] | root cell %A already has requiredRootCellExponent %d" rootCell requiredRootCellExponent
209209

210-
let merged = LayerSet.Merge patches
211-
212-
let flattended = LayerSet.Flatten patches
210+
let flattended = LayerSet.Flatten config.Verbose patches
213211

214212
failwith "TODO"
215213

src/Aardvark.Geometry.Quadtree/Layer.fs

Lines changed: 160 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,31 @@ open Aardvark.Data
55
open System
66
open System.Collections.Immutable
77
open System.Collections.Generic
8-
open System.Diagnostics
98

109
#nowarn "44"
1110

1211
type ILayer =
12+
1313
abstract member Def : Durable.Def
14+
1415
abstract member Mapping : DataMapping
16+
1517
/// Returns this layer with new window w (Some), or None if new window is not inside the current layer window.
1618
abstract member WithWindow : Box2l -> ILayer option
19+
1720
abstract member MapSingleCenteredSampleTo : Cell2d -> ILayer
21+
1822
abstract member WithSemantic : Durable.Def -> ILayer
23+
1924
abstract member Materialize : unit -> ILayer
25+
2026
abstract member ToDurableMap : unit -> seq<KeyValuePair<Durable.Def, obj>>
27+
2128
abstract member Mask : byte[] option
2229

30+
/// Resamples this layer to specified sample exponent.
31+
abstract member Resample : int -> ILayer
32+
2333
[<AutoOpen>]
2434
module ILayerExtensions =
2535
type ILayer with
@@ -77,36 +87,6 @@ type Layer<'a when 'a : equality>(def : Durable.Def, data : 'a[], mapping : Data
7787
member this.WithSemantic (newSemantic : Durable.Def) =
7888
Layer(newSemantic, data, mapping, mask) :> ILayer
7989

80-
member this.Materialize () =
81-
if mapping.Window.Min = V2l.OO && mapping.WindowSize = mapping.BufferSize then
82-
this :> ILayer
83-
else
84-
let size = V2i(mapping.WindowSize)
85-
let newArrayLength = int mapping.Window.Area
86-
let newdata = Array.zeroCreate<'a> newArrayLength
87-
let mutable i = 0
88-
for y = 0 to size.Y - 1 do
89-
for x = 0 to size.X - 1 do
90-
let c = Cell2d(mapping.Window.Min.X + int64 x, mapping.Window.Min.Y + int64 y, mapping.BufferOrigin.Exponent)
91-
let s = this.GetSample(Fail, c)
92-
newdata[i] <- s
93-
i <- i + 1
94-
95-
let newmask =
96-
match mask with
97-
| None -> None
98-
| Some mask ->
99-
let mutable i = 0
100-
let newmask = Array.zeroCreate<byte> newArrayLength
101-
for y = 0 to size.Y - 1 do
102-
for x = 0 to size.X - 1 do
103-
newmask[i] <- mask[mapping.GetBufferIndex(mapping.BufferOrigin.X + int64 x, mapping.BufferOrigin.Y + int64 y)]
104-
i <- i + 1
105-
Some newmask
106-
107-
let m = DataMapping(Cell2d(mapping.Window.Min, mapping.BufferOrigin.Exponent), size)
108-
Layer<'a>(def, newdata, m, newmask) :> ILayer
109-
11090
member this.ToDurableMap () = seq {
11191
yield kvp Defs.Layer.DefId def.Id
11292
yield kvp Defs.Layer.BufferOrigin mapping.BufferOrigin
@@ -116,6 +96,10 @@ type Layer<'a when 'a : equality>(def : Durable.Def, data : 'a[], mapping : Data
11696
match mask with | Some x ->yield kvp Defs.Mask1b x | None -> ()
11797
}
11898

99+
member this.Materialize () = this.Materialize () :> ILayer
100+
101+
member this.Resample (e : int) = this.Resample(e) :> ILayer
102+
119103
member this.Def with get() = def
120104
member this.Mapping with get() = mapping
121105
member this.Data with get() = data
@@ -165,6 +149,98 @@ type Layer<'a when 'a : equality>(def : Durable.Def, data : 'a[], mapping : Data
165149
let s = mapping.GetSampleCell globalPos
166150
this.GetSample(mode, s)
167151

152+
member this.Materialize () : Layer<'a> =
153+
if mapping.Window.Min = V2l.OO && mapping.WindowSize = mapping.BufferSize then
154+
this
155+
else
156+
let size = V2i(mapping.WindowSize)
157+
let newArrayLength = int mapping.Window.Area
158+
let newdata = Array.zeroCreate<'a> newArrayLength
159+
let mutable i = 0
160+
for y = 0 to size.Y - 1 do
161+
for x = 0 to size.X - 1 do
162+
let c = Cell2d(mapping.Window.Min.X + int64 x, mapping.Window.Min.Y + int64 y, mapping.BufferOrigin.Exponent)
163+
let s = this.GetSample(Fail, c)
164+
newdata[i] <- s
165+
i <- i + 1
166+
167+
let newmask =
168+
match mask with
169+
| None -> None
170+
| Some mask ->
171+
let mutable i = 0
172+
let newmask = Array.zeroCreate<byte> newArrayLength
173+
for y = 0 to size.Y - 1 do
174+
for x = 0 to size.X - 1 do
175+
newmask[i] <- mask[mapping.GetBufferIndex(mapping.BufferOrigin.X + int64 x, mapping.BufferOrigin.Y + int64 y)]
176+
i <- i + 1
177+
Some newmask
178+
179+
let m = DataMapping(Cell2d(mapping.Window.Min, mapping.BufferOrigin.Exponent), size)
180+
Layer<'a>(def, newdata, m, newmask)
181+
182+
member this.Resample (targetSampleExponent : int) =
183+
184+
if (targetSampleExponent = this.SampleExponent) then
185+
// nothing to do, this layer already has desired sample exponent
186+
this
187+
else
188+
if this.SampleExponent > targetSampleExponent then
189+
190+
if this.Mapping.BufferOrigin.IsCenteredAtOrigin then
191+
failwith "Resampling of layer with centered cell origin is not supported. Error 4f3d2ef0-9d9e-499d-baef-eeaa12e9ade9."
192+
193+
if (this :> ILayer).Mask.IsSome then
194+
failwith "Resampling layer with mask is not supported. Error e29241e5-ef53-45fb-8aee-0f8116231e8f."
195+
196+
let mutable e = this.SampleExponent
197+
let mutable w = this.SampleWindow
198+
199+
let mutable buffer = this.Materialize().Data
200+
201+
invariantm (int64 buffer.Length = this.SampleWindow.Area)
202+
(fun () -> sprintf "Expected materialized buffer of length %d, but found length %d." this.SampleWindow.Area buffer.Length)
203+
"7b2df0b0-4feb-4907-bd1e-ed68b93b62b3"
204+
205+
/// xs contains size.Y rows of size.X values (row major)
206+
let supersample (size : V2i) (xs : 'a[]) : 'a[] =
207+
let rs = Array.zeroCreate (xs.Length * 4)
208+
let mutable j = 0 // next index to write in rs array
209+
210+
// write each input row twice to output buffer with each value written twice
211+
//
212+
// xs: a b c ---> rs: a a b b c c
213+
// d e f a a b b c c
214+
// d d e e f f
215+
// d d e e f f
216+
217+
let rowLength = size.X
218+
219+
for y = 0 to size.Y - 1 do
220+
221+
let yStart = y * rowLength
222+
let writeRow y =
223+
for i = yStart to yStart + rowLength - 1 do
224+
rs[j] <- xs[i]; j <- j + 1
225+
rs[j] <- xs[i]; j <- j + 1 // write i-th value twice
226+
227+
writeRow y
228+
writeRow y // write y-th row twice
229+
230+
()
231+
232+
rs
233+
234+
while e > targetSampleExponent do
235+
buffer <- supersample (V2i(w.Size)) buffer
236+
w <- Box2l(w.Min * 2L, w.Max * 2L)
237+
e <- e - 1
238+
239+
failwith "TODO supersample"
240+
else
241+
failwith "Subsampling layers not supported. Error 88e63cb7-7be7-4136-976f-d81bd12e3246."
242+
243+
168244
module Layer =
169245

170246
let private verbose = false
@@ -259,7 +335,6 @@ module Layer =
259335
| :? (C4f[]) -> Layer<C4f> (def, data :?> C4f[] , mapping, mask) :> ILayer
260336
| _ -> failwith <| sprintf "Unknown type %A. Invariant 4e797062-04a2-445f-9725-79f66823aff8." (data.GetType())
261337

262-
263338
let BoundingBox (layer : ILayer) = layer.Mapping.BoundingBox
264339

265340
let Window (layer : ILayer) = layer.Mapping.Window
@@ -351,31 +426,51 @@ module Layer =
351426
printfn "[DEBUG][Layer.mergeTyped] debugCollisionSamples.Count = %d" debugCollisionSamples.Count
352427
printfn "[DEBUG][Layer.mergeTyped] debugCountOccupied.Count = %d / %d ... %5.2f" coundOccupiedSamples finalMask.Length (float coundOccupiedSamples / float finalMask.Length)
353428

429+
let countOccupied = finalMask |> Array.filter (fun x -> x <> 255uy) |> Array.length
430+
let countUndefined = finalMask |> Array.filter (fun x -> x = 255uy) |> Array.length
431+
printfn "[DEBUG][Layer.mergeTyped][OCCUPANCY][e = %d][%A][%A] countOccupied = %d, countUndefined = %d" e finalWindow finalWindow.Size countOccupied countUndefined
432+
354433
// rewrite mask (1 ... occupied, 0 ... undefined)
355-
356-
let countOccupied = finalMask |> Array.filter (fun x -> x <> 255uy) |> Array.length
357-
let countUndefined = finalMask |> Array.filter (fun x -> x = 255uy) |> Array.length
358-
printfn "[OCCUPANCY][e = %d][%A][%A] countOccupied = %d, countUndefined = %d" e finalWindow finalWindow.Size countOccupied countUndefined
359-
360434
for i = 0 to finalMask.Length-1 do
361435
finalMask[i] <- if finalMask[i] = 255uy then 0uy else 1uy
362436

363437
Layer(def, finalData, finalMapping, if coundOccupiedSamples > 0 then Some finalMask else None)
364438

365-
let private flattenTyped<'a when 'a : equality> (undefinedValue : 'a) (layers : Layer<'a>[]) : Layer<'a> =
366-
let def = ensureSameDef layers
367-
if verbose then
368-
printfn "[Layer.flattenTyped] .... def = %s" def.Name
439+
/// Input layers may have different resolutions (sample sizes).
440+
/// The result layer will have the smallest sample size of all input layers.
441+
/// Input layers will be "painted" into the result layer, potentially overdrawing previous layers.
442+
/// The drawing order is by descending sample exponent (coarse to fine resultion).
443+
/// Coarser input layers will be super-sampled to the result layer sample size.
444+
/// Remaining holes (places where no input layers were "painted") are identified via the result layer's mask property.
445+
let private flattenTyped<'a when 'a : equality> (verbose : bool) (undefinedValue : 'a) (layers : Layer<'a>[]) : Layer<'a> =
369446

370-
failwith "TODO"
447+
let def = ensureSameDef layers
448+
let sampleSizeRange = new Range1i(layers |> Seq.map(fun x -> x.SampleExponent))
371449

372-
let e = layers.[0].SampleExponent
373-
if not (layers |> Array.forall (fun l -> l.SampleExponent = e)) then
374-
failwith "Cannot flatten layers with different resolutions."
450+
// order input layers by descending sample size (from coarse to fine)
451+
let layersOrdered = layers |> Array.sortByDescending (fun x -> x.SampleExponent)
375452

376453
if verbose then
377-
printfn "[Layer.flattenTyped] .... e = %d" e
454+
printfn "[Layer.flattenTyped] ******** BEGIN ******** %d layers; def = %s; sampleSizeRange = %A" layers.Length def.Name sampleSizeRange
455+
456+
/// result sample exponent
457+
let e = sampleSizeRange.Min
378458

459+
460+
let mutable i = 0
461+
for l in layersOrdered do
462+
463+
if verbose then
464+
printfn "[Layer.flattenTyped] | layersOrdered[%d] : e=%d origin=%A size=%A" i l.SampleExponent l.SampleWindow.Min l.SampleWindow.Size
465+
466+
if l.SampleExponent <> e then
467+
let resampledLayer = (l :> ILayer).Resample e
468+
failwith "TODO"
469+
470+
i <- i + 1
471+
472+
failwith "TODO"
473+
379474
let finalWindow = layers |> Seq.map (fun l -> l.SampleWindow) |> Box2l
380475
let finalOrigin = Cell2d(finalWindow.Min, e)
381476
let finalMapping = DataMapping(finalOrigin, V2i finalWindow.Size, finalWindow)
@@ -454,15 +549,14 @@ module Layer =
454549

455550
Layer(def, finalData, finalMapping, if coundOccupiedSamples > 0 then Some finalMask else None)
456551

457-
458552
let private toTyped<'a when 'a : equality> (layers : ILayer[]) : Layer<'a>[] =
459553
layers |> Array.map (fun x -> x :?> Layer<'a>)
460554

461555
let private mergeUntyped_<'a when 'a : equality> (undefinedValue : 'a) xs : ILayer =
462556
xs |> toTyped<'a> |> (mergeTyped undefinedValue) :> ILayer
463557

464-
let private flattenUntyped_<'a when 'a : equality> (undefinedValue : 'a) xs : ILayer =
465-
xs |> toTyped<'a> |> (flattenTyped undefinedValue) :> ILayer
558+
let private flattenUntyped_<'a when 'a : equality> verbose (undefinedValue : 'a) xs : ILayer =
559+
xs |> toTyped<'a> |> (flattenTyped verbose undefinedValue) :> ILayer
466560

467561
/// Merge layers of same type (def).
468562
let Merge (layers : ILayer seq) =
@@ -499,7 +593,7 @@ module Layer =
499593
Some mergedLayers
500594

501595
/// Flatten layers of same type (def).
502-
let Flatten (layers : ILayer seq) =
596+
let Flatten (verbose : bool) (layers : ILayer seq) =
503597
let ls = layers |> Array.ofSeq
504598
match ls.Length with
505599
| 0 ->
@@ -514,20 +608,20 @@ module Layer =
514608
if verbose then printfn "[Layer.Flatten] %d layers" n
515609
let mergedLayers =
516610
match ls.[0] with
517-
| :? Layer<int> -> ls |> flattenUntyped_<int> Int32.MinValue
518-
| :? Layer<int64> -> ls |> flattenUntyped_<int64> Int64.MinValue
519-
| :? Layer<float> -> ls |> flattenUntyped_<float> nan
520-
| :? Layer<float32> -> ls |> flattenUntyped_<float32> nanf
521-
| :? Layer<V2f> -> ls |> flattenUntyped_<V2f> V2f.NaN
522-
| :? Layer<V2d> -> ls |> flattenUntyped_<V2d> V2d.NaN
523-
| :? Layer<V3f> -> ls |> flattenUntyped_<V3f> V3f.NaN
524-
| :? Layer<V3d> -> ls |> flattenUntyped_<V3d> V3d.NaN
525-
| :? Layer<V4f> -> ls |> flattenUntyped_<V4f> V4f.NaN
526-
| :? Layer<V4d> -> ls |> flattenUntyped_<V4d> V4d.NaN
527-
| :? Layer<C3b> -> ls |> flattenUntyped_<C3b> (C3b(0, 0, 0))
528-
| :? Layer<C4b> -> ls |> flattenUntyped_<C4b> (C4b(0, 0, 0, 0))
529-
| :? Layer<C3f> -> ls |> flattenUntyped_<C3f> (C3f(0, 0, 0))
530-
| :? Layer<C4f> -> ls |> flattenUntyped_<C4f> (C4f(0, 0, 0, 0))
611+
| :? Layer<int> -> ls |> flattenUntyped_<int> verbose Int32.MinValue
612+
| :? Layer<int64> -> ls |> flattenUntyped_<int64> verbose Int64.MinValue
613+
| :? Layer<float> -> ls |> flattenUntyped_<float> verbose nan
614+
| :? Layer<float32> -> ls |> flattenUntyped_<float32> verbose nanf
615+
| :? Layer<V2f> -> ls |> flattenUntyped_<V2f> verbose V2f.NaN
616+
| :? Layer<V2d> -> ls |> flattenUntyped_<V2d> verbose V2d.NaN
617+
| :? Layer<V3f> -> ls |> flattenUntyped_<V3f> verbose V3f.NaN
618+
| :? Layer<V3d> -> ls |> flattenUntyped_<V3d> verbose V3d.NaN
619+
| :? Layer<V4f> -> ls |> flattenUntyped_<V4f> verbose V4f.NaN
620+
| :? Layer<V4d> -> ls |> flattenUntyped_<V4d> verbose V4d.NaN
621+
| :? Layer<C3b> -> ls |> flattenUntyped_<C3b> verbose (C3b(0, 0, 0))
622+
| :? Layer<C4b> -> ls |> flattenUntyped_<C4b> verbose (C4b(0, 0, 0, 0))
623+
| :? Layer<C3f> -> ls |> flattenUntyped_<C3f> verbose (C3f(0, 0, 0))
624+
| :? Layer<C4f> -> ls |> flattenUntyped_<C4f> verbose (C4f(0, 0, 0, 0))
531625
| _ -> failwith <| sprintf "Unsupported layer type %A. Invariant 0d379726-27dd-4063-9175-8f13ac44ad83." ls.[0]
532626

533627
Some mergedLayers
@@ -631,7 +725,7 @@ module LayerSet =
631725
/// Flattens multiple layer sets (different resolutions are allowed) down to a single layer set.
632726
/// Holes (which were not covered by any source layerset) are marked by an optional mask.
633727
/// All layer sets must have identical layers (same number, same semantics, same order).
634-
let Flatten (layerSets : LayerSet seq) : LayerSet =
728+
let Flatten (verbose : bool) (layerSets : LayerSet seq) : LayerSet =
635729

636730
let layerSets = layerSets |> Array.ofSeq
637731
let layersPerLayerSet = layerSets[0].Layers.Length
@@ -642,7 +736,7 @@ module LayerSet =
642736
indices
643737
|> List.choose (fun i ->
644738
// merge the i-th layers from all layer sets
645-
layerSets |> Array.map (fun x -> x.Layers[i]) |> Layer.Flatten
739+
layerSets |> Array.map (fun x -> x.Layers[i]) |> Layer.Flatten verbose
646740
)
647741
|> Array.ofList
648742

0 commit comments

Comments
 (0)