PLYIO.cpp
Go to the documentation of this file.
1 
42 #include "lvr2/io/PLYIO.hpp"
43 #include "lvr2/io/Timestamp.hpp"
44 
45 #include <cstring>
46 #include <ctime>
47 #include <sstream>
48 #include <fstream>
49 
50 #include <boost/filesystem.hpp>
51 #include <opencv2/opencv.hpp>
52 
53 namespace lvr2
54 {
55 
56 
57 void PLYIO::save( string filename )
58 {
59  if ( !m_model )
60  {
61  std::cerr << timestamp << "No data to save." << std::endl;
62  return;
63  }
64 
65  /* Handle options. */
67 
68  // Local buffer shortcuts
69  floatArr m_vertices;
70  floatArr m_vertexConfidence;
71  floatArr m_vertexIntensity;
72  floatArr m_vertexNormals;
73  floatArr m_points;
74  floatArr m_pointConfidences;
75  floatArr m_pointIntensities;
76  floatArr m_pointNormals;
77 
78  size_t dummy = 0;
79  size_t w_point_color = 0;
80  size_t w_vertex_color = 0;
81  size_t m_numVertices = 0;
82  size_t m_numVertexColors = 0;
83  size_t m_numVertexConfidences = 0;
84  size_t m_numVertexIntensities = 0;
85  size_t m_numVertexNormals = 0;
86 
87  size_t m_numPoints = 0;
88  size_t m_numPointColors = 0;
89  size_t m_numPointConfidence = 0;
90  size_t m_numPointIntensities = 0;
91  size_t m_numPointNormals = 0;
92  size_t m_numFaces = 0;
93 
94  ucharArr m_vertexColors;
95  ucharArr m_pointColors;
96  uintArr m_faceIndices;
97 
98  // Get buffers
99  if ( m_model->m_pointCloud )
100  {
101  PointBufferPtr pc( m_model->m_pointCloud );
102 
103  m_numPoints = pc->numPoints();
104  m_numPointNormals = m_numPoints;
105  m_numPointColors = m_numPoints;
106 
107  m_points = pc->getPointArray();
108  m_pointConfidences = pc->getFloatArray("confidences", m_numPointConfidence, dummy);
109  m_pointColors = pc->getColorArray(w_point_color);
110  m_pointIntensities = pc->getFloatArray("intensities", m_numPointIntensities, dummy);
111  m_pointNormals = pc->getNormalArray();
112  }
113 
114  if ( m_model->m_mesh )
115  {
116  MeshBufferPtr mesh( m_model->m_mesh );
117  m_numVertices = mesh->numVertices();
118  m_numFaces = mesh->numFaces();
119  m_numVertexColors = m_numVertices;
120  m_numVertexNormals = m_numVertices;
121 
122  m_vertices = mesh->getVertices();
123  m_vertexColors = mesh->getVertexColors(w_vertex_color);
124  m_vertexConfidence = mesh->getFloatArray("vertex_confidences", m_numVertexConfidences, dummy);
125  m_vertexIntensity = mesh->getFloatArray("vertex_intensities", m_numVertexIntensities, dummy);
126  m_vertexNormals = mesh->getVertexNormals();
127  m_faceIndices = mesh->getFaceIndices();
128  }
129 
130 
131  p_ply oply = ply_create( filename.c_str(), mode, NULL, 0, NULL );
132  if ( !oply )
133  {
134  std::cerr << timestamp << "Could not create »" << filename << "«" << std::endl;
135  return;
136  }
137 
138  /* Check if we have vertex information. */
139  if ( !( m_vertices || m_points ) )
140  {
141  std::cout << timestamp << "Neither vertices nor points to write." << std::endl;
142  if ( !ply_close( oply ) )
143  {
144  std::cerr << timestamp << "Could not close file." << std::endl;
145  }
146  return;
147  }
148 
149  /* First: Write Header information according to data. */
150 
151  bool vertex_color = false;
152  bool vertex_intensity = false;
153  bool vertex_confidence = false;
154  bool vertex_normal = false;
155  bool point_color = false;
156  bool point_intensity = false;
157  bool point_confidence = false;
158  bool point_normal = false;
159 
160 
161  /* Add vertex element. */
162  if ( m_vertices )
163  {
164  ply_add_element( oply, "vertex", m_numVertices );
165 
166  /* Add vertex properties: x, y, z, (r, g, b) */
167  ply_add_scalar_property( oply, "x", PLY_FLOAT );
168  ply_add_scalar_property( oply, "y", PLY_FLOAT );
169  ply_add_scalar_property( oply, "z", PLY_FLOAT );
170 
171  /* Add color information if there is any. */
172  if ( m_vertexColors )
173  {
174  if ( m_numVertexColors != m_numVertices )
175  {
176  std::cerr << timestamp << "Amount of vertices and color information is"
177  << " not equal. Color information won't be written." << std::endl;
178  }
179  else
180  {
181  ply_add_scalar_property( oply, "red", PLY_UCHAR );
182  ply_add_scalar_property( oply, "green", PLY_UCHAR );
183  ply_add_scalar_property( oply, "blue", PLY_UCHAR );
184  vertex_color = true;
185  }
186  }
187 
188  /* Add intensity. */
189  if ( m_vertexIntensity )
190  {
191  if ( m_numVertexIntensities != m_numVertices )
192  {
193  std::cout << timestamp << "Amount of vertices and intensity"
194  << " information is not equal. Intensity information won't be"
195  << " written." << std::endl;
196  }
197  else
198  {
199  ply_add_scalar_property( oply, "intensity", PLY_FLOAT );
200  vertex_intensity = true;
201  }
202  }
203 
204  /* Add confidence. */
205  if ( m_vertexConfidence )
206  {
207  if ( m_numVertexConfidences != m_numVertices )
208  {
209  std::cout << timestamp << "Amount of vertices and confidence"
210  << " information is not equal. Confidence information won't be"
211  << " written." << std::endl;
212  }
213  else
214  {
215  ply_add_scalar_property( oply, "confidence", PLY_FLOAT );
216  vertex_confidence = true;
217  }
218  }
219 
220  /* Add normals if there are any. */
221  if ( m_vertexNormals )
222  {
223  if ( m_numVertexNormals != m_numVertices )
224  {
225  std::cout << timestamp << "Amount of vertices and normals"
226  << " does not match. Normals won't be written." << std::endl;
227  }
228  else
229  {
230  ply_add_scalar_property( oply, "nx", PLY_FLOAT );
231  ply_add_scalar_property( oply, "ny", PLY_FLOAT );
232  ply_add_scalar_property( oply, "nz", PLY_FLOAT );
233  vertex_normal = true;
234  }
235  }
236 
237  /* Add faces. */
238  if ( m_faceIndices )
239  {
240  ply_add_element( oply, "face", m_numFaces );
241  ply_add_list_property( oply, "vertex_indices", PLY_UCHAR, PLY_INT );
242  }
243  }
244 
245  /* Add point element */
246  if ( m_points )
247  {
248  ply_add_element( oply, "point", m_numPoints );
249 
250  /* Add point properties: x, y, z, (r, g, b) */
251  ply_add_scalar_property( oply, "x", PLY_FLOAT );
252  ply_add_scalar_property( oply, "y", PLY_FLOAT );
253  ply_add_scalar_property( oply, "z", PLY_FLOAT );
254 
255  /* Add color information if there is any. */
256  if ( m_pointColors )
257  {
258  if ( m_numPointColors != m_numPoints )
259  {
260  std::cout << timestamp << "Amount of points and color information is"
261  << " not equal. Color information won't be written." << std::endl;
262  }
263  else
264  {
265  ply_add_scalar_property( oply, "red", PLY_UCHAR );
266  ply_add_scalar_property( oply, "green", PLY_UCHAR );
267  ply_add_scalar_property( oply, "blue", PLY_UCHAR );
268  point_color = true;
269  }
270  }
271 
272  /* Add intensity. */
273  if ( m_pointIntensities )
274  {
275  if ( m_numPointIntensities != m_numPoints )
276  {
277  std::cout << timestamp << "Amount of points and intensity"
278  << " information is not equal. Intensity information won't be"
279  << " written." << std::endl;
280  }
281  else
282  {
283  ply_add_scalar_property( oply, "intensity", PLY_FLOAT );
284  point_intensity = true;
285  }
286  }
287 
288  /* Add confidence. */
289  if ( m_pointConfidences )
290  {
291  if ( m_numPointConfidence != m_numPoints )
292  {
293  std::cout << timestamp << "Amount of point and confidence"
294  << " information is not equal. Confidence information won't be"
295  << " written." << std::endl;
296  }
297  else
298  {
299  ply_add_scalar_property( oply, "confidence", PLY_FLOAT );
300  point_confidence = true;
301  }
302  }
303 
304  /* Add normals if there are any. */
305  if ( m_pointNormals )
306  {
307  if ( m_numPointNormals != m_numPoints )
308  {
309  std::cout << timestamp << "Amount of point and normals does"
310  << " not match. Normals won't be written." << std::endl;
311  }
312  else
313  {
314  ply_add_scalar_property( oply, "nx", PLY_FLOAT );
315  ply_add_scalar_property( oply, "ny", PLY_FLOAT );
316  ply_add_scalar_property( oply, "nz", PLY_FLOAT );
317  point_normal = true;
318  }
319  }
320  }
321 
322  /* Write header to file. */
323  if ( !ply_write_header( oply ) )
324  {
325  std::cerr << timestamp << "Could not write header." << std::endl;
326  return;
327  }
328 
329  /* Second: Write data. */
330 
331  for (size_t i = 0; i < m_numVertices; i++ )
332  {
333  ply_write( oply, (double) m_vertices[ i * 3 ] ); /* x */
334  ply_write( oply, (double) m_vertices[ i * 3 + 1 ] ); /* y */
335  ply_write( oply, (double) m_vertices[ i * 3 + 2 ] ); /* z */
336  if ( vertex_color )
337  {
338  ply_write( oply, m_vertexColors[ i * w_vertex_color ] ); /* red */
339  ply_write( oply, m_vertexColors[ i * w_vertex_color + 1 ] ); /* green */
340  ply_write( oply, m_vertexColors[ i * w_vertex_color + 2 ] ); /* blue */
341  }
342  if ( vertex_intensity )
343  {
344  ply_write( oply, m_vertexIntensity[ i ] );
345  }
346  if ( vertex_confidence )
347  {
348  ply_write( oply, m_vertexConfidence[ i ] );
349  }
350  if ( vertex_normal )
351  {
352  ply_write( oply, (double) m_vertexNormals[ i * 3 ] ); /* nx */
353  ply_write( oply, (double) m_vertexNormals[ i * 3 + 1 ] ); /* ny */
354  ply_write( oply, (double) m_vertexNormals[ i * 3 + 2 ] ); /* nz */
355  }
356  }
357 
358  /* Write faces (Only if we also have vertices). */
359  if ( m_vertices )
360  {
361  for ( size_t i = 0; i < m_numFaces; i++ )
362  {
363  ply_write( oply, 3.0 ); /* Indices per face. */
364  ply_write( oply, (double) m_faceIndices[ i * 3 ] );
365  ply_write( oply, (double) m_faceIndices[ i * 3 + 1 ] );
366  ply_write( oply, (double) m_faceIndices[ i * 3 + 2 ] );
367  }
368  }
369 
370  for ( size_t i = 0; i < m_numPoints; i++ )
371  {
372  ply_write( oply, (double) m_points[ i * 3 ] ); /* x */
373  ply_write( oply, (double) m_points[ i * 3 + 1 ] ); /* y */
374  ply_write( oply, (double) m_points[ i * 3 + 2 ] ); /* z */
375  if ( point_color )
376  {
377  ply_write( oply, m_pointColors[ i * w_point_color ] ); /* red */
378  ply_write( oply, m_pointColors[ i * w_point_color + 1 ] ); /* green */
379  ply_write( oply, m_pointColors[ i * w_point_color + 2 ] ); /* blue */
380  }
381  if ( point_intensity )
382  {
383  ply_write( oply, m_pointIntensities[ i ] );
384  }
385  if ( point_confidence )
386  {
387  ply_write( oply, m_pointConfidences[ i ] );
388  }
389  if ( point_normal )
390  {
391  ply_write( oply, (double) m_pointNormals[ i * 3 ] ); /* nx */
392  ply_write( oply, (double) m_pointNormals[ i * 3 + 1 ] ); /* ny */
393  ply_write( oply, (double) m_pointNormals[ i * 3 + 2 ] ); /* nz */
394  }
395  }
396 
397  if ( !ply_close( oply ) )
398  {
399  std::cerr << timestamp << "Could not close file." << std::endl;
400  }
401 
402 }
403 
404 
406 {
407  return read( filename, true );
408 }
409 
413 template <typename T>
414 void swap(T*& arr, size_t i1, size_t i2, size_t n)
415 {
416  std::swap_ranges(arr + i1, arr + i1 + n, arr + i2);
417 }
418 
419 ModelPtr PLYIO::read( string filename, bool readColor, bool readConfidence,
420  bool readIntensity, bool readNormals, bool readFaces, bool readPanoramaCoords )
421 {
422 
423  /* Start reading new PLY */
424  p_ply ply = ply_open( filename.c_str(), NULL, 0, NULL );
425 
426  if ( !ply )
427  {
428  std::cerr << timestamp << "Could not open »" << filename << "«."
429  << std::endl;
430  return ModelPtr();
431  }
432  if ( !ply_read_header( ply ) )
433  {
434  std::cerr << timestamp << "Could not read header." << std::endl;
435  return ModelPtr();
436  }
437  //std::cout << timestamp << "Loading »" << filename << "«." << std::endl;
438 
439  /* Check if there are vertices and get the amount of vertices. */
440  char buf[256] = "";
441  const char * name = buf;
442  long int n;
443  p_ply_element elem = NULL;
444 
445  // Buffer count variables
446  size_t numVertices = 0;
447  size_t numVertexColors = 0;
448  size_t numVertexConfidences = 0;
449  size_t numVertexIntensities = 0;
450  size_t numVertexNormals = 0;
451  size_t numVertexPanoramaCoords = 0;
452 
453  size_t numPoints = 0;
454  size_t numPointColors = 0;
455  size_t numPointConfidence = 0;
456  size_t numPointIntensities = 0;
457  size_t numPointNormals = 0;
458  size_t numPointPanoramaCoords = 0;
459  size_t numPointSpectralChannels = 0;
460  size_t numFaces = 0;
461 
462  size_t n_channels = 0; // Number of spectral channels
463 
464 
465  while ( ( elem = ply_get_next_element( ply, elem ) ) )
466  {
467  ply_get_element_info( elem, &name, &n );
468  if ( !strcmp( name, "vertex" ) )
469  {
470  numVertices = n;
471  p_ply_property prop = NULL;
472  while ( ( prop = ply_get_next_property( elem, prop ) ) )
473  {
474  ply_get_property_info( prop, &name, NULL, NULL, NULL );
475  if ( !strcmp( name, "red" ) && readColor )
476  {
477  /* We have color information */
478  numVertexColors = n;
479  }
480  else if ( !strcmp( name, "confidence" ) && readConfidence )
481  {
482  /* We have confidence information */
483  numVertexConfidences = n;
484  }
485  else if ( !strcmp( name, "intensity" ) && readIntensity )
486  {
487  /* We have intensity information */
488  numVertexIntensities = n;
489  }
490  else if ( !strcmp( name, "nx" ) && readNormals )
491  {
492  /* We have normals */
493  numVertexNormals = n;
494  }
495  else if ( !strcmp( name, "x_coords" ) && readPanoramaCoords )
496  {
497  /* We have panorama coordinates */
498  numVertexPanoramaCoords = n;
499  }
500  }
501  }
502  else if ( !strcmp( name, "point" ) )
503  {
504  numPoints = n;
505  p_ply_property prop = NULL;
506  while ( ( prop = ply_get_next_property( elem, prop ) ) )
507  {
508  ply_get_property_info( prop, &name, NULL, NULL, NULL );
509  if ( !strcmp( name, "red" ) && readColor )
510  {
511  /* We have color information */
512  numPointColors = n;
513  }
514  else if ( !strcmp( name, "confidence" ) && readConfidence )
515  {
516  /* We have confidence information */
517  numPointConfidence = n;
518  }
519  else if ( !strcmp( name, "intensity" ) && readIntensity )
520  {
521  /* We have intensity information */
522  numPointIntensities = n;
523  }
524  else if ( !strcmp( name, "nx" ) && readNormals )
525  {
526  /* We have normals */
527  numPointNormals = n;
528  }
529  else if ( !strcmp( name, "x_coords" ) && readPanoramaCoords )
530  {
531  /* We have panorama coordinates */
532  numPointPanoramaCoords = n;
533  }
534  }
535  }
536  else if ( !strcmp( name, "face" ) && readFaces )
537  {
538  numFaces = n;
539  }
540  }
541 
542  if ( !( numVertices || numPoints ) )
543  {
544  std::cout << timestamp << "Neither vertices nor points in ply."
545  << std::endl;
546  return ModelPtr();
547  }
548 
549  // Buffers
550  floatArr vertices;
551  floatArr vertexConfidence;
552  floatArr vertexIntensity;
553  floatArr vertexNormals;
554  floatArr points;
555  floatArr pointConfidences;
556  floatArr pointIntensities;
557  floatArr pointNormals;
558  ucharArr pointSpectralChannels;
559 
560  ucharArr vertexColors;
561  ucharArr pointColors;
562 
563  shortArr vertexPanoramaCoords;
564  shortArr pointPanoramaCoords;
565 
566  uintArr faceIndices;
567 
568 
569  /* Allocate memory. */
570  if ( numVertices )
571  {
572  vertices = floatArr( new float[ numVertices * 3 ] );
573  }
574  if ( numVertexColors )
575  {
576  vertexColors = ucharArr( new unsigned char[ numVertices * 3 ] );
577  }
578  if ( numVertexConfidences )
579  {
580  vertexConfidence = floatArr( new float[ numVertices ] );
581  }
582  if ( numVertexIntensities )
583  {
584  vertexIntensity = floatArr( new float[ numVertices ] );
585  }
586  if ( numVertexNormals )
587  {
588  vertexNormals = floatArr( new float[ numVertices * 3 ] );
589  }
590  if ( numVertexPanoramaCoords )
591  {
592  vertexPanoramaCoords = shortArr( new short[ numVertices * 2 ] );
593  }
594  if ( numFaces )
595  {
596  faceIndices = indexArray( new unsigned int[ numFaces * 3 ] );
597  }
598  if ( numPoints )
599  {
600  points = floatArr( new float[ numPoints * 3 ] );
601  }
602  if ( numPointColors )
603  {
604  pointColors = ucharArr( new unsigned char[ numPoints * 3 ] );
605  }
606  if ( numPointConfidence )
607  {
608  pointConfidences = floatArr( new float[numPoints] );
609  }
610  if ( numPointIntensities )
611  {
612  pointIntensities = floatArr( new float[numPoints] );
613  }
614  if ( numPointNormals )
615  {
616  pointNormals = floatArr( new float[ numPoints * 3 ] );
617  }
618  if ( numPointPanoramaCoords )
619  {
620  pointPanoramaCoords = shortArr( new short[ numPoints * 2 ] );
621  }
622 
623 
624  float* vertex = vertices.get();
625  uint8_t* vertex_color = vertexColors.get();
626  float* vertex_confidence = vertexConfidence.get();
627  float* vertex_intensity = vertexIntensity.get();
628  float* vertex_normal = vertexNormals.get();
629  short* vertex_panorama_coords = vertexPanoramaCoords.get();
630  unsigned int* face = faceIndices.get();
631  float* point = points.get();
632  uint8_t* point_color = pointColors.get();
633  float* point_confidence = pointConfidences.get();
634  float* point_intensity = pointIntensities.get();
635  float* point_normal = pointNormals.get();
636  short* point_panorama_coords = pointPanoramaCoords.get();
637 
638 
639  /* Set callbacks. */
640  if ( vertex )
641  {
642  ply_set_read_cb( ply, "vertex", "x", readVertexCb, &vertex, 0 );
643  ply_set_read_cb( ply, "vertex", "y", readVertexCb, &vertex, 0 );
644  ply_set_read_cb( ply, "vertex", "z", readVertexCb, &vertex, 1 );
645  }
646  if ( vertex_color )
647  {
648  ply_set_read_cb( ply, "vertex", "red", readColorCb, &vertex_color, 0 );
649  ply_set_read_cb( ply, "vertex", "green", readColorCb, &vertex_color, 0 );
650  ply_set_read_cb( ply, "vertex", "blue", readColorCb, &vertex_color, 1 );
651  }
652  if ( vertex_confidence )
653  {
654  ply_set_read_cb( ply, "vertex", "confidence", readVertexCb, &vertex_confidence, 1 );
655  }
656  if ( vertex_intensity )
657  {
658  ply_set_read_cb( ply, "vertex", "intensity", readVertexCb, &vertex_intensity, 1 );
659  }
660  if ( vertex_normal )
661  {
662  ply_set_read_cb( ply, "vertex", "nx", readVertexCb, &vertex_normal, 0 );
663  ply_set_read_cb( ply, "vertex", "ny", readVertexCb, &vertex_normal, 0 );
664  ply_set_read_cb( ply, "vertex", "nz", readVertexCb, &vertex_normal, 1 );
665  }
666  if ( vertex_panorama_coords )
667  {
668  ply_set_read_cb( ply, "vertex", "x_coords", readPanoramaCoordCB, &vertex_panorama_coords, 0 );
669  ply_set_read_cb( ply, "vertex", "y_coords", readPanoramaCoordCB, &vertex_panorama_coords, 1 );
670  }
671 
672  if ( face )
673  {
674  ply_set_read_cb( ply, "face", "vertex_indices", readFaceCb, &face, 0 );
675  ply_set_read_cb( ply, "face", "vertex_index", readFaceCb, &face, 0 );
676  }
677 
678  if ( point )
679  {
680  ply_set_read_cb( ply, "point", "x", readVertexCb, &point, 0 );
681  ply_set_read_cb( ply, "point", "y", readVertexCb, &point, 0 );
682  ply_set_read_cb( ply, "point", "z", readVertexCb, &point, 1 );
683  }
684  if ( point_color )
685  {
686  ply_set_read_cb( ply, "point", "red", readColorCb, &point_color, 0 );
687  ply_set_read_cb( ply, "point", "green", readColorCb, &point_color, 0 );
688  ply_set_read_cb( ply, "point", "blue", readColorCb, &point_color, 1 );
689  }
690  if ( point_confidence )
691  {
692  ply_set_read_cb( ply, "point", "confidence", readVertexCb, &point_confidence, 1 );
693  }
694  if ( point_intensity )
695  {
696  ply_set_read_cb( ply, "point", "intensity", readVertexCb, &point_intensity, 1 );
697  }
698  if ( point_normal )
699  {
700  ply_set_read_cb( ply, "point", "nx", readVertexCb, &point_normal, 0 );
701  ply_set_read_cb( ply, "point", "ny", readVertexCb, &point_normal, 0 );
702  ply_set_read_cb( ply, "point", "nz", readVertexCb, &point_normal, 1 );
703  }
704  if ( point_panorama_coords )
705  {
706  ply_set_read_cb( ply, "point", "x_coords", readPanoramaCoordCB, &point_panorama_coords, 0 );
707  ply_set_read_cb( ply, "point", "y_coords", readPanoramaCoordCB, &point_panorama_coords, 1 );
708  }
709 
710  /* Read ply file. */
711  if ( !ply_read( ply ) )
712  {
713  std::cerr << timestamp << "Could not read »" << filename << "«."
714  << std::endl;
715  }
716 
717  /* Check if we got only vertices and neither points nor faces. If that is
718  * the case then use the vertices as points. */
719  if ( vertices && !points && !faceIndices )
720  {
721  std::cout << timestamp << "PLY contains neither faces nor points. "
722  << "Assuming that vertices are meant to be points." << std::endl;
723  points = vertices;
724  pointColors = vertexColors;
725  pointConfidences = vertexConfidence;
726  pointIntensities = vertexIntensity;
727  pointNormals = vertexNormals;
728  pointPanoramaCoords = vertexPanoramaCoords;
729  point = points.get();
730  point_color = pointColors.get();
731  point_confidence = pointConfidences.get();
732  point_intensity = pointIntensities.get();
733  point_normal = pointNormals.get();
734  point_panorama_coords = pointPanoramaCoords.get();
735  numPoints = numVertices;
736  numPointColors = numVertexColors;
737  numPointConfidence = numVertexConfidences;
738  numPointIntensities = numVertexIntensities;
739  numPointNormals = numVertexNormals;
740  numPointPanoramaCoords = numVertexPanoramaCoords;
741  numVertices = 0;
742  numVertexColors = 0;
743  numVertexConfidences = 0;
744  numVertexIntensities = 0;
745  numVertexNormals = 0;
746  numVertexPanoramaCoords = 0;
747  vertices.reset();
748  vertexColors.reset();
749  vertexConfidence.reset();
750  vertexIntensity.reset();
751  vertexNormals.reset();
752  vertexPanoramaCoords.reset();
753  }
754 
755  ply_close( ply );
756 
757  // read Panorama Images if we have annotated data
758  if (numPointPanoramaCoords)
759  {
760  // move all the Points that don't have spectral information to the end
761  for (int i = 0; i < numPointPanoramaCoords; i++)
762  {
763  if (point_panorama_coords[2 * i] == -1)
764  {
765  // swap with last element
766  numPointPanoramaCoords--;
767 
768  const int n = numPointPanoramaCoords;
769  swap(point_panorama_coords, 2 * i, 2 * numPointPanoramaCoords, 2);
770  swap(point, 3 * i, 3 * numPointPanoramaCoords, 3);
771  if (numPointColors) swap(point_color, 3*i, 3*numPointPanoramaCoords, 3);
772  if (numPointConfidence) swap(point_confidence, i, numPointPanoramaCoords, 1);
773  if (numPointIntensities) swap(point_intensity, i, numPointPanoramaCoords, 1);
774  if (numPointNormals) swap(point_normal, 3*i, 3*numPointPanoramaCoords, 3);
775 
776  i--;
777  }
778  }
779 
780  std::cout << timestamp << numPoints << "Found " << (numPoints - numPointPanoramaCoords) << " without spectral data. Reodering..." << std::endl;
781 
782 
783  size_t pos_underscore = filename.find_last_of("_");
784  size_t pos_extension = filename.find_last_of(".");
785  string scanNr = filename.substr(pos_underscore + 1, pos_extension - pos_underscore - 1);
786 
787  string channelDirName = string("panorama_channels_") + scanNr;
788 
789  boost::filesystem::path dir(filename);
790  dir = dir.parent_path() / "panoramas_fixed" / channelDirName;
791 
792  if (!boost::filesystem::exists(dir / "channel0.png"))
793  {
794  std::cerr << timestamp << "Annotated Data given, but " + dir.string() + " does not contain channel files" << std::endl;
795  }
796  else
797  {
798  std::cout << timestamp << "Found Annotated Data. Loading spectral channel images from: " << dir.string() << "/" << std::endl;
799  std::cout << timestamp << "This may take a while depending on data size" << std::endl;
800 
801  std::vector<cv::Mat> imgs;
802  std::vector<unsigned char*> pixels;
803 
804  cv::VideoCapture images(dir.string() + "/channel%d.png");
805  cv::Mat img, imgFlipped;
806  while (images.read(img))
807  {
808  imgs.push_back(cv::Mat());
809  cv::flip(img, imgFlipped, 0); // TODO: FIXME: Data is currently stored mirrored and offset
810  cv::cvtColor(imgFlipped, imgs.back(), cv::COLOR_RGB2GRAY);
811  pixels.push_back(imgs.back().data);
812  }
813 
814  n_channels = imgs.size();
815  int width = imgs[0].cols;
816  int height = imgs[0].rows;
817 
818  numPointSpectralChannels = numPointPanoramaCoords;
819  pointSpectralChannels = ucharArr(new unsigned char[numPointPanoramaCoords * n_channels]);
820 
821  unsigned char* point_spectral_channels = pointSpectralChannels.get();
822 
823  std::cout << timestamp << "Finished loading " << n_channels << " channel images" << std::endl;
824 
825  #pragma omp parallel for
826  for (int i = 0; i < numPointPanoramaCoords; i++)
827  {
828  int pc_index = 2 * i; // x_coords, y_coords
829  short x = point_panorama_coords[pc_index];
830  short y = point_panorama_coords[pc_index + 1];
831  x = (x + width / 2) % width; // TODO: FIXME: Data is currently stored mirrored and offset
832 
833  int panoramaPosition = y * width + x;
834  unsigned char* pixel = point_spectral_channels + n_channels * i;
835 
836  for (int channel = 0; channel < n_channels; channel++)
837  {
838  pixel[channel] = pixels[channel][panoramaPosition];
839  }
840  }
841  std::cout << timestamp << "Finished extracting channel information" << std::endl;
842  }
843  }
844 
845 
846  // Save buffers in model
847  PointBufferPtr pc;
849  if(points)
850  {
851  pc = PointBufferPtr( new PointBuffer );
852  pc->setPointArray(points, numPoints);
853 
854  if (pointColors)
855  {
856  pc->setColorArray(pointColors, numPointColors);
857  }
858 
859  if (pointIntensities)
860  {
861  pc->addFloatChannel(pointIntensities, "intensities", numPointIntensities, 1);
862  }
863 
864  if (pointConfidences)
865  {
866  pc->addFloatChannel(pointConfidences, "confidences", numPointConfidence, 1);
867  }
868 
869  if (pointNormals)
870  {
871  pc->setNormalArray(pointNormals, numPointNormals);
872  }
873 
874  // only add spectral data if we really have some...
875  if (pointSpectralChannels)
876  {
877  pc->addUCharChannel(pointSpectralChannels, "spectral_channels", numPointSpectralChannels, n_channels);
878 
879  // there is no way to read min-, maxchannel from ply file => assume default 400-1000nm
880  pc->addIntAtomic(400, "spectral_wavelength_min");
881  pc->addIntAtomic(400 + 4 * n_channels, "spectral_wavelength_max");
882  pc->addIntAtomic(n_channels, "num_spectral_channels");
883  }
884  }
885 
886  if(vertices)
887  {
888  mesh = MeshBufferPtr( new MeshBuffer );
889  mesh->setVertices(vertices, numVertices );
890 
891  if (faceIndices)
892  {
893  mesh->setFaceIndices(faceIndices, numFaces);
894  }
895 
896  if (vertexNormals)
897  {
898  mesh->setVertexNormals(vertexNormals);
899  }
900 
901  if (vertexColors)
902  {
903  mesh->setVertexColors(vertexColors);
904  }
905 
906  if (vertexIntensity)
907  {
908  mesh->addFloatChannel(vertexIntensity, "vertex_intensities", numVertexIntensities, 1);
909  }
910 
911  if (vertexConfidence)
912  {
913  mesh->addFloatChannel(vertexConfidence, "vertex_confidences", numVertexConfidences, 1);
914  }
915  }
916 
917  ModelPtr m( new Model( mesh, pc ) );
918  m_model = m;
919  return m;
920 
921 }
922 
923 
925 {
926  float ** ptr;
927  ply_get_argument_user_data( argument, (void **) &ptr, NULL );
928  **ptr = ply_get_argument_value( argument );
929  (*ptr)++;
930  return 1;
931 
932 }
933 
934 
936 {
937 
938  uint8_t ** color;
939  ply_get_argument_user_data( argument, (void **) &color, NULL );
940  **color = ply_get_argument_value( argument );
941  (*color)++;
942  return 1;
943 
944 }
945 
946 
948 {
949 
950  unsigned int ** face;
951  long int length, value_index;
952  ply_get_argument_user_data( argument, (void **) &face, NULL );
953  ply_get_argument_property( argument, NULL, &length, &value_index );
954  if ( value_index < 0 )
955  {
956  /* We got info about amount of face vertices. */
957  if ( ply_get_argument_value( argument ) == 3 )
958  {
959  return 1;
960  }
961  std::cerr << timestamp << "Mesh is not a triangle mesh." << std::endl;
962  return 0;
963  }
964  **face = ply_get_argument_value( argument );
965  (*face)++;
966 
967  return 1;
968 
969 }
970 
972 {
973 
974  short ** ptr;
975  ply_get_argument_user_data( argument, (void **) &ptr, NULL );
976  **ptr = ply_get_argument_value( argument );
977  (*ptr)++;
978  return 1;
979 
980 }
981 
982 } // namespace lvr2
int ply_read(p_ply ply)
Definition: rply.c:429
A class to handle point information with an arbitrarily large number of attribute channels...
Definition: PointBuffer.hpp:51
int ply_add_scalar_property(p_ply ply, const char *name, e_ply_type type)
Definition: rply.c:497
Definition: rply.c:193
void save(string filename)
Save PLY with previously specified data.
Definition: PLYIO.cpp:57
int ply_get_argument_user_data(p_ply_argument argument, void **pdata, long *idata)
Definition: rply.c:762
HalfEdgeMesh< Vec > mesh
std::shared_ptr< MeshBuffer > MeshBufferPtr
Definition: MeshBuffer.hpp:217
boost::shared_array< unsigned int > uintArr
Definition: DataStruct.hpp:130
double ply_get_argument_value(p_ply_argument argument)
Definition: rply.c:771
int ply_close(p_ply ply)
Definition: rply.c:658
boost::shared_array< short > shortArr
Definition: DataStruct.hpp:139
Definition: rply.h:42
static Timestamp timestamp
A global time stamp object for program runtime measurement.
Definition: Timestamp.hpp:116
I/O support for PLY files.
ModelPtr read(string filename, bool readColor, bool readConfidence=true, bool readIntensity=true, bool readNormals=true, bool readFaces=true, bool readPanoramaCoords=true)
Read specified PLY file.
Definition: PLYIO.cpp:419
int ply_get_property_info(p_ply_property property, const char **name, e_ply_type *type, e_ply_type *length_type, e_ply_type *value_type)
Definition: rply.c:713
boost::shared_array< unsigned char > ucharArr
Definition: DataStruct.hpp:137
int ply_write_header(p_ply ply)
Definition: rply.c:577
enum e_ply_storage_mode_ e_ply_storage_mode
std::shared_ptr< PointBuffer > PointBufferPtr
p_ply_property ply_get_next_property(p_ply_element element, p_ply_property last)
Definition: rply.c:704
p_ply ply_create(const char *name, e_ply_storage_mode storage_mode, p_ply_error_cb error_cb, long idata, void *pdata)
Definition: rply.c:447
static int readColorCb(p_ply_argument argument)
Callback for read color information.
Definition: PLYIO.cpp:935
ModelPtr m_model
Definition: BaseIO.hpp:104
boost::shared_array< unsigned int > indexArray
Definition: DataStruct.hpp:128
long ply_set_read_cb(p_ply ply, const char *element_name, const char *property_name, p_ply_read_cb read_cb, void *pdata, long idata)
Definition: rply.c:413
Definition: rply.h:41
boost::shared_array< float > floatArr
Definition: DataStruct.hpp:133
int ply_add_element(p_ply ply, const char *name, long ninstances)
Definition: rply.c:482
Definition: rply.h:42
static int readPanoramaCoordCB(p_ply_argument argument)
Callback for read panorama coords.
Definition: PLYIO.cpp:971
static int readFaceCb(p_ply_argument argument)
Callback for read faces.
Definition: PLYIO.cpp:947
p_ply_element ply_get_next_element(p_ply ply, p_ply_element last)
Definition: rply.c:687
int ply_get_argument_property(p_ply_argument argument, p_ply_property *property, long *length, long *value_index)
Definition: rply.c:752
static int readVertexCb(p_ply_argument argument)
Callback for read vertices.
Definition: PLYIO.cpp:924
std::shared_ptr< Model > ModelPtr
Definition: Model.hpp:80
int ply_get_element_info(p_ply_element element, const char **name, long *ninstances)
Definition: rply.c:696
void swap(T *&arr, size_t i1, size_t i2, size_t n)
Definition: PLYIO.cpp:414
int ply_add_list_property(p_ply ply, const char *name, e_ply_type length_type, e_ply_type value_type)
Definition: rply.c:515
p_ply ply_open(const char *name, p_ply_error_cb error_cb, long idata, void *pdata)
Definition: rply.c:355
The MeshBuffer Mesh representation for I/O modules.
Definition: MeshBuffer.hpp:41
#define NULL
Definition: mydefs.hpp:141
int ply_read_header(p_ply ply)
Definition: rply.c:384
int ply_write(p_ply ply, double value)
Definition: rply.c:616


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:08