-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMI_Mining_Information.html
691 lines (663 loc) · 40.4 KB
/
MI_Mining_Information.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style_reset.css">
<link rel="stylesheet" type="text/css" href="style_zword.css">
<title>M.I. File: Mine Information File</title>
</head>
<body class="zword">
<h1 class="zword">M.I. File: Mine Information File</h1>
<p class="zword"><strong><code>Author: </code></strong> Robbert de Groot</p>
<p class="zword"><strong><code>Date: </code></strong> 2019-05-15</p>
<p class="zword"><strong><code>Copyright: </code></strong> 2019, Robbert de Groot</p>
<p class="zword"><strong><code>License (Library): </code></strong> MIT License.</p>
<p class="zword"><strong><code>License (Document):</code></strong> Creative Commons Attribution-NoDerivs.<a href="https://creativecommons.org/licenses/by-nd:4.0">(CC BY-ND)</a></p>
<h2 class="zword">Table Of Contents:</h2>
<p class="zword_toc1"><a href="#1">1 - M.I.</a></p>
<p class="zword_toc2"><a href="#1.1">1.1 - Discussion</a></p>
<p class="zword_toc2"><a href="#1.2">1.2 - Goals</a></p>
<p class="zword_toc2"><a href="#1.3">1.3 - Disclosure</a></p>
<p class="zword_toc1"><a href="#2">2 - MI Format</a></p>
<p class="zword_toc2"><a href="#2.1">2.1 - Header</a></p>
<p class="zword_toc1"><a href="#3">3 - Mine Information Block (MIB)</a></p>
<p class="zword_toc2"><a href="#3.1">3.1 - Information Block</a></p>
<p class="zword_toc2"><a href="#3.2">3.2 - Item Block</a></p>
<p class="zword_toc2"><a href="#3.3">3.3 - Image Block</a></p>
<p class="zword_toc2"><a href="#3.4">3.4 - Drillhole Block</a></p>
<p class="zword_toc2"><a href="#3.5">3.5 - Geometry Block</a></p>
<p class="zword_toc2"><a href="#3.6">3.6 - Model Data</a></p>
<p class="zword_toc3"><a href="#3.6.1">3.6.1 - Model Block</a></p>
<p class="zword_toc2"><a href="#3.7">3.7 - Model Block:</a></p>
<p class="zword_toc3"><a href="#3.7.1">3.7.1 - SubBlock: Fixed</a></p>
<p class="zword_toc3"><a href="#3.7.2">3.7.2 - SubBlock: Semi</a></p>
<p class="zword_toc3"><a href="#3.7.3">3.7.3 - SubBlock: Octree</a></p>
<p class="zword_toc3"><a href="#3.7.4">3.7.4 - SubBlock: Free</a></p>
<h1 class="zword"><a name="1">1 - M.I.</a></h1>
<h2 class="zword"><a name="1.1">1.1 - Discussion</a></h2>
<p class="zword"><strong>What is the purpose of M.I. (MI)?</strong></p>
<p class="zword">MI is intended to be a file format for exporting and importing data from one mining software package to another software package.</p>
<p class="zword">I would imagine users of software packages are annoyed at the lack of interoperability between software packages. Currently some software packages attempt to do their best at supporting competitor file formats (read only) but there is often a lot of loss of data or, as data formats in each package evolves, suffer from compatibility issues. Often data needs to be dumped to formats that come 'close' but are not exact, like DXF/DWG, or down to very basic ASCII files, like csv files, which are often lacking compared to the original data. Users will need to massage this raw data in order to import it into their target software package.</p>
<p class="zword">A lot of the client's time is lost with all this work and often lock them into one system because getting data out or in from that system is too onerous. The idea with an information format is to remove some of the pain of this data transfer task and put more of the pain on the software vendors of doing the hard part of reading in the data to their expectations. The software users will not need to know some of the intricacies of the data or task.</p>
<h2 class="zword"><a name="1.2">1.2 - Goals</a></h2>
<p class="zword">The main goal of this format is to be specifically a data passing format. It is not intended to be a native format for any software package. The focus is to make it easy for the developers from any software package to export their data to this format and, without too much difficulty, to import into another vendor's software.</p>
<p class="zword">For the users of the software packages, the process of moving data from package to package will be much easier, less time consuming, less error prone, and less data loss as they will only have to export and import to just one type of file instead of various file formats and requiring more intimate knowledge of the data transfer process specific to their software packages.</p>
<ul class="zword">
<li class="zword"><strong>Simple</strong>, The format should be simple for the developers to export their data. Import may still be challenging because of the differences between software packages but the format to import the data should not impose too much pain for the developers either. The simplicity should go a long way in getting the format adopted and implemented.</li>
<li class="zword"><strong>Inclusive</strong>, All data from all venders should be representable with the least amount of compromises in the data being exported.</li>
<li class="zword"><strong>Brief</strong>, The format should not produce unnecessary waste. The data in some cases will be quite large so it should not bloat the data too much. Meaning, file sizes should not become overly large. However, because of point 1 there will always be some bloat.</li>
<li class="zword"><strong>Flexible</strong>, The format needs to be able to accomodate change or account for vendor specific data. A few software vendors started life in the 70's with time shared machines. Over the years the amount of data and the types of data the clients want to maintain has changed and grown. A format needs to try its best to keep up without importers and exporters to be completely remade.</li>
</ul>
<h2 class="zword"><a name="1.3">1.3 - Disclosure</a></h2>
<p class="zword">As of this writing I, Robbert de Groot, am a Principal Software Developer with Hexagon (previously known as (pka) Hexagon Mining, pka MineSight, pka Mintec Inc.), the current owners of MinePlan 3D software (pka MineSight 3D; pka MEDSystem.); Leica Geosystems, the makers of survey equipment and related material; as well as other mine related hardware and software products.</p>
<p class="zword">This format is currently not sanctioned by any software vendor, including Hexagon. This was something I am doing as an experiment to satisfy my curiosity. It was brought about by recent efforts being made by Global Mining Guidelines (GMG), with their Open Mining Format (OMF), which seems to have the backing of some big players in the industry. My issue with OMF, for now, is that they only have a Python library that implements the format available publically. The format is strictly binary, which is not entirely a bad idea considering the data that needs to be passed around, but binary formats can be very fussy. The format is also based on a ZIP archive. The good thing about ZIP is that it will have excellent compression. The bad thing is that ZIP archives are, in my opinion, not a great file format.</p>
<p class="zword">So, I thought I would try my hand at defining a format that I think would be good as an information format. I am trying to write MI independent of any software package. However there may be some unintended bias as I am most familiar with MinePlan 3D for which I have worked on since 1995. I do intend to keep this format as inclusive as possible to address other software package requirements as best as I understand them. I know I will make mistakes there because I have only superficial knowledge of most of the competing software in the industry.</p>
<p class="zword">If anyone is interested in educating me on some features they would like to see with respect to their software package of choice I would love to hear from you. You can reach me at the following email address.</p>
<p class="zword">[email protected]</p>
<h1 class="zword"><a name="2">2 - MI Format</a></h1>
<p class="zword">MI is not restricted to any particular format. Here I will specify two, MIFF and JSON. See the MIFF_Mixed_Information_File_Format document for the discussion of the MIFF file format. Refer to JSON.org for information about JSON. This document will cover specifics related to using MI but it will not be restricted to any particular underlying format.</p>
<p class="zword">The library connect to this document will read and write to either MIFF or JSON. XML could be an option but I would not suggest it.</p>
<p class="zword">The data mining companies need to keep track of and transfer around.</p>
<p class="zwordPre">- General information
- Project limits
- Project coordinate space
- Project units
- Company information
- Value Specifications
- Project items and limits
- Project item binning
- Display properties
- Geometry
- 3D
- Points
- Polylines (open and closed)
- Surfaces:Generic (open and closed (solids))
- Surfaces:Grid
- Text
- Symbol
- 2D (Planar, Fence)
- Points
- Polylines (open and closed)
- Text
- Symbol
- Survey
- Points, Polylines but using angles instead of coordinates.
- Drillhole
- Drillhole survery information.
- Drillhole assay information.
- Drillhole composite information.
- Blast hole shot information.
- Chip assay information.
- Design vs Actual information.
- Model
- Block model information.
- Block
- Regular (all blocks the same)
- Plan Regular, Variable Bench (all blocks same i and j dimensions but k (bench) can vary.)
- Octree
- Regular sub-blocked (all sub-blocks are the same)
- Multi-level sub-blocked
- Seam
- Surface
- Seam model information.
- Regular
- Sub-blocked
- Surface model information.
- Sub-blocked
</p>
<p class="zword">File naming can help in file importing. It is suggested to use the following file extensions...</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Extension</th>
<th class="zword_fill">File Contents</th>
</tr>
<tr class="zword">
<td class="zword">*.miff, *.json</td>
<td class="zword">Still valid but can be anything. What is it?</td>
</tr>
<tr class="zword">
<td class="zword">*.miffMI, *.jsonMI</td>
<td class="zword">for a very general Mine Information of anything mine related.</td>
</tr>
<tr class="zword">
<td class="zword">*.miffMIDrill, *.jsonMIDrill</td>
<td class="zword">for only Drillhole related data.</td>
</tr>
<tr class="zword">
<td class="zword">*.miffMIGeom, *.jsonMIGeom</td>
<td class="zword">for only Geometry related data.</td>
</tr>
<tr class="zword">
<td class="zword">*.miffMIModel, *.jsonMIModel</td>
<td class="zword">for only Model related data.</td>
</tr>
</tbody></table>
<p class="zword">This information is duplicated inside the file so reading in the file should match the extension but it will help the user if the extension is properly set and will make it easier on the software on how to read in the file if these are properly set.</p>
<h2 class="zword"><a name="2.1">2.1 - Header</a></h2>
<p class="zword">MIFF has fields for a Sub-Format Name and Version. For an MI file this will be set to...</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Field</th>
<th class="zword_fill">Value</th>
</tr>
<tr class="zword">
<td class="zword"><nobr>Sub-Fromat Name</td>
<td class="zword">Mining Information</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>Sub-Format Version</td>
<td class="zword">1</td>
</tr>
</tbody></table>
<p class="zword">For a JSON file, since it doesn't have a header, create base object for all the blocks in the file. First block should be the "format" block.</p>
<p class="zwordPre">{
"format":{
"name": "Mining Information",
"version":1,
},
...
}
</p>
<h1 class="zword"><a name="3">3 - Mine Information Block (MIB)</a></h1>
<p class="zword"><strong>Block Name</strong>: mine</p>
<p class="zword">An MI file can have 1 or more MIBs. One MIB represents a unique mining project or project area.</p>
<p class="zword">Each mine block in a file separates information related to one specific mine. Meaning, you could have more than one mine in a MI file. One mine could be a gold mine in Australia while another could be a bitumen mine in Africa. This will probably not happen often because the file size just for one mine could be very large so adding more than one mine would probably not be a good idea, but it is doable.</p>
<p class="zword">Inside a MIB you will have the following blocks.</p>
<ul class="zword">
<li class="zword"><strong>Information block</strong> to hold general information about the project. This must be the first block.</li>
<li class="zword"><strong>Item list block</strong> to hold the item definitions. Items being the values that are stored in the drillhole, model, cuts, and whatever else that is being tracked. There will only be one Item List block.</li>
<li class="zword"><strong>Image list block</strong> to hold the images. Images can be used for texturing, symbols, etc.</li>
<li class="zword"><strong>Geometry block</strong> to hold geometry information. There can be more than one Geoemtry block.</li>
<li class="zword"><strong>Drillhole block</strong> to hold drillhole information. Item List block must already be defined or else you are not providing assay or survey values with your drillhole data. There can be more than one Drillhole block.</li>
<li class="zword"><strong>Model block</strong> to hold model information. Item List block must already be defined or else you are not providing any values with your model data. There can be more than one Model block.</li>
</ul>
<h2 class="zword"><a name="3.1">3.1 - Information Block</a></h2>
<p class="zword"><strong>Block Name</strong>: info</p>
<p class="zword">Common to all MI files for any of the types above, there will be an information block providing general, project wide information.</p>
<p class="zword">This information block should be before other blocks.</p>
<p class="zword">Inside the information block we have the following possible key values. Not all are required.</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Name</th>
<th class="zword_fill">Description</th>
</tr>
<tr class="zword">
<td class="zword"><nobr>type</td>
<td class="zword_fill">The type of the MI file. See further down.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>company</td>
<td class="zword_fill">The name of the company related to the mine.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>copyright</td>
<td class="zword_fill">Copyright information</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>author</td>
<td class="zword_fill">Author or person who prepared this data.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>software</td>
<td class="zword_fill">The software that was used to prepare this data.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>softwareVersion</td>
<td class="zword_fill">The version of the above software.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>comment</td>
<td class="zword_fill">Any comments provided by the author or software about the data. This comment should hold no information that needs to be parsed by an importer of the data.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>projectSystem</td>
<td class="zword_fill">Indicates what coordinates system the all coordinate data should be considered to be in. It will be a string as defined in a package like GDAL which can translate from one coordinate system to another. Like "WGS84" or "NAD27". Even the [projectMin] and [projectMax] will be in this system. Use "local" to indicate that the project coordinates are in a local flat earth space.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>projectName</td>
<td class="zword_fill">The name of the project.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>projectMin</td>
<td class="zword_fill">Array of 3 real values in the given project system.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>projectMax</td>
<td class="zword_fill">Array of 3 real values in the given project system.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>other</td>
<td class="zword">A place to put other information that is not accounted for by the MI format but will be useful by the original software that wrote the file. This will be an array of string values.</td>
</tr>
</tbody></table>
<p class="zword">Most keys are self explanatory.</p>
<p class="zword"><strong>[Type]</strong> is one of...</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Value</th>
<th class="zword_fill">Description</th>
</tr>
<tr class="zword">
<td class="zword">Mixed</td>
<td class="zword">Combination of any of the types below.</td>
</tr>
<tr class="zword">
<td class="zword">Drillhole</td>
<td class="zword">Only holds drillhole data.</td>
</tr>
<tr class="zword">
<td class="zword">Geometry</td>
<td class="zword">Only holds geometry data.</td>
</tr>
<tr class="zword">
<td class="zword">Model</td>
<td class="zword">Only holds model data.</td>
</tr>
</tbody></table>
<p class="zword"><strong>projectMin</strong> and <strong>projectMax</strong> should given an indication on the data range of the project. This does not need to be exactly defining the outer limits of the all the data, just the rough range that the data should live inside or near.</p>
<h2 class="zword"><a name="3.2">3.2 - Item Block</a></h2>
<p class="zword"><strong>Block Name</strong>: item</p>
<p class="zword">Item will describe a value that will be stored in the various places where the item is being tracked. For instance, a drillhole assay value, a block model item value, a geometry element value, a geometry point value, etc.</p>
<p class="zword">Items need to be defined before they are used elsewhere in the MI file.</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Name</th>
<th class="zword_fill">Description</th>
</tr>
<tr class="zword">
<td class="zword"><nobr>key</td>
<td class="zword">A unique key for the item. This is stored as a string even if it is a number by the software that sets it. This key needs to be unique so that no two items have the same key value.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>name</td>
<td class="zword">The name of the item. A UTF8 string limited to 255 bytes. Not necessarily unique but generally, it would be a good idea.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>type</td>
<td class="zword">The type of the item. See lower down.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>range</td>
<td class="zword">If a number type, the minimum and maximum value for the item.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>value</td>
<td class="zword">If the item has limited number of values, list the array of values here.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>precision</td>
<td class="zword">If a real type, how many decimal places is this values accurrate to.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>default</td>
<td class="zword">The default value for something that did not have a value assigned.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>calculation</td>
<td class="zword">The formula used to calculate the value of this item. In other words, this item has not stored value. The value will be calculated when needed.</td>
</tr>
<tr class="zword">
<td class="zword"><nobr>other</td>
<td class="zword">A place to put other information that is not accounted for by the MI format but will be useful by the original software that wrote the file. This will be an array of string values.</td>
</tr>
</tbody></table>
<p class="zword">Each item will be given an index value starting at 0 and incrementing with every new item added to the MI file.</p>
<p class="zword"><strong>type</strong> will define the value being stored for this item. Type is one of string, real, real4, natural, integer, date, time, dateTime, or formula (formula meaning the item's value is calculated.)</p>
<p class="zword"><strong>range</strong> defines the limits for an item. Only applicable if item type is a real, real4, natural, or integer. If these are missing then the range is the full range as defined by the type.</p>
<p class="zword"><strong>valueList</strong> defines the actual values that will ever be used for this item. This can exist for any type. If values are used then what is stored in the drillhole assay, block model block, or geometry attribute will be an index into this list of values. A string type and a valueList essentially defines an enumerated value.</p>
<p class="zword"><strong>precision</strong> is the accuracy of the number. Only applicable if item type is a real and real4.</p>
<p class="zword"><strong>default</strong> will define the default value for this item if block is skipped. If this value is not set then the default value is 'unset'.</p>
<p class="zword"><strong>calculation</strong> is an equation that is performed to obtain the item's value. Only applicable if item type is formula. Use "@[item key]@" in the formula to refer to another item value in the current context. Full discussion about the formula composition will be discussed elsewhere.</p>
<p class="zword">When precision is used, it will change how the values are stored. Say we have a min of 0 and an max of 10 and a precision of 0.1. As a result we have a total of 101 unique values. 0.0, 0.1, ..., 9.9, 10.0. 102 unique values when we include 'unset value' as well. If this is all the values that need to be recorded, then we do not really need to use a full real or real4 value to store it. We will be storing instead a natural value such that the natural value, multiplied by the precision and added to the min value will recover the real value which is being stored. In this case, 102 values only requires a single byte natural to encode all the values in the range.</p>
<p class="zwordPre">Calculation example:
(@ore%@ * @cu@) - @i_am_making_something_up@
</p>
<h2 class="zword"><a name="3.3">3.3 - Image Block</a></h2>
<p class="zword"><strong>Block Name</strong>: image</p>
<p class="zword">Defining an image.</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Name</th>
<th class="zword_fill">Description</th>
</tr>
<tr class="zword">
<td class="zword">key</td>
<td class="zword">Unique identifier for the image.</td>
</tr>
<tr class="zword">
<td class="zword">name</td>
<td class="zword">A nice name for the image.</td>
</tr>
<tr class="zword">
<td class="zword">rgb</td>
<td class="zword">The pixels as a raw image.<br />[width int][tb][height int][tb][hex dump of image pixels in 8 bit rgb values]</td>
</tr>
<tr class="zword">
<td class="zword">rgba</td>
<td class="zword">The pixels as a raw image.<br />[width int][tb][height int][tb][hex dump of image pixels in 8 bit rgba values]</td>
</tr>
<tr class="zword">
<td class="zword">file</td>
<td class="zword">A hex dump of the image file.</td>
</tr>
<tr class="zword">
<td class="zword">filePath</td>
<td class="zword">A relative path to an image file. The file should be relative to the MI file and should be in the same folder or in a sub folder of this folder. The file should be an image file.</td>
</tr>
</tbody></table>
<p class="zword">An image will only have one of the following 4 items (rgb, rgba, file, filePath) and never more than one.</p>
<h2 class="zword"><a name="3.4">3.4 - Drillhole Block</a></h2>
<p class="zword">Drillhole data holds information about drillholes.</p>
<h2 class="zword"><a name="3.5">3.5 - Geometry Block</a></h2>
<p class="zword">Within the geometry list you will only find geometry blocks.</p>
<p class="zwordPre">{ geom
" name 1 [geom name]
" item list geom [item Count] [name of item]*
" item list point [item count] [name of item]*
" item list line [item count] [name of item]*
type type 1 [geom type]
[geom type] data 1 [data of geom type]
attr geom 1 [geom attr list]
attr point [point count] [point attr list]
attr line [point count] [line attr list]
}
</p>
<p class="zword">Each piece of geometry can have some attributes. The attributes need to be an item in the item list and the list of attributes is defined by attrList array. When this array is read in, a user type is create by using the item list items' definition to build it up. The values in the user type will be in the order listed.</p>
<p class="zword">Each piece of polyline geometry can have point and line attributes. Like geometry attributes above, the user type will be dynamically created by the library based off of the items listed and in that order.</p>
<p class="zword">attrList, pointAttrList, and lineAttrList can change between geom blocks and they need to be defined before the geom blocks which will use them.</p>
<p class="zword">In binary the type number for the attr, pointAttr, and lineAttr will be all 1's (4095) as we will know what type to use based off of this format.</p>
<p class="zword">Each geom has a unique id.</p>
<p class="zword">Each geom will have a type. One of point, pointGroup, polyline, surface, mesh, grid, or text.</p>
<p class="zword">Each geom will have data of the given type.</p>
<p class="zword">Each geom may have an optional geomAttr key value block.</p>
<p class="zword">If the geometry is a polyline, then there may be an optional pointAttr and lineAttr arrays. 1 set of attributes per point and line segment.</p>
<h2 class="zword"><a name="3.6">3.6 - Model Data</a></h2>
<p class="zword">Some of the information found here is based off of the block model formats that are used at Hexagon, where I work, but also from information found freely on the internet.</p>
<p class="zword"><a href="https://www.deswik.com/wp-content/uploads/2019/01/Block-model-knowledge-for-mining-engineers-An-introduction-1.pdf">Block Model Knowledge For Mining Engineers - An Introduction</a></p>
<p class="zword">There are 3 basic model formats that are in use as Hexagon.</p>
<ul class="zword">
<li class="zword">Block Model</li>
<li class="zword">Seam Model</li>
<li class="zword">Surface Model</li>
</ul>
<p class="zword"><strong>Block Model</strong> is a regular collection of, usually, uniform blocks. Each block will have values for items that are being tracked by the client.</p>
<p class="zword"><strong>Seam Model</strong> is a bit fancier Block Model. This model is subdivided uniformly in the row and column directions of the model but instead of levels, seams are described. Each block in a seam will have an elevation top and bottom to indicate the seam's limits, as well as any other values that are found within that seam block just like a normal block model.</p>
<p class="zword"><strong>Surface Model</strong> is much more limited than the other two as it just holds a stack of surfaces instead of defining any volume. This model is subdivided uniformly in the row and column directions of the model but instead of seams you will have a surface. Each 'block', or really the contact point, for a surface will have an elevation value as well as other values that are being tracked by the client at that surface point.</p>
<p class="zword">Even though only Block Models are sub-blocked, MI does not limit you to only allowing sub-blocks for Block Models. The logic could be applied to the other two types of models. As far as I know, no software vendors sub-block for Seam or Surface Models. In general, if you are sub-blocking for these other two cases, you are just going to define a model at the resolution of the sub-block size instead of this two layered approach in my opinion.</p>
<h3 class="zword"><a name="3.6.1">3.6.1 - Model Block</a></h3>
<p class="zword">After the general information block the next block will be the Model Information block.</p>
<p class="zwordPre">{ model
" type 1 [model type]
b is subblocked 1 [true if subblocked]
" subblock type 1 [subblock type]
abcn4 subblock option 1 [subblock fixed resolution]
abn4 subblock option 1 [subblock row col resolution]
n1 subblock option 1 [subblock octtree level count]
abcr8 origin 1 [origin point]
abcr8 column vector 1 [column vector, length if vector is the length of the block]
abcr4 row vector 1 [row vector, length of the vector is the length of the block]
abcr4 level vector 1 [level vector, length of the vector id the length of the block]
abcn4 block count 1 [number of column, row, level blocks]
b is level size variable 1 [true if variable level heights]
r4 level list [number of levels] [length]*
" item list [item Count] [name of item]*
}
</p>
<p class="zword"><strong>[model type]</strong> will be one of...</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Value</th>
<th class="zword_fill">Description</th>
</tr>
<tr class="zword">
<td class="zword">block</td>
<td class="zword">For a block model.</td>
</tr>
<tr class="zword">
<td class="zword">seam</td>
<td class="zword">For a seam model.</td>
</tr>
<tr class="zword">
<td class="zword">surface</td>
<td class="zword">For a surface model.</td>
</tr>
</tbody></table>
<p class="zword"><strong>[subblock type]</strong> will be one of...</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Value</th>
<th class="zword_fill">Description</th>
</tr>
<tr class="zword">
<td class="zword">fixed</td>
<td class="zword"><p class="zword">For a regular division of the block in the east, north, and z directions of the block.</p>
<p class="zwordPre">Using just a cross section.
Level +--+--+--+--+
| | | | | | <--- Each sub-block of the parent block is of uniform size.
| +--+--+--+--+
| | | | | |
| +--+--+--+--+
| | | | | |
V +--+--+--+--+
Row or Column --->
</p>
</td>
</tr>
<tr class="zword">
<td class="zword">semi</td>
<td class="zword"><p class="zword">For a regular division of a block in the east and north directions but an infinitely variable z value for block height.</p>
<p class="zwordPre">+--+--+--+--+
| +--+ | |
| | +--+ |
| +--+ | | Infinitely variable in the level direction.
+--+ | | |
+--+--+--+--+
Uniform divisions in the row and column directions.
</p>
</td>
</tr>
<tr class="zword">
<td class="zword">octree</td>
<td class="zword"><p class="zword">For an oct-tree subvision of a block.</p>
<p class="zwordPre">+-----+-----+
| | |
+--+--+-----+ Recursive bisecting the blocks until a limit.
+--+--+ |
+--+--+-----+
</p>
</td>
</tr>
<tr class="zword">
<td class="zword">free</td>
<td class="zword"><p class="zword">For a free subdivision of a block where each subblock is individually defined as being some subvolume of the parent.</p>
<p class="zwordPre">+-----------+
| +----+ |
| | | |
| +----+ | Bad diagram but essentially possible with this option. This is a catchall case for
+--+ | those types of subblocking I have not addressed.
| | |
+--+--------+
</p>
</td>
</tr>
</tbody></table>
<p class="zword">Depending on what is set for [subblock type] there will be one of 3 [subblockOption] values.</p>
<ul class="zword">
<li class="zword">fixed subblocking requires a v3n4 to define the number of divisions in the east, north and z directions.</li>
<li class="zword">semiFixed subblocking requires a v2n4 to define the number of divisions in the east and north directions.</li>
<li class="zword">octree subblocking requires a n1 to define the max number of oct-tree divisions that can occur for a block.</li>
<li class="zword">free subblocking does not require an option.</li>
</ul>
<p class="zwordPre"> \ /
\ /
+ Column 1
/ \
Row 1 / \ /
/ \ /
/Lev 0 +
\ / Row 0 /|
\ / Col 0/ |
+ / <----- colVec (Length is block size. Direction is direction of increasing column index.)
|\ / |/
| \ <----------- rowVec (Length is block size. Direction is direction of increasing row index.)
\ | \ / /|
\| o <--------- origin (3D point indicating the outter most corner of the first block.)
+ | /
|\ | <--------- levVec (Length can be block size or unit, depends see below. Direction is direction of increasing level index.)
| \ | /
\|/
+
| Level 1
|
</p>
<p class="zword"><strong>origin</strong> - The extreme most point of the first column, first row, and first level block of the model.</p>
<p class="zword"><strong>colVec, rowVec, levVec</strong> - The direction vectors of increasing block index for the column, row, and level directions. The length of this vector is the size of the block in the column, row and level directions. levVec does not need to be sized if the level height is variable. It should at least be unit length. All vectors need not be perpendicular to each other but usually this is the case in most software. I believe there is one software where colVec and rowVec are not 90 degrees to the levVec. Essentially creating non-square/cuboid blocks.</p>
<p class="zword"><strong>blockCount</strong> - The number of column, row, and level blocks.</p>
<p class="zword"><strong>isLevVariable</strong> - Flag to indicate the level heights are not uniform. This does not need to be present if the levels are a fixed height.</p>
<p class="zword"><strong>levList</strong> - A list of level heights starting from first level. Only required if isLevVariable is true.</p>
<h2 class="zword"><a name="3.7">3.7 - Model Block:</a></h2>
<p class="zword">This is where the model data is placed. The format is slightly different in that it is a key value list but without value headers and potentially optional values depending on the key.</p>
<p class="zwordPre">{ model
</p>
<p class="zword">The model data will be enclosed in a value stream chunk. The contents are broken down in key, or key and value pairs.</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Key (1 Byte)</th>
<th class="zword_fill">Value</th>
</tr>
<tr class="zword">
<td class="zword">B</td>
<td class="zword">n2 value follows immediately. Jump to current level index + N. Reset current row, current column, and current item to 0</td>
</tr>
<tr class="zword">
<td class="zword">b</td>
<td class="zword">No value. Jump to next level. Reset current row, current column, and current item to 0</td>
</tr>
<tr class="zword">
<td class="zword">R</td>
<td class="zword">n2 value follows immediately. Jump to current row index + N. Reset currrent column and current item to 0</td>
</tr>
<tr class="zword">
<td class="zword">r</td>
<td class="zword">No value. Jump to next row. Reset current column and current item to 0.</td>
</tr>
<tr class="zword">
<td class="zword">C</td>
<td class="zword">n2 value follows immediately. Jump to current column index + N. Reset current item to 0</td>
</tr>
<tr class="zword">
<td class="zword">c</td>
<td class="zword">No value. Jump to next column. Reset current item to 0</td>
</tr>
<tr class="zword">
<td class="zword">s</td>
<td class="zword">Defining subblock but parent block as values. Provide parent block item values before subblock values. 'c' follows immediately if parent block has no values.</td>
</tr>
<tr class="zword">
<td class="zword">I</td>
<td class="zword">n1 value follows immediately. Jump to item index + N. Skipped over items get default values.</td>
</tr>
<tr class="zword">
<td class="zword">i</td>
<td class="zword">Jump to next item. Skipped over item gets default value.</td>
</tr>
<tr class="zword">
<td class="zword">V</td>
<td class="zword">n1 value follows. Provide the values for the next n1 items.</td>
</tr>
<tr class="zword">
<td class="zword">v</td>
<td class="zword">Provide the values for the rest of the block or subblock.</td>
</tr>
<tr class="zword">
<td class="zword">D</td>
<td class="zword">n1 value follows immediately. Duplicate the next n1 values from the last block or subblock.</td>
</tr>
<tr class="zword">
<td class="zword">d</td>
<td class="zword">Duplicate the remaining values from the last block or subblock.</td>
</tr>
<tr class="zword">
<td class="zword">X</td>
<td class="zword">n1 value follows immediately. Clone last block n1 times. This is for all the item values.</td>
</tr>
<tr class="zword">
<td class="zword">.</td>
<td class="zword">No value. Indicates end of the item date or subblock data.</td>
</tr>
<tr class="zword">
<td class="zword">\n</td>
<td class="zword">No value. Indicates end value stream.</td>
</tr>
</tbody></table>
<p class="zword">The above may not make that much sense yet so here is an example of a 5x5 block model where we have 3 i4 values per block.</p>
<p class="zwordPre">File What is happening
-------------------- -----------------
model [...]-\n Start of the model data value stream.
Current block is 0 (first) level, 0 (first) row, 0 (column)
B2 Add 2 to the level index.
Current block jumps to 2, 0, 0.
All blocks on levels 0 and 1 have default values.
R2 Add 2 to the row index.
Curent block jumps to 2, 2, 0.
All blocks on level 2, rows 0 and 1 have default values.
C2 Add 2 to the column index.
Current block jumps to 2, 2, 2.
Block 2, 2, 0, and Block 2, 2, 1 have default values.
v1 2 3 Block 2, 2, 2 has values 1, 2, 3.
Current block jumps to 2, 2, 3.
c Block 2, 2, 3 get default value.
Current block after this line is 2, 2, 4.
c Block 2, 2, 4 get default value.
Current block after this line is 2, 3, 0.
We jumped to the next row
\n This indicates that the rest of the model is set to default values.
</p>
<p class="zword">Note that there are no \n after every key value pairs. This is to keep the text representation as compact as possible. So in actual text file this will look like...</p>
<p class="zwordPre">{ model
B2R2C2v1 2 3cc.\n
}
</p>
<p class="zword">Note, if you can removed a separator without losing then that should be done.</p>
<h3 class="zword"><a name="3.7.1">3.7.1 - SubBlock: Fixed</a></h3>
<p class="zword">In the fixed case of subblocking, as soon as an 's' key is hit, that block is divided into the subblocks as defined in the infoModel section. Use B, b, R, r, C, c, and . in the same way as for the parent blocks.</p>
<h3 class="zword"><a name="3.7.2">3.7.2 - SubBlock: Semi</a></h3>
<p class="zword">In the semi fixed case of subblocking, as soon as an 's' key is hit, that block is divided into the subblocks as defined in the infoModel section. One difference...</p>
<p class="zword">In this scheme of subblocking, there is an infinite variability in the z direction for each subblock. This is defined by an 'H' key for the first level of blocks of the subblocks. The number of level subblocks will depend on how many times H is used for the same column.</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Key</th>
<th class="zword_fill">Value</th>
</tr>
<tr class="zword">
<td class="zword">H</td>
<td class="zword">r4 value immediately follows. The r4 value is a percent of the block height. This record needs to preceed a v record.</td>
</tr>
<tr class="zword">
<td class="zword">h</td>
<td class="zword">No value. The rest of the subblock cylinder is used.</td>
</tr>
</tbody></table>
<p class="zword">If H or h follows an H or h then the previous block will be holding default values, and the current block will be incremented to the next subblock. The following H or h will determin the height of the new current block.</p>
<p class="zword">If a subblock cell has already defined the entire height of the block then these will be skipped over when jumping to the next subblock. This means that some subblock cells could have a different number of levels that others.</p>
<h3 class="zword"><a name="3.7.3">3.7.3 - SubBlock: Octree</a></h3>
<p class="zword">In the octree case, an 's' key will split the block or subblock in to 8 uniform pieces. If we are already at a subblock then that subblock will be split into small 8 uniform pieces. This should not exceed the subblock option count defined in the model information block.</p>
<p class="zword">The 's' key need to preceed the v record.</p>
<h3 class="zword"><a name="3.7.4">3.7.4 - SubBlock: Free</a></h3>
<p class="zword">In the free block case, an 's' key will indicate the parent block is subblocked. However after that you will need to define the blocks manually.</p>
<table class="zword"><tbody class="zword">
<tr class="zword">
<th class="zword"><nobr>Key</th>
<th class="zword_fill">Value</th>
</tr>
<tr class="zword">
<td class="zword">c</td>
<td class="zword">6 x r4 values follow. First 3 r4 values are percents for the min point and the second 3 r4 values are percents for the max point of the subblock.</td>
</tr>
<tr class="zword">
<td class="zword">.</td>
<td class="zword">Indicates we are done with the subblocking and to process to the next parent block.</td>
</tr>
</tbody></table>
</body>
</html>