@@ -10,16 +10,9 @@ open System.Diagnostics
10
10
11
11
module Builder =
12
12
13
- let private debugOutput =
14
- #if DEBUG
15
- false
16
- #else
17
- false
18
- #endif
13
+ let rec private build ' ( config : BuildConfig ) ( sampleExponent : int ) ( rootCell : Cell2d ) ( patches : LayerSet []) =
19
14
20
- let rec private build ' ( sampleExponent : int ) ( rootCell : Cell2d ) ( patches : LayerSet []) =
21
-
22
- if debugOutput then
15
+ if config.Verbose then
23
16
printfn " [DEBUG] build' rootCell = %A , %d patches" rootCell patches.Length
24
17
25
18
for p in patches do
@@ -35,7 +28,7 @@ module Builder =
35
28
36
29
let theSinglePatch = patches[ 0 ]
37
30
38
- if debugOutput then
31
+ if config.Verbose then
39
32
printfn " [DEBUG] SINGLE patch (%A )" theSinglePatch.SampleWindow
40
33
41
34
Quadtree.Build BuildConfig.Default theSinglePatch.Layers
@@ -49,7 +42,7 @@ module Builder =
49
42
50
43
let bbWindow = patches |> Seq.map ( fun patch -> patch.SampleWindow) |> Box2l
51
44
52
- if debugOutput then
45
+ if config.Verbose then
53
46
printfn " [DEBUG] MERGE %d patches; %A " n ( bbWindow - rootBounds.Min)
54
47
55
48
//if debugOutput then
@@ -67,18 +60,18 @@ module Builder =
67
60
( fun () -> sprintf " Expected root cell exponent %d to be smaller than requiredRootCellSplitLimit %d ." rootCell.Exponent requiredRootCellSplitLimit)
68
61
" 4911adf3-7b87-4234-9bcc-bc3076df846e"
69
62
70
- if debugOutput then
63
+ if config.Verbose then
71
64
printfn " [DEBUG] must adjust root cell %A exponent to %d " rootCell requiredRootCellSplitLimit
72
65
73
66
while rootCell.Exponent < requiredRootCellSplitLimit do rootCell <- rootCell.Parent
74
67
75
- if debugOutput then
68
+ if config.Verbose then
76
69
printfn " [DEBUG] adjusted root cell is %A " rootCell
77
70
78
71
let merged = LayerSet.Merge patches
79
72
let qnode = QNode( Guid.NewGuid(), ebb, rootCell, BuildConfig.Default.SplitLimitPowerOfTwo, merged)
80
73
81
- if debugOutput then
74
+ if config.Verbose then
82
75
printfn " [DEBUG] CREATED QNode with split limit = %d " qnode.SplitLimitExponent
83
76
84
77
//let xs = qnode |> InMemoryNode |> Query.All Query.Config.Default |> Seq.map (fun x -> x.GetSamples<V4f>(Defs.HeightsBilinear4f)) |> Array.ofSeq |> Array.collect id
@@ -98,7 +91,7 @@ module Builder =
98
91
)
99
92
100
93
101
- if debugOutput then
94
+ if config.Verbose then
102
95
printfn " [DEBUG] SPLIT %d patches" n
103
96
104
97
//for i in 0..3 do
@@ -108,53 +101,79 @@ module Builder =
108
101
let subNodes = patchesPerQuadrant |> Array.map ( fun ( subCell , subPatches ) ->
109
102
match subPatches.Length with
110
103
| 0 -> NoNode
111
- | _ -> build' sampleExponent subCell subPatches
104
+ | _ -> build' config sampleExponent subCell subPatches
112
105
)
113
106
114
107
let hasMask = subNodes |> Array.exists ( fun n -> n.HasMask)
115
- if debugOutput && hasMask then
108
+ if config.Verbose && hasMask then
116
109
printfn " [DEBUG] has mask %A " rootCell
117
110
let result = { Id = Guid.NewGuid(); ExactBoundingBox = ebb; Cell = rootCell; SplitLimitExponent = BuildConfig.Default.SplitLimitPowerOfTwo; HasMask = hasMask; SubNodes = subNodes }
118
111
result |> InMemoryInner
119
112
120
- let rec private build '' ( rootCell : Cell2d ) ( patches : LayerSet []) =
113
+ let rec private build '' ( config : BuildConfig ) ( rootCell : Cell2d ) ( patches : LayerSet []) =
121
114
122
- if debugOutput then
115
+ if config.Verbose then
123
116
printfn " [DEBUG] build' rootCell = %A , %d patches" rootCell patches.Length
124
117
125
118
let minSampleExponent = patches |> Seq.map ( fun p -> p.SampleExponent) |> Seq.min
126
119
127
120
match patches.Length with
128
121
129
- | 0 -> NoNode
122
+ | 0 ->
123
+
124
+ if config.Verbose then
125
+ printfn " [DEBUG][build''] ZERO patches"
126
+
127
+ NoNode
130
128
131
129
| 1 ->
132
130
131
+ if config.Verbose then
132
+ printfn " [DEBUG][build''] SINGLE patch (%A )" patches[ 0 ]. SampleWindow
133
+
133
134
let theSinglePatch = patches[ 0 ]
134
135
135
- if debugOutput then
136
- printfn " [DEBUG] SINGLE patch (%A )" theSinglePatch.SampleWindow
136
+ Quadtree.Build config theSinglePatch.Layers
137
137
138
- Quadtree.Build BuildConfig.Default theSinglePatch.Layers
138
+ | 2 ->
139
+
140
+ if config.Verbose then
141
+ printfn " [DEBUG][build''] TWO patches (%A , %A )" patches[ 0 ]. SampleWindow patches[ 1 ]. SampleWindow
142
+
143
+ let p0 = Quadtree.Build' config patches[ 0 ]
144
+ let p1 = Quadtree.Build' config patches[ 1 ]
145
+
146
+ Quadtree.Merge Dominance.MoreDetailedOrSecond p0 p1
139
147
140
148
| n -> // n patches
141
149
150
+ if config.Verbose then
151
+ printfn " [DEBUG][build''] n=%d patches" patches.Length
152
+
142
153
let ebb = patches |> Seq.map ( fun patch -> patch.BoundingBox) |> Box2d
143
154
155
+ invariantm ( config.SplitLimitPowerOfTwo >= 0 )
156
+ ( fun () -> sprintf " Expected config.SplitLimitPowerOfTwo to be non-negative, but found %d ." config.SplitLimitPowerOfTwo)
157
+ " 95c43529-9649-42d6-9b47-c6f8fb6da301"
158
+
159
+ let tileSize = 2 <<< config.SplitLimitPowerOfTwo
144
160
let rootBounds = getBoundsForExponent minSampleExponent rootCell
145
- if rootBounds.Size.X <= 256 && rootBounds.Size.Y <= 256 then
161
+
162
+ if rootBounds.Size.X <= tileSize && rootBounds.Size.Y <= tileSize then
146
163
164
+ if config.Verbose then
165
+ printfn " [DEBUG][build''] MERGE %d patches; because reached split limit" n
166
+
167
+ failwith " TODO"
168
+
147
169
let bbWindow = patches |> Seq.map ( fun patch -> patch.SampleWindow) |> Box2l
148
170
149
- if debugOutput then
150
- printfn " [DEBUG] MERGE %d patches; %A " n ( bbWindow - rootBounds.Min)
151
-
152
171
//if debugOutput then
153
172
// for patch in patches do
154
173
// printfn "[DEBUG] %A (exact %A)" (patch.SampleWindow - rootBounds.Min) (bbWindow - rootBounds.Min)
155
174
156
175
// adjust root cell for split limit
157
- let requiredRootCellSplitLimit = minSampleExponent + BuildConfig.Default .SplitLimitPowerOfTwo
176
+ let requiredRootCellSplitLimit = minSampleExponent + config .SplitLimitPowerOfTwo
158
177
159
178
let mutable rootCell = rootCell
160
179
@@ -164,45 +183,47 @@ module Builder =
164
183
( fun () -> sprintf " Expected root cell exponent %d to be smaller than requiredRootCellSplitLimit %d ." rootCell.Exponent requiredRootCellSplitLimit)
165
184
" 4911adf3-7b87-4234-9bcc-bc3076df846e"
166
185
167
- if debugOutput then
168
- printfn " [DEBUG] must adjust root cell %A exponent to %d " rootCell requiredRootCellSplitLimit
186
+ if config.Verbose then
187
+ printfn " [DEBUG][build''] must adjust root cell %A exponent to %d " rootCell requiredRootCellSplitLimit
169
188
170
189
while rootCell.Exponent < requiredRootCellSplitLimit do rootCell <- rootCell.Parent
171
190
172
- if debugOutput then
173
- printfn " [DEBUG] adjusted root cell is %A " rootCell
191
+ if config.Verbose then
192
+ printfn " [DEBUG][build''] adjusted root cell is %A " rootCell
174
193
175
194
let merged = LayerSet.Merge patches
176
- let qnode = QNode( Guid.NewGuid(), ebb, rootCell, BuildConfig.Default .SplitLimitPowerOfTwo, merged)
195
+ let qnode = QNode( Guid.NewGuid(), ebb, rootCell, config .SplitLimitPowerOfTwo, merged)
177
196
178
- if debugOutput then
179
- printfn " [DEBUG] CREATED QNode with split limit = %d " qnode.SplitLimitExponent
197
+ if config.Verbose then
198
+ printfn " [DEBUG][build''] CREATED QNode with split limit = %d " qnode.SplitLimitExponent
180
199
181
200
//let xs = qnode |> InMemoryNode |> Query.All Query.Config.Default |> Seq.map (fun x -> x.GetSamples<V4f>(Defs.HeightsBilinear4f)) |> Array.ofSeq |> Array.collect id
182
201
//for x in xs do printfn "%A" x
183
202
qnode |> InMemoryNode
184
203
185
204
else
186
-
205
+
206
+ if config.Verbose then
207
+ printfn " [DEBUG][build''] SPLIT %d patches into quadrants of %A ... " n rootCell
208
+
187
209
//let bbQuadrants = rootCell.Children |> Array.map (fun subCell -> subCell.GetBoundsForExponent(sampleExponent))
188
210
189
211
let patchesPerQuadrant =
190
212
rootCell.Children
191
213
|> Array.map ( fun subCell ->
192
- let bbQuadrant = subCell.GetBoundsForExponent( minSampleExponent)
193
214
let subPatches =
194
215
patches // TODO: ensure that bbQuadrant is in same resolution as patch ?!?
195
216
|> Array.choose ( fun patch ->
196
- if patch.SampleExponent <> minSampleExponent then Debugger.Break()
217
+ let bbQuadrant = subCell.GetBoundsForExponent( patch.SampleExponent)
218
+ //if patch.SampleExponent <> minSampleExponent then Debugger.Break()
197
219
patch.WithWindow bbQuadrant
198
220
)
199
221
200
222
( subCell, subPatches)
201
223
)
202
224
203
-
204
- if debugOutput then
205
- printfn " [DEBUG] SPLIT %d patches" n
225
+ if config.Verbose then
226
+ printfn " [DEBUG][build''] SPLIT %d patches into quadrants of %A --> %A " n rootCell ( patchesPerQuadrant |> Array.map( fun ( _ , xs ) -> xs.Length))
206
227
207
228
//for i in 0..3 do
208
229
// let (subCell, subPatches) = patchesPerQuadrant[i]
@@ -211,24 +232,20 @@ module Builder =
211
232
let subNodes = patchesPerQuadrant |> Array.map ( fun ( subCell , subPatches ) ->
212
233
match subPatches.Length with
213
234
| 0 -> NoNode
214
- | _ -> build'' subCell subPatches
235
+ | _ -> build'' config subCell subPatches
215
236
)
216
237
217
238
let hasMask = subNodes |> Array.exists ( fun n -> n.HasMask)
218
- if debugOutput && hasMask then
219
- printfn " [DEBUG] has mask %A " rootCell
220
- let result = { Id = Guid.NewGuid(); ExactBoundingBox = ebb; Cell = rootCell; SplitLimitExponent = BuildConfig.Default .SplitLimitPowerOfTwo; HasMask = hasMask; SubNodes = subNodes }
239
+ if config.Verbose && hasMask then
240
+ printfn " [DEBUG][build''] has mask %A " rootCell
241
+ let result = { Id = Guid.NewGuid(); ExactBoundingBox = ebb; Cell = rootCell; SplitLimitExponent = config .SplitLimitPowerOfTwo; HasMask = hasMask; SubNodes = subNodes }
221
242
result |> InMemoryInner
222
243
223
244
/// Creates a quadtree from many small patches.
224
- let Build ( patches : LayerSet seq ) : QNodeRef =
245
+ let Build ( config : BuildConfig ) ( patches : LayerSet seq ) : QNodeRef =
225
246
let patches = patches |> Array.ofSeq
226
247
let rootCell = patches |> Seq.map ( fun patch -> patch.BoundingBox) |> Box2d |> Cell2d
227
-
228
- //let sampleExponent = (patches |> Array.distinctBy (fun x -> x.SampleExponent) |> Array.exactlyOne).SampleExponent
229
- //build' sampleExponent rootCell patches
230
-
231
- build'' rootCell patches
248
+ build'' config rootCell patches
232
249
233
250
/// Creates a quadtree from many small patches.
234
251
type Builder () =
@@ -294,15 +311,15 @@ type Builder () =
294
311
for patch in patches do this.Add( patch)
295
312
296
313
/// Build a quadtree from all the patches that have been added to this builder.
297
- member this.Build () : QNodeRef option =
314
+ member this.Build ( config : BuildConfig ) : QNodeRef option =
298
315
299
316
let mutable mergesCount = 0
300
317
301
318
patches
302
319
// (1) sort per-resolution patch lists from coarse to fine resolution ...
303
320
|> Seq.sortByDescending ( fun kv -> kv.Key) |> Seq.map ( fun kv -> kv.Value)
304
321
// (2) create a quadtree for each resolution ...
305
- |> Seq.map Builder.Build
322
+ |> Seq.map ( Builder.Build config )
306
323
// (3) merge quadtrees with finer resolution always dominating ...
307
324
|> Seq.fold ( fun state item ->
308
325
match state with
@@ -315,14 +332,10 @@ type Builder () =
315
332
None // initial state
316
333
317
334
/// Build a quadtree from all the patches that have been added to this builder.
318
- member this.Build2 () : QNodeRef option =
319
-
320
- let mutable mergesCount = 0
321
-
335
+ member this.Build2 ( config : BuildConfig ) : QNodeRef option =
322
336
let allPatches = this.GetPatches()
323
- Builder.Build allPatches |> Some
337
+ Builder.Build config allPatches |> Some
324
338
325
-
326
339
/// Enumerate all patches.
327
340
member this.GetPatches () : seq < LayerSet > =
328
341
patches |> Seq.map ( fun kv -> kv.Value) |> Seq.collect id
0 commit comments