ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvFacet.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 "ecvFacet.h"
9 
10 #include "ecvMesh.h"
11 #include "ecvPointCloud.h"
12 #include "ecvPolyline.h"
13 
14 // CV_CORE_LIB
15 #include <Delaunay2dMesh.h>
17 #include <Logging.h>
18 #include <MeshSamplingTools.h>
19 #include <PointProjectionTools.h>
20 
21 static const char DEFAULT_POLYGON_MESH_NAME[] = "2D polygon";
22 static const char DEFAULT_CONTOUR_NAME[] = "Contour";
23 static const char DEFAULT_CONTOUR_POINTS_NAME[] = "Contour points";
24 static const char DEFAULT_ORIGIN_POINTS_NAME[] = "Origin points";
25 
27  QString name /*=QString("Facet")*/)
28  : ccHObject(name),
29  ccPlanarEntityInterface(getUniqueID()),
30  m_arrow(nullptr),
31  m_polygonMesh(nullptr),
32  m_contourPolyline(nullptr),
33  m_contourVertices(nullptr),
34  m_originPoints(nullptr),
35  m_center(0, 0, 0),
36  m_rms(0.0),
37  m_surface(0.0),
38  m_maxEdgeLength(maxEdgeLength) {
39  m_planeEquation[0] = 0;
40  m_planeEquation[1] = 0;
41  m_planeEquation[2] = 1;
42  m_planeEquation[3] = 0;
43 
44  setVisible(true);
45  lockVisibility(false);
46 }
47 
49  : ccHObject(poly.getName()),
50  ccPlanarEntityInterface(getUniqueID()),
51  m_arrow(nullptr),
52  m_polygonMesh(nullptr),
53  m_contourPolyline(nullptr),
54  m_contourVertices(nullptr),
55  m_originPoints(nullptr),
56  m_center(0, 0, 0),
57  m_rms(0.0),
58  m_surface(0.0),
59  m_maxEdgeLength(0) {
60  poly.clone(this);
61 }
62 
64 
66  ccFacet* facet = new ccFacet(m_maxEdgeLength, m_name);
67 
68  if (!clone(facet)) {
69  return nullptr;
70  }
71 
72  return facet;
73 }
74 
75 bool ccFacet::clone(ccFacet* facet) const {
76  if (!facet || this->IsEmpty()) {
77  return false;
78  }
79 
80  // clone contour
81  if (m_contourPolyline) {
82  assert(m_contourVertices);
84  facet->m_contourVertices = dynamic_cast<ccPointCloud*>(
86 
87  if (!facet->m_contourPolyline || !facet->m_contourVertices) {
88  // not enough memory?!
90  QString("[ccFacet::clone][%1] Failed to clone countour!")
91  .arg(getName()));
92  delete facet;
93  return false;
94  }
95 
96  // the copy constructor of ccFacet creates a new cloud (the copy of this
97  // facet's 'contour points') but set it by default as a child of the
98  // polyline (while we want the opposite in a facet)
100 
107  facet->addChild(facet->m_contourVertices);
108  }
109 
110  // clone mesh
111  if (m_polygonMesh) {
112  facet->m_polygonMesh =
114  if (!facet->m_polygonMesh) {
115  // not enough memory?!
117  QString("[ccFacet::clone][%1] Failed to clone polygon!")
118  .arg(getName()));
119  delete facet;
120  return false;
121  }
122 
125  if (facet->m_contourVertices)
126  facet->m_contourVertices->addChild(facet->m_polygonMesh);
127  else
128  facet->addChild(facet->m_polygonMesh);
129  }
130 
131  if (m_originPoints) {
132  facet->m_originPoints =
133  dynamic_cast<ccPointCloud*>(m_originPoints->clone());
134  if (!facet->m_originPoints) {
135  CVLog::Warning(QString("[ccFacet::clone][%1] Failed to clone "
136  "origin points!")
137  .arg(getName()));
138  // delete facet;
139  // return 0;
140  } else {
143  facet->addChild(facet->m_originPoints);
144  }
145  }
146 
147  if (m_arrow) {
148  if (!facet->m_arrow) {
149  facet->m_arrow = std::shared_ptr<ccMesh>();
150  facet->m_arrow->CreateInternalCloud();
151  }
152  *facet->m_arrow = *m_arrow;
153  }
154 
155  facet->m_center = m_center;
156  facet->m_rms = m_rms;
157  facet->m_surface = m_surface;
159  memcpy(facet->m_planeEquation, m_planeEquation,
160  sizeof(PointCoordinateType) * 4);
161  facet->setVisible(isVisible());
163 
164  return true;
165 }
166 
168  PointCoordinateType maxEdgeLength /*=0*/,
169  bool transferOwnership /*=false*/,
170  const PointCoordinateType* planeEquation /*=0*/) {
171  assert(cloud);
172 
173  // we need at least 3 points to compute a mesh or a plane! ;)
174  if (!cloud || cloud->size() < 3) {
175  CVLog::Error(
176  "[ccFacet::Create] Need at least 3 points to create a valid "
177  "facet!");
178  return nullptr;
179  }
180 
181  // create facet structure
182  ccFacet* facet = new ccFacet(maxEdgeLength, "facet");
183  if (!facet->createInternalRepresentation(cloud, planeEquation)) {
184  delete facet;
185  return nullptr;
186  }
187 
188  ccPointCloud* pc = dynamic_cast<ccPointCloud*>(cloud);
189  if (pc) {
190  facet->setName(pc->getName() + QString(".facet"));
191  if (facet->getPolygon()) {
192  facet->getPolygon()->setOpacity(0.5f);
194  }
195  if (facet->getContour()) {
197  facet->getContour()->showColors(true);
198  }
199 
200  if (transferOwnership) {
202  pc->setEnabled(false);
203  pc->setLocked(true);
204  facet->addChild(pc);
205  facet->setOriginPoints(pc);
206  }
207  }
208 
209  return facet;
210 }
211 
212 bool ccFacet::createInternalRepresentation(
214  const PointCoordinateType* planeEquation /*=0*/) {
215  assert(points);
216  if (!points) return false;
217  unsigned ptsCount = points->size();
218  if (ptsCount < 3) return false;
219 
221 
222  // get corresponding plane
223  if (!planeEquation) {
224  planeEquation = Yk.getLSPlane();
225  if (!planeEquation) {
227  "[ccFacet::createInternalRepresentation] Failed to compute "
228  "the LS plane passing through the input points!");
229  return false;
230  }
231  }
232  memcpy(m_planeEquation, planeEquation, sizeof(PointCoordinateType) * 4);
233 
234  // we project the input points on a plane
235  std::vector<cloudViewer::PointProjectionTools::IndexedCCVector2> points2D;
236  // local base
237  CCVector3 X;
238  CCVector3 Y;
239 
240  if (!Yk.projectPointsOn2DPlane<
242  points2D, nullptr, &m_center, &X, &Y)) {
243  CVLog::Error(
244  "[ccFacet::createInternalRepresentation] Not enough memory!");
245  return false;
246  }
247 
248  // compute resulting RMS
251 
252  // update the points indexes (not done by
253  // Neighbourhood::projectPointsOn2DPlane)
254  {
255  for (unsigned i = 0; i < ptsCount; ++i) {
256  points2D[i].index = i;
257  }
258  }
259 
260  // try to get the points on the convex/concave hull to build the contour and
261  // the polygon
262  {
263  std::list<cloudViewer::PointProjectionTools::IndexedCCVector2*>
264  hullPoints;
266  points2D, hullPoints, m_maxEdgeLength * m_maxEdgeLength)) {
267  CVLog::Error(
268  "[ccFacet::createInternalRepresentation] Failed to compute "
269  "the convex hull of the input points!");
270  }
271 
272  unsigned hullPtsCount = static_cast<unsigned>(hullPoints.size());
273 
274  // create vertices
276  {
277  if (!m_contourVertices->reserve(hullPtsCount)) {
278  delete m_contourVertices;
279  m_contourVertices = nullptr;
280  CVLog::Error(
281  "[ccFacet::createInternalRepresentation] Not enough "
282  "memory!");
283  return false;
284  }
285 
286  // projection on the LS plane (in 3D)
287  for (std::list<cloudViewer::PointProjectionTools::
288  IndexedCCVector2*>::const_iterator it =
289  hullPoints.begin();
290  it != hullPoints.end(); ++it) {
291  m_contourVertices->addPoint(m_center + X * (*it)->x +
292  Y * (*it)->y);
293  }
298  }
299 
300  // we create the corresponding (3D) polyline
301  {
303  if (m_contourPolyline->reserve(hullPtsCount)) {
304  m_contourPolyline->addPointIndex(0, hullPtsCount);
312  } else {
313  delete m_contourPolyline;
314  m_contourPolyline = nullptr;
316  "[ccFacet::createInternalRepresentation] Not enough "
317  "memory to create the contour polyline!");
318  }
319  }
320 
321  // we create the corresponding (2D) mesh
322  std::vector<CCVector2> hullPointsVector;
323  try {
324  hullPointsVector.reserve(hullPoints.size());
325  for (std::list<cloudViewer::PointProjectionTools::
326  IndexedCCVector2*>::const_iterator it =
327  hullPoints.begin();
328  it != hullPoints.end(); ++it) {
329  hullPointsVector.push_back(**it);
330  }
331  } catch (...) {
333  "[ccFacet::createInternalRepresentation] Not enough memory "
334  "to create the contour mesh!");
335  }
336 
337  // if we have computed a concave hull, we must remove triangles falling
338  // outside!
339  bool removePointsOutsideHull = (m_maxEdgeLength > 0);
340 
341  if (!hullPointsVector.empty() &&
343  // compute the facet surface
345  std::string errorStr;
346  if (dm.buildMesh(hullPointsVector,
348  errorStr)) {
349  if (removePointsOutsideHull)
350  dm.removeOuterTriangles(hullPointsVector, hullPointsVector);
351  unsigned triCount = dm.size();
352  assert(triCount != 0);
353 
355  if (m_polygonMesh->reserve(triCount)) {
356  // import faces
357  for (unsigned i = 0; i < triCount; ++i) {
358  const cloudViewer::VerticesIndexes* tsi =
360  m_polygonMesh->addTriangle(tsi->i1, tsi->i2, tsi->i3);
361  }
362  m_polygonMesh->setVisible(true);
364 
365  // unique normal for facets
367  NormsIndexesTableType* normsTable =
368  new NormsIndexesTableType();
369  normsTable->reserve(1);
371  normsTable->addElement(
373  m_polygonMesh->setTriNormsTable(normsTable);
374  for (unsigned i = 0; i < triCount; ++i)
376  0, 0, 0); // all triangles will have the
377  // same normal!
378  m_polygonMesh->showNormals(true);
379  m_polygonMesh->setLocked(true);
384  } else {
386  "[ccFacet::createInternalRepresentation] Not "
387  "enough memory to create the polygon mesh's "
388  "normals!");
389  }
390 
391  // update facet surface
393  m_polygonMesh);
394  } else {
395  delete m_polygonMesh;
396  m_polygonMesh = nullptr;
398  "[ccFacet::createInternalRepresentation] Not "
399  "enough memory to create the polygon mesh!");
400  }
401  } else {
402  CVLog::Warning(QString("[ccFacet::createInternalRepresentation]"
403  " Failed to create the polygon mesh "
404  "(third party lib. said '%1'")
405  .arg(QString::fromStdString(errorStr)));
406  }
407  }
408  }
409 
410  return true;
411 }
412 
417  }
418 
419  if (m_contourPolyline) {
422  }
423  showColors(true);
424 }
425 
426 std::shared_ptr<ccMesh> ccFacet::getNormalVectorMesh(bool update) {
427  // const auto boundingbox = GetAxisAlignedBoundingBox();
428  // double scale = std::max(0.01, boundingbox.GetMaxExtent() * 0.2);
429  if (normalVectorIsShown() && update || !m_arrow) {
430  PointCoordinateType scale = 1.0;
431  // the surface might be 0 if Delaunay 2.5D triangulation is not
432  // supported
433  if (m_surface > 0) {
434  scale = sqrt(m_surface);
435  } else {
436  scale = sqrt(m_contourPolyline->computeLength());
437  }
438  m_arrow = ccMesh::CreateArrow(0.02 * scale, 0.05 * scale, 0.9 * scale,
439  0.1 * scale);
440  // m_arrow->ComputeVertexNormals();
441  m_arrow->setTempColor(m_contourPolyline->getColor());
442  m_arrow->showColors(true);
443 
444  Eigen::Matrix4d transformation;
446  getNormal());
447  transformation = ccGLMatrixd::ToEigenMatrix4(mat);
448  m_arrow->Transform(transformation);
449 
450  transformation = Eigen::Matrix4d::Identity();
451  transformation.block<3, 1>(0, 3) = CCVector3d::fromArray(getCenter());
452  m_arrow->Transform(transformation);
453  }
454 
455  return m_arrow;
456 }
457 
459  if (!MACRO_Draw3D(context)) return;
460 
461  if (!isRedraw()) {
462  return;
463  }
464 
465  // show normal vector
466  if (m_contourPolyline) {
467  PointCoordinateType scale = 1.0;
468  if (normalVectorIsShown()) {
469  if (m_surface > 0) // the surface might be 0 if Delaunay 2.5D
470  // triangulation is not supported
471  {
472  scale = sqrt(m_surface);
473  } else {
474  scale = sqrt(m_contourPolyline->computeLength());
475  }
476  }
477 
479  }
480 }
481 
482 bool ccFacet::toFile_MeOnly(QFile& out, short dataVersion) const {
483  assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
484  if (dataVersion < 32) {
485  assert(false);
486  return false;
487  }
488 
489  if (!ccHObject::toFile_MeOnly(out, dataVersion)) return false;
490 
491  // we can't save the origin points here (as it will be automatically saved
492  // as a child) so instead we save it's unique ID (dataVersion>=32) WARNING:
493  // the cloud must be saved in the same BIN file! (responsibility of the
494  // caller)
495  {
496  uint32_t originPointsUniqueID =
497  (m_originPoints ? (uint32_t)m_originPoints->getUniqueID() : 0);
498  if (out.write((const char*)&originPointsUniqueID, 4) < 0)
499  return WriteError();
500  }
501 
502  // we can't save the contour points here (as it will be automatically saved
503  // as a child) so instead we save it's unique ID (dataVersion>=32) WARNING:
504  // the cloud must be saved in the same BIN file! (responsibility of the
505  // caller)
506  {
507  uint32_t contourPointsUniqueID =
509  : 0);
510  if (out.write((const char*)&contourPointsUniqueID, 4) < 0)
511  return WriteError();
512  }
513 
514  // we can't save the contour polyline here (as it will be automatically
515  // saved as a child) so instead we save it's unique ID (dataVersion>=32)
516  // WARNING: the polyline must be saved in the same BIN file! (responsibility
517  // of the caller)
518  {
519  uint32_t contourPolyUniqueID =
521  : 0);
522  if (out.write((const char*)&contourPolyUniqueID, 4) < 0)
523  return WriteError();
524  }
525 
526  // we can't save the polygon mesh here (as it will be automatically saved as
527  // a child) so instead we save it's unique ID (dataVersion>=32) WARNING: the
528  // mesh must be saved in the same BIN file! (responsibility of the caller)
529  {
530  uint32_t polygonMeshUniqueID =
531  (m_polygonMesh ? (uint32_t)m_polygonMesh->getUniqueID() : 0);
532  if (out.write((const char*)&polygonMeshUniqueID, 4) < 0)
533  return WriteError();
534  }
535 
536  // plane equation (dataVersion>=32)
537  if (out.write((const char*)&m_planeEquation,
538  sizeof(PointCoordinateType) * 4) < 0)
539  return WriteError();
540 
541  // center (dataVersion>=32)
542  if (out.write((const char*)m_center.u, sizeof(PointCoordinateType) * 3) < 0)
543  return WriteError();
544 
545  // RMS (dataVersion>=32)
546  if (out.write((const char*)&m_rms, sizeof(double)) < 0) return WriteError();
547 
548  // surface (dataVersion>=32)
549  if (out.write((const char*)&m_surface, sizeof(double)) < 0)
550  return WriteError();
551 
552  // Max edge length (dataVersion>=32)
553  if (out.write((const char*)&m_maxEdgeLength, sizeof(PointCoordinateType)) <
554  0)
555  return WriteError();
556 
557  return true;
558 }
559 
561  return std::max(static_cast<short>(32),
563 }
564 
566  short dataVersion,
567  int flags,
568  LoadedIDMap& oldToNewIDMap) {
569  if (!ccHObject::fromFile_MeOnly(in, dataVersion, flags, oldToNewIDMap))
570  return false;
571 
572  if (dataVersion < 32) return false;
573 
574  // origin points (dataVersion>=32)
575  // as the cloud will be saved automatically (as a child)
576  // we only store its unique ID --> we hope we will find it at loading time
577  {
578  uint32_t origPointsUniqueID = 0;
579  if (in.read((char*)&origPointsUniqueID, 4) < 0) return ReadError();
580  //[DIRTY] WARNING: temporarily, we set the cloud unique ID in the
581  //'m_originPoints' pointer!!!
582  *(uint32_t*)(&m_originPoints) = origPointsUniqueID;
583  }
584 
585  // contour points
586  // as the cloud will be saved automatically (as a child)
587  // we only store its unique ID --> we hope we will find it at loading time
588  {
589  uint32_t contourPointsUniqueID = 0;
590  if (in.read((char*)&contourPointsUniqueID, 4) < 0) return ReadError();
591  //[DIRTY] WARNING: temporarily, we set the cloud unique ID in the
592  //'m_contourVertices' pointer!!!
593  *(uint32_t*)(&m_contourVertices) = contourPointsUniqueID;
594  }
595 
596  // contour points
597  // as the polyline will be saved automatically (as a child)
598  // we only store its unique ID --> we hope we will find it at loading time
599  {
600  uint32_t contourPolyUniqueID = 0;
601  if (in.read((char*)&contourPolyUniqueID, 4) < 0) return ReadError();
602  //[DIRTY] WARNING: temporarily, we set the polyline unique ID in the
603  //'m_contourPolyline' pointer!!!
604  *(uint32_t*)(&m_contourPolyline) = contourPolyUniqueID;
605  }
606 
607  // polygon mesh
608  // as the mesh will be saved automatically (as a child)
609  // we only store its unique ID --> we hope we will find it at loading time
610  {
611  uint32_t polygonMeshUniqueID = 0;
612  if (in.read((char*)&polygonMeshUniqueID, 4) < 0) return ReadError();
613  //[DIRTY] WARNING: temporarily, we set the polyline unique ID in the
614  //'m_contourPolyline' pointer!!!
615  *(uint32_t*)(&m_polygonMesh) = polygonMeshUniqueID;
616  }
617 
618  // plane equation (dataVersion>=32)
619  if (in.read((char*)&m_planeEquation, sizeof(PointCoordinateType) * 4) < 0)
620  return ReadError();
621 
622  // center (dataVersion>=32)
623  if (in.read((char*)m_center.u, sizeof(PointCoordinateType) * 3) < 0)
624  return ReadError();
625 
626  // RMS (dataVersion>=32)
627  if (in.read((char*)&m_rms, sizeof(double)) < 0) return ReadError();
628 
629  // surface (dataVersion>=32)
630  if (in.read((char*)&m_surface, sizeof(double)) < 0) return ReadError();
631 
632  // Max edge length (dataVersion>=32)
633  if (in.read((char*)&m_maxEdgeLength, sizeof(PointCoordinateType)) < 0)
634  return ReadError();
635 
636  return true;
637 }
638 
641 
642  // move/rotate the center to its new location
643  trans.apply(m_center);
644 
645  // apply the rotation to the normal of the plane equation
647 
648  // compute new d-parameter from the updated values
650  m_planeEquation[3] = n.dot(m_center);
651 }
652 
654  for (int i = 0; i < 4; ++i) {
656  }
657 }
658 
659 bool ccFacet::IsEmpty() const {
660  return (!m_polygonMesh || m_polygonMesh->size() == 0 ||
662 }
663 
664 Eigen::Vector3d ccFacet::GetMinBound() const {
665  if (getPolygon()) {
666  return getPolygon()->GetMinBound();
667  } else {
668  return Eigen::Vector3d();
669  }
670 }
671 
672 Eigen::Vector3d ccFacet::GetMaxBound() const {
673  if (getPolygon()) {
674  return getPolygon()->GetMaxBound();
675  } else {
676  return Eigen::Vector3d();
677  }
678 }
679 
680 Eigen::Vector3d ccFacet::GetCenter() const {
681  if (getPolygon()) {
682  return getPolygon()->GetCenter();
683  } else {
684  return Eigen::Vector3d();
685  }
686 }
687 
689  if (getPolygon()) {
691  } else {
692  return ccBBox();
693  }
694 }
695 
697  if (getPolygon()) {
699  } else {
700  return ecvOrientedBBox();
701  }
702 }
703 
704 ccFacet& ccFacet::Transform(const Eigen::Matrix4d& transformation) {
705  if (!getPolygon()) {
706  return *this;
707  }
708 
709  getPolygon()->Transform(transformation);
710  return *this;
711 }
712 
713 ccFacet& ccFacet::Translate(const Eigen::Vector3d& translation, bool relative) {
714  if (!getPolygon()) {
715  return *this;
716  }
717 
718  getPolygon()->Translate(translation, relative);
719  return *this;
720 }
721 
722 ccFacet& ccFacet::Scale(const double s, const Eigen::Vector3d& center) {
723  if (!getPolygon()) {
724  return *this;
725  }
726 
727  getPolygon()->Scale(s, center);
728  return *this;
729 }
730 
731 ccFacet& ccFacet::Rotate(const Eigen::Matrix3d& R,
732  const Eigen::Vector3d& center) {
733  if (!getPolygon()) {
734  return *this;
735  }
736 
737  getPolygon()->Rotate(R, center);
738  return *this;
739 }
740 
742  cloudViewer::utility::LogWarning("ccFace does not support '+=' operator!");
743  return (*this);
744 }
745 
747  if (facet.IsEmpty()) return (*this);
748  if (this == &facet) {
749  return (*this);
750  }
751 
752  facet.clone(this);
753  return (*this);
754 }
755 
756 ccFacet ccFacet::operator+(const ccFacet& facet) const {
757  cloudViewer::utility::LogWarning("ccFace does not support '=' operator!");
758  return ccFacet();
759 }
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
Definition: CVConst.h:67
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 name
int points
void * X
Definition: SmallVector.cpp:45
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
Array of compressed 3D normals (single index)
Type u[3]
Definition: CVGeom.h:139
Type dot(const Vector3Tpl &v) const
Dot product.
Definition: CVGeom.h:408
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Definition: CVGeom.h:268
void addElement(const Type &value)
Definition: ecvArray.h:105
Bounding box structure.
Definition: ecvBBox.h:25
virtual bool isVisible() const
Returns whether entity is visible or not.
virtual bool isVisibilityLocked() const
Returns whether visibility is locked or not.
virtual void lockVisibility(bool state)
Locks/unlocks visibility.
virtual void setVisible(bool state)
Sets entity visibility.
virtual void setTempColor(const ecvColor::Rgb &col, bool autoActivate=true)
Sets current temporary (unique)
virtual bool isRedraw() const
Returns whether entity is to be redraw.
virtual void showColors(bool state)
Sets colors visibility.
virtual void setOpacity(float opacity)
Set opacity activation state.
Facet.
Definition: ecvFacet.h:25
ccMesh * getPolygon()
Returns polygon mesh (if any)
Definition: ecvFacet.h:81
short minimumFileVersion_MeOnly() const override
Definition: ecvFacet.cpp:560
std::shared_ptr< ccMesh > getNormalVectorMesh(bool update=false)
Gets normal vector mesh.
Definition: ecvFacet.cpp:426
virtual ccFacet & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
Definition: ecvFacet.cpp:704
ccFacet operator+(const ccFacet &polyline) const
Definition: ecvFacet.cpp:756
ccPolyline * getContour()
Returns contour polyline (if any)
Definition: ecvFacet.h:86
virtual ~ccFacet() override
Destructor.
Definition: ecvFacet.cpp:63
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
Definition: ecvFacet.cpp:565
double m_rms
RMS (relatively to m_associatedPoints)
Definition: ecvFacet.h:181
ccFacet & operator+=(const ccFacet &polyline)
Definition: ecvFacet.cpp:741
ccFacet(PointCoordinateType maxEdgeLength=0, QString name=QString("Facet"))
Default constructor.
Definition: ecvFacet.cpp:26
ccMesh * m_polygonMesh
Facet.
Definition: ecvFacet.h:166
ccFacet * clone() const
Clones this facet.
Definition: ecvFacet.cpp:65
double m_surface
Surface (m_polygon)
Definition: ecvFacet.h:184
ccFacet & operator=(const ccFacet &polyline)
Definition: ecvFacet.cpp:746
virtual ccFacet & Scale(const double s, const Eigen::Vector3d &center) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
Definition: ecvFacet.cpp:722
ccPointCloud * m_originPoints
Origin points.
Definition: ecvFacet.h:172
CCVector3 getNormal() const override
Returns the entity normal.
Definition: ecvFacet.h:63
virtual Eigen::Vector3d GetMinBound() const override
Returns min bounds for geometry coordinates.
Definition: ecvFacet.cpp:664
PointCoordinateType m_maxEdgeLength
Max length.
Definition: ecvFacet.h:187
void invertNormal()
Inverts the facet normal.
Definition: ecvFacet.cpp:653
virtual ccFacet & Rotate(const Eigen::Matrix3d &R, const Eigen::Vector3d &center) override
Apply rotation to the geometry coordinates and normals. Given a rotation matrix , and center ,...
Definition: ecvFacet.cpp:731
virtual Eigen::Vector3d GetMaxBound() const override
Returns max bounds for geometry coordinates.
Definition: ecvFacet.cpp:672
ccPolyline * m_contourPolyline
Facet contour.
Definition: ecvFacet.h:168
virtual bool IsEmpty() const override
Definition: ecvFacet.cpp:659
virtual ccBBox GetAxisAlignedBoundingBox() const override
Returns an axis-aligned bounding box of the geometry.
Definition: ecvFacet.cpp:688
void setColor(const ecvColor::Rgb &rgb)
Sets the facet unique color.
Definition: ecvFacet.cpp:413
std::shared_ptr< ccMesh > m_arrow
for python interface use
Definition: ecvFacet.h:163
virtual ccFacet & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
Definition: ecvFacet.cpp:713
virtual void applyGLTransformation(const ccGLMatrix &trans) override
Applies a GL transformation to the entity.
Definition: ecvFacet.cpp:639
virtual Eigen::Vector3d GetCenter() const override
Returns the center of the geometry coordinates.
Definition: ecvFacet.cpp:680
CCVector3 m_center
Facet centroid.
Definition: ecvFacet.h:178
const CCVector3 & getCenter() const
Returns the facet center.
Definition: ecvFacet.h:78
static ccFacet * Create(cloudViewer::GenericIndexedCloudPersist *cloud, PointCoordinateType maxEdgeLength=0, bool transferOwnership=false, const PointCoordinateType *planeEquation=nullptr)
Creates a facet from a set of points.
Definition: ecvFacet.cpp:167
virtual void drawMeOnly(CC_DRAW_CONTEXT &context) override
Draws the entity only (not its children)
Definition: ecvFacet.cpp:458
PointCoordinateType m_planeEquation[4]
Plane equation - as usual in CC plane equation is ax + by + cz = d.
Definition: ecvFacet.h:175
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
Definition: ecvFacet.cpp:482
ccPointCloud * m_contourVertices
Shared vertices (between polygon and contour)
Definition: ecvFacet.h:170
virtual ecvOrientedBBox GetOrientedBoundingBox() const override
Definition: ecvFacet.cpp:696
void setOriginPoints(ccPointCloud *cloud)
Sets origin points.
Definition: ecvFacet.h:113
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
static ccGLMatrixTpl< float > FromToRotation(const Vector3Tpl< float > &from, const Vector3Tpl< float > &to)
Creates a transformation matrix that rotates a vector to another.
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
static Eigen::Matrix< double, 4, 4 > ToEigenMatrix4(const ccGLMatrixTpl< float > &mat)
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
void showNormals(bool state) override
Sets normals visibility.
void enableStippling(bool state)
Enables polygon stippling.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual short minimumFileVersion_MeOnly() const
virtual bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap)
Loads own object data.
void detachChild(ccHObject *child)
Detaches a specific child.
Definition: ecvHObject.cpp:988
virtual bool toFile_MeOnly(QFile &out, short dataVersion) const
Save own object data.
virtual void applyGLTransformation(const ccGLMatrix &trans)
Applies a GL transformation to the entity.
Definition: ecvHObject.cpp:944
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
Definition: ecvHObject.cpp:534
Triangular mesh.
Definition: ecvMesh.h:35
ccMesh * cloneMesh(ccGenericPointCloud *vertices=nullptr, ccMaterialSet *clonedMaterials=nullptr, NormsIndexesTableType *clonedNormsTable=nullptr, TextureCoordsContainer *cloneTexCoords=nullptr)
Clones this entity.
Definition: ecvMesh.cpp:1109
virtual ecvOrientedBBox GetOrientedBoundingBox() const override
Definition: ecvMesh.cpp:848
virtual ccMesh & Scale(const double s, const Eigen::Vector3d &center) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
Definition: ecvMesh.cpp:872
virtual Eigen::Vector3d GetMaxBound() const override
Returns max bounds for geometry coordinates.
Definition: ecvMesh.cpp:828
virtual unsigned size() const override
Returns the number of triangles.
Definition: ecvMesh.cpp:2143
void setTriNormsTable(NormsIndexesTableType *triNormsTable, bool autoReleaseOldTable=true)
Sets per-triangle normals array (may be shared)
Definition: ecvMesh.cpp:470
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
Definition: ecvMesh.cpp:2475
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
Definition: ecvMesh.cpp:2428
virtual ccBBox GetAxisAlignedBoundingBox() const override
Returns an axis-aligned bounding box of the geometry.
Definition: ecvMesh.cpp:844
bool reservePerTriangleNormalIndexes()
Reserves memory to store per-triangle triplets of normal indexes.
Definition: ecvMesh.cpp:3328
void addTriangleNormalIndexes(int i1, int i2, int i3)
Adds a triplet of normal indexes for next triangle.
Definition: ecvMesh.cpp:3340
static std::shared_ptr< ccMesh > CreateArrow(double cylinder_radius=1.0, double cone_radius=1.5, double cylinder_height=5.0, double cone_height=4.0, int resolution=20, int cylinder_split=4, int cone_split=1)
virtual ccMesh & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
Definition: ecvMesh.cpp:863
virtual ccMesh & Rotate(const Eigen::Matrix3d &R, const Eigen::Vector3d &center) override
Apply rotation to the geometry coordinates and normals. Given a rotation matrix , and center ,...
Definition: ecvMesh.cpp:882
virtual Eigen::Vector3d GetMinBound() const override
Returns min bounds for geometry coordinates.
Definition: ecvMesh.cpp:820
virtual Eigen::Vector3d GetCenter() const override
Returns the center of the geometry coordinates.
Definition: ecvMesh.cpp:836
virtual ccMesh & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
Definition: ecvMesh.cpp:852
static CompressedNormType GetNormIndex(const PointCoordinateType N[])
Returns the compressed index corresponding to a normal vector.
virtual void setLocked(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:117
virtual bool isLocked() const
Returns whether the object is locked or not.
Definition: ecvObject.h:112
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
virtual unsigned getUniqueID() const
Returns object unique ID.
Definition: ecvObject.h:86
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
virtual bool isEnabled() const
Returns whether the object is enabled or not.
Definition: ecvObject.h:97
QString m_name
Object name.
Definition: ecvObject.h:219
Interface for a planar entity.
void glDrawNormal(CC_DRAW_CONTEXT &context, const CCVector3 &pos, float scale, const ecvColor::Rgb *color=0)
Draws a normal vector (OpenGL)
bool normalVectorIsShown() const
Whether normal vector is shown or not.
bool m_showNormalVector
Whether the facet normal vector should be displayed or not.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool setRGBColor(ColorCompType r, ColorCompType g, ColorCompType b)
Set a unique color for the whole cloud (shortcut)
ccGenericPointCloud * clone(ccGenericPointCloud *destCloud=nullptr, bool ignoreChildren=false) override
Clones this entity.
Colored polyline.
Definition: ecvPolyline.h:24
PointCoordinateType computeLength() const
Computes the polyline length.
const ecvColor::Rgb & getColor() const
Returns the polyline color.
Definition: ecvPolyline.h:99
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
Definition: ecvPolyline.h:81
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
A class to compute and handle a Delaunay 2D mesh on a subset of points.
VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
virtual unsigned size() const override
Returns the number of triangles.
static bool Available()
Returns whether 2D Delaunay triangulation is supported or not.
virtual bool removeOuterTriangles(const std::vector< CCVector2 > &vertices2D, const std::vector< CCVector2 > &polygon2D, bool removeOutside=true)
Removes the triangles falling outside of a given (2D) polygon.
virtual bool buildMesh(const std::vector< CCVector2 > &points2D, std::size_t pointCountToUse, std::string &outputErrorStr)
Build the Delaunay mesh on top a set of 2D points.
static constexpr int USE_ALL_POINTS
static ScalarType computeCloud2PlaneDistanceRMS(GenericCloud *cloud, const PointCoordinateType *planeEquation)
Computes the Root Mean Square (RMS) distance between a cloud and a plane.
virtual unsigned size() const =0
Returns the number of points.
A generic 3D point cloud with index-based and presistent access to points.
static double computeMeshArea(GenericMesh *mesh)
Computes the mesh area.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
static bool extractConcaveHull2D(std::vector< IndexedCCVector2 > &points, std::list< IndexedCCVector2 * > &hullPoints, PointCoordinateType maxSquareLength=0)
Determines the 'concave' hull of a set of points.
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 GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
RGB color structure.
Definition: ecvColorTypes.h:49
#define LogWarning(...)
Definition: Logging.h:72
#define MACRO_Draw3D(context)
static const char DEFAULT_ORIGIN_POINTS_NAME[]
Definition: ecvFacet.cpp:24
static const char DEFAULT_CONTOUR_POINTS_NAME[]
Definition: ecvFacet.cpp:23
static const char DEFAULT_CONTOUR_NAME[]
Definition: ecvFacet.cpp:22
static const char DEFAULT_POLYGON_MESH_NAME[]
Definition: ecvFacet.cpp:21
ImGuiContext * context
Definition: Window.cpp:76
normal_z rgb
constexpr Rgb darkGrey(MAX/2, MAX/2, MAX/2)
constexpr Rgb green(0, MAX, 0)
Display context.
Triangle described by the indexes of its 3 vertices.