3
3
open Aardvark.Base
4
4
open System
5
5
open System.Collections .Generic
6
+ open Serialization
7
+
8
+ #nowarn " 1337"
6
9
7
10
module Builder =
8
11
@@ -77,7 +80,7 @@ module Builder =
77
80
if debugOutput then
78
81
printfn " [DEBUG] CREATED QNode with split limit = %d " qnode.SplitLimitExponent
79
82
80
- let xs = qnode |> InMemoryNode |> Query.All Query.Config.Default |> Seq.map ( fun x -> x.GetSamples< V4f>( Defs.HeightsBilinear4f)) |> Array.ofSeq |> Array.collect id
83
+ // let xs = qnode |> InMemoryNode |> Query.All Query.Config.Default |> Seq.map (fun x -> x.GetSamples<V4f>(Defs.HeightsBilinear4f)) |> Array.ofSeq |> Array.collect id
81
84
//for x in xs do printfn "%A" x
82
85
qnode |> InMemoryNode
83
86
@@ -108,6 +111,8 @@ module Builder =
108
111
)
109
112
110
113
let hasMask = subNodes |> Array.exists ( fun n -> n.HasMask)
114
+ if debugOutput && hasMask then
115
+ printfn " [DEBUG] has mask %A " rootCell
111
116
let result = { Id = Guid.NewGuid(); ExactBoundingBox = ebb; Cell = rootCell; SplitLimitExponent = BuildConfig.Default.SplitLimitPowerOfTwo; HasMask = hasMask; SubNodes = subNodes }
112
117
result |> InMemoryInner
113
118
@@ -118,7 +123,6 @@ module Builder =
118
123
let sampleExponent = ( patches |> Array.distinctBy ( fun x -> x.SampleExponent) |> Array.exactlyOne) .SampleExponent
119
124
build' sampleExponent rootCell patches
120
125
121
-
122
126
/// Creates a quadtree from many small patches.
123
127
type Builder () =
124
128
@@ -127,6 +131,12 @@ type Builder () =
127
131
let mutable isEmpty = true
128
132
let mutable layerCount = 0
129
133
134
+ static let ensureDir path =
135
+ let path = System.IO.Path.GetFullPath( path)
136
+ let dir = System.IO.DirectoryInfo( path)
137
+ if not dir.Exists then dir.Create()
138
+ path
139
+
130
140
/// Add patch.
131
141
member this.Add ( patch : LayerSet ) : unit = lock l ( fun () ->
132
142
@@ -150,6 +160,12 @@ type Builder () =
150
160
list.Add( patch)
151
161
)
152
162
163
+ /// Add patch.
164
+ member this.Add ( patch : LayerSet option ) : unit =
165
+ match patch with
166
+ | None -> ()
167
+ | Some patch -> this.Add( patch)
168
+
153
169
/// Add patch.
154
170
member this.Add ( patch : ILayer ) : unit =
155
171
this.Add( LayerSet([| patch |]))
@@ -158,6 +174,18 @@ type Builder () =
158
174
member this.Add ( patch : QNode ) : unit =
159
175
this.Add( patch.LayerSet)
160
176
177
+ /// Add all leaf nodes of given quadtree as patches.
178
+ member this.Add ( root : QNodeRef ) : unit =
179
+ root |> Quadtree.EnumerateLeafNodesInMemory |> this.AddRange
180
+
181
+ /// Add multiple patches.
182
+ member this.AddRange ( patches : seq < QNode >) : unit =
183
+ for patch in patches do this.Add( patch)
184
+
185
+ /// Add multiple patches.
186
+ member this.AddRange ( patches : seq < LayerSet >) : unit =
187
+ for patch in patches do this.Add( patch)
188
+
161
189
/// Build a quadtree from all the patches that have been added to this builder.
162
190
member this.Build () : QNodeRef option =
163
191
@@ -173,7 +201,11 @@ type Builder () =
173
201
| Some state -> Quadtree.Merge Dominance.SecondDominates state item |> Some
174
202
)
175
203
None // initial state
176
-
204
+
205
+ /// Enumerate all patches.
206
+ member this.GetPatches () : seq < LayerSet > =
207
+ patches |> Seq.map ( fun kv -> kv.Value) |> Seq.collect id
208
+
177
209
member this.Print () : unit =
178
210
179
211
printfn " Builder("
@@ -186,4 +218,57 @@ type Builder () =
186
218
printfn " global root cell = %A " ( Cell2d bbGlobal)
187
219
188
220
printfn " )"
189
- ()
221
+ ()
222
+
223
+ /// Save builder. Returns id of saved builder.
224
+ member this.Save ( options : SerializationOptions ) : Guid =
225
+ Defs.init ()
226
+ let patches = this.GetPatches() |> Array.ofSeq
227
+ Serialization.SavePatches options patches
228
+
229
+ /// Load builder with given id.
230
+ static member Load ( options : SerializationOptions ) ( id : Guid ) : Builder option =
231
+ Defs.init ()
232
+ match Serialization.LoadPatches options id with
233
+ | None -> None
234
+ | Some patches ->
235
+ let builder = Builder()
236
+ builder.AddRange( patches)
237
+ Some builder
238
+
239
+ /// Export builder to directory.
240
+ member this.Export ( dir : string ) : Guid =
241
+
242
+ let storeDir = ensureDir dir
243
+
244
+ let now = DateTimeOffset.Now
245
+ let fileNameKey = sprintf( " builder.%04d%02d%02d%02d%02d%02d .%d .key.txt" ) now.Year now.Month now.Day now.Hour now.Minute now.Second now.Ticks
246
+
247
+ use store = new Uncodium.SimpleStore.SimpleDiskStore( System.IO.Path.Combine( storeDir, " store.dur" ))
248
+ let options = SerializationOptions.SimpleStore( store)
249
+ let key = this.Save( options)
250
+
251
+ System.IO.File.WriteAllText( System.IO.Path.Combine( storeDir, fileNameKey), key.ToString())
252
+
253
+ key
254
+
255
+ /// Imports builder with given id from directory.
256
+ static member Import ( dir : string , id : Guid ) : Builder option =
257
+
258
+ let storeFileName =
259
+ if System.IO.File.Exists( dir) then
260
+ dir
261
+ else
262
+ if System.IO.Directory.Exists( dir) then
263
+ System.IO.Path.Combine( dir, " store.dur" )
264
+ else
265
+ sprintf " Unknown path %s . Error 094f64b9-ba1e-4d9d-a5e1-bc471665f332." dir |> failwith
266
+
267
+ use store = new Uncodium.SimpleStore.SimpleDiskStore( storeFileName)
268
+ let options = SerializationOptions.SimpleStore( store)
269
+ match Serialization.LoadPatches options id with
270
+ | None -> None
271
+ | Some patches ->
272
+ let builder = Builder()
273
+ builder.AddRange( patches)
274
+ Some builder
0 commit comments