ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ReaderImpl.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com)
3  * Copyright (c) 2020 PTC Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person or organization
6  * obtaining a copy of the software and accompanying documentation covered by
7  * this license (the "Software") to use, reproduce, display, distribute,
8  * execute, and transmit the Software, and to prepare derivative works of the
9  * Software, and to permit third-parties to whom the Software is furnished to
10  * do so, all subject to the following:
11  *
12  * The copyright notices in the Software and this entire statement, including
13  * the above license grant, this restriction and the following disclaimer,
14  * must be included in all copies of the Software, in whole or in part, and
15  * all derivative works of the Software, unless such copies or derivative
16  * works are solely in the form of machine-executable object code generated by
17  * a source language processor.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include "ReaderImpl.h"
29 
30 namespace e57
31 {
32 
33  ReaderImpl::ReaderImpl( const ustring &filePath ) :
34  imf_( filePath, "r" ), root_( imf_.root() ), data3D_( root_.get( "/data3D" ) ),
35  images2D_( root_.get( "/images2D" ) )
36  {
37  }
38 
40  {
41  if ( IsOpen() )
42  {
43  Close();
44  }
45  }
46 
47  // This function returns true if the file is open
48  bool ReaderImpl::IsOpen() const
49  {
50  return imf_.isOpen();
51  }
52 
53  // This function closes the file
55  {
56  if ( !IsOpen() )
57  {
58  return false;
59  }
60 
61  imf_.close();
62  return true;
63  }
64 
65  // This function returns the file header information
66  bool ReaderImpl::GetE57Root( E57Root &fileHeader ) const
67  {
68  if ( !IsOpen() )
69  {
70  return false;
71  }
72 
73  fileHeader = {};
74 
75  fileHeader.formatName = StringNode( root_.get( "formatName" ) ).value();
76  fileHeader.versionMajor = (uint32_t)IntegerNode( root_.get( "versionMajor" ) ).value();
77  fileHeader.versionMinor = (uint32_t)IntegerNode( root_.get( "versionMinor" ) ).value();
78  fileHeader.guid = StringNode( root_.get( "guid" ) ).value();
79  if ( root_.isDefined( "e57LibraryVersion" ) )
80  {
81  fileHeader.e57LibraryVersion = StringNode( root_.get( "e57LibraryVersion" ) ).value();
82  }
83 
84  if ( root_.isDefined( "coordinateMetadata" ) )
85  {
86  fileHeader.coordinateMetadata = StringNode( root_.get( "coordinateMetadata" ) ).value();
87  }
88 
89  if ( root_.isDefined( "creationDateTime" ) )
90  {
91  StructureNode creationDateTime( root_.get( "creationDateTime" ) );
92  fileHeader.creationDateTime.dateTimeValue = FloatNode( creationDateTime.get( "dateTimeValue" ) ).value();
94  (int32_t)IntegerNode( creationDateTime.get( "isAtomicClockReferenced" ) ).value();
95  }
96 
97  fileHeader.data3DSize = data3D_.childCount();
98  fileHeader.images2DSize = images2D_.childCount();
99 
100  return true;
101  }
102 
104  {
105  return images2D_.childCount();
106  }
107 
108  // This function returns the Image2Ds header and positions the cursor
109  bool ReaderImpl::ReadImage2D( int64_t imageIndex, Image2D &image2DHeader ) const
110  {
111  if ( !IsOpen() )
112  {
113  return false;
114  }
115  if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) )
116  {
117  return false;
118  }
119 
120  image2DHeader = {};
121 
122  StructureNode image( images2D_.get( imageIndex ) );
123 
124  image2DHeader.guid = StringNode( image.get( "guid" ) ).value();
125 
126  if ( image.isDefined( "name" ) )
127  {
128  image2DHeader.name = StringNode( image.get( "name" ) ).value();
129  }
130 
131  if ( image.isDefined( "description" ) )
132  {
133  image2DHeader.description = StringNode( image.get( "description" ) ).value();
134  }
135 
136  if ( image.isDefined( "sensorVendor" ) )
137  {
138  image2DHeader.sensorVendor = StringNode( image.get( "sensorVendor" ) ).value();
139  }
140  if ( image.isDefined( "sensorModel" ) )
141  {
142  image2DHeader.sensorModel = StringNode( image.get( "sensorModel" ) ).value();
143  }
144  if ( image.isDefined( "sensorSerialNumber" ) )
145  {
146  image2DHeader.sensorSerialNumber = StringNode( image.get( "sensorSerialNumber" ) ).value();
147  }
148 
149  if ( image.isDefined( "associatedData3DGuid" ) )
150  {
151  image2DHeader.associatedData3DGuid = StringNode( image.get( "associatedData3DGuid" ) ).value();
152  }
153 
154  if ( image.isDefined( "acquisitionDateTime" ) )
155  {
156  StructureNode acquisitionDateTime( image.get( "acquisitionDateTime" ) );
157  image2DHeader.acquisitionDateTime.dateTimeValue =
158  FloatNode( acquisitionDateTime.get( "dateTimeValue" ) ).value();
160  (int32_t)IntegerNode( acquisitionDateTime.get( "isAtomicClockReferenced" ) ).value();
161  }
162 
163  // Get pose structure for scan.
164  if ( image.isDefined( "pose" ) )
165  {
166  StructureNode pose( image.get( "pose" ) );
167  if ( pose.isDefined( "rotation" ) )
168  {
169  StructureNode rotation( pose.get( "rotation" ) );
170  image2DHeader.pose.rotation.w = FloatNode( rotation.get( "w" ) ).value();
171  image2DHeader.pose.rotation.x = FloatNode( rotation.get( "x" ) ).value();
172  image2DHeader.pose.rotation.y = FloatNode( rotation.get( "y" ) ).value();
173  image2DHeader.pose.rotation.z = FloatNode( rotation.get( "z" ) ).value();
174  }
175  if ( pose.isDefined( "translation" ) )
176  {
177  StructureNode translation( pose.get( "translation" ) );
178  image2DHeader.pose.translation.x = FloatNode( translation.get( "x" ) ).value();
179  image2DHeader.pose.translation.y = FloatNode( translation.get( "y" ) ).value();
180  image2DHeader.pose.translation.z = FloatNode( translation.get( "z" ) ).value();
181  }
182  }
183 
184  if ( image.isDefined( "visualReferenceRepresentation" ) )
185  {
186  StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) );
187 
188  if ( visualReferenceRepresentation.isDefined( "jpegImage" ) )
189  {
191  BlobNode( visualReferenceRepresentation.get( "jpegImage" ) ).byteCount();
192  }
193  if ( visualReferenceRepresentation.isDefined( "pngImage" ) )
194  {
196  BlobNode( visualReferenceRepresentation.get( "pngImage" ) ).byteCount();
197  }
198  if ( visualReferenceRepresentation.isDefined( "imageMask" ) )
199  {
201  BlobNode( visualReferenceRepresentation.get( "imageMask" ) ).byteCount();
202  }
203 
205  (int32_t)IntegerNode( visualReferenceRepresentation.get( "imageHeight" ) ).value();
207  (int32_t)IntegerNode( visualReferenceRepresentation.get( "imageWidth" ) ).value();
208  }
209 
210  if ( image.isDefined( "pinholeRepresentation" ) )
211  {
212  StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) );
213 
214  if ( pinholeRepresentation.isDefined( "jpegImage" ) )
215  {
216  image2DHeader.pinholeRepresentation.jpegImageSize =
217  BlobNode( pinholeRepresentation.get( "jpegImage" ) ).byteCount();
218  }
219  if ( pinholeRepresentation.isDefined( "pngImage" ) )
220  {
221  image2DHeader.pinholeRepresentation.pngImageSize =
222  BlobNode( pinholeRepresentation.get( "pngImage" ) ).byteCount();
223  }
224  if ( pinholeRepresentation.isDefined( "imageMask" ) )
225  {
226  image2DHeader.pinholeRepresentation.imageMaskSize =
227  BlobNode( pinholeRepresentation.get( "imageMask" ) ).byteCount();
228  }
229 
230  image2DHeader.pinholeRepresentation.focalLength =
231  FloatNode( pinholeRepresentation.get( "focalLength" ) ).value();
232  image2DHeader.pinholeRepresentation.imageHeight =
233  (int32_t)IntegerNode( pinholeRepresentation.get( "imageHeight" ) ).value();
234  image2DHeader.pinholeRepresentation.imageWidth =
235  (int32_t)IntegerNode( pinholeRepresentation.get( "imageWidth" ) ).value();
236 
237  image2DHeader.pinholeRepresentation.pixelHeight =
238  FloatNode( pinholeRepresentation.get( "pixelHeight" ) ).value();
239  image2DHeader.pinholeRepresentation.pixelWidth =
240  FloatNode( pinholeRepresentation.get( "pixelWidth" ) ).value();
241  image2DHeader.pinholeRepresentation.principalPointX =
242  FloatNode( pinholeRepresentation.get( "principalPointX" ) ).value();
243  image2DHeader.pinholeRepresentation.principalPointY =
244  FloatNode( pinholeRepresentation.get( "principalPointY" ) ).value();
245  }
246  else if ( image.isDefined( "sphericalRepresentation" ) )
247  {
248  StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) );
249 
250  if ( sphericalRepresentation.isDefined( "jpegImage" ) )
251  {
252  image2DHeader.sphericalRepresentation.jpegImageSize =
253  BlobNode( sphericalRepresentation.get( "jpegImage" ) ).byteCount();
254  }
255  if ( sphericalRepresentation.isDefined( "pngImage" ) )
256  {
257  image2DHeader.sphericalRepresentation.pngImageSize =
258  BlobNode( sphericalRepresentation.get( "pngImage" ) ).byteCount();
259  }
260  if ( sphericalRepresentation.isDefined( "imageMask" ) )
261  {
262  image2DHeader.sphericalRepresentation.imageMaskSize =
263  BlobNode( sphericalRepresentation.get( "imageMask" ) ).byteCount();
264  }
265 
266  image2DHeader.sphericalRepresentation.imageHeight =
267  (int32_t)IntegerNode( sphericalRepresentation.get( "imageHeight" ) ).value();
268  image2DHeader.sphericalRepresentation.imageWidth =
269  (int32_t)IntegerNode( sphericalRepresentation.get( "imageWidth" ) ).value();
270 
271  image2DHeader.sphericalRepresentation.pixelHeight =
272  FloatNode( sphericalRepresentation.get( "pixelHeight" ) ).value();
273  image2DHeader.sphericalRepresentation.pixelWidth =
274  FloatNode( sphericalRepresentation.get( "pixelWidth" ) ).value();
275  }
276  else if ( image.isDefined( "cylindricalRepresentation" ) )
277  {
278  StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) );
279 
280  if ( cylindricalRepresentation.isDefined( "jpegImage" ) )
281  {
283  BlobNode( cylindricalRepresentation.get( "jpegImage" ) ).byteCount();
284  }
285  if ( cylindricalRepresentation.isDefined( "pngImage" ) )
286  {
288  BlobNode( cylindricalRepresentation.get( "pngImage" ) ).byteCount();
289  }
290  if ( cylindricalRepresentation.isDefined( "imageMask" ) )
291  {
293  BlobNode( cylindricalRepresentation.get( "imageMask" ) ).byteCount();
294  }
295 
296  image2DHeader.cylindricalRepresentation.imageHeight =
297  (int32_t)IntegerNode( cylindricalRepresentation.get( "imageHeight" ) ).value();
298  image2DHeader.cylindricalRepresentation.imageWidth =
299  (int32_t)IntegerNode( cylindricalRepresentation.get( "imageWidth" ) ).value();
300 
301  image2DHeader.cylindricalRepresentation.pixelHeight =
302  FloatNode( cylindricalRepresentation.get( "pixelHeight" ) ).value();
303  image2DHeader.cylindricalRepresentation.pixelWidth =
304  FloatNode( cylindricalRepresentation.get( "pixelWidth" ) ).value();
306  FloatNode( cylindricalRepresentation.get( "principalPointY" ) ).value();
307  image2DHeader.cylindricalRepresentation.radius =
308  FloatNode( cylindricalRepresentation.get( "radius" ) ).value();
309  }
310 
311  return true;
312  }
313 
314  // This function reads one of the image blobs
315  int64_t ReaderImpl::ReadImage2DNode( StructureNode image, Image2DType imageType, void *pBuffer, int64_t start,
316  int64_t count ) const
317  {
318  int64_t transferred = 0;
319  switch ( imageType )
320  {
321  case E57_NO_IMAGE:
322  {
323  return 0;
324  }
325  case E57_JPEG_IMAGE:
326  {
327  if ( image.isDefined( "jpegImage" ) )
328  {
329  BlobNode jpegImage( image.get( "jpegImage" ) );
330  jpegImage.read( (uint8_t *)pBuffer, start, (size_t)count );
331  transferred = count;
332  }
333  break;
334  }
335  case E57_PNG_IMAGE:
336  {
337  if ( image.isDefined( "pngImage" ) )
338  {
339  BlobNode pngImage( image.get( "pngImage" ) );
340  pngImage.read( (uint8_t *)pBuffer, start, (size_t)count );
341  transferred = count;
342  }
343  break;
344  }
345  case E57_PNG_IMAGE_MASK:
346  {
347  if ( image.isDefined( "imageMask" ) )
348  {
349  BlobNode imageMask( image.get( "imageMask" ) );
350  imageMask.read( (uint8_t *)pBuffer, start, (size_t)count );
351  transferred = count;
352  }
353  break;
354  }
355  }
356  return transferred;
357  }
358 
359  // This function reads one of the image blobs
360  bool ReaderImpl::GetImage2DNodeSizes( StructureNode image, Image2DType &imageType, int64_t &imageWidth,
361  int64_t &imageHeight, int64_t &imageSize, Image2DType &imageMaskType ) const
362  {
363  imageWidth = 0;
364  imageHeight = 0;
365  imageSize = 0;
366  imageType = E57_NO_IMAGE;
367  imageMaskType = E57_NO_IMAGE;
368 
369  if ( image.isDefined( "imageWidth" ) )
370  {
371  imageWidth = IntegerNode( image.get( "imageWidth" ) ).value();
372  }
373  else
374  {
375  return false;
376  }
377 
378  if ( image.isDefined( "imageHeight" ) )
379  {
380  imageHeight = IntegerNode( image.get( "imageHeight" ) ).value();
381  }
382  else
383  {
384  return false;
385  }
386 
387  if ( image.isDefined( "jpegImage" ) )
388  {
389  imageSize = BlobNode( image.get( "jpegImage" ) ).byteCount();
390  imageType = E57_JPEG_IMAGE;
391  }
392  else if ( image.isDefined( "pngImage" ) )
393  {
394  imageSize = BlobNode( image.get( "pngImage" ) ).byteCount();
395  imageType = E57_PNG_IMAGE;
396  }
397 
398  if ( image.isDefined( "imageMask" ) )
399  {
400  if ( imageType == E57_NO_IMAGE )
401  {
402  imageSize = BlobNode( image.get( "imageMask" ) ).byteCount();
403  imageType = E57_PNG_IMAGE_MASK;
404  }
405  imageMaskType = E57_PNG_IMAGE_MASK;
406  }
407  return true;
408  }
409 
410  // This function returns the image sizes
411  bool ReaderImpl::GetImage2DSizes( int64_t imageIndex, Image2DProjection &imageProjection, Image2DType &imageType,
412  int64_t &imageWidth, int64_t &imageHeight, int64_t &imageSize,
413  Image2DType &imageMaskType, Image2DType &imageVisualType ) const
414  {
415  if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) )
416  {
417  return 0;
418  }
419 
420  imageProjection = E57_NO_PROJECTION;
421  imageType = E57_NO_IMAGE;
422  imageMaskType = E57_NO_IMAGE;
423  imageVisualType = E57_NO_IMAGE;
424 
425  bool ret = false;
426  StructureNode image( images2D_.get( imageIndex ) );
427 
428  if ( image.isDefined( "visualReferenceRepresentation" ) )
429  {
430  imageProjection = E57_VISUAL;
431  StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) );
432  ret = GetImage2DNodeSizes( visualReferenceRepresentation, imageType, imageWidth, imageHeight, imageSize,
433  imageMaskType );
434  imageVisualType = imageType;
435  }
436 
437  if ( image.isDefined( "pinholeRepresentation" ) )
438  {
439  imageProjection = E57_PINHOLE;
440  StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) );
441  ret =
442  GetImage2DNodeSizes( pinholeRepresentation, imageType, imageWidth, imageHeight, imageSize, imageMaskType );
443  }
444  else if ( image.isDefined( "sphericalRepresentation" ) )
445  {
446  imageProjection = E57_SPHERICAL;
447  StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) );
448  ret = GetImage2DNodeSizes( sphericalRepresentation, imageType, imageWidth, imageHeight, imageSize,
449  imageMaskType );
450  }
451  else if ( image.isDefined( "cylindricalRepresentation" ) )
452  {
453  imageProjection = E57_CYLINDRICAL;
454  StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) );
455  ret = GetImage2DNodeSizes( cylindricalRepresentation, imageType, imageWidth, imageHeight, imageSize,
456  imageMaskType );
457  }
458 
459  return ret;
460  }
461 
462  // This function reads the block
463  int64_t ReaderImpl::ReadImage2DData( int64_t imageIndex, Image2DProjection imageProjection, Image2DType imageType,
464  void *pBuffer, int64_t start, int64_t count ) const
465  {
466  if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) )
467  {
468  return 0;
469  }
470 
471  int64_t transferred = 0;
472  StructureNode image( images2D_.get( imageIndex ) );
473 
474  switch ( imageProjection )
475  {
476  case E57_NO_PROJECTION:
477  return 0;
478  case E57_VISUAL:
479  if ( image.isDefined( "visualReferenceRepresentation" ) )
480  {
481  StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) );
482  transferred = ReadImage2DNode( visualReferenceRepresentation, imageType, pBuffer, start, count );
483  }
484  break;
485 
486  case E57_PINHOLE:
487  if ( image.isDefined( "pinholeRepresentation" ) )
488  {
489  StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) );
490  transferred = ReadImage2DNode( pinholeRepresentation, imageType, pBuffer, start, count );
491  }
492  break;
493 
494  case E57_SPHERICAL:
495  if ( image.isDefined( "sphericalRepresentation" ) )
496  {
497  StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) );
498  transferred = ReadImage2DNode( sphericalRepresentation, imageType, pBuffer, start, count );
499  }
500  break;
501 
502  case E57_CYLINDRICAL:
503  if ( image.isDefined( "cylindricalRepresentation" ) )
504  {
505  StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) );
506  transferred = ReadImage2DNode( cylindricalRepresentation, imageType, pBuffer, start, count );
507  }
508  break;
509  }
510 
511  return transferred;
512  }
513 
515  {
516  return data3D_.childCount();
517  }
518 
520  {
521  return root_;
522  }
523 
525  {
526  return data3D_;
527  }
528 
530  {
531  return images2D_;
532  }
533 
535  {
536  return imf_;
537  }
538 
539  bool ReaderImpl::ReadData3D( int64_t dataIndex, Data3D &data3DHeader ) const
540  {
541  if ( !IsOpen() )
542  {
543  return false;
544  }
545  if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) )
546  {
547  return false;
548  }
549 
550  data3DHeader = {};
551 
552  StructureNode scan( data3D_.get( dataIndex ) );
553  CompressedVectorNode points( scan.get( "points" ) );
554 
555  data3DHeader.pointsSize = points.childCount();
556  StructureNode proto( points.prototype() );
557 
558  data3DHeader.guid = StringNode( scan.get( "guid" ) ).value();
559 
560  if ( scan.isDefined( "name" ) )
561  {
562  data3DHeader.name = StringNode( scan.get( "name" ) ).value();
563  }
564  if ( scan.isDefined( "description" ) )
565  {
566  data3DHeader.description = StringNode( scan.get( "description" ) ).value();
567  }
568 
569  if ( scan.isDefined( "originalGuids" ) )
570  {
571  VectorNode originalGuids( scan.get( "originalGuids" ) );
572  if ( originalGuids.childCount() > 0 )
573  {
574  data3DHeader.originalGuids.clear();
575  int i;
576  for ( i = 0; i < originalGuids.childCount(); i++ )
577  {
578  ustring str = StringNode( originalGuids.get( i ) ).value();
579  data3DHeader.originalGuids.push_back( str );
580  }
581  }
582  }
583 
584  // Get various sensor and version strings to scan.
585  if ( scan.isDefined( "sensorVendor" ) )
586  {
587  data3DHeader.sensorVendor = StringNode( scan.get( "sensorVendor" ) ).value();
588  }
589  if ( scan.isDefined( "sensorModel" ) )
590  {
591  data3DHeader.sensorModel = StringNode( scan.get( "sensorModel" ) ).value();
592  }
593  if ( scan.isDefined( "sensorSerialNumber" ) )
594  {
595  data3DHeader.sensorSerialNumber = StringNode( scan.get( "sensorSerialNumber" ) ).value();
596  }
597  if ( scan.isDefined( "sensorHardwareVersion" ) )
598  {
599  data3DHeader.sensorHardwareVersion = StringNode( scan.get( "sensorHardwareVersion" ) ).value();
600  }
601  if ( scan.isDefined( "sensorSoftwareVersion" ) )
602  {
603  data3DHeader.sensorSoftwareVersion = StringNode( scan.get( "sensorSoftwareVersion" ) ).value();
604  }
605  if ( scan.isDefined( "sensorFirmwareVersion" ) )
606  {
607  data3DHeader.sensorFirmwareVersion = StringNode( scan.get( "sensorFirmwareVersion" ) ).value();
608  }
609 
610  // Get temp/humidity to scan.
611  if ( scan.isDefined( "temperature" ) )
612  {
613  data3DHeader.temperature = (float)FloatNode( scan.get( "temperature" ) ).value();
614  }
615  if ( scan.isDefined( "relativeHumidity" ) )
616  {
617  data3DHeader.relativeHumidity = (float)FloatNode( scan.get( "relativeHumidity" ) ).value();
618  }
619  if ( scan.isDefined( "atmosphericPressure" ) )
620  {
621  data3DHeader.atmosphericPressure = (float)FloatNode( scan.get( "atmosphericPressure" ) ).value();
622  }
623 
624  if ( scan.isDefined( "indexBounds" ) )
625  {
626  StructureNode ibox( scan.get( "indexBounds" ) );
627  if ( ibox.isDefined( "rowMaximum" ) )
628  {
629  data3DHeader.indexBounds.rowMinimum = IntegerNode( ibox.get( "rowMinimum" ) ).value();
630  data3DHeader.indexBounds.rowMaximum = IntegerNode( ibox.get( "rowMaximum" ) ).value();
631  }
632  if ( ibox.isDefined( "columnMaximum" ) )
633  {
634  data3DHeader.indexBounds.columnMinimum = IntegerNode( ibox.get( "columnMinimum" ) ).value();
635  data3DHeader.indexBounds.columnMaximum = IntegerNode( ibox.get( "columnMaximum" ) ).value();
636  }
637  if ( ibox.isDefined( "returnMaximum" ) )
638  {
639  data3DHeader.indexBounds.returnMinimum = IntegerNode( ibox.get( "returnMinimum" ) ).value();
640  data3DHeader.indexBounds.returnMaximum = IntegerNode( ibox.get( "returnMaximum" ) ).value();
641  }
642  }
643 
644  if ( scan.isDefined( "pointGroupingSchemes" ) )
645  {
646  StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) );
647  if ( pointGroupingSchemes.isDefined( "groupingByLine" ) )
648  {
649  StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) );
650 
652  StringNode( groupingByLine.get( "idElementName" ) ).value();
653 
654  CompressedVectorNode groups( groupingByLine.get( "groups" ) );
656 
657  StructureNode lineGroupRecord( groups.prototype() );
658  if ( lineGroupRecord.isDefined( "pointCount" ) )
659  {
661  IntegerNode( lineGroupRecord.get( "pointCount" ) ).maximum();
662  }
663  }
664  }
665 
666  // Get Cartesian bounding box to scan.
667  if ( scan.isDefined( "cartesianBounds" ) )
668  {
669  StructureNode bbox( scan.get( "cartesianBounds" ) );
670  if ( bbox.get( "xMinimum" ).type() == E57_SCALED_INTEGER )
671  {
672  data3DHeader.cartesianBounds.xMinimum = (double)ScaledIntegerNode( bbox.get( "xMinimum" ) ).scaledValue();
673  data3DHeader.cartesianBounds.xMaximum = (double)ScaledIntegerNode( bbox.get( "xMaximum" ) ).scaledValue();
674  data3DHeader.cartesianBounds.yMinimum = (double)ScaledIntegerNode( bbox.get( "yMinimum" ) ).scaledValue();
675  data3DHeader.cartesianBounds.yMaximum = (double)ScaledIntegerNode( bbox.get( "yMaximum" ) ).scaledValue();
676  data3DHeader.cartesianBounds.zMinimum = (double)ScaledIntegerNode( bbox.get( "zMinimum" ) ).scaledValue();
677  data3DHeader.cartesianBounds.zMaximum = (double)ScaledIntegerNode( bbox.get( "zMaximum" ) ).scaledValue();
678  }
679  else if ( bbox.get( "xMinimum" ).type() == E57_FLOAT )
680  {
681  data3DHeader.cartesianBounds.xMinimum = FloatNode( bbox.get( "xMinimum" ) ).value();
682  data3DHeader.cartesianBounds.xMaximum = FloatNode( bbox.get( "xMaximum" ) ).value();
683  data3DHeader.cartesianBounds.yMinimum = FloatNode( bbox.get( "yMinimum" ) ).value();
684  data3DHeader.cartesianBounds.yMaximum = FloatNode( bbox.get( "yMaximum" ) ).value();
685  data3DHeader.cartesianBounds.zMinimum = FloatNode( bbox.get( "zMinimum" ) ).value();
686  data3DHeader.cartesianBounds.zMaximum = FloatNode( bbox.get( "zMaximum" ) ).value();
687  }
688  }
689 
690  if ( scan.isDefined( "sphericalBounds" ) )
691  {
692  StructureNode sbox( scan.get( "sphericalBounds" ) );
693  if ( sbox.get( "rangeMinimum" ).type() == E57_SCALED_INTEGER )
694  {
695  data3DHeader.sphericalBounds.rangeMinimum =
696  (double)ScaledIntegerNode( sbox.get( "rangeMinimum" ) ).scaledValue();
697  data3DHeader.sphericalBounds.rangeMaximum =
698  (double)ScaledIntegerNode( sbox.get( "rangeMaximum" ) ).scaledValue();
699  }
700  else if ( sbox.get( "rangeMinimum" ).type() == E57_FLOAT )
701  {
702  data3DHeader.sphericalBounds.rangeMinimum = FloatNode( sbox.get( "rangeMinimum" ) ).value();
703  data3DHeader.sphericalBounds.rangeMaximum = FloatNode( sbox.get( "rangeMaximum" ) ).value();
704  }
705 
706  if ( sbox.get( "elevationMinimum" ).type() == E57_SCALED_INTEGER )
707  {
708  data3DHeader.sphericalBounds.elevationMinimum =
709  (double)ScaledIntegerNode( sbox.get( "elevationMinimum" ) ).scaledValue();
710  data3DHeader.sphericalBounds.elevationMaximum =
711  (double)ScaledIntegerNode( sbox.get( "elevationMaximum" ) ).scaledValue();
712  }
713  else if ( sbox.get( "elevationMinimum" ).type() == E57_FLOAT )
714  {
715  data3DHeader.sphericalBounds.elevationMinimum = FloatNode( sbox.get( "elevationMinimum" ) ).value();
716  data3DHeader.sphericalBounds.elevationMaximum = FloatNode( sbox.get( "elevationMaximum" ) ).value();
717  }
718 
719  if ( sbox.get( "azimuthStart" ).type() == E57_SCALED_INTEGER )
720  {
721  data3DHeader.sphericalBounds.azimuthStart =
722  (double)ScaledIntegerNode( sbox.get( "azimuthStart" ) ).scaledValue();
723  data3DHeader.sphericalBounds.azimuthEnd =
724  (double)ScaledIntegerNode( sbox.get( "azimuthEnd" ) ).scaledValue();
725  }
726  else if ( sbox.get( "azimuthStart" ).type() == E57_FLOAT )
727  {
728  data3DHeader.sphericalBounds.azimuthStart = FloatNode( sbox.get( "azimuthStart" ) ).value();
729  data3DHeader.sphericalBounds.azimuthEnd = FloatNode( sbox.get( "azimuthEnd" ) ).value();
730  }
731  }
732 
733  // Get pose structure for scan.
734  if ( scan.isDefined( "pose" ) )
735  {
736  StructureNode pose( scan.get( "pose" ) );
737  if ( pose.isDefined( "rotation" ) )
738  {
739  StructureNode rotation( pose.get( "rotation" ) );
740  data3DHeader.pose.rotation.w = FloatNode( rotation.get( "w" ) ).value();
741  data3DHeader.pose.rotation.x = FloatNode( rotation.get( "x" ) ).value();
742  data3DHeader.pose.rotation.y = FloatNode( rotation.get( "y" ) ).value();
743  data3DHeader.pose.rotation.z = FloatNode( rotation.get( "z" ) ).value();
744  }
745  if ( pose.isDefined( "translation" ) )
746  {
747  StructureNode translation( pose.get( "translation" ) );
748  data3DHeader.pose.translation.x = FloatNode( translation.get( "x" ) ).value();
749  data3DHeader.pose.translation.y = FloatNode( translation.get( "y" ) ).value();
750  data3DHeader.pose.translation.z = FloatNode( translation.get( "z" ) ).value();
751  }
752  }
753 
754  // Get start/stop acquisition times to scan.
755  if ( scan.isDefined( "acquisitionStart" ) )
756  {
757  StructureNode acquisitionStart( scan.get( "acquisitionStart" ) );
758  data3DHeader.acquisitionStart.dateTimeValue = FloatNode( acquisitionStart.get( "dateTimeValue" ) ).value();
760  (int32_t)IntegerNode( acquisitionStart.get( "isAtomicClockReferenced" ) ).value();
761  }
762 
763  if ( scan.isDefined( "acquisitionEnd" ) )
764  {
765  StructureNode acquisitionEnd( scan.get( "acquisitionEnd" ) );
766  data3DHeader.acquisitionEnd.dateTimeValue = FloatNode( acquisitionEnd.get( "dateTimeValue" ) ).value();
768  (int32_t)IntegerNode( acquisitionEnd.get( "isAtomicClockReferenced" ) ).value();
769  }
770 
771  // Get a prototype of datatypes that will be stored in points record.
772  data3DHeader.pointFields.cartesianXField = proto.isDefined( "cartesianX" );
773  data3DHeader.pointFields.cartesianYField = proto.isDefined( "cartesianY" );
774  data3DHeader.pointFields.cartesianZField = proto.isDefined( "cartesianZ" );
775  data3DHeader.pointFields.cartesianInvalidStateField = proto.isDefined( "cartesianInvalidState" );
776 
778  data3DHeader.pointFields.pointRangeMinimum = 0.;
779  data3DHeader.pointFields.pointRangeMaximum = 0.;
780 
781  if ( proto.isDefined( "cartesianX" ) )
782  {
783  if ( proto.get( "cartesianX" ).type() == E57_SCALED_INTEGER )
784  {
785  double scale = ScaledIntegerNode( proto.get( "cartesianX" ) ).scale();
786  double offset = ScaledIntegerNode( proto.get( "cartesianX" ) ).offset();
787  int64_t minimum = ScaledIntegerNode( proto.get( "cartesianX" ) ).minimum();
788  int64_t maximum = ScaledIntegerNode( proto.get( "cartesianX" ) ).maximum();
789  data3DHeader.pointFields.pointRangeMinimum = (double)minimum * scale + offset;
790  data3DHeader.pointFields.pointRangeMaximum = (double)maximum * scale + offset;
791  data3DHeader.pointFields.pointRangeScaledInteger = scale;
792  }
793  else if ( proto.get( "cartesianX" ).type() == E57_FLOAT )
794  {
795  data3DHeader.pointFields.pointRangeMinimum = FloatNode( proto.get( "cartesianX" ) ).minimum();
796  data3DHeader.pointFields.pointRangeMaximum = FloatNode( proto.get( "cartesianX" ) ).maximum();
798  }
799  }
800  else if ( proto.isDefined( "sphericalRange" ) )
801  {
802  if ( proto.get( "sphericalRange" ).type() == E57_SCALED_INTEGER )
803  {
804  double scale = ScaledIntegerNode( proto.get( "sphericalRange" ) ).scale();
805  double offset = ScaledIntegerNode( proto.get( "sphericalRange" ) ).offset();
806  int64_t minimum = ScaledIntegerNode( proto.get( "sphericalRange" ) ).minimum();
807  int64_t maximum = ScaledIntegerNode( proto.get( "sphericalRange" ) ).maximum();
808  data3DHeader.pointFields.pointRangeMinimum = (double)minimum * scale + offset;
809  data3DHeader.pointFields.pointRangeMaximum = (double)maximum * scale + offset;
810  data3DHeader.pointFields.pointRangeScaledInteger = scale;
811  }
812  else if ( proto.get( "sphericalRange" ).type() == E57_FLOAT )
813  {
814  data3DHeader.pointFields.pointRangeMinimum = FloatNode( proto.get( "sphericalRange" ) ).minimum();
815  data3DHeader.pointFields.pointRangeMaximum = FloatNode( proto.get( "sphericalRange" ) ).maximum();
817  }
818  }
819 
820  data3DHeader.pointFields.sphericalRangeField = proto.isDefined( "sphericalRange" );
821  data3DHeader.pointFields.sphericalAzimuthField = proto.isDefined( "sphericalAzimuth" );
822  data3DHeader.pointFields.sphericalElevationField = proto.isDefined( "sphericalElevation" );
823  data3DHeader.pointFields.sphericalInvalidStateField = proto.isDefined( "sphericalInvalidState" );
824 
825  data3DHeader.pointFields.angleScaledInteger = E57_NOT_SCALED_USE_FLOAT; // FloatNode
826  data3DHeader.pointFields.angleMinimum = 0.;
827  data3DHeader.pointFields.angleMaximum = 0.;
828 
829  if ( proto.isDefined( "sphericalAzimuth" ) )
830  {
831  if ( proto.get( "sphericalAzimuth" ).type() == E57_SCALED_INTEGER )
832  {
833  double scale = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).scale();
834  double offset = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).offset();
835  int64_t minimum = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).minimum();
836  int64_t maximum = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).maximum();
837  data3DHeader.pointFields.angleMinimum = (double)minimum * scale + offset;
838  data3DHeader.pointFields.angleMaximum = (double)maximum * scale + offset;
839  data3DHeader.pointFields.angleScaledInteger = scale;
840  }
841  else if ( proto.get( "sphericalAzimuth" ).type() == E57_FLOAT )
842  {
843  data3DHeader.pointFields.angleMinimum = FloatNode( proto.get( "sphericalAzimuth" ) ).minimum();
844  data3DHeader.pointFields.angleMaximum = FloatNode( proto.get( "sphericalAzimuth" ) ).maximum();
846  }
847  }
848 
849  data3DHeader.pointFields.rowIndexField = proto.isDefined( "rowIndex" );
850  data3DHeader.pointFields.columnIndexField = proto.isDefined( "columnIndex" );
851  data3DHeader.pointFields.rowIndexMaximum = 0;
852  data3DHeader.pointFields.columnIndexMaximum = 0;
853 
854  if ( proto.isDefined( "rowIndex" ) )
855  {
856  data3DHeader.pointFields.rowIndexMaximum = (uint32_t)IntegerNode( proto.get( "rowIndex" ) ).maximum();
857  }
858 
859  if ( proto.isDefined( "columnIndex" ) )
860  {
861  data3DHeader.pointFields.columnIndexMaximum = (uint32_t)IntegerNode( proto.get( "columnIndex" ) ).maximum();
862  }
863 
864  data3DHeader.pointFields.returnIndexField = proto.isDefined( "returnIndex" );
865  data3DHeader.pointFields.returnCountField = proto.isDefined( "returnCount" );
866  data3DHeader.pointFields.returnMaximum = 0;
867 
868  if ( proto.isDefined( "returnIndex" ) )
869  {
870  data3DHeader.pointFields.returnMaximum = (uint8_t)IntegerNode( proto.get( "returnIndex" ) ).maximum();
871  }
872 
873  data3DHeader.pointFields.timeStampField = proto.isDefined( "timeStamp" );
874  data3DHeader.pointFields.isTimeStampInvalidField = proto.isDefined( "isTimeStampInvalid" );
875  data3DHeader.pointFields.timeMaximum = 0.;
876  data3DHeader.pointFields.timeMinimum = 0.;
878 
879  if ( proto.isDefined( "timeStamp" ) )
880  {
881  if ( proto.get( "timeStamp" ).type() == E57_INTEGER )
882  {
883  data3DHeader.pointFields.timeMaximum = (double)IntegerNode( proto.get( "timeStamp" ) ).maximum();
884  data3DHeader.pointFields.timeMinimum = (double)IntegerNode( proto.get( "timeStamp" ) ).minimum();
886  }
887  else if ( proto.get( "timeStamp" ).type() == E57_SCALED_INTEGER )
888  {
889  double scale = ScaledIntegerNode( proto.get( "timeStamp" ) ).scale();
890  double offset = ScaledIntegerNode( proto.get( "timeStamp" ) ).offset();
891  int64_t minimum = ScaledIntegerNode( proto.get( "timeStamp" ) ).minimum();
892  int64_t maximum = ScaledIntegerNode( proto.get( "timeStamp" ) ).maximum();
893  data3DHeader.pointFields.timeMinimum = (double)minimum * scale + offset;
894  data3DHeader.pointFields.timeMaximum = (double)maximum * scale + offset;
895  data3DHeader.pointFields.timeScaledInteger = scale;
896  }
897  else if ( proto.get( "timeStamp" ).type() == E57_FLOAT )
898  {
899  data3DHeader.pointFields.timeMinimum = FloatNode( proto.get( "timeStamp" ) ).minimum();
900  data3DHeader.pointFields.timeMaximum = FloatNode( proto.get( "timeStamp" ) ).maximum();
902  }
903  }
904 
905  data3DHeader.pointFields.intensityField = proto.isDefined( "intensity" );
906  data3DHeader.pointFields.isIntensityInvalidField = proto.isDefined( "isIntensityInvalid" );
907  data3DHeader.intensityLimits.intensityMinimum = 0.;
908  data3DHeader.intensityLimits.intensityMaximum = 0.;
910 
911  if ( scan.isDefined( "intensityLimits" ) )
912  {
913  StructureNode intbox( scan.get( "intensityLimits" ) );
914  if ( intbox.get( "intensityMaximum" ).type() == E57_SCALED_INTEGER )
915  {
916  data3DHeader.intensityLimits.intensityMaximum =
917  (double)ScaledIntegerNode( intbox.get( "intensityMaximum" ) ).scaledValue();
918  data3DHeader.intensityLimits.intensityMinimum =
919  (double)ScaledIntegerNode( intbox.get( "intensityMinimum" ) ).scaledValue();
920  }
921  else if ( intbox.get( "intensityMaximum" ).type() == E57_FLOAT )
922  {
923  data3DHeader.intensityLimits.intensityMaximum = FloatNode( intbox.get( "intensityMaximum" ) ).value();
924  data3DHeader.intensityLimits.intensityMinimum = FloatNode( intbox.get( "intensityMinimum" ) ).value();
925  }
926  else if ( intbox.get( "intensityMaximum" ).type() == E57_INTEGER )
927  {
928  data3DHeader.intensityLimits.intensityMaximum =
929  (double)IntegerNode( intbox.get( "intensityMaximum" ) ).value();
930  data3DHeader.intensityLimits.intensityMinimum =
931  (double)IntegerNode( intbox.get( "intensityMinimum" ) ).value();
932  }
933  }
934  if ( proto.isDefined( "intensity" ) )
935  {
936  if ( proto.get( "intensity" ).type() == E57_INTEGER )
937  {
938  if ( data3DHeader.intensityLimits.intensityMaximum == 0. )
939  {
940  data3DHeader.intensityLimits.intensityMinimum =
941  (double)IntegerNode( proto.get( "intensity" ) ).minimum();
942  data3DHeader.intensityLimits.intensityMaximum =
943  (double)IntegerNode( proto.get( "intensity" ) ).maximum();
944  }
946  }
947  else if ( proto.get( "intensity" ).type() == E57_SCALED_INTEGER )
948  {
949  double scale = ScaledIntegerNode( proto.get( "intensity" ) ).scale();
950  double offset = ScaledIntegerNode( proto.get( "intensity" ) ).offset();
951 
952  if ( data3DHeader.intensityLimits.intensityMaximum == 0. )
953  {
954  int64_t minimum = ScaledIntegerNode( proto.get( "intensity" ) ).minimum();
955  int64_t maximum = ScaledIntegerNode( proto.get( "intensity" ) ).maximum();
956  data3DHeader.intensityLimits.intensityMinimum = (double)minimum * scale + offset;
957  data3DHeader.intensityLimits.intensityMaximum = (double)maximum * scale + offset;
958  }
959  data3DHeader.pointFields.intensityScaledInteger = scale;
960  }
961  else if ( proto.get( "intensity" ).type() == E57_FLOAT )
962  {
963  if ( data3DHeader.intensityLimits.intensityMaximum == 0. )
964  {
965  data3DHeader.intensityLimits.intensityMinimum = FloatNode( proto.get( "intensity" ) ).minimum();
966  data3DHeader.intensityLimits.intensityMaximum = FloatNode( proto.get( "intensity" ) ).maximum();
967  }
969  }
970  }
971 
972  data3DHeader.pointFields.colorRedField = proto.isDefined( "colorRed" );
973  data3DHeader.pointFields.colorGreenField = proto.isDefined( "colorGreen" );
974  data3DHeader.pointFields.colorBlueField = proto.isDefined( "colorBlue" );
975  data3DHeader.pointFields.isColorInvalidField = proto.isDefined( "isColorInvalid" );
976 
977  data3DHeader.colorLimits.colorRedMinimum = 0.;
978  data3DHeader.colorLimits.colorRedMaximum = 0.;
979  data3DHeader.colorLimits.colorGreenMinimum = 0.;
980  data3DHeader.colorLimits.colorGreenMaximum = 0.;
981  data3DHeader.colorLimits.colorBlueMinimum = 0.;
982  data3DHeader.colorLimits.colorBlueMaximum = 0.;
983 
984  if ( scan.isDefined( "colorLimits" ) )
985  {
986  StructureNode colorbox( scan.get( "colorLimits" ) );
987  if ( colorbox.get( "colorRedMaximum" ).type() == E57_SCALED_INTEGER )
988  {
989  data3DHeader.colorLimits.colorRedMaximum =
990  (double)ScaledIntegerNode( colorbox.get( "colorRedMaximum" ) ).scaledValue();
991  data3DHeader.colorLimits.colorRedMinimum =
992  (double)ScaledIntegerNode( colorbox.get( "colorRedMinimum" ) ).scaledValue();
993  data3DHeader.colorLimits.colorGreenMaximum =
994  (double)ScaledIntegerNode( colorbox.get( "colorGreenMaximum" ) ).scaledValue();
995  data3DHeader.colorLimits.colorGreenMinimum =
996  (double)ScaledIntegerNode( colorbox.get( "colorGreenMinimum" ) ).scaledValue();
997  data3DHeader.colorLimits.colorBlueMaximum =
998  (double)ScaledIntegerNode( colorbox.get( "colorBlueMaximum" ) ).scaledValue();
999  data3DHeader.colorLimits.colorBlueMinimum =
1000  (double)ScaledIntegerNode( colorbox.get( "colorBlueMinimum" ) ).scaledValue();
1001  }
1002  else if ( colorbox.get( "colorRedMaximum" ).type() == E57_FLOAT )
1003  {
1004  data3DHeader.colorLimits.colorRedMaximum = FloatNode( colorbox.get( "colorRedMaximum" ) ).value();
1005  data3DHeader.colorLimits.colorRedMinimum = FloatNode( colorbox.get( "colorRedMinimum" ) ).value();
1006  data3DHeader.colorLimits.colorGreenMaximum = FloatNode( colorbox.get( "colorGreenMaximum" ) ).value();
1007  data3DHeader.colorLimits.colorGreenMinimum = FloatNode( colorbox.get( "colorGreenMinimum" ) ).value();
1008  data3DHeader.colorLimits.colorBlueMaximum = FloatNode( colorbox.get( "colorBlueMaximum" ) ).value();
1009  data3DHeader.colorLimits.colorBlueMinimum = FloatNode( colorbox.get( "colorBlueMinimum" ) ).value();
1010  }
1011  else if ( colorbox.get( "colorRedMaximum" ).type() == E57_INTEGER )
1012  {
1013  data3DHeader.colorLimits.colorRedMaximum = (double)IntegerNode( colorbox.get( "colorRedMaximum" ) ).value();
1014  data3DHeader.colorLimits.colorRedMinimum = (double)IntegerNode( colorbox.get( "colorRedMinimum" ) ).value();
1015  data3DHeader.colorLimits.colorGreenMaximum =
1016  (double)IntegerNode( colorbox.get( "colorGreenMaximum" ) ).value();
1017  data3DHeader.colorLimits.colorGreenMinimum =
1018  (double)IntegerNode( colorbox.get( "colorGreenMinimum" ) ).value();
1019  data3DHeader.colorLimits.colorBlueMaximum =
1020  (double)IntegerNode( colorbox.get( "colorBlueMaximum" ) ).value();
1021  data3DHeader.colorLimits.colorBlueMinimum =
1022  (double)IntegerNode( colorbox.get( "colorBlueMinimum" ) ).value();
1023  }
1024  }
1025 
1026  if ( ( data3DHeader.colorLimits.colorRedMaximum == 0. ) && proto.isDefined( "colorRed" ) )
1027  {
1028  if ( proto.get( "colorRed" ).type() == E57_INTEGER )
1029  {
1030  data3DHeader.colorLimits.colorRedMinimum = (uint16_t)IntegerNode( proto.get( "colorRed" ) ).minimum();
1031  data3DHeader.colorLimits.colorRedMaximum = (uint16_t)IntegerNode( proto.get( "colorRed" ) ).maximum();
1032  }
1033  else if ( proto.get( "colorRed" ).type() == E57_FLOAT )
1034  {
1035  data3DHeader.colorLimits.colorRedMinimum = (uint16_t)FloatNode( proto.get( "colorRed" ) ).minimum();
1036  data3DHeader.colorLimits.colorRedMaximum = (uint16_t)FloatNode( proto.get( "colorRed" ) ).maximum();
1037  }
1038  else if ( proto.get( "colorRed" ).type() == E57_SCALED_INTEGER )
1039  {
1040  double scale = ScaledIntegerNode( proto.get( "colorRed" ) ).scale();
1041  double offset = ScaledIntegerNode( proto.get( "colorRed" ) ).offset();
1042  int64_t minimum = ScaledIntegerNode( proto.get( "colorRed" ) ).minimum();
1043  int64_t maximum = ScaledIntegerNode( proto.get( "colorRed" ) ).maximum();
1044  data3DHeader.colorLimits.colorRedMinimum = (uint16_t)minimum * scale + offset;
1045  data3DHeader.colorLimits.colorRedMaximum = (uint16_t)maximum * scale + offset;
1046  }
1047  }
1048  if ( ( data3DHeader.colorLimits.colorGreenMaximum == 0. ) && proto.isDefined( "colorGreen" ) )
1049  {
1050  if ( proto.get( "colorGreen" ).type() == E57_INTEGER )
1051  {
1052  data3DHeader.colorLimits.colorGreenMinimum = (uint16_t)IntegerNode( proto.get( "colorGreen" ) ).minimum();
1053  data3DHeader.colorLimits.colorGreenMaximum = (uint16_t)IntegerNode( proto.get( "colorGreen" ) ).maximum();
1054  }
1055  else if ( proto.get( "colorGreen" ).type() == E57_FLOAT )
1056  {
1057  data3DHeader.colorLimits.colorGreenMinimum = (uint16_t)FloatNode( proto.get( "colorGreen" ) ).minimum();
1058  data3DHeader.colorLimits.colorGreenMaximum = (uint16_t)FloatNode( proto.get( "colorGreen" ) ).maximum();
1059  }
1060  else if ( proto.get( "colorGreen" ).type() == E57_SCALED_INTEGER )
1061  {
1062  double scale = ScaledIntegerNode( proto.get( "colorGreen" ) ).scale();
1063  double offset = ScaledIntegerNode( proto.get( "colorGreen" ) ).offset();
1064  int64_t minimum = ScaledIntegerNode( proto.get( "colorGreen" ) ).minimum();
1065  int64_t maximum = ScaledIntegerNode( proto.get( "colorGreen" ) ).maximum();
1066  data3DHeader.colorLimits.colorGreenMinimum = (uint16_t)minimum * scale + offset;
1067  data3DHeader.colorLimits.colorGreenMaximum = (uint16_t)maximum * scale + offset;
1068  }
1069  }
1070  if ( ( data3DHeader.colorLimits.colorBlueMaximum == 0. ) && proto.isDefined( "colorBlue" ) )
1071  {
1072  if ( proto.get( "colorBlue" ).type() == E57_INTEGER )
1073  {
1074  data3DHeader.colorLimits.colorBlueMinimum = (uint16_t)IntegerNode( proto.get( "colorBlue" ) ).minimum();
1075  data3DHeader.colorLimits.colorBlueMaximum = (uint16_t)IntegerNode( proto.get( "colorBlue" ) ).maximum();
1076  }
1077  else if ( proto.get( "colorBlue" ).type() == E57_FLOAT )
1078  {
1079  data3DHeader.colorLimits.colorBlueMinimum = (uint16_t)FloatNode( proto.get( "colorBlue" ) ).minimum();
1080  data3DHeader.colorLimits.colorBlueMaximum = (uint16_t)FloatNode( proto.get( "colorBlue" ) ).maximum();
1081  }
1082  else if ( proto.get( "colorBlue" ).type() == E57_SCALED_INTEGER )
1083  {
1084  double scale = ScaledIntegerNode( proto.get( "colorBlue" ) ).scale();
1085  double offset = ScaledIntegerNode( proto.get( "colorBlue" ) ).offset();
1086  int64_t minimum = ScaledIntegerNode( proto.get( "colorBlue" ) ).minimum();
1087  int64_t maximum = ScaledIntegerNode( proto.get( "colorBlue" ) ).maximum();
1088  data3DHeader.colorLimits.colorRedMinimum = (uint16_t)minimum * scale + offset;
1089  data3DHeader.colorLimits.colorRedMaximum = (uint16_t)maximum * scale + offset;
1090  }
1091  }
1092 
1093  // E57_EXT_surface_normals
1094  ustring norExtUri;
1095  if ( imf_.extensionsLookupPrefix( "nor", norExtUri ) )
1096  {
1097  data3DHeader.pointFields.normalX = proto.isDefined( "nor:normalX" );
1098  data3DHeader.pointFields.normalY = proto.isDefined( "nor:normalY" );
1099  data3DHeader.pointFields.normalZ = proto.isDefined( "nor:normalZ" );
1100  }
1101 
1102  return true;
1103  }
1104 
1105  // This function returns the size of the point data
1106  bool ReaderImpl::GetData3DSizes( int64_t dataIndex, int64_t &row, int64_t &column, int64_t &pointsSize,
1107  int64_t &groupsSize, int64_t &countSize, bool &bColumnIndex ) const
1108  {
1109  row = 0;
1110  column = 0;
1111  pointsSize = 0;
1112  groupsSize = 0;
1113  int64_t elementSize = 0;
1114  countSize = 0;
1115  bColumnIndex = false;
1116 
1117  if ( !IsOpen() )
1118  {
1119  return false;
1120  }
1121  if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) )
1122  {
1123  return false;
1124  }
1125 
1126  StructureNode scan( data3D_.get( dataIndex ) );
1127 
1128  CompressedVectorNode points( scan.get( "points" ) );
1129  pointsSize = points.childCount();
1130 
1131  if ( scan.isDefined( "indexBounds" ) )
1132  {
1133  StructureNode indexBounds( scan.get( "indexBounds" ) );
1134  if ( indexBounds.isDefined( "columnMaximum" ) )
1135  {
1136  column = IntegerNode( indexBounds.get( "columnMaximum" ) ).value() -
1137  IntegerNode( indexBounds.get( "columnMinimum" ) ).value() + 1;
1138  }
1139 
1140  if ( indexBounds.isDefined( "rowMaximum" ) )
1141  {
1142  row = IntegerNode( indexBounds.get( "rowMaximum" ) ).value() -
1143  IntegerNode( indexBounds.get( "rowMinimum" ) ).value() + 1;
1144  }
1145  }
1146 
1147  if ( scan.isDefined( "pointGroupingSchemes" ) )
1148  {
1149  StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) );
1150  if ( pointGroupingSchemes.isDefined( "groupingByLine" ) )
1151  {
1152  StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) );
1153 
1154  StringNode idElementName( groupingByLine.get( "idElementName" ) );
1155  if ( idElementName.value().compare( "columnIndex" ) == 0 )
1156  {
1157  bColumnIndex = true;
1158  }
1159 
1160  CompressedVectorNode groups( groupingByLine.get( "groups" ) );
1161  groupsSize = groups.childCount();
1162 
1163  StructureNode lineGroupRecord( groups.prototype() );
1164 
1165  if ( lineGroupRecord.isDefined( "idElementValue" ) )
1166  {
1167  elementSize = IntegerNode( lineGroupRecord.get( "idElementValue" ) ).maximum() -
1168  IntegerNode( lineGroupRecord.get( "idElementValue" ) ).minimum() + 1;
1169  }
1170  else if ( bColumnIndex )
1171  {
1172  elementSize = column;
1173  }
1174  else
1175  {
1176  elementSize = row;
1177  }
1178 
1179  if ( lineGroupRecord.isDefined( "pointCount" ) )
1180  {
1181  countSize = IntegerNode( lineGroupRecord.get( "pointCount" ) ).maximum();
1182  }
1183  else if ( bColumnIndex )
1184  {
1185  countSize = row;
1186  }
1187  else
1188  {
1189  countSize = column;
1190  }
1191  }
1192  }
1193 
1194  // if indexBounds is not given
1195  if ( row == 0 )
1196  {
1197  if ( bColumnIndex )
1198  {
1199  row = countSize;
1200  }
1201  else
1202  {
1203  row = elementSize;
1204  }
1205  }
1206  if ( column == 0 )
1207  {
1208  if ( bColumnIndex )
1209  {
1210  column = elementSize;
1211  }
1212  else
1213  {
1214  column = countSize;
1215  }
1216  }
1217 
1218  return true;
1219  }
1220 
1221  // This funtion writes out the group data
1222  bool ReaderImpl::ReadData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue,
1223  int64_t *startPointIndex, int64_t *pointCount ) const
1224  {
1225  if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) )
1226  {
1227  return false;
1228  }
1229 
1230  StructureNode scan( data3D_.get( dataIndex ) );
1231  if ( !scan.isDefined( "pointGroupingSchemes" ) )
1232  {
1233  return false;
1234  }
1235 
1236  StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) );
1237  if ( !pointGroupingSchemes.isDefined( "groupingByLine" ) )
1238  {
1239  return false;
1240  }
1241 
1242  StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) );
1243 
1244  StringNode idElementName( groupingByLine.get( "idElementName" ) );
1245  CompressedVectorNode groups( groupingByLine.get( "groups" ) );
1246  StructureNode lineGroupRecord( groups.prototype() ); // not used here
1247 
1248  int64_t protoCount = lineGroupRecord.childCount();
1249  int64_t protoIndex;
1250  std::vector<SourceDestBuffer> groupSDBuffers;
1251 
1252  for ( protoIndex = 0; protoIndex < protoCount; protoIndex++ )
1253  {
1254  ustring name = lineGroupRecord.get( protoIndex ).elementName();
1255 
1256  if ( ( name.compare( "idElementValue" ) == 0 ) && lineGroupRecord.isDefined( "idElementValue" ) &&
1257  ( idElementValue != nullptr ) )
1258  {
1259  groupSDBuffers.emplace_back( imf_, "idElementValue", idElementValue, groupCount, true );
1260  }
1261 
1262  if ( ( name.compare( "startPointIndex" ) == 0 ) && lineGroupRecord.isDefined( "startPointIndex" ) &&
1263  ( startPointIndex != nullptr ) )
1264  {
1265  groupSDBuffers.emplace_back( imf_, "startPointIndex", startPointIndex, groupCount, true );
1266  }
1267 
1268  if ( ( name.compare( "pointCount" ) == 0 ) && lineGroupRecord.isDefined( "pointCount" ) &&
1269  ( pointCount != nullptr ) )
1270  {
1271  groupSDBuffers.emplace_back( imf_, "pointCount", pointCount, groupCount, true );
1272  }
1273  }
1274 
1275  CompressedVectorReader reader = groups.reader( groupSDBuffers );
1276 
1277  reader.read();
1278  reader.close();
1279 
1280  return true;
1281  }
1282 
1283  template <typename COORDTYPE>
1285  const Data3DPointsData_t<COORDTYPE> &buffers ) const
1286  {
1287  StructureNode scan( data3D_.get( dataIndex ) );
1288  CompressedVectorNode points( scan.get( "points" ) );
1289  StructureNode proto( points.prototype() );
1290 
1291  int64_t protoCount = proto.childCount();
1292  int64_t protoIndex;
1293 
1294  std::vector<SourceDestBuffer> destBuffers;
1295 
1296  for ( protoIndex = 0; protoIndex < protoCount; protoIndex++ )
1297  {
1298  ustring name = proto.get( protoIndex ).elementName();
1299  NodeType type = proto.get( protoIndex ).type();
1300  bool scaled = type == E57_SCALED_INTEGER ? true : false;
1301  // E57_EXT_surface_normals
1302  ustring norExtUri;
1303  bool haveNormalsExt = imf_.extensionsLookupPrefix( "nor", norExtUri );
1304 
1305  if ( ( name.compare( "cartesianX" ) == 0 ) && proto.isDefined( "cartesianX" ) &&
1306  ( buffers.cartesianX != nullptr ) )
1307  {
1308  destBuffers.emplace_back( imf_, "cartesianX", buffers.cartesianX, count, true, scaled );
1309  }
1310  else if ( ( name.compare( "cartesianY" ) == 0 ) && proto.isDefined( "cartesianY" ) &&
1311  ( buffers.cartesianY != nullptr ) )
1312  {
1313  destBuffers.emplace_back( imf_, "cartesianY", buffers.cartesianY, count, true, scaled );
1314  }
1315  else if ( ( name.compare( "cartesianZ" ) == 0 ) && proto.isDefined( "cartesianZ" ) &&
1316  ( buffers.cartesianZ != nullptr ) )
1317  {
1318  destBuffers.emplace_back( imf_, "cartesianZ", buffers.cartesianZ, count, true, scaled );
1319  }
1320  else if ( ( name.compare( "cartesianInvalidState" ) == 0 ) && proto.isDefined( "cartesianInvalidState" ) &&
1321  ( buffers.cartesianInvalidState != nullptr ) )
1322  {
1323  destBuffers.emplace_back( imf_, "cartesianInvalidState", buffers.cartesianInvalidState, count, true );
1324  }
1325  else if ( ( name.compare( "sphericalRange" ) == 0 ) && proto.isDefined( "sphericalRange" ) &&
1326  ( buffers.sphericalRange != nullptr ) )
1327  {
1328  destBuffers.emplace_back( imf_, "sphericalRange", buffers.sphericalRange, count, true, scaled );
1329  }
1330  else if ( ( name.compare( "sphericalAzimuth" ) == 0 ) && proto.isDefined( "sphericalAzimuth" ) &&
1331  ( buffers.sphericalAzimuth != nullptr ) )
1332  {
1333  destBuffers.emplace_back( imf_, "sphericalAzimuth", buffers.sphericalAzimuth, count, true, scaled );
1334  }
1335  else if ( ( name.compare( "sphericalElevation" ) == 0 ) && proto.isDefined( "sphericalElevation" ) &&
1336  ( buffers.sphericalElevation != nullptr ) )
1337  {
1338  destBuffers.emplace_back( imf_, "sphericalElevation", buffers.sphericalElevation, count, true, scaled );
1339  }
1340  else if ( ( name.compare( "sphericalInvalidState" ) == 0 ) && proto.isDefined( "sphericalInvalidState" ) &&
1341  ( buffers.sphericalInvalidState != nullptr ) )
1342  {
1343  destBuffers.emplace_back( imf_, "sphericalInvalidState", buffers.sphericalInvalidState, count, true );
1344  }
1345  else if ( ( name.compare( "rowIndex" ) == 0 ) && proto.isDefined( "rowIndex" ) &&
1346  ( buffers.rowIndex != nullptr ) )
1347  {
1348  destBuffers.emplace_back( imf_, "rowIndex", buffers.rowIndex, count, true );
1349  }
1350  else if ( ( name.compare( "columnIndex" ) == 0 ) && proto.isDefined( "columnIndex" ) &&
1351  ( buffers.columnIndex != nullptr ) )
1352  {
1353  destBuffers.emplace_back( imf_, "columnIndex", buffers.columnIndex, count, true );
1354  }
1355  else if ( ( name.compare( "returnIndex" ) == 0 ) && proto.isDefined( "returnIndex" ) &&
1356  ( buffers.returnIndex != nullptr ) )
1357  {
1358  destBuffers.emplace_back( imf_, "returnIndex", buffers.returnIndex, count, true );
1359  }
1360  else if ( ( name.compare( "returnCount" ) == 0 ) && proto.isDefined( "returnCount" ) &&
1361  ( buffers.returnCount != nullptr ) )
1362  {
1363  destBuffers.emplace_back( imf_, "returnCount", buffers.returnCount, count, true );
1364  }
1365  else if ( ( name.compare( "timeStamp" ) == 0 ) && proto.isDefined( "timeStamp" ) &&
1366  ( buffers.timeStamp != nullptr ) )
1367  {
1368  destBuffers.emplace_back( imf_, "timeStamp", buffers.timeStamp, count, true, scaled );
1369  }
1370  else if ( ( name.compare( "isTimeStampInvalid" ) == 0 ) && proto.isDefined( "isTimeStampInvalid" ) &&
1371  ( buffers.isTimeStampInvalid != nullptr ) )
1372  {
1373  destBuffers.emplace_back( imf_, "isTimeStampInvalid", buffers.isTimeStampInvalid, count, true );
1374  }
1375  else if ( ( name.compare( "intensity" ) == 0 ) && proto.isDefined( "intensity" ) &&
1376  ( buffers.intensity != nullptr ) )
1377  {
1378  destBuffers.emplace_back( imf_, "intensity", buffers.intensity, count, true, scaled );
1379  }
1380  else if ( ( name.compare( "isIntensityInvalid" ) == 0 ) && proto.isDefined( "isIntensityInvalid" ) &&
1381  ( buffers.isIntensityInvalid != nullptr ) )
1382  {
1383  destBuffers.emplace_back( imf_, "isIntensityInvalid", buffers.isIntensityInvalid, count, true );
1384  }
1385  else if ( ( name.compare( "colorRed" ) == 0 ) && proto.isDefined( "colorRed" ) &&
1386  ( buffers.colorRed != nullptr ) )
1387  {
1388  destBuffers.emplace_back( imf_, "colorRed", buffers.colorRed, count, true, scaled );
1389  }
1390  else if ( ( name.compare( "colorGreen" ) == 0 ) && proto.isDefined( "colorGreen" ) &&
1391  ( buffers.colorGreen != nullptr ) )
1392  {
1393  destBuffers.emplace_back( imf_, "colorGreen", buffers.colorGreen, count, true, scaled );
1394  }
1395  else if ( ( name.compare( "colorBlue" ) == 0 ) && proto.isDefined( "colorBlue" ) &&
1396  ( buffers.colorBlue != nullptr ) )
1397  {
1398  destBuffers.emplace_back( imf_, "colorBlue", buffers.colorBlue, count, true, scaled );
1399  }
1400  else if ( ( name.compare( "isColorInvalid" ) == 0 ) && proto.isDefined( "isColorInvalid" ) &&
1401  ( buffers.isColorInvalid != nullptr ) )
1402  {
1403  destBuffers.emplace_back( imf_, "isColorInvalid", buffers.isColorInvalid, count, true );
1404  }
1405  else if ( haveNormalsExt && ( name.compare( "nor:normalX" ) == 0 ) && proto.isDefined( "nor:normalX" ) &&
1406  ( buffers.normalX != nullptr ) )
1407  {
1408  destBuffers.emplace_back( imf_, "nor:normalX", buffers.normalX, count, true, scaled );
1409  }
1410  else if ( haveNormalsExt && ( name.compare( "nor:normalY" ) == 0 ) && proto.isDefined( "nor:normalY" ) &&
1411  ( buffers.normalY != nullptr ) )
1412  {
1413  destBuffers.emplace_back( imf_, "nor:normalY", buffers.normalY, count, true, scaled );
1414  }
1415  else if ( haveNormalsExt && ( name.compare( "nor:normalZ" ) == 0 ) && proto.isDefined( "nor:normalZ" ) &&
1416  ( buffers.normalZ != nullptr ) )
1417  {
1418  destBuffers.emplace_back( imf_, "nor:normalZ", buffers.normalZ, count, true, scaled );
1419  }
1420  }
1421 
1422  CompressedVectorReader reader = points.reader( destBuffers );
1423 
1424  return reader;
1425  }
1426 
1427  // Explicit template instantiation
1428  template CompressedVectorReader ReaderImpl::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount,
1429  const Data3DPointsData_t<float> &buffers ) const;
1430 
1431  template CompressedVectorReader ReaderImpl::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount,
1432  const Data3DPointsData_t<double> &buffers ) const;
1433 
1434 } // end namespace e57
Image2DType
Identifies the format representation for the image data.
Definition: E57Header.h:196
std::shared_ptr< core::Tensor > image
std::string name
int count
int offset
int points
char type
An E57 element encoding an fixed-length sequence of bytes with an opaque format.
An E57 element encoding an integer value.
An E57 element containing named child nodes.
int64_t byteCount() const
Get size of blob declared when it was created.
Definition: E57Format.cpp:4218
CompressedVectorReader reader(const std::vector< SourceDestBuffer > &dbufs)
Create an iterator object for reading a series of blocks of data from a CompressedVectorNode.
Definition: E57Format.cpp:3068
Node prototype() const
Get the prototype tree that describes the types in the record.
Definition: E57Format.cpp:2909
int64_t childCount() const
Get current number of records in a CompressedVectorNode.
Definition: E57Format.cpp:2894
unsigned read()
Request transfer of blocks of data from CompressedVectorNode into previously designated destination b...
Definition: E57Format.cpp:2285
void close()
End the read operation.
Definition: E57Format.cpp:2400
double minimum() const
Get the declared minimum that the value may take.
Definition: E57Format.cpp:3820
double maximum() const
Get the declared maximum that the value may take.
Definition: E57Format.cpp:3838
double value() const
Get IEEE floating point value stored.
Definition: E57Format.cpp:3787
bool isOpen() const
Test whether ImageFile is still open for accessing.
Definition: E57Format.cpp:4586
bool extensionsLookupPrefix(const ustring &prefix, ustring &uri) const
Get URI associated with an E57 extension prefix in the ImageFile.
Definition: E57Format.cpp:4721
void close()
Complete any write operations on an ImageFile, and close the file on the disk.
Definition: E57Format.cpp:4557
int64_t value() const
Get integer value stored.
Definition: E57Format.cpp:3199
int64_t maximum() const
Get the declared maximum that the value may take.
Definition: E57Format.cpp:3227
int64_t minimum() const
Get the declared minimum that the value may take.
Definition: E57Format.cpp:3213
ustring elementName() const
Get element name of node.
Definition: E57Format.cpp:1060
NodeType type() const
Return the NodeType of a generic Node.
Definition: E57Format.cpp:942
bool GetImage2DSizes(int64_t imageIndex, Image2DProjection &imageProjection, Image2DType &imageType, int64_t &imageWidth, int64_t &imageHeight, int64_t &imageSize, Image2DType &imageMaskType, Image2DType &imageVisualType) const
Definition: ReaderImpl.cpp:411
ReaderImpl(const ustring &filePath)
Definition: ReaderImpl.cpp:33
bool GetData3DSizes(int64_t dataIndex, int64_t &rowMax, int64_t &columnMax, int64_t &pointsSize, int64_t &groupsSize, int64_t &countSize, bool &bColumnIndex) const
bool ReadData3DGroupsData(int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, int64_t *startPointIndex, int64_t *pointCount) const
VectorNode GetRawImages2D() const
Definition: ReaderImpl.cpp:529
int64_t ReadImage2DData(int64_t imageIndex, Image2DProjection imageProjection, Image2DType imageType, void *pBuffer, int64_t start, int64_t count) const
Definition: ReaderImpl.cpp:463
int64_t GetData3DCount() const
Definition: ReaderImpl.cpp:514
StructureNode GetRawE57Root() const
Definition: ReaderImpl.cpp:519
bool IsOpen() const
Definition: ReaderImpl.cpp:48
bool ReadData3D(int64_t dataIndex, Data3D &data3DHeader) const
Definition: ReaderImpl.cpp:539
bool GetE57Root(E57Root &fileHeader) const
Definition: ReaderImpl.cpp:66
bool ReadImage2D(int64_t imageIndex, Image2D &Image2DHeader) const
Definition: ReaderImpl.cpp:109
int64_t GetImage2DCount() const
Definition: ReaderImpl.cpp:103
ImageFile GetRawIMF() const
Definition: ReaderImpl.cpp:534
VectorNode GetRawData3D() const
Definition: ReaderImpl.cpp:524
CompressedVectorReader SetUpData3DPointsData(int64_t dataIndex, size_t pointCount, const Data3DPointsData_t< COORDTYPE > &buffers) const
double scale() const
Get declared scaling factor.
Definition: E57Format.cpp:3561
int64_t minimum() const
Get the declared minimum that the raw value may take.
Definition: E57Format.cpp:3509
int64_t maximum() const
Get the declared maximum that the raw value may take.
Definition: E57Format.cpp:3535
double offset() const
Get declared offset.
Definition: E57Format.cpp:3575
ustring value() const
Get Unicode character string value stored.
Definition: E57Format.cpp:4013
bool isDefined(const ustring &pathName) const
Is the given pathName defined relative to this node.
Definition: E57Format.cpp:1297
Node get(int64_t index) const
Get a child element by positional index.
Definition: E57Format.cpp:1319
int64_t childCount() const
Return number of child nodes contained by this StructureNode.
Definition: E57Format.cpp:1275
Node get(int64_t index) const
Get a child element by positional index.
Definition: E57Format.cpp:1641
int64_t childCount() const
Get number of child elements in this VectorNode.
Definition: E57Format.cpp:1599
constexpr double E57_NOT_SCALED_USE_INTEGER
Indicates to use ScaledIntegerNode insterad of FloatNode in fields that can use both.
Definition: E57SimpleData.h:42
Image2DProjection
Identifies the representation for the image data.
@ E57_SPHERICAL
SphericalRepresentation for the image data.
@ E57_CYLINDRICAL
CylindricalRepresentation for the image data.
@ E57_NO_PROJECTION
No representation for the image data is present.
@ E57_VISUAL
VisualReferenceRepresentation for the image data.
@ E57_PINHOLE
PinholeRepresentation for the image data.
Image2DType
Identifies the format representation for the image data.
@ E57_JPEG_IMAGE
JPEG format image data.
@ E57_PNG_IMAGE
PNG format image data.
@ E57_NO_IMAGE
No image data.
@ E57_PNG_IMAGE_MASK
PNG format image mask.
constexpr double E57_NOT_SCALED_USE_FLOAT
Indicates to use FloatNode instead of ScaledIntegerNode in fields that can use both.
Definition: E57SimpleData.h:40
std::string ustring
UTF-8 encodeded Unicode string.
Definition: E57Format.h:54
NodeType
Identifiers for types of E57 elements.
Definition: E57Format.h:58
@ E57_INTEGER
IntegerNode class.
Definition: E57Format.h:62
@ E57_SCALED_INTEGER
ScaledIntegerNode class.
Definition: E57Format.h:63
@ E57_FLOAT
FloatNode class.
Definition: E57Format.h:64
double zMaximum
The maximum extent of the bounding box in the Z direction.
double xMaximum
The maximum extent of the bounding box in the X direction.
double yMinimum
The minimum extent of the bounding box in the Y direction.
double zMinimum
The minimum extent of the bounding box in the Z direction.
double yMaximum
The maximum extent of the bounding box in the Y direction.
double xMinimum
The minimum extent of the bounding box in the X direction.
double colorGreenMinimum
The minimum producible green color value. Unit is unspecified.
double colorBlueMinimum
The minimum producible blue color value. Unit is unspecified.
double colorRedMaximum
The maximum producible red color value. Unit is unspecified.
double colorBlueMaximum
The maximum producible blue color value. Unit is unspecified.
double colorRedMinimum
The minimum producible red color value. Unit is unspecified.
double colorGreenMaximum
The maximum producible green color value. Unit is unspecified.
double pixelHeight
The height of a pixel in the image (in meters). Shall be positive.
int32_t imageWidth
The image width (in pixels). Shall be positive.
int32_t imageHeight
The image height (in pixels). Shall be positive.
double pixelWidth
The width of a pixel in the image (in radians). Shall be positive.
int64_t jpegImageSize
Size of JPEG format image data in Blob.
int64_t pngImageSize
Size of PNG format image data in Blob.
int64_t imageMaskSize
Size of PNG format image mask in Blob.
Stores pointers to user-provided buffers.
float * normalZ
The Z component of a surface normal vector (E57_EXT_surface_normals).
COORDTYPE * cartesianX
pointer to a buffer with the X coordinate (in meters) of the point in Cartesian coordinates
float * normalX
The X component of a surface normal vector (E57_EXT_surface_normals).
int8_t * isColorInvalid
Value = 0 if the color is considered valid, 1 otherwise.
int8_t * cartesianInvalidState
Value = 0 if the point is considered valid, 1 otherwise.
float * normalY
The Y component of a surface normal vector (E57_EXT_surface_normals).
COORDTYPE * sphericalAzimuth
pointer to a buffer with the Azimuth angle (in radians) of point in spherical coordinates
COORDTYPE * sphericalElevation
pointer to a buffer with the Elevation angle (in radians) of point in spherical coordinates
COORDTYPE * cartesianY
pointer to a buffer with the Y coordinate (in meters) of the point in Cartesian coordinates
int8_t * sphericalInvalidState
Value = 0 if the range is considered valid, 1 otherwise.
uint8_t * colorRed
pointer to a buffer with the Red color coefficient. Unit is unspecified
float * intensity
pointer to a buffer with the Point response intensity. Unit is unspecified
int8_t * isIntensityInvalid
Value = 0 if the intensity is considered valid, 1 otherwise.
COORDTYPE * sphericalRange
pointer to a buffer with the range (in meters) of points in spherical coordinates....
int8_t * isTimeStampInvalid
Value = 0 if the timeStamp is considered valid, 1 otherwise.
COORDTYPE * cartesianZ
pointer to a buffer with the Z coordinate (in meters) of the point in Cartesian coordinates
uint8_t * colorGreen
pointer to a buffer with the Green color coefficient. Unit is unspecified
uint8_t * colorBlue
pointer to a buffer with the Blue color coefficient. Unit is unspecified
Stores the top-level information for a single lidar scan.
int64_t pointsSize
DateTime acquisitionStart
The start date and time that the data was acquired.
RigidBodyTransform pose
DateTime acquisitionEnd
The end date and time that the data was acquired.
float relativeHumidity
ustring guid
A globally unique identification string for the current version of the Data3D object.
CartesianBounds cartesianBounds
ustring sensorHardwareVersion
The version number for the sensor hardware at the time of data collection.
ustring sensorFirmwareVersion
std::vector< ustring > originalGuids
ustring name
A user-defined name for the Data3D.
ColorLimits colorLimits
IndexBounds indexBounds
The bounds of the row, column, and return number of all the points in this Data3D.
IntensityLimits intensityLimits
The limits for the value of signal intensity that the sensor is capable of producing.
SphericalBounds sphericalBounds
ustring sensorSerialNumber
The serial number for the sensor.
PointGroupingSchemes pointGroupingSchemes
The defined schemes that group points in different ways.
float temperature
PointStandardizedFieldsAvailable pointFields
This defines the active fields used in the WritePoints function.
ustring description
A user-defined description of the Image.
ustring sensorModel
The model name or number for the sensor.
float atmosphericPressure
ustring sensorVendor
The name of the manufacturer for the sensor used to collect the points in this Data3D.
ustring sensorSoftwareVersion
The version number for the software used for the data collection.
int32_t isAtomicClockReferenced
double dateTimeValue
The time, in seconds, since GPS time was zero. This time specification may include fractions of a sec...
Stores the top-level information for the XML section of the file.
int64_t images2DSize
ustring formatName
Contains the string "ASTM E57 3D Image File".
ustring guid
A globally unique identification string for the current version of the file.
ustring e57LibraryVersion
The version identifier for the E57 file format library that wrote the file.
uint32_t versionMajor
Major version number, should be 1.
uint32_t versionMinor
Minor version number, should be 0.
int64_t data3DSize
Size of the Data3D vector for storing 3D imaging data.
ustring coordinateMetadata
Information describing the Coordinate Reference System to be used for the file.
DateTime creationDateTime
Date/time that the file was created.
int64_t groupsSize
Size of the groups compressedVector of LineGroupRecord structures.
int64_t pointCountSize
This is the size value for the LineGroupRecord::pointCount.
Stores an image from a camera.
ustring sensorVendor
The name of the manufacturer for the sensor used to collect the points in this Data3D.
ustring guid
A globally unique identification string for the current version of the Image2D object.
ustring description
A user-defined description of the Image2D.
ustring name
A user-defined name for the Image2D.
PinholeRepresentation pinholeRepresentation
Representation for an image using the pinhole camera projection model.
ustring sensorModel
The model name or number for the sensor.
SphericalRepresentation sphericalRepresentation
Representation for an image using the spherical camera projection model.
ustring associatedData3DGuid
RigidBodyTransform pose
ustring sensorSerialNumber
The serial number for the sensor.
CylindricalRepresentation cylindricalRepresentation
Representation for an image using the cylindrical camera projection model.
DateTime acquisitionDateTime
The date and time that the image was taken.
VisualReferenceRepresentation visualReferenceRepresentation
int64_t rowMaximum
The maximum rowIndex value of any point represented by this IndexBounds object.
int64_t returnMinimum
The minimum returnIndex value of any point represented by this IndexBounds object.
int64_t columnMinimum
The minimum columnIndex value of any point represented by this IndexBounds object.
int64_t columnMaximum
The maximum columnIndex value of any point represented by this IndexBounds object.
int64_t rowMinimum
The minimum rowIndex value of any point represented by this IndexBounds object.
int64_t returnMaximum
The maximum returnIndex value of any point represented by this IndexBounds object.
double intensityMaximum
The maximum producible intensity value. Unit is unspecified.
double intensityMinimum
The minimum producible intensity value. Unit is unspecified.
double principalPointY
The Y coordinate in the image of the principal point (in pixels).
int64_t imageMaskSize
Size of PNG format image mask in BlobNode.
int32_t imageHeight
The image height (in pixels). Shall be positive.
double focalLength
The camera's focal length (in meters). Shall be positive.
int64_t jpegImageSize
Size of JPEG format image data in BlobNode.
double pixelWidth
The width of the pixels in the camera (in meters). Shall be positive.
double pixelHeight
The height of the pixels in the camera (in meters). Shall be positive.
int32_t imageWidth
The image width (in pixels). Shall be positive.
int64_t pngImageSize
Size of PNG format image data in BlobNode.
GroupingByLine groupingByLine
Grouping information by row or column index.
bool returnCountField
Indicates that the PointRecord returnCount field is active.
bool isColorInvalidField
Indicates that the PointRecord isColorInvalid field is active.
bool normalZ
Indicates that the PointRecord nor:normalZ field is active.
bool timeStampField
Indicates that the PointRecord timeStamp field is active.
bool returnIndexField
Indicates that the PointRecord returnIndex field is active.
bool colorGreenField
indicates that the PointRecord colorGreen field is active
bool normalY
Indicates that the PointRecord nor:normalY field is active.
bool sphericalRangeField
Indicates that the PointRecord sphericalRange field is active.
bool columnIndexField
Indicates that the PointRecord columnIndex field is active.
bool cartesianYField
Indicates that the PointRecord cartesianY field is active.
bool cartesianInvalidStateField
Indicates that the PointRecord cartesianInvalidState field is active.
bool rowIndexField
Indicates that the PointRecord rowIndex field is active.
bool isIntensityInvalidField
Indicates that the PointRecord isIntensityInvalid field is active.
bool sphericalElevationField
Indicates that the PointRecord sphericalElevation field is active.
bool sphericalAzimuthField
Indicates that the PointRecord sphericalAzimuth field is active.
bool sphericalInvalidStateField
Indicates that the PointRecord sphericalInvalidState field is active.
bool normalX
Indicates that the PointRecord nor:normalX field is active.
bool cartesianZField
Indicates that the PointRecord cartesianZ field is active.
bool colorBlueField
indicates that the PointRecord colorBlue field is active
bool intensityField
Indicates that the PointRecord intensity field is active.
bool cartesianXField
Indicates that the PointRecord cartesianX field is active.
bool colorRedField
indicates that the PointRecord colorRed field is active
bool isTimeStampInvalidField
Indicates that the PointRecord isTimeStampInvalid field is active.
double z
The k coefficient of the quaternion.
Definition: E57SimpleData.h:77
double y
The j coefficient of the quaternion.
Definition: E57SimpleData.h:76
double x
The i coefficient of the quaternion.
Definition: E57SimpleData.h:75
double w
The real part of the quaternion. Shall be nonnegative.
Definition: E57SimpleData.h:74
Translation translation
The translation point vector, t, of the transform.
Quaternion rotation
A unit quaternion representing the rotation, R, of the transform.
Definition: E57SimpleData.h:99
double azimuthEnd
The ending azimuth angle defining the extent of the bounding region around the z axix.
double elevationMaximum
The maximum extent of the bounding region from the horizontal plane.
double rangeMinimum
The minimum extent of the bounding region in the r direction.
double rangeMaximum
The maximum extent of the bounding region in the r direction.
double elevationMinimum
The minimum extent of the bounding region from the horizontal plane.
double azimuthStart
The starting azimuth angle defining the extent of the bounding region around the z axis.
int32_t imageHeight
The image height (in pixels). Shall be positive.
int64_t imageMaskSize
Size of PNG format image mask in BlobNode.
double pixelHeight
The height of a pixel in the image (in radians). Shall be positive.
int64_t jpegImageSize
Size of JPEG format image data in BlobNode.
double pixelWidth
The width of a pixel in the image (in radians). Shall be positive.
int32_t imageWidth
The image width (in pixels). Shall be positive.
int64_t pngImageSize
Size of PNG format image data in BlobNode.
double y
The Y coordinate of the translation (in meters)
Definition: E57SimpleData.h:53
double x
The X coordinate of the translation (in meters)
Definition: E57SimpleData.h:52
double z
The Z coordinate of the translation (in meters)
Definition: E57SimpleData.h:54
int32_t imageHeight
The image height (in pixels). Shall be positive.
int64_t imageMaskSize
Size of PNG format image mask in BlobNode.
int32_t imageWidth
The image width (in pixels). Shall be positive.
int64_t jpegImageSize
Size of JPEG format image data in BlobNode.
int64_t pngImageSize
Size of PNG format image data in BlobNode.