ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvMesh.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 // cloudViewer
11 #include <Helper.h>
12 #include <PointProjectionTools.h>
13 #include <SimpleTriangle.h>
14 
15 #include <Eigen/Core>
16 
17 // Local
18 #include <unordered_map>
19 #include <unordered_set>
20 
21 #include "Image.h"
22 #include "ecvGenericMesh.h"
23 
24 namespace cloudViewer {
25 namespace geometry {
26 class TetraMesh;
27 }
28 } // namespace cloudViewer
29 
30 class ccPolyline;
31 class ecvOrientedBBox;
32 class ecvProgressDialog;
33 
36 public:
38 
40  explicit ccMesh(ccGenericPointCloud* vertices = nullptr);
41 
42  ccMesh(const ccMesh& mesh);
43 
48  explicit ccMesh(const std::vector<Eigen::Vector3d>& vertices,
49  const std::vector<Eigen::Vector3i>& triangles);
50 
52 
56  explicit ccMesh(cloudViewer::GenericIndexedMesh* giMesh,
57  ccGenericPointCloud* giVertices);
58 
60  ~ccMesh() override;
61 
63  CV_CLASS_ENUM getClassID() const override { return CV_TYPES::MESH; }
64 
66  void setAssociatedCloud(ccGenericPointCloud* cloud);
67 
68  // Creates associated vertices cloud internally.
69  bool CreateInternalCloud();
70 
72 
78  ccMesh* cloneMesh(ccGenericPointCloud* vertices = nullptr,
79  ccMaterialSet* clonedMaterials = nullptr,
80  NormsIndexesTableType* clonedNormsTable = nullptr,
81  TextureCoordsContainer* cloneTexCoords = nullptr);
82 
84 
89  ccMesh* partialClone(const std::vector<unsigned>& triangleIndices,
90  int* warnings = nullptr) const;
91 
93  int vidx1,
94  int vidx2) {
95  if (vidx0 > vidx2) {
96  std::swap(vidx0, vidx2);
97  }
98  if (vidx0 > vidx1) {
99  std::swap(vidx0, vidx1);
100  }
101  if (vidx1 > vidx2) {
102  std::swap(vidx1, vidx2);
103  }
104  return cloudViewer::VerticesIndexes(static_cast<unsigned int>(vidx0),
105  static_cast<unsigned int>(vidx1),
106  static_cast<unsigned int>(vidx2));
107  }
108 
110 
112  static ccMesh* Triangulate(ccGenericPointCloud* cloud,
114  bool updateNormals = false,
115  PointCoordinateType maxEdgeLength = 0,
116  unsigned char dim = 2);
117 
119  static ccMesh* TriangulateTwoPolylines(ccPolyline* p1,
120  ccPolyline* p2,
121  CCVector3* projectionDir = nullptr);
122 
124 
128  bool merge(const ccMesh* mesh, bool createSubMesh);
129 
130  ccMesh& operator=(const ccMesh& mesh);
131  ccMesh& operator+=(const ccMesh& mesh);
132  ccMesh operator+(const ccMesh& mesh) const;
133 
134  void clear();
135 
136  // inherited methods (ccHObject)
137  unsigned getUniqueIDForDisplay() const override;
138  ccBBox getOwnBB(bool withGLFeatures = false) override;
139  bool isSerializable() const override { return true; }
140  const ccGLMatrix& getGLTransformationHistory() const override;
141 
142  // inherited methods (ccGenericMesh)
143  inline ccGenericPointCloud* getAssociatedCloud() const override {
144  return m_associatedCloud;
145  }
146  void refreshBB() override;
147  bool interpolateNormalsBC(unsigned triIndex,
148  const CCVector3d& w,
149  CCVector3& N) override;
150  bool interpolateColors(unsigned triIndex,
151  const CCVector3& P,
152  ecvColor::Rgb& C) override;
153  void computeInterpolationWeights(unsigned triIndex,
154  const CCVector3& P,
155  CCVector3d& weights) const override;
156  bool getColorFromMaterial(unsigned triIndex,
157  const CCVector3& P,
158  ecvColor::Rgb& C,
159  bool interpolateColorIfNoTexture) override;
160  bool getVertexColorFromMaterial(unsigned triIndex,
161  unsigned char vertIndex,
162  ecvColor::Rgb& C,
163  bool returnColorIfNoTexture) override;
164  unsigned capacity() const override;
165 
166  // inherited methods (GenericIndexedMesh)
167  void forEach(genericTriangleAction action) override;
168  void placeIteratorAtBeginning() override;
169  cloudViewer::GenericTriangle* _getNextTriangle() override; // temporary
171  unsigned triangleIndex) override; // temporary
174  unsigned triangleIndex) override;
175  virtual void getTriangleVertices(unsigned triangleIndex,
176  CCVector3& A,
177  CCVector3& B,
178  CCVector3& C) const override;
179  virtual void getTriangleVertices(unsigned triangleIndex,
180  double A[3],
181  double B[3],
182  double C[3]) const override;
183 
184  unsigned int getVerticeSize() const;
185 
186  Eigen::Vector3d getVertice(size_t index) const;
187  void setVertice(size_t index, const Eigen::Vector3d& vertice);
188  void addVertice(const Eigen::Vector3d& vertice);
189  std::vector<Eigen::Vector3d> getEigenVertices() const;
190  void addEigenVertices(const std::vector<Eigen::Vector3d>& vertices);
191  void setEigenVertices(const std::vector<Eigen::Vector3d>& vertices);
192 
193  Eigen::Vector3d getVertexNormal(size_t index) const;
194  void setVertexNormal(size_t index, const Eigen::Vector3d& normal);
195  void addVertexNormal(const Eigen::Vector3d& normal);
196  std::vector<Eigen::Vector3d> getVertexNormals() const;
197  void addVertexNormals(const std::vector<Eigen::Vector3d>& normals);
198  void setVertexNormals(const std::vector<Eigen::Vector3d>& normals);
199 
200  Eigen::Vector3d getVertexColor(size_t index) const;
201  void setVertexColor(size_t index, const Eigen::Vector3d& color);
202  void addVertexColor(const Eigen::Vector3d& color);
203  std::vector<Eigen::Vector3d> getVertexColors() const;
204  ColorsTableType* getVertexColorsPtr();
205  void addVertexColors(const std::vector<Eigen::Vector3d>& colors);
206  void setVertexColors(const std::vector<Eigen::Vector3d>& colors);
207 
208  inline bool HasVertices() const { return getVerticeSize() != 0; }
209 
210  std::vector<CCVector3>& getVerticesPtr();
211  const std::vector<CCVector3>& getVertices() const;
212 
213  virtual unsigned size() const override;
214  void getBoundingBox(CCVector3& bbMin, CCVector3& bbMax) override;
215  bool normalsAvailable() const override { return hasNormals(); }
216  bool interpolateNormals(unsigned triIndex,
217  const CCVector3& P,
218  CCVector3& N) override;
219 
220  // const version of getTriangleVertIndexes
221  void getTriangleVertIndexes(size_t triangleIndex,
222  Eigen::Vector3i& vertIndx) const;
224  unsigned triangleIndex) const;
225 
226  // inherited methods (ccDrawableObject)
227  bool hasColors() const override;
228  bool hasNormals() const override;
229  bool HasVertexNormals() const;
230  bool hasScalarFields() const override;
231  bool hasDisplayedScalarField() const override;
232  bool normalsShown() const override;
234 
236 
238  void invertNormals();
239 
241 
243  void shiftTriangleIndexes(unsigned shift);
244 
246 
248  void flipTriangles();
249 
251 
258  void addTriangle(unsigned i1, unsigned i2, unsigned i3);
259  void addTriangle(const cloudViewer::VerticesIndexes& triangle);
260  inline void addTriangle(const Eigen::Vector3i& index) {
261  addTriangle(static_cast<unsigned>(index[0]),
262  static_cast<unsigned>(index[1]),
263  static_cast<unsigned>(index[2]));
264  }
265  inline void addTriangles(const std::vector<Eigen::Vector3i>& triangles) {
266  for (auto& tri : triangles) {
267  addTriangle(tri);
268  }
269  }
270 
271  void setTriangle(size_t index, const Eigen::Vector3i& triangle);
272  void setTriangles(const std::vector<Eigen::Vector3i>& triangles);
273  Eigen::Vector3i getTriangle(size_t index) const;
274  std::vector<Eigen::Vector3i> getTriangles() const;
275 
280  return m_triVertIndexes;
281  }
282 
284 
287  bool reserve(std::size_t n);
288  bool reserveAssociatedCloud(std::size_t n,
289  bool init_color = false,
290  bool init_normal = false);
291 
293 
298  bool resize(size_t n);
299  bool resizeAssociatedCloud(std::size_t n);
300 
302  inline void shrinkToFit() {
303  if (size() < capacity()) resize(size());
304  }
305  void shrinkVertexToFit();
306 
307  /*********************************************************/
308  /************** PER-TRIANGLE NORMALS ***************/
309  /*********************************************************/
310 
311  // inherited from ccGenericMesh
312  bool hasTriNormals() const override;
313  // for compatibility
314  inline bool HasTriangleNormals() const { return hasTriNormals(); }
315  void getTriangleNormalIndexes(unsigned triangleIndex,
316  int& i1,
317  int& i2,
318  int& i3) const override;
319  bool getTriangleNormals(unsigned triangleIndex,
320  CCVector3& Na,
321  CCVector3& Nb,
322  CCVector3& Nc) const override;
323  bool getTriangleNormals(unsigned triangleIndex,
324  double Na[3],
325  double Nb[3],
326  double Nc[3]) const override;
327  bool getTriangleNormals(unsigned triangleIndex,
328  Eigen::Vector3d& Na,
329  Eigen::Vector3d& Nb,
330  Eigen::Vector3d& Nc) const override;
331  std::vector<Eigen::Vector3d> getTriangleNormals() const;
332  std::vector<CCVector3*> getTriangleNormalsPtr() const;
333  Eigen::Vector3d getTriangleNorm(size_t index) const;
334  bool setTriangleNorm(size_t index, const Eigen::Vector3d& triangle_normal);
335  bool setTriangleNormalIndexes(size_t triangleIndex,
336  CompressedNormType value);
337  CompressedNormType getTriangleNormalIndexes(size_t triangleIndex);
338  bool addTriangleNorm(const CCVector3& N);
339  bool addTriangleNorm(const Eigen::Vector3d& N);
340  std::vector<Eigen::Vector3d> getTriangleNorms() const;
341  bool setTriangleNorms(const std::vector<Eigen::Vector3d>& triangle_normals);
342  bool addTriangleNorms(const std::vector<Eigen::Vector3d>& triangle_normals);
343 
345  return m_triNormals;
346  }
347 
349  void setTriNormsTable(NormsIndexesTableType* triNormsTable,
350  bool autoReleaseOldTable = true);
351 
353  void clearTriNormals() { setTriNormsTable(nullptr); }
354 
356 
366  bool arePerTriangleNormalsEnabled() const;
367 
369 
378  bool reservePerTriangleNormalIndexes();
379 
381 
387  void addTriangleNormalIndexes(int i1, int i2, int i3);
388 
390 
395  void setTriangleNormalIndexes(unsigned triangleIndex,
396  int i1,
397  int i2,
398  int i3);
399 
401  void removePerTriangleNormalIndexes();
402 
404  void invertPerTriangleNormals();
405 
406  /********************************************************/
407  /************ PER-TRIANGLE MATERIAL ***************/
408  /********************************************************/
409 
410  // inherited from ccGenericMesh
411  bool hasMaterials() const override;
412  const ccMaterialSet* getMaterialSet() const override { return m_materials; }
413  int getTriangleMtlIndex(unsigned triangleIndex) const override;
414 
416 
418  bool convertMaterialsToVertexColors();
419 
422  return m_triMtlIndexes && m_triMtlIndexes->isAllocated();
423  }
424 
426 
435  bool reservePerTriangleMtlIndexes();
436 
438  void removePerTriangleMtlIndexes();
439 
441 
444  void addTriangleMtlIndex(int mtlIndex);
445 
448 
450  void setTriangleMtlIndexesTable(triangleMaterialIndexesSet* matIndexesTable,
451  bool autoReleaseOldTable = true);
452 
455  const {
456  return m_triMtlIndexes;
457  }
458 
460 
464  void setTriangleMtlIndex(unsigned triangleIndex, int mtlIndex);
465 
467  void setMaterialSet(ccMaterialSet* materialSet,
468  bool autoReleaseOldMaterialSet = true);
469 
470  /******************************************************************/
471  /************ PER-TRIANGLE TEXTURE COORDINATE ***************/
472  /******************************************************************/
473 
474  // inherited from ccGenericMesh
475  bool hasTextures() const override;
477  return m_texCoords;
478  }
479  void getTriangleTexCoordinates(unsigned triIndex,
480  TexCoords2D*& tx1,
481  TexCoords2D*& tx2,
482  TexCoords2D*& tx3) const override;
483  void getTexCoordinates(unsigned index, TexCoords2D*& tx) const override;
484  bool hasPerTriangleTexCoordIndexes() const override {
485  return m_texCoordIndexes && m_texCoordIndexes->isAllocated();
486  }
487  void getTriangleTexCoordinatesIndexes(unsigned triangleIndex,
488  int& i1,
489  int& i2,
490  int& i3) const override;
491 
493  void setTexCoordinatesTable(TextureCoordsContainer* texCoordsTable,
494  bool autoReleaseOldTable = true);
495 
497 
506  bool reservePerTriangleTexCoordIndexes();
507 
509  void removePerTriangleTexCoordIndexes();
510 
512 
518  void addTriangleTexCoordIndexes(int i1, int i2, int i3);
519 
521 
526  void setTriangleTexCoordIndexes(unsigned triangleIndex,
527  int i1,
528  int i2,
529  int i3);
530 
532 
535  bool computeNormals(bool perVertex);
536 
538  bool computePerVertexNormals();
539 
541  bool computePerTriangleNormals();
542 
544 
548  bool laplacianSmooth(
549  unsigned nbIteration = 100,
550  PointCoordinateType factor = static_cast<PointCoordinateType>(0.01),
551  ecvProgressDialog* progressCb = nullptr);
552 
557  };
558 
561 
569  bool processScalarField(MESH_SCALAR_FIELD_PROCESS process);
570 
573 
575  ccMesh* subdivide(PointCoordinateType maxArea) const;
576 
578 
595  ccMesh* createNewMeshFromSelection(
596  bool removeSelectedTriangles,
597  std::vector<int>* newIndexesOfRemainingTriangles = nullptr,
598  bool withChildEntities = false);
599 
601 
604  void swapTriangles(unsigned index1, unsigned index2);
605 
606  void removeTriangles(size_t index);
607 
609  void transformTriNormals(const ccGLMatrix& trans);
610 
612  static const unsigned char DefaultMergeDulicateVerticesLevel = 10;
613 
615  bool mergeDuplicatedVertices(
616  unsigned char octreeLevel = DefaultMergeDulicateVerticesLevel,
617  QWidget* parentWidget = nullptr);
618 
619 public: // some cloudViewer interface
622  std::vector<std::unordered_set<int>> adjacency_list_;
623 
625  std::vector<Eigen::Vector2d> triangle_uvs_;
626 
627  struct Material {
629  float f4[4] = {0};
630 
632  f4[0] = 0;
633  f4[1] = 0;
634  f4[2] = 0;
635  f4[3] = 0;
636  }
637 
638  MaterialParameter(const float v1,
639  const float v2,
640  const float v3,
641  const float v4) {
642  f4[0] = v1;
643  f4[1] = v2;
644  f4[2] = v3;
645  f4[3] = v4;
646  }
647 
648  MaterialParameter(const float v1, const float v2, const float v3) {
649  f4[0] = v1;
650  f4[1] = v2;
651  f4[2] = v3;
652  f4[3] = 1;
653  }
654 
655  MaterialParameter(const float v1, const float v2) {
656  f4[0] = v1;
657  f4[1] = v2;
658  f4[2] = 0;
659  f4[3] = 0;
660  }
661 
662  explicit MaterialParameter(const float v1) {
663  f4[0] = v1;
664  f4[1] = 0;
665  f4[2] = 0;
666  f4[3] = 0;
667  }
668 
669  static MaterialParameter CreateRGB(const float r,
670  const float g,
671  const float b) {
672  return {r, g, b, 1.f};
673  }
674 
675  float r() const { return f4[0]; }
676  float g() const { return f4[1]; }
677  float b() const { return f4[2]; }
678  float a() const { return f4[3]; }
679  };
680 
682  float baseMetallic = 0.f;
683  float baseRoughness = 1.f;
684  float baseReflectance = 0.5f;
685  float baseClearCoat = 0.f;
686  float baseClearCoatRoughness = 0.f;
687  float baseAnisotropy = 0.f;
688 
689  std::shared_ptr<cloudViewer::geometry::Image> albedo;
690  std::shared_ptr<cloudViewer::geometry::Image> normalMap;
691  std::shared_ptr<cloudViewer::geometry::Image> ambientOcclusion;
692  std::shared_ptr<cloudViewer::geometry::Image> metallic;
693  std::shared_ptr<cloudViewer::geometry::Image> roughness;
694  std::shared_ptr<cloudViewer::geometry::Image> reflectance;
695  std::shared_ptr<cloudViewer::geometry::Image> clearCoat;
696  std::shared_ptr<cloudViewer::geometry::Image> clearCoatRoughness;
697  std::shared_ptr<cloudViewer::geometry::Image> anisotropy;
698 
699  std::unordered_map<std::string, MaterialParameter> floatParameters;
700  std::unordered_map<std::string, cloudViewer::geometry::Image>
702  };
703 
704  std::vector<std::pair<std::string, Material>> materials_;
705 
707  std::vector<int> triangle_material_ids_;
709  std::vector<cloudViewer::geometry::Image> textures_;
710 
712  bool hasAdjacencyList() const {
713  return getVerticeSize() > 0 &&
714  adjacency_list_.size() == getVerticeSize();
715  }
716 
717  inline bool hasTriangleUvs() const {
718  return hasTriangles() && triangle_uvs_.size() == 3 * size();
719  }
720 
721  bool hasTriangleMaterialIds() const {
722  return hasTriangles() && triangle_material_ids_.size() == size();
723  }
724 
726  bool hasEigenTextures() const {
727  bool is_all_texture_valid = std::accumulate(
728  textures_.begin(), textures_.end(), true,
729  [](bool a, const cloudViewer::geometry::Image& b) {
730  return a && !b.IsEmpty();
731  });
732  return !textures_.empty() && is_all_texture_valid;
733  }
734 
735  inline virtual bool IsEmpty() const override {
736  return !HasVertices() || !hasTriangles();
737  }
738 
739  virtual Eigen::Vector3d GetMinBound() const override;
740  virtual Eigen::Vector3d GetMaxBound() const override;
741  virtual Eigen::Vector3d GetCenter() const override;
742  virtual ccBBox GetAxisAlignedBoundingBox() const override;
743  virtual ecvOrientedBBox GetOrientedBoundingBox() const override;
744  virtual ccMesh& Transform(const Eigen::Matrix4d& transformation) override;
745  virtual ccMesh& Translate(const Eigen::Vector3d& translation,
746  bool relative = true) override;
747  virtual ccMesh& Scale(const double s,
748  const Eigen::Vector3d& center) override;
749  virtual ccMesh& Rotate(const Eigen::Matrix3d& R,
750  const Eigen::Vector3d& center) override;
751 
755  ccMesh& PaintUniformColor(const Eigen::Vector3d& color);
756 
757  std::tuple<std::shared_ptr<ccMesh>, std::vector<size_t>> ComputeConvexHull()
758  const;
759 
768  std::unordered_map<Eigen::Vector2i,
769  double,
771  ComputeEdgeWeightsCot(
772  const std::unordered_map<
774  std::vector<int>,
776  edges_to_vertices,
777  double min_weight = std::numeric_limits<double>::lowest()) const;
778 
781  ccMesh& ComputeTriangleNormals(bool normalized = true);
782 
785  ccMesh& ComputeVertexNormals(bool normalized = true);
786 
789  ccMesh& NormalizeNormals();
790 
792  ccMesh& ComputeAdjacencyList();
793 
796  ccMesh& RemoveDuplicatedVertices();
797 
801  ccMesh& RemoveDuplicatedTriangles();
802 
805  ccMesh& RemoveUnreferencedVertices();
806 
811  ccMesh& RemoveDegenerateTriangles();
812 
817  ccMesh& RemoveNonManifoldEdges();
818 
825  ccMesh& MergeCloseVertices(double eps);
826 
836  std::shared_ptr<ccMesh> FilterSharpen(
837  int number_of_iterations,
838  double strength,
839  FilterScope scope = FilterScope::All) const;
840 
849  std::shared_ptr<ccMesh> FilterSmoothSimple(
850  int number_of_iterations,
851  FilterScope scope = FilterScope::All) const;
852 
863  std::shared_ptr<ccMesh> FilterSmoothLaplacian(
864  int number_of_iterations,
865  double lambda,
866  FilterScope scope = FilterScope::All) const;
867 
878  std::shared_ptr<ccMesh> FilterSmoothTaubin(
879  int number_of_iterations,
880  double lambda = 0.5,
881  double mu = -0.53,
882  FilterScope scope = FilterScope::All) const;
883 
887  int EulerPoincareCharacteristic() const;
888 
892  std::vector<Eigen::Vector2i> GetNonManifoldEdges(
893  bool allow_boundary_edges = true) const;
894 
899  bool IsEdgeManifold(bool allow_boundary_edges = true) const;
900 
904  std::vector<int> GetNonManifoldVertices() const;
905 
909  bool IsVertexManifold() const;
910 
913  std::vector<Eigen::Vector2i> GetSelfIntersectingTriangles() const;
914 
917  bool IsSelfIntersecting() const;
918 
921  bool IsBoundingBoxIntersecting(const ccMesh& other) const;
922 
925  bool IsIntersecting(const ccMesh& other) const;
926 
930  bool IsOrientable() const;
931 
935  bool IsWatertight() const;
936 
940  bool OrientTriangles();
941 
944  std::unordered_map<Eigen::Vector2i,
945  std::vector<int>,
947  GetEdgeToTrianglesMap() const;
948 
951  std::unordered_map<Eigen::Vector2i,
952  std::vector<int>,
954  GetEdgeToVerticesMap() const;
955 
958  double GetTriangleArea(size_t triangle_idx) const;
959 
961  static double ComputeTriangleArea(const Eigen::Vector3d& p0,
962  const Eigen::Vector3d& p1,
963  const Eigen::Vector3d& p2);
964 
965  static inline Eigen::Vector3i GetEigneOrderedTriangle(int vidx0,
966  int vidx1,
967  int vidx2) {
968  if (vidx0 > vidx2) {
969  std::swap(vidx0, vidx2);
970  }
971  if (vidx0 > vidx1) {
972  std::swap(vidx0, vidx1);
973  }
974  if (vidx1 > vidx2) {
975  std::swap(vidx1, vidx2);
976  }
977  return Eigen::Vector3i(vidx0, vidx1, vidx2);
978  }
979 
982  double GetSurfaceArea() const;
983 
986  double GetSurfaceArea(std::vector<double>& triangle_areas) const;
987 
991  double GetVolume() const;
992 
996  static Eigen::Vector4d ComputeTrianglePlane(const Eigen::Vector3d& p0,
997  const Eigen::Vector3d& p1,
998  const Eigen::Vector3d& p2);
999 
1002  Eigen::Vector4d GetTrianglePlane(size_t triangle_idx) const;
1003 
1005  static inline Eigen::Vector2i GetOrderedEdge(int vidx0, int vidx1) {
1006  return Eigen::Vector2i(std::min(vidx0, vidx1), std::max(vidx0, vidx1));
1007  }
1008 
1011  std::shared_ptr<ccPointCloud> SamplePointsUniformlyImpl(
1012  size_t number_of_points,
1013  std::vector<double>& triangle_areas,
1014  double surface_area,
1015  bool use_triangle_normal,
1016  int seed);
1017 
1025  std::shared_ptr<ccPointCloud> SamplePointsUniformly(
1026  size_t number_of_points,
1027  bool use_triangle_normal = false,
1028  int seed = -1);
1029 
1041  std::shared_ptr<ccPointCloud> SamplePointsPoissonDisk(
1042  size_t number_of_points,
1043  double init_factor = 5,
1044  const std::shared_ptr<ccPointCloud> pcl_init = nullptr,
1045  bool use_triangle_normal = false,
1046  int seed = -1);
1047 
1053  std::shared_ptr<ccMesh> SubdivideMidpoint(int number_of_iterations) const;
1054 
1060  std::shared_ptr<ccMesh> SubdivideLoop(int number_of_iterations) const;
1061 
1068  std::shared_ptr<ccMesh> SimplifyVertexClustering(
1069  double voxel_size,
1070  SimplificationContraction contraction =
1071  SimplificationContraction::Average) const;
1072 
1080  std::shared_ptr<ccMesh> SimplifyQuadricDecimation(
1081  int target_number_of_triangles,
1082  double maximum_error = std::numeric_limits<double>::infinity(),
1083  double boundary_weight = 1.0) const;
1084 
1094  std::shared_ptr<ccMesh> SelectByIndex(const std::vector<size_t>& indices,
1095  bool cleanup = true) const;
1096 
1101  std::shared_ptr<ccMesh> Crop(const ccBBox& bbox) const;
1102 
1107  std::shared_ptr<ccMesh> Crop(const ecvOrientedBBox& bbox) const;
1108 
1115  std::tuple<std::vector<int>, std::vector<size_t>, std::vector<double>>
1116  ClusterConnectedTriangles() const;
1117 
1124  void RemoveTrianglesByIndex(const std::vector<size_t>& triangle_indices);
1125 
1132  void RemoveTrianglesByMask(const std::vector<bool>& triangle_mask);
1133 
1140  void RemoveVerticesByIndex(const std::vector<size_t>& vertex_indices);
1141 
1148  void RemoveVerticesByMask(const std::vector<bool>& vertex_mask);
1149 
1163  std::shared_ptr<ccMesh> DeformAsRigidAsPossible(
1164  const std::vector<int>& constraint_vertex_indices,
1165  const std::vector<Eigen::Vector3d>& constraint_vertex_positions,
1166  size_t max_iter,
1167  DeformAsRigidAsPossibleEnergy energy =
1168  DeformAsRigidAsPossibleEnergy::Spokes,
1169  double smoothed_alpha = 0.01) const;
1170 
1182  static std::shared_ptr<ccMesh> CreateFromPointCloudAlphaShape(
1183  const ccPointCloud& pcd,
1184  double alpha,
1185  std::shared_ptr<cloudViewer::geometry::TetraMesh> tetra_mesh =
1186  nullptr,
1187  std::vector<size_t>* pt_map = nullptr);
1188 
1201  static std::shared_ptr<ccMesh> CreateFromPointCloudBallPivoting(
1202  const ccPointCloud& pcd, const std::vector<double>& radii);
1203 
1240  static std::tuple<std::shared_ptr<ccMesh>, std::vector<double>>
1241  CreateFromPointCloudPoisson(const ccPointCloud& pcd,
1242  size_t depth = 8,
1243  size_t width = 0,
1244  float scale = 1.1f,
1245  bool linear_fit = false,
1246  float point_weight = 2.f,
1247  float samples_per_node = 1.5f,
1248  int boundary_type = 2 /*BOUNDARY_NEUMANN*/,
1249  int n_threads = -1);
1250 
1256  static std::shared_ptr<ccMesh> CreateTetrahedron(
1257  double radius = 1.0, bool create_uv_map = false);
1258 
1264  static std::shared_ptr<ccMesh> CreateOctahedron(double radius = 1.0,
1265  bool create_uv_map = false);
1266 
1271  static std::shared_ptr<ccMesh> CreateIcosahedron(
1272  double radius = 1.0, bool create_uv_map = false);
1273 
1279  static std::shared_ptr<ccMesh> CreatePlane(double width = 1.0,
1280  double height = 1.0,
1281  bool create_uv_map = false);
1282 
1291  static std::shared_ptr<ccMesh> CreateBox(
1292  double width = 1.0,
1293  double height = 1.0,
1294  double depth = 1.0,
1295  bool create_uv_map = false,
1296  bool map_texture_to_each_face = false);
1297 
1308  static std::shared_ptr<ccMesh> CreateSphere(double radius = 1.0,
1309  int resolution = 20,
1310  bool create_uv_map = false);
1311 
1323  static std::shared_ptr<ccMesh> CreateCylinder(double radius = 1.0,
1324  double height = 2.0,
1325  int resolution = 20,
1326  int split = 4,
1327  bool create_uv_map = false);
1328 
1339  static std::shared_ptr<ccMesh> CreateCone(double radius = 1.0,
1340  double height = 2.0,
1341  int resolution = 20,
1342  int split = 1,
1343  bool create_uv_map = false);
1344 
1355  static std::shared_ptr<ccMesh> CreateTorus(double torus_radius = 1.0,
1356  double tube_radius = 0.5,
1357  int radial_resolution = 30,
1358  int tubular_resolution = 20);
1359 
1380  static std::shared_ptr<ccMesh> CreateArrow(double cylinder_radius = 1.0,
1381  double cone_radius = 1.5,
1382  double cylinder_height = 5.0,
1383  double cone_height = 4.0,
1384  int resolution = 20,
1385  int cylinder_split = 4,
1386  int cone_split = 1);
1387 
1393  static std::shared_ptr<ccMesh> CreateCoordinateFrame(
1394  double size = 1.0,
1395  const Eigen::Vector3d& origin = Eigen::Vector3d(0.0, 0.0, 0.0));
1396 
1407  static std::shared_ptr<ccMesh> CreateMobius(int length_split = 70,
1408  int width_split = 15,
1409  int twists = 1,
1410  double radius = 1,
1411  double flatness = 1,
1412  double width = 1,
1413  double scale = 1);
1414 
1415 protected:
1416  void FilterSmoothLaplacianHelper(
1417  std::shared_ptr<ccMesh>& mesh,
1418  const std::vector<CCVector3>& prev_vertices,
1419  const std::vector<CCVector3>& prev_vertex_normals,
1420  const ColorsTableType& prev_vertex_colors,
1421  const std::vector<std::unordered_set<int>>& adjacency_list,
1422  double lambda,
1423  bool filter_vertex,
1424  bool filter_normal,
1425  bool filter_color) const;
1426 
1427 protected:
1428  // inherited from ccHObject
1429  void drawMeOnly(CC_DRAW_CONTEXT& context) override;
1430  bool toFile_MeOnly(QFile& out, short dataVersion) const override;
1431  short minimumFileVersion_MeOnly() const override;
1432  bool fromFile_MeOnly(QFile& in,
1433  short dataVersion,
1434  int flags,
1435  LoadedIDMap& oldToNewIDMap) override;
1436  void applyGLTransformation(const ccGLMatrix& trans) override;
1437  void onUpdateOf(ccHObject* obj) override;
1438  void onDeletionOf(const ccHObject* obj) override;
1439 
1443  const cloudViewer::VerticesIndexes& vertIndexes,
1444  const CCVector3& P,
1445  CCVector3d& weights) const;
1448  bool interpolateNormals(const cloudViewer::VerticesIndexes& vertIndexes,
1449  const CCVector3d& w,
1450  CCVector3& N,
1451  const Tuple3i* triNormIndexes = nullptr);
1454  bool interpolateColors(const cloudViewer::VerticesIndexes& vertIndexes,
1455  const CCVector3& P,
1456  ecvColor::Rgb& C);
1457 
1459  bool pushSubdivide(/*PointCoordinateType maxArea, */ unsigned indexA,
1460  unsigned indexB,
1461  unsigned indexC);
1462 
1463  /*** EXTENDED CALL SCRIPTS (FOR CC_SUB_MESHES) ***/
1464 
1465  // 0 parameter
1466 #define ccMesh_extended_call0(baseName, recursiveName) \
1467  inline virtual void recursiveName() { \
1468  baseName(); \
1469  for (Container::iterator it = m_children.begin(); \
1470  it != m_children.end(); ++it) \
1471  if ((*it)->isA(CV_TYPES::SUB_MESH)) \
1472  static_cast<ccGenericMesh*>(*it)->baseName(); \
1473  }
1474 
1475  // 1 parameter
1476 #define ccMesh_extended_call1(baseName, param1Type, recursiveName) \
1477  inline virtual void recursiveName(param1Type p) { \
1478  baseName(p); \
1479  for (Container::iterator it = m_children.begin(); \
1480  it != m_children.end(); ++it) \
1481  if ((*it)->isA(CV_TYPES::SUB_MESH)) \
1482  static_cast<ccGenericMesh*>(*it)->baseName(p); \
1483  }
1484 
1485  // recursive equivalents of some of ccGenericMesh methods (applied to
1486  // sub-meshes as well)
1487  ccMesh_extended_call1(showNormals, bool, showNormals_extended)
1488 
1489 
1490  ccGenericPointCloud* m_associatedCloud;
1491 
1493  NormsIndexesTableType* m_triNormals;
1494 
1497 
1499  ccMaterialSet* m_materials;
1500 
1502  triangleIndexesContainer* m_triVertIndexes;
1503 
1505  unsigned m_globalIterator;
1507  cloudViewer::SimpleRefTriangle m_currentTriangle;
1508 
1510  ccBBox m_bBox;
1511 
1513  triangleMaterialIndexesSet* m_triMtlIndexes;
1514 
1518  triangleTexCoordIndexesSet* m_texCoordIndexes;
1519 
1523  triangleNormalsIndexesSet* m_triNormalIndexes;
1524 };
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
int64_t CV_CLASS_ENUM
Type of object type flags (64 bits)
Definition: CVTypes.h:97
#define CV_DB_LIB_API
Definition: CV_db.h:15
double normal[3]
int width
int size
int height
char type
math::float4 color
double voxel_size
Definition: VoxelGridIO.cpp:28
Eigen::Vector3d origin
Definition: VoxelGridIO.cpp:26
const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2)
Definition: qcustomplot.h:611
Array of RGB colors for each point.
Array of compressed 3D normals (single index)
Array of 2D texture coordinates.
Shareable array that can be properly inserted in the DB tree.
Definition: ecvArray.h:21
Bounding box structure.
Definition: ecvBBox.h:25
virtual bool hasDisplayedScalarField() const
Returns whether an active scalar field is available or not.
virtual bool hasColors() const
Returns whether colors are enabled or not.
virtual bool normalsShown() const
Returns whether normals are shown or not.
virtual bool hasNormals() const
Returns whether normals are enabled or not.
virtual bool hasScalarFields() const
Returns whether one or more scalar fields are instantiated.
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
Generic mesh interface.
virtual bool materialsShown() const
Sets whether textures/material should be displayed or not.
virtual bool hasTextures() const =0
Returns whether textures are available for this mesh.
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
virtual void getTriangleNormalIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const =0
Returns a triplet of normal indexes for a given triangle (if any)
virtual void getTriangleTexCoordinatesIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const =0
Returns the triplet of tex coords indexes for a given triangle.
virtual bool hasTriNormals() const =0
Returns whether the mesh has per-triangle normals.
virtual bool getTriangleNormals(unsigned triangleIndex, CCVector3 &Na, CCVector3 &Nb, CCVector3 &Nc) const =0
Returns a given triangle normal.
virtual bool interpolateNormalsBC(unsigned triIndex, const CCVector3d &w, CCVector3 &N)=0
Interpolates normal(s) inside a given triangle.
virtual int getTriangleMtlIndex(unsigned triangleIndex) const =0
Returns a given triangle material indexes.
virtual void computeInterpolationWeights(unsigned triIndex, const CCVector3 &P, CCVector3d &weights) const
Returns the (barycentric) interpolation weights for a given triangle.
short minimumFileVersion_MeOnly() const override
virtual bool interpolateColors(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C)=0
Interpolates RGB colors inside a given triangle.
virtual bool getVertexColorFromMaterial(unsigned triIndex, unsigned char vertIndex, ecvColor::Rgb &C, bool returnColorIfNoTexture)=0
virtual void getTriangleTexCoordinates(unsigned triIndex, TexCoords2D *&tx1, TexCoords2D *&tx2, TexCoords2D *&tx3) const =0
Returns per-triangle texture coordinates (pointer to)
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
virtual void getTexCoordinates(unsigned index, TexCoords2D *&tx) const =0
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
void drawMeOnly(CC_DRAW_CONTEXT &context) override
Enables (OpenGL) stipple mask.
virtual unsigned capacity() const =0
Returns max capacity.
virtual void refreshBB()=0
Forces bounding-box update.
virtual bool getColorFromMaterial(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C, bool interpolateColorIfNoTexture)=0
virtual bool hasMaterials() const =0
A 3D cloud interface with associated features (color, normals, octree, etc.)
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual ecvOrientedBBox GetOrientedBoundingBox() const
Definition: ecvHObject.cpp:449
virtual ccHObject & Scale(const double s, const Eigen::Vector3d &center)
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
Definition: ecvHObject.h:176
virtual const ccGLMatrix & getGLTransformationHistory() const
Returns the transformation 'history' matrix.
Definition: ecvHObject.h:631
virtual Eigen::Vector3d GetCenter() const
Returns the center of the geometry coordinates.
Definition: ecvHObject.h:150
virtual ccHObject & Translate(const Eigen::Vector3d &translation, bool relative=true)
Apply translation to the geometry coordinates.
Definition: ecvHObject.h:165
virtual void onUpdateOf(ccHObject *obj)
This method is called when another object (geometry) is updated.
Definition: ecvHObject.h:706
virtual ccHObject & Rotate(const Eigen::Matrix3d &R, const Eigen::Vector3d &center)
Apply rotation to the geometry coordinates and normals. Given a rotation matrix , and center ,...
Definition: ecvHObject.h:186
virtual unsigned getUniqueIDForDisplay() const
Returns object unqiue ID used for display.
Definition: ecvHObject.h:626
virtual void applyGLTransformation(const ccGLMatrix &trans)
Applies a GL transformation to the entity.
Definition: ecvHObject.cpp:944
virtual Eigen::Vector3d GetMaxBound() const
Returns max bounds for geometry coordinates.
Definition: ecvHObject.h:147
virtual Eigen::Vector3d GetMinBound() const
Returns min bounds for geometry coordinates.
Definition: ecvHObject.h:144
virtual ccHObject & Transform(const Eigen::Matrix4d &transformation)
Apply transformation (4x4 matrix) to the geometry coordinates.
Definition: ecvHObject.h:157
virtual void onDeletionOf(const ccHObject *obj)
This method is called when another object is deleted.
Definition: ecvHObject.cpp:519
virtual ccBBox getOwnBB(bool withGLFeatures=false)
Returns the entity's own bounding-box.
Definition: ecvHObject.cpp:757
virtual ccBBox GetAxisAlignedBoundingBox() const
Returns an axis-aligned bounding box of the geometry.
Definition: ecvHObject.cpp:447
Mesh (triangle) material.
Triangular mesh.
Definition: ecvMesh.h:35
CV_CLASS_ENUM getClassID() const override
Returns class ID.
Definition: ecvMesh.h:63
const ccMaterialSet * getMaterialSet() const override
Definition: ecvMesh.h:412
TextureCoordsContainer * getTexCoordinatesTable() const override
Returns per-triangle texture coordinates array.
Definition: ecvMesh.h:476
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
Definition: ecvMesh.h:344
triangleIndexesContainer * getTrianglesPtr() const
Definition: ecvMesh.h:279
const triangleMaterialIndexesSet * getTriangleMtlIndexesTable() const
Returns the per-triangle material indexes array.
Definition: ecvMesh.h:454
bool hasAdjacencyList() const
Returns true if the mesh contains adjacency normals.
Definition: ecvMesh.h:712
virtual bool IsEmpty() const override
Definition: ecvMesh.h:735
void toggleMaterials() override
Toggles material display state.
Definition: ecvMesh.h:233
void addTriangles(const std::vector< Eigen::Vector3i > &triangles)
Definition: ecvMesh.h:265
std::vector< int > triangle_material_ids_
List of material ids.
Definition: ecvMesh.h:707
void addTriangle(const Eigen::Vector3i &index)
Definition: ecvMesh.h:260
std::vector< Eigen::Vector2d > triangle_uvs_
List of uv coordinates per triangle.
Definition: ecvMesh.h:625
static cloudViewer::VerticesIndexes GetOrderedTriangle(int vidx0, int vidx1, int vidx2)
Definition: ecvMesh.h:92
MESH_SCALAR_FIELD_PROCESS
Mesh scalar field processes.
Definition: ecvMesh.h:554
@ ENHANCE_MESH_SF
Definition: ecvMesh.h:556
@ SMOOTH_MESH_SF
Definition: ecvMesh.h:555
std::vector< std::unordered_set< int > > adjacency_list_
Definition: ecvMesh.h:622
void clearTriNormals()
Removes per-triangle normals.
Definition: ecvMesh.h:353
bool isSerializable() const override
Returns whether object is serializable of not.
Definition: ecvMesh.h:139
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvMesh.h:143
bool hasEigenTextures() const
Returns true if the mesh has texture.
Definition: ecvMesh.h:726
bool normalsAvailable() const override
Returns whether normals are available.
Definition: ecvMesh.h:215
bool hasPerTriangleTexCoordIndexes() const override
Returns whether this mesh as per-triangle triplets of tex coords indexes.
Definition: ecvMesh.h:484
bool HasVertices() const
Definition: ecvMesh.h:208
static Eigen::Vector3i GetEigneOrderedTriangle(int vidx0, int vidx1, int vidx2)
Definition: ecvMesh.h:965
bool HasTriangleNormals() const
Definition: ecvMesh.h:314
bool hasTriangleMaterialIds() const
Definition: ecvMesh.h:721
std::vector< cloudViewer::geometry::Image > textures_
Textures of the image.
Definition: ecvMesh.h:709
static Eigen::Vector2i GetOrderedEdge(int vidx0, int vidx1)
Helper function to get an edge with ordered vertex indices.
Definition: ecvMesh.h:1005
void shrinkToFit()
Removes unused capacity.
Definition: ecvMesh.h:302
std::vector< std::pair< std::string, Material > > materials_
Definition: ecvMesh.h:704
bool hasPerTriangleMtlIndexes() const
Returns whether this mesh as per-triangle material index.
Definition: ecvMesh.h:421
bool hasTriangleUvs() const
Definition: ecvMesh.h:717
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
Colored polyline.
Definition: ecvPolyline.h:24
A generic mesh with index-based vertex access.
virtual bool interpolateNormals(unsigned triIndex, const CCVector3 &P, CCVector3 &N)
Interpolates normal(s) inside a given triangle.
virtual GenericTriangle * _getTriangle(unsigned triangleIndex)=0
Returns the ith triangle.
virtual VerticesIndexes * getNextTriangleVertIndexes()=0
virtual VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex)=0
Returns the indexes of the vertices of a given triangle.
virtual void getTriangleVertices(unsigned triangleIndex, CCVector3 &A, CCVector3 &B, CCVector3 &C) const =0
Returns the vertices of a given triangle.
virtual unsigned size() const =0
Returns the number of triangles.
virtual void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax)=0
Returns the mesh bounding-box.
virtual GenericTriangle * _getNextTriangle()=0
Returns the next triangle (relatively to the global iterator position)
virtual void placeIteratorAtBeginning()=0
Places the mesh iterator at the beginning.
virtual void forEach(genericTriangleAction action)=0
Fast iteration mechanism.
virtual bool hasTriangles() const
Definition: GenericMesh.h:60
A generic triangle interface.
The Image class stores image with customizable width, height, num of channels and bytes per channel.
Definition: Image.h:33
RGB color structure.
Definition: ecvColorTypes.h:49
Graphical progress indicator (thread-safe)
double colors[3]
double normals[3]
unsigned int CompressedNormType
Compressed normals type.
Definition: ecvBasicTypes.h:16
#define ccMesh_extended_call1(baseName, param1Type, recursiveName)
Definition: ecvMesh.h:1476
a[190]
ImGuiContext * context
Definition: Window.cpp:76
@ MESH
Definition: CVTypes.h:105
vtkSmartPointer< vtkPolyData > CreatePlane(const pcl::ModelCoefficients &coefficients, double x, double y, double z, double scale=1)
Definition: PclTools.cpp:517
bool invertNormals(const ccHObject::Container &selectedEntities)
bool computeNormals(const ccHObject::Container &selectedEntities, QWidget *parent)
void SelectByIndex(benchmark::State &state, bool remove_duplicates, const core::Device &device)
Definition: PointCloud.cpp:149
static std::unordered_map< Edge< T >, std::vector< size_t >, utility::hash_tuple< Edge< T > > > GetEdgeToTrianglesMap(const core::Tensor &tris_cpu)
void operator+=(MiniVec< T, N > &a, const MiniVec< T, N > &b)
Definition: MiniVec.h:150
Generic file read and write utility for python interface.
TRIANGULATION_TYPES
Triangulation types.
Eigen::Matrix< Index, 3, 1 > Vector3i
Definition: knncpp.h:30
Eigen::Matrix< Index, 2, 1 > Vector2i
Definition: knncpp.h:29
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1370
unsigned char octreeLevel
std::vector< PointCoordinateType > radii
Definition: qM3C2Tools.cpp:42
2D texture coordinates
Display context.
MaterialParameter(const float v1, const float v2, const float v3, const float v4)
Definition: ecvMesh.h:638
MaterialParameter(const float v1, const float v2, const float v3)
Definition: ecvMesh.h:648
static MaterialParameter CreateRGB(const float r, const float g, const float b)
Definition: ecvMesh.h:669
MaterialParameter(const float v1)
Definition: ecvMesh.h:662
MaterialParameter(const float v1, const float v2)
Definition: ecvMesh.h:655
std::shared_ptr< cloudViewer::geometry::Image > anisotropy
Definition: ecvMesh.h:697
std::shared_ptr< cloudViewer::geometry::Image > ambientOcclusion
Definition: ecvMesh.h:691
std::shared_ptr< cloudViewer::geometry::Image > metallic
Definition: ecvMesh.h:692
std::shared_ptr< cloudViewer::geometry::Image > clearCoat
Definition: ecvMesh.h:695
std::unordered_map< std::string, MaterialParameter > floatParameters
Definition: ecvMesh.h:699
std::shared_ptr< cloudViewer::geometry::Image > reflectance
Definition: ecvMesh.h:694
MaterialParameter baseColor
Definition: ecvMesh.h:681
std::shared_ptr< cloudViewer::geometry::Image > albedo
Definition: ecvMesh.h:689
std::unordered_map< std::string, cloudViewer::geometry::Image > additionalMaps
Definition: ecvMesh.h:701
std::shared_ptr< cloudViewer::geometry::Image > clearCoatRoughness
Definition: ecvMesh.h:696
std::shared_ptr< cloudViewer::geometry::Image > roughness
Definition: ecvMesh.h:693
std::shared_ptr< cloudViewer::geometry::Image > normalMap
Definition: ecvMesh.h:690
Triangle described by the indexes of its 3 vertices.