ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
profileLoader.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 "profileLoader.h"
9 
10 // CV_DB_LIB
11 #include <ecvPointCloud.h>
12 #include <ecvPolyline.h>
13 
14 // ECV_PLUGINS
15 #include <ecvMainAppInterface.h>
16 
17 // Qt
18 #include <QFile>
19 #include <QFileInfo>
20 #include <QTextStream>
21 
22 // Qt5/Qt6 Compatibility
23 #include <QtCompat.h>
24 
26  CCVector3& origin,
27  ecvMainAppInterface* app /*=0*/) {
28  // load profile as a polyline
29  QFile file(filename);
30  assert(file.exists());
31  if (!file.open(QFile::ReadOnly | QFile::Text)) {
32  if (app)
33  app->dispToConsole(QString("Failed to open file for reading! Check "
34  "access rights"),
36  return 0;
37  }
38 
39  QTextStream stream(&file);
40 
41  ccPolyline* polyline = 0;
42 
43  bool error = false;
44  for (unsigned n = 0; n < 1; ++n) // fake loop for easy break ;)
45  {
46  // read origin
47  {
48  QString headerLine = stream.readLine();
49  if (headerLine.isEmpty() || !headerLine.startsWith("X")) {
50  if (app)
51  app->dispToConsole(
52  QString("Malformed file (origin header expected on "
53  "first line)"),
55  error = true;
56  break;
57  }
58  QString centerLine = stream.readLine();
59  {
60  QStringList tokens = qtCompatSplitRegex(
61  centerLine, "\\s+", QtCompat::SkipEmptyParts);
62  bool validLine = false;
63  if (tokens.size() == 3) {
64  bool ok[3] = {false, false, false};
65  origin.x = static_cast<PointCoordinateType>(
66  tokens[0].toDouble(ok + 0));
67  origin.y = static_cast<PointCoordinateType>(
68  tokens[1].toDouble(ok + 1));
69  origin.z = static_cast<PointCoordinateType>(
70  tokens[2].toDouble(ok + 2));
71  validLine = ok[0] && ok[1] && ok[2];
72  }
73  if (!validLine) {
74  if (app)
75  app->dispToConsole(
76  QString("Malformed file (origin coordinates "
77  "expected on second line)"),
79  error = true;
80  break;
81  }
82  }
83  }
84 
85  // read elevations
86  {
87  QString headerLine = stream.readLine();
88  if (headerLine.isEmpty() || !headerLine.startsWith("R")) {
89  if (app)
90  app->dispToConsole(
91  QString("Malformed file (radii/heights header "
92  "expected on third line)"),
94  error = true;
95  break;
96  }
97 
98  QString line = stream.readLine();
99  std::vector<CCVector2d> points;
100  while (!line.isEmpty()) {
101  QStringList tokens = qtCompatSplitRegex(
102  line, "\\s+", QtCompat::SkipEmptyParts);
103  if (tokens.size() < 2) {
104  if (app)
105  app->dispToConsole(
106  QString("Malformed file (radius/height couple "
107  "expected from the 4th line and "
108  "afterwards)"),
110  error = true;
111  break;
112  }
113 
114  CCVector2d P;
115  P.x = tokens[0].toDouble(); // radius
116  P.y = tokens[1].toDouble(); // height
117 
118  try {
119  points.push_back(P);
120  } catch (const std::bad_alloc&) {
121  // not enough memory
122  if (app)
123  app->dispToConsole(
124  QString("Not enough memory!"),
126  error = true;
127  break;
128  }
129 
130  line = stream.readLine();
131  }
132 
133  // convert 2D points to polyline
134  {
135  unsigned count = static_cast<unsigned>(points.size());
136  if (count > 1) {
137  ccPointCloud* vertices = new ccPointCloud("vertices");
138  polyline = new ccPolyline(vertices);
139  polyline->addChild(vertices);
140  if (!vertices->reserve(count) ||
141  !polyline->reserve(count)) {
142  // not enough memory
143  if (app)
144  app->dispToConsole(
145  QString("Not enough memory!"),
147  error = true;
148  break;
149  }
150 
151  // add vertices
152  {
153  for (unsigned i = 0; i < count; ++i) {
154  vertices->addPoint(
155  CCVector3(static_cast<PointCoordinateType>(
156  points[i].x),
157  static_cast<PointCoordinateType>(
158  points[i].y),
159  0));
160  }
161  }
162 
163  // add segments
164  polyline->addPointIndex(0, count);
165  polyline->setClosed(false); // just to be sure
166  polyline->set2DMode(true);
167 
168  // add to DB
169  polyline->setName(QFileInfo(filename).baseName());
170  polyline->setColor(ecvColor::green);
171  polyline->showColors(true);
172  polyline->setEnabled(true);
173  polyline->setLocked(
174  true); // as we have applied a purely visual
175  // transformation, we can't let the user
176  // rotate it!!!
177  vertices->setEnabled(false);
178  } else {
179  if (app)
180  app->dispToConsole(
181  QString("Not enough points in profile?!"),
183 
184  error = true;
185  break;
186  }
187  }
188  }
189  }
190 
191  file.close();
192 
193  if (error) {
194  delete polyline;
195  polyline = 0;
196  }
197 
198  return polyline;
199 }
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
std::string filename
int count
int points
QStringList qtCompatSplitRegex(const QString &str, const QString &pattern, Qt::SplitBehavior behavior=Qt::KeepEmptyParts)
Definition: QtCompat.h:308
static ccPolyline * Load(QString filename, CCVector3 &origin, ecvMainAppInterface *app=0)
Loads a 2D profile from a file.
Type y
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:36
Type y
Definition: CVGeom.h:36
virtual void showColors(bool state)
Sets colors visibility.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
virtual void setLocked(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:117
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
Colored polyline.
Definition: ecvPolyline.h:24
void set2DMode(bool state)
Defines if the polyline is considered as 2D or 3D.
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
Definition: ecvPolyline.h:81
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
void setClosed(bool state)
Sets whether the polyline is closed or not.
Definition: Polyline.h:29
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
Main application interface (for plugins)
virtual void dispToConsole(QString message, ConsoleMessageLevel level=STD_CONSOLE_MESSAGE)=0
static void error(char *msg)
Definition: lsd.c:159
constexpr Qt::SplitBehavior SkipEmptyParts
Definition: QtCompat.h:302
constexpr Rgb green(0, MAX, 0)