ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvTools.h
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 #pragma once
9 
10 #ifdef _MSC_VER
11 #pragma warning(disable : 4996)
12 #pragma warning(disable : 4819)
13 #endif
14 
15 #include <Utils/PCLCloud.h>
16 #include <Utils/PCLConv.h>
17 #include <Utils/sm2cc.h>
18 
19 // PCL COMMON
20 #include <pcl/ModelCoefficients.h>
21 #include <pcl/PointIndices.h>
22 #include <pcl/Vertices.h>
23 
24 // CV_DB_LIB
25 #include <ecvColorTypes.h>
26 #include <ecvPointCloud.h>
27 #include <ecvPolyline.h>
28 
29 namespace ecvTools {
30 static std::vector<int> IntersectionVector(std::vector<int>& a,
31  std::vector<int>& b) {
32  std::vector<int> c;
33  sort(a.begin(), a.end());
34  sort(b.begin(), b.end());
35  set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(c));
36  return c;
37 }
38 
39 static std::vector<int> UnionVector(std::vector<int>& a, std::vector<int>& b) {
40  std::vector<int> c;
41  set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(c));
42  return c;
43 }
44 
45 static std::vector<int> DiffVector(std::vector<int> a, std::vector<int> b) {
46  std::vector<int> c;
47  sort(a.begin(), a.end());
48  sort(b.begin(), b.end());
49  set_difference(a.begin(), a.end(), b.begin(), b.end(), back_inserter(c));
50  return c;
51 }
52 
54  if (col.r <= 1 && col.g <= 1 && col.b <= 1) {
55  return ecvColor::Rgbf(col.r, col.g, col.b);
56  } else {
57  return ecvColor::Rgbf(col.r / 255.0f, col.g / 255.0f, col.b / 255.0f);
58  }
59 }
60 
62  if (col.r <= 1 && col.g <= 1 && col.b <= 1) {
63  return ecvColor::Rgbf(col.r, col.g, col.b);
64  } else {
65  return ecvColor::Rgbf(col.r / 255.0f, col.g / 255.0f, col.b / 255.0f);
66  }
67 }
68 
69 static ccPolyline* GetPolylines(PCLCloud::Ptr& curve_sm,
70  const QString& name = "curve",
71  bool closed = true,
73  if (curve_sm->width * curve_sm->height == 0) {
74  return nullptr;
75  }
76 
77  ccPointCloud* polyVertices = pcl2cc::Convert(*curve_sm, true, true);
78  {
79  if (!polyVertices) {
80  return nullptr;
81  }
82  polyVertices->setPointSize(5);
83  polyVertices->showColors(true);
84  polyVertices->setTempColor(ecvColor::red);
85  }
86 
87  ccPolyline* curvePoly = new ccPolyline(polyVertices);
88  {
89  if (!curvePoly) {
90  return nullptr;
91  }
92 
93  int verticesCount = polyVertices->size();
94  if (curvePoly->reserve(verticesCount)) {
95  curvePoly->addPointIndex(0, verticesCount);
96  curvePoly->setColor(color);
97  curvePoly->showColors(true);
98  curvePoly->setVisible(true);
99  curvePoly->setClosed(closed);
100  curvePoly->setName(name);
101  curvePoly->addChild(polyVertices);
102  } else {
103  delete curvePoly;
104  curvePoly = nullptr;
105  return nullptr;
106  }
107  }
108 
109  return curvePoly;
110 }
111 
112 static void AddPointCloud(ccHObject* ecvGroup,
113  PCLCloud::Ptr sm_cloud,
114  bool& error,
115  QString label,
116  const ccPointCloud* ccCloud = nullptr,
117  bool randomColors = true) {
118  ccPointCloud* out_cloud_cc = pcl2cc::Convert(*sm_cloud);
119 
120  if (!out_cloud_cc) {
121  // not enough memory!
122  error = true;
123  } else {
124  // shall we colorize it with a random color?
125  if (randomColors) {
127  out_cloud_cc->setRGBColor(col);
128  out_cloud_cc->showColors(true);
129  out_cloud_cc->showSF(false); // just in case
130  }
131 
132  QString cloudName = QString("%1 %2 (size=%3)")
133  .arg(label)
134  .arg(ecvGroup->getChildrenNumber())
135  .arg(out_cloud_cc->size());
136  out_cloud_cc->setName(cloudName);
137 
138  // copy global shift & scale
139  if (ccCloud) {
140  out_cloud_cc->setGlobalScale(ccCloud->getGlobalScale());
141  out_cloud_cc->setGlobalShift(ccCloud->getGlobalShift());
142  }
143 
144  ecvGroup->addChild(out_cloud_cc);
145  }
146 }
147 
149  const ccPointCloud* ccCloud,
150  const PointCloudT::ConstPtr xyzCloud,
151  const std::vector<pcl::PointIndices>& cluster_indices,
152  unsigned minPointsPerComponent,
153  bool randomColors,
154  bool& error) {
155  if (!xyzCloud) {
156  return nullptr;
157  }
158 
159  // we create a new group to store all input CCs as 'clusters'
160  ccHObject* ecvGroup = new ccHObject(ccCloud ? ccCloud->getName()
161  : "" + QString(" [clusters]-"));
162  ecvGroup->setVisible(true);
163  error = false;
164 
165  // for each cluster
166  for (std::vector<pcl::PointIndices>::const_iterator it =
167  cluster_indices.begin();
168  it != cluster_indices.end(); ++it) {
169  PointCloudT::Ptr cloud_cluster(new PointCloudT);
170  for (std::vector<int>::const_iterator pit = it->indices.begin();
171  pit != it->indices.end(); ++pit)
172  cloud_cluster->points.push_back(xyzCloud->points[*pit]);
173  cloud_cluster->width =
174  static_cast<uint32_t>(cloud_cluster->points.size());
175  cloud_cluster->height = 1;
176  cloud_cluster->is_dense = true;
177 
178  PCLCloud::Ptr sm_cloud(new PCLCloud);
179  TO_PCL_CLOUD(*cloud_cluster, *sm_cloud);
180 
181  if (sm_cloud->height * sm_cloud->width == 0) {
182  error = true;
183  continue;
184  }
185 
186  AddPointCloud(ecvGroup, sm_cloud, error, "cluster", ccCloud,
187  randomColors);
188  }
189 
190  if (ecvGroup->getChildrenNumber() == 0) {
191  delete ecvGroup;
192  ecvGroup = nullptr;
193  }
194 
195  return ecvGroup;
196 }
197 
199  const ccPointCloud* ccCloud,
200  const std::vector<std::vector<size_t>>& cluster_indices,
201  unsigned minPointsPerComponent,
202  bool randomColors,
203  bool& error) {
204  if (!ccCloud) {
205  return nullptr;
206  }
207 
208  // we create a new group to store all input CCs as 'clusters'
209  ccHObject* ecvGroup = new ccHObject(ccCloud->getName());
210  ecvGroup->setVisible(true);
211  error = false;
212 
213  // for each cluster
214  for (auto& cluster : cluster_indices) {
215  ccPointCloud* cloud = ccPointCloud::From(ccCloud, cluster);
216  if (cloud) {
217  // shall we colorize it with a random color?
218  if (randomColors) {
220  cloud->setRGBColor(col);
221  cloud->showColors(true);
222  cloud->showSF(false); // just in case
223  }
224 
225  QString cloudName = QString("%1 %2 (size=%3)")
226  .arg("cluster")
227  .arg(ecvGroup->getChildrenNumber())
228  .arg(cloud->size());
229  cloud->setName(cloudName);
230 
231  ecvGroup->addChild(cloud);
232  } else {
233  error = true;
234  continue;
235  }
236  }
237 
238  if (ecvGroup->getChildrenNumber() == 0) {
239  delete ecvGroup;
240  ecvGroup = nullptr;
241  }
242 
243  return ecvGroup;
244 }
245 
247  const ccPointCloud* ccCloud,
248  const PointCloudT::ConstPtr cloudRemained,
249  const std::vector<PointCloudT::Ptr>& cloudExtractions,
250  bool randomColors,
251  bool& error) {
252  // we create a new group to store all input CCs as 'clusters'
253  ccHObject* ecvGroup = new ccHObject(
254  ccCloud ? ccCloud->getName() : "" + QString(" [segmentation]-"));
255  ecvGroup->setVisible(true);
256  error = false;
257 
258  // save remaining
259  if (cloudRemained) {
260  PCLCloud::Ptr sm_cloud(new PCLCloud);
261  TO_PCL_CLOUD(*cloudRemained, *sm_cloud);
262  if (sm_cloud->height * sm_cloud->width != 0) {
263  AddPointCloud(ecvGroup, sm_cloud, error, "remaining", ccCloud,
264  randomColors);
265  } else {
266  error = true;
267  }
268  }
269 
270  // for each extracted segment saving
271  for (std::vector<PointCloudT::Ptr>::const_iterator it =
272  cloudExtractions.begin();
273  it != cloudExtractions.end(); ++it) {
274  PCLCloud::Ptr sm_cloud(new PCLCloud);
275  TO_PCL_CLOUD(**it, *sm_cloud);
276  if (sm_cloud->height * sm_cloud->width == 0) {
277  error = true;
278  continue;
279  }
280 
281  AddPointCloud(ecvGroup, sm_cloud, error, "segment", ccCloud,
282  randomColors);
283  }
284 
285  if (ecvGroup->getChildrenNumber() == 0) {
286  delete ecvGroup;
287  ecvGroup = nullptr;
288  }
289 
290  return ecvGroup;
291 }
292 
293 }; // namespace ecvTools
std::string name
math::float4 color
pcl::PointCloud< PointT > PointCloudT
Definition: PCLCloud.h:17
pcl::PCLPointCloud2 PCLCloud
Definition: PCLCloud.h:34
#define TO_PCL_CLOUD
Definition: PCLConv.h:12
virtual void setVisible(bool state)
Sets entity visibility.
virtual void setTempColor(const ecvColor::Rgb &col, bool autoActivate=true)
Sets current temporary (unique)
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
void setPointSize(unsigned size=0)
Sets point size.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
unsigned getChildrenNumber() const
Returns the number of children.
Definition: ecvHObject.h:312
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
Definition: ecvHObject.cpp:534
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
static ccPointCloud * From(const cloudViewer::GenericIndexedCloud *cloud, const ccGenericPointCloud *sourceCloud=nullptr)
Creates a new point cloud object from a GenericIndexedCloud.
bool setRGBColor(ColorCompType r, ColorCompType g, ColorCompType b)
Set a unique color for the whole cloud (shortcut)
Colored polyline.
Definition: ecvPolyline.h:24
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
Definition: ecvPolyline.h:81
virtual void setGlobalShift(double x, double y, double z)
Sets shift applied to original coordinates (information storage only)
virtual void setGlobalScale(double scale)
unsigned size() const override
Definition: PointCloudTpl.h:38
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.
static Rgb Random(bool lightOnly=true)
Generates a random color.
RGB color structure.
Definition: ecvColorTypes.h:49
static ccMesh * Convert(PCLTextureMesh::ConstPtr textureMesh)
Converts a PCL point cloud to a ccPointCloud.
a[190]
constexpr Rgb red(MAX, 0, 0)
RgbTpl< float > Rgbf
3 components, float type
constexpr Rgb green(0, MAX, 0)
static std::vector< int > DiffVector(std::vector< int > a, std::vector< int > b)
Definition: ecvTools.h:45
static std::vector< int > UnionVector(std::vector< int > &a, std::vector< int > &b)
Definition: ecvTools.h:39
static ccHObject * GetSegmentationGroup(const ccPointCloud *ccCloud, const PointCloudT::ConstPtr cloudRemained, const std::vector< PointCloudT::Ptr > &cloudExtractions, bool randomColors, bool &error)
Definition: ecvTools.h:246
static ecvColor::Rgbf TransFormRGB(const ecvColor::Rgb &col)
Definition: ecvTools.h:53
static void AddPointCloud(ccHObject *ecvGroup, PCLCloud::Ptr sm_cloud, bool &error, QString label, const ccPointCloud *ccCloud=nullptr, bool randomColors=true)
Definition: ecvTools.h:112
static ccHObject * GetClousterGroup(const ccPointCloud *ccCloud, const PointCloudT::ConstPtr xyzCloud, const std::vector< pcl::PointIndices > &cluster_indices, unsigned minPointsPerComponent, bool randomColors, bool &error)
Definition: ecvTools.h:148
static ccPolyline * GetPolylines(PCLCloud::Ptr &curve_sm, const QString &name="curve", bool closed=true, const ecvColor::Rgb &color=ecvColor::green)
Definition: ecvTools.h:69
static std::vector< int > IntersectionVector(std::vector< int > &a, std::vector< int > &b)
Definition: ecvTools.h:30