ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
SoiFilter.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "SoiFilter.h"
9 
10 // CV_DB_LIB
11 #include <CVLog.h>
12 #include <ecvPointCloud.h>
13 #include <ecvProgressDialog.h>
14 
15 // Max number of characters per line in an ASCII file
16 // TODO: use QFile instead!
17 const int MAX_ASCII_FILE_LINE_LENGTH = 4096;
18 
20  : FileIOFilter({"_Soisic Filter",
21  DEFAULT_PRIORITY, // priority
22  QStringList{"soi"}, "soi",
23  QStringList{"Mensi Soisic cloud (*.soi)"}, QStringList(),
24  Import}) {}
25 
27  ccHObject& container,
28  LoadParameters& parameters) {
29  // open the file
30  FILE* fp = fopen(qPrintable(filename), "rt");
31  if (!fp) return CC_FERR_READING;
32 
33  std::string line;
34  line.resize(MAX_ASCII_FILE_LINE_LENGTH);
35  unsigned nbScansTotal = 0;
36  unsigned nbPointsTotal = 0;
37 
38  // we read the first line
39  char* eof = fgets((char*)line.c_str(), MAX_ASCII_FILE_LINE_LENGTH, fp);
40  char* pEnd;
41 
42  // header
43  while ((strcmp((char*)line.substr(0, 4).c_str(), "#CC#") != 0) &&
44  (eof != nullptr)) {
45  if (strcmp(line.substr(0, 4).c_str(), "#NP#") == 0) {
46  std::string numPoints(line, 4, line.size() - 4);
47  nbPointsTotal = strtol(numPoints.c_str(), &pEnd, 0);
48  // CVLog::Print("[SoiFilter::loadFile] Total number of points:
49  // %i",nbPointsTotal);
50  } else if (strcmp(line.substr(0, 4).c_str(), "#NS#") == 0) {
51  std::string numScans(line, 4, line.size() - 4);
52  nbScansTotal = strtol(numScans.c_str(), &pEnd, 0);
53  // CVLog::Print("[SoiFilter::loadFile] Total number of scans:
54  // %i",nbScansTotal);
55  }
56 
57  eof = fgets((char*)line.c_str(), MAX_ASCII_FILE_LINE_LENGTH, fp);
58  }
59 
60  if ((nbScansTotal == 0) || (nbPointsTotal == 0)) {
62  "[SoiFilter::loadFile] No points or scans defined in this "
63  "file!");
64  fclose(fp);
65  return CC_FERR_NO_LOAD;
66  }
67 
68  // Progress dialog
69  QScopedPointer<ecvProgressDialog> pDlg(0);
70  if (parameters.parentWidget) {
71  pDlg.reset(new ecvProgressDialog(
72  false, parameters.parentWidget)); // cancel is not supported
73  pDlg->setMethodTitle(QObject::tr("Open SOI file"));
74  pDlg->setInfo(QObject::tr("%1 scans / %2 points")
75  .arg(nbScansTotal)
76  .arg(nbPointsTotal));
77  pDlg->start();
78  }
79  cloudViewer::NormalizedProgress nprogress(pDlg.data(), nbPointsTotal);
80 
81  // Scan by scan
82  for (unsigned k = 0; k < nbScansTotal; k++) {
83  char* eof = fgets((char*)line.c_str(), MAX_ASCII_FILE_LINE_LENGTH, fp);
84 
85  // we only look for points (we ignore the rest)
86  while ((strcmp(line.substr(0, 4).c_str(), "#pt#") != 0) &&
87  (eof != nullptr))
88  eof = fgets((char*)line.c_str(), MAX_ASCII_FILE_LINE_LENGTH, fp);
89 
90  unsigned nbOfPoints = 0;
91 
92  if (strcmp(line.substr(0, 4).c_str(), "#pt#") == 0) {
93  std::string numPoints(line, 4, line.size() - 4);
94  nbOfPoints = strtol(numPoints.c_str(), &pEnd, 0);
95  // CVLog::Print("[SoiFilter::loadFile] Scan %i - points:
96  // %i",k+1,nbOfPoints);
97  } else {
98  CVLog::Warning("[SoiFilter::loadFile] Can't find marker '#pt#'!");
99  fclose(fp);
101  }
102 
103  if (nbOfPoints == 0) {
104  CVLog::Warning("[SoiFilter::loadFile] Scan #%i is empty!", k);
105  continue;
106  }
107 
108  // Creation de la liste de points
109  QString name = QString("unnamed - Scan #%1").arg(k);
110 
111  ccPointCloud* loadedCloud = new ccPointCloud(name);
112  if (!loadedCloud->reserveThePointsTable(nbOfPoints) ||
113  !loadedCloud->reserveTheRGBTable()) {
114  fclose(fp);
115  delete loadedCloud;
117  }
118  loadedCloud->showColors(true);
119 
120  // we can read points now
121  for (unsigned i = 0; i < nbOfPoints; i++) {
122  float P[3];
123  int c = 0;
124  if (fscanf(fp, "%f %f %f %i", P, P + 1, P + 2, &c) < 4) {
125  fclose(fp);
126  delete loadedCloud;
127  return CC_FERR_MALFORMED_FILE;
128  }
129 
130  loadedCloud->addPoint(CCVector3::fromArray(P));
131  loadedCloud->addGreyColor(static_cast<ColorCompType>(
132  c << 3)); //<<2 ? <<3 ? we lack some info. here ...
133 
134  if (pDlg) {
135  nprogress.oneStep();
136  }
137  }
138 
139  container.addChild(loadedCloud);
140  }
141 
142  fclose(fp);
143 
144  return CC_FERR_NO_ERROR;
145 }
std::string filename
std::string name
CC_FILE_ERROR
Typical I/O filter errors.
Definition: FileIOFilter.h:20
@ CC_FERR_NO_LOAD
Definition: FileIOFilter.h:28
@ CC_FERR_MALFORMED_FILE
Definition: FileIOFilter.h:32
@ CC_FERR_NO_ERROR
Definition: FileIOFilter.h:21
@ CC_FERR_READING
Definition: FileIOFilter.h:26
@ CC_FERR_NOT_ENOUGH_MEMORY
Definition: FileIOFilter.h:31
@ CC_FERR_WRONG_FILE_TYPE
Definition: FileIOFilter.h:24
const int MAX_ASCII_FILE_LINE_LENGTH
Definition: SoiFilter.cpp:17
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
Generic file I/O filter.
Definition: FileIOFilter.h:46
static constexpr float DEFAULT_PRIORITY
Definition: FileIOFilter.h:313
virtual CC_FILE_ERROR loadFile(const QString &filename, ccHObject &container, LoadParameters &parameters) override
Loads one or more entities from a file.
Definition: SoiFilter.cpp:26
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Definition: CVGeom.h:268
virtual void showColors(bool state)
Sets colors visibility.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void addGreyColor(ColorCompType g)
Pushes a grey color on stack (shortcut)
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
bool reserveThePointsTable(unsigned _numberOfPoints)
Reserves memory to store the points coordinates.
bool oneStep()
Increments total progress value of a single unit.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
Graphical progress indicator (thread-safe)
unsigned char ColorCompType
Default color components type (R,G and B)
Definition: ecvColorTypes.h:29
Generic loading parameters.
Definition: FileIOFilter.h:51
QWidget * parentWidget
Parent widget (if any)
Definition: FileIOFilter.h:78