Open3D (C++ API)
TriangleMesh.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2018 www.open3d.org
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // ----------------------------------------------------------------------------
26 
27 #pragma once
28 
29 #include <Eigen/Core>
30 #include <memory>
31 #include <unordered_map>
32 #include <unordered_set>
33 #include <vector>
34 
36 #include "Open3D/Utility/Helper.h"
37 
38 namespace open3d {
39 namespace geometry {
40 
41 class PointCloud;
42 
43 class TriangleMesh : public Geometry3D {
44 public:
53 
60  enum class FilterScope { All, Color, Normal, Vertex };
61 
63  ~TriangleMesh() override {}
64 
65 public:
66  void Clear() override;
67  bool IsEmpty() const override;
68  Eigen::Vector3d GetMinBound() const override;
69  Eigen::Vector3d GetMaxBound() const override;
70  TriangleMesh &Transform(const Eigen::Matrix4d &transformation) override;
71  TriangleMesh &Translate(const Eigen::Vector3d &translation) override;
72  TriangleMesh &Scale(const double scale, bool center = true) override;
73  TriangleMesh &Rotate(const Eigen::Vector3d &rotation,
74  bool center = true,
76 
77 public:
78  TriangleMesh &operator+=(const TriangleMesh &mesh);
79  TriangleMesh operator+(const TriangleMesh &mesh) const;
80 
82  void ComputeTriangleNormals(bool normalized = true);
83 
85  void ComputeVertexNormals(bool normalized = true);
86 
88  void ComputeAdjacencyList();
89 
92  virtual void RemoveDuplicatedVertices();
93 
96  virtual void RemoveDuplicatedTriangles();
97 
100  virtual void RemoveUnreferencedVertices();
101 
105  virtual void RemoveDegenerateTriangles();
106 
110  virtual void RemoveNonManifoldEdges();
111 
118  void FilterSharpen(int number_of_iterations,
119  double strength,
120  FilterScope scope = FilterScope::All);
121 
128  void FilterSmoothSimple(int number_of_iterations,
129  FilterScope scope = FilterScope::All);
130 
139  void FilterSmoothLaplacian(int number_of_iterations,
140  double lambda,
141  FilterScope scope = FilterScope::All);
142 
150  void FilterSmoothTaubin(int number_of_iterations,
151  double lambda = 0.5,
152  double mu = -0.53,
153  FilterScope scope = FilterScope::All);
154 
155 protected:
156  // Forward child class type to avoid indirect nonvirtual base
158 
159 public:
160  bool HasVertices() const { return vertices_.size() > 0; }
161 
162  bool HasTriangles() const {
163  return vertices_.size() > 0 && triangles_.size() > 0;
164  }
165 
166  bool HasVertexNormals() const {
167  return vertices_.size() > 0 &&
168  vertex_normals_.size() == vertices_.size();
169  }
170 
171  bool HasVertexColors() const {
172  return vertices_.size() > 0 &&
173  vertex_colors_.size() == vertices_.size();
174  }
175 
176  bool HasTriangleNormals() const {
177  return HasTriangles() && triangles_.size() == triangle_normals_.size();
178  }
179 
180  bool HasAdjacencyList() const {
181  return vertices_.size() > 0 &&
182  adjacency_list_.size() == vertices_.size();
183  }
184 
186  for (size_t i = 0; i < vertex_normals_.size(); i++) {
187  vertex_normals_[i].normalize();
188  if (std::isnan(vertex_normals_[i](0))) {
189  vertex_normals_[i] = Eigen::Vector3d(0.0, 0.0, 1.0);
190  }
191  }
192  for (size_t i = 0; i < triangle_normals_.size(); i++) {
193  triangle_normals_[i].normalize();
194  if (std::isnan(triangle_normals_[i](0))) {
195  triangle_normals_[i] = Eigen::Vector3d(0.0, 0.0, 1.0);
196  }
197  }
198  }
199 
201  void PaintUniformColor(const Eigen::Vector3d &color) {
202  vertex_colors_.resize(vertices_.size());
203  for (size_t i = 0; i < vertices_.size(); i++) {
204  vertex_colors_[i] = color;
205  }
206  }
207 
211  int EulerPoincareCharacteristic() const;
212 
216  std::vector<Eigen::Vector2i> GetNonManifoldEdges(
217  bool allow_boundary_edges = true) const;
218 
223  bool IsEdgeManifold(bool allow_boundary_edges = true) const;
224 
228  std::vector<int> GetNonManifoldVertices() const;
229 
233  bool IsVertexManifold() const;
234 
237  std::vector<Eigen::Vector2i> GetSelfIntersectingTriangles() const;
238 
241  bool IsSelfIntersecting() const;
242 
245  bool IsBoundingBoxIntersecting(const TriangleMesh &other) const;
246 
249  bool IsIntersecting(const TriangleMesh &other) const;
250 
254  bool IsOrientable() const;
255 
258  bool OrientTriangles();
259 
262  std::unordered_map<Eigen::Vector2i,
263  std::vector<int>,
265  GetEdgeToTrianglesMap() const;
266 
269  double GetTriangleArea(size_t triangle_idx) const;
270 
273  double GetSurfaceArea() const;
274 
277  double GetSurfaceArea(std::vector<double> &triangle_areas) const;
278 
281  Eigen::Vector4d GetTrianglePlane(size_t triangle_idx) const;
282 
283 public:
284  std::vector<Eigen::Vector3d> vertices_;
285  std::vector<Eigen::Vector3d> vertex_normals_;
286  std::vector<Eigen::Vector3d> vertex_colors_;
287  std::vector<Eigen::Vector3i> triangles_;
288  std::vector<Eigen::Vector3d> triangle_normals_;
289  std::vector<std::unordered_set<int>> adjacency_list_;
290 };
291 
293 double ComputeTriangleArea(const Eigen::Vector3d &p0,
294  const Eigen::Vector3d &p1,
295  const Eigen::Vector3d &p2);
296 
300 Eigen::Vector4d ComputeTrianglePlane(const Eigen::Vector3d &p0,
301  const Eigen::Vector3d &p1,
302  const Eigen::Vector3d &p2);
303 
305 std::shared_ptr<TriangleMesh> ComputeMeshConvexHull(const TriangleMesh &mesh);
306 
308 std::shared_ptr<PointCloud> SamplePointsUniformly(const TriangleMesh &input,
309  size_t number_of_points);
310 
317 std::shared_ptr<PointCloud> SamplePointsPoissonDisk(
318  const TriangleMesh &input,
319  size_t number_of_points,
320  double init_factor = 5,
321  const std::shared_ptr<PointCloud> pcl_init = nullptr);
322 
326 std::shared_ptr<TriangleMesh> SubdivideMidpoint(const TriangleMesh &input,
327  int number_of_iterations);
328 
332 std::shared_ptr<TriangleMesh> SubdivideLoop(const TriangleMesh &input,
333  int number_of_iterations);
334 
337 std::shared_ptr<TriangleMesh> SimplifyVertexClustering(
338  const TriangleMesh &input,
339  double voxel_size,
342 
345 std::shared_ptr<TriangleMesh> SimplifyQuadricDecimation(
346  const TriangleMesh &input, int target_number_of_triangles);
347 
351 std::shared_ptr<TriangleMesh> SelectDownSample(
352  const TriangleMesh &input, const std::vector<size_t> &indices);
353 
357 std::shared_ptr<TriangleMesh> CropTriangleMesh(
358  const TriangleMesh &input,
359  const Eigen::Vector3d &min_bound,
360  const Eigen::Vector3d &max_bound);
361 
365 std::shared_ptr<TriangleMesh> CreateMeshTetrahedron(double radius = 1.0);
366 
370 std::shared_ptr<TriangleMesh> CreateMeshOctahedron(double radius = 1.0);
371 
375 std::shared_ptr<TriangleMesh> CreateMeshIcosahedron(double radius = 1.0);
376 
381 std::shared_ptr<TriangleMesh> CreateMeshBox(double width = 1.0,
382  double height = 1.0,
383  double depth = 1.0);
384 
390 std::shared_ptr<TriangleMesh> CreateMeshSphere(double radius = 1.0,
391  int resolution = 20);
392 
397 std::shared_ptr<TriangleMesh> CreateMeshCylinder(double radius = 1.0,
398  double height = 2.0,
399  int resolution = 20,
400  int split = 4);
401 
406 std::shared_ptr<TriangleMesh> CreateMeshCone(double radius = 1.0,
407  double height = 2.0,
408  int resolution = 20,
409  int split = 1);
410 
416 std::shared_ptr<TriangleMesh> CreateMeshTorus(double torus_radius = 1.0,
417  double tube_radius = 0.5,
418  int radial_resolution = 30,
419  int tubular_resolution = 20);
420 
431 std::shared_ptr<TriangleMesh> CreateMeshArrow(double cylinder_radius = 1.0,
432  double cone_radius = 1.5,
433  double cylinder_height = 5.0,
434  double cone_height = 4.0,
435  int resolution = 20,
436  int cylinder_split = 4,
437  int cone_split = 1);
438 
443 std::shared_ptr<TriangleMesh> CreateMeshCoordinateFrame(
444  double size = 1.0,
445  const Eigen::Vector3d &origin = Eigen::Vector3d(0.0, 0.0, 0.0));
446 
455 std::shared_ptr<TriangleMesh> CreateMeshMoebius(int length_split = 70,
456  int width_split = 15,
457  int twists = 1,
458  double radius = 1,
459  double flatness = 1,
460  double width = 1,
461  double scale = 1);
462 
463 } // namespace geometry
464 } // namespace open3d
std::shared_ptr< TriangleMesh > CreateMeshSphere(double radius=1.0, int resolution=20)
Definition: TriangleMeshFactory.cpp:160
void ComputeVertexNormals(bool normalized=true)
Function to compute vertex normals, usually called before rendering.
Definition: TriangleMesh.cpp:228
std::vector< Eigen::Vector3d > vertex_colors_
Definition: TriangleMesh.h:286
std::shared_ptr< TriangleMesh > CreateMeshMoebius(int length_split=70, int width_split=15, int twists=1, double radius=1, double flatness=1, double width=1, double scale=1)
Definition: TriangleMeshFactory.cpp:469
bool IsSelfIntersecting() const
Definition: TriangleMesh.cpp:1242
std::vector< Eigen::Vector3i > triangles_
Definition: TriangleMesh.h:287
bool IsOrientable() const
Definition: TriangleMesh.cpp:1003
std::shared_ptr< TriangleMesh > CreateMeshOctahedron(double radius=1.0)
Definition: TriangleMeshFactory.cpp:55
virtual void RemoveDuplicatedVertices()
Definition: TriangleMesh.cpp:672
Eigen::Vector3d GetMaxBound() const override
Definition: TriangleMesh.cpp:77
void PaintUniformColor(const Eigen::Vector3d &color)
Assigns each vertex in the TriangleMesh the same color.
Definition: TriangleMesh.h:201
std::shared_ptr< TriangleMesh > CropTriangleMesh(const TriangleMesh &input, const Eigen::Vector3d &min_bound, const Eigen::Vector3d &max_bound)
Definition: DownSample.cpp:490
Definition: Helper.h:90
Definition: Geometry.h:32
std::vector< int > GetNonManifoldVertices() const
Definition: TriangleMesh.cpp:1149
void ComputeTriangleNormals(bool normalized=true)
Function to compute triangle normals, usually called before rendering.
Definition: TriangleMesh.cpp:215
std::shared_ptr< TriangleMesh > CreateMeshArrow(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)
Definition: TriangleMeshFactory.cpp:375
void Clear() override
Definition: TriangleMesh.cpp:44
virtual void RemoveDuplicatedTriangles()
Definition: TriangleMesh.cpp:714
std::vector< Eigen::Vector3d > vertices_
Definition: TriangleMesh.h:284
std::unordered_map< Eigen::Vector2i, std::vector< int >, utility::hash_eigen::hash< Eigen::Vector2i > > GetEdgeToTrianglesMap() const
Definition: TriangleMesh.cpp:1018
std::shared_ptr< TriangleMesh > ComputeMeshConvexHull(const TriangleMesh &mesh)
Function that computes the convex hull of the triangle mesh using qhull.
Definition: TriangleMesh.cpp:1273
bool IsBoundingBoxIntersecting(const TriangleMesh &other) const
Definition: TriangleMesh.cpp:1246
virtual void RemoveUnreferencedVertices()
Definition: TriangleMesh.cpp:759
TriangleMesh()
Definition: TriangleMesh.h:62
bool HasVertices() const
Definition: TriangleMesh.h:160
void FilterSmoothSimple(int number_of_iterations, FilterScope scope=FilterScope::All)
Definition: TriangleMesh.cpp:376
void FilterSharpen(int number_of_iterations, double strength, FilterScope scope=FilterScope::All)
Definition: TriangleMesh.cpp:317
Definition: TriangleMeshSimplification.cpp:42
bool IsEdgeManifold(bool allow_boundary_edges=true) const
Definition: TriangleMesh.cpp:1136
Eigen::Vector4d GetTrianglePlane(size_t triangle_idx) const
Definition: TriangleMesh.cpp:1090
bool IsEmpty() const override
Definition: TriangleMesh.cpp:53
std::shared_ptr< TriangleMesh > CreateMeshCone(double radius=1.0, double height=2.0, int resolution=20, int split=1)
Definition: TriangleMeshFactory.cpp:262
std::vector< Eigen::Vector2i > GetSelfIntersectingTriangles() const
Definition: TriangleMesh.cpp:1209
RotationType
Definition: Geometry3D.h:40
TriangleMesh & Rotate(const Eigen::Vector3d &rotation, bool center=true, RotationType type=RotationType::XYZ) override
Definition: TriangleMesh.cpp:143
TriangleMesh & operator+=(const TriangleMesh &mesh)
Definition: TriangleMesh.cpp:165
int size
Definition: FilePCD.cpp:55
void NormalizeNormals()
Definition: TriangleMesh.h:185
TriangleMesh & Scale(const double scale, bool center=true) override
Definition: TriangleMesh.cpp:130
std::shared_ptr< TriangleMesh > SimplifyVertexClustering(const TriangleMesh &input, double voxel_size, TriangleMesh::SimplificationContraction contraction=TriangleMesh::SimplificationContraction::Average)
Definition: TriangleMeshSimplification.cpp:92
bool IsVertexManifold() const
Definition: TriangleMesh.cpp:1205
FilterScope
Definition: TriangleMesh.h:60
std::shared_ptr< PointCloud > SelectDownSample(const PointCloud &input, const std::vector< size_t > &indices, bool invert)
Definition: DownSample.cpp:144
bool IsIntersecting(const TriangleMesh &other) const
Definition: TriangleMesh.cpp:1251
std::shared_ptr< PointCloud > SamplePointsUniformly(const TriangleMesh &input, size_t number_of_points, std::vector< double > &triangle_areas, double surface_area)
Definition: TriangleMesh.cpp:257
Definition: Geometry3D.h:38
double ComputeTriangleArea(const Eigen::Vector3d &p0, const Eigen::Vector3d &p1, const Eigen::Vector3d &p2)
Function that computes the area of a mesh triangle.
Definition: TriangleMesh.cpp:1037
TriangleMesh & Transform(const Eigen::Matrix4d &transformation) override
Definition: TriangleMesh.cpp:99
std::shared_ptr< TriangleMesh > CreateMeshTetrahedron(double radius=1.0)
Definition: TriangleMeshFactory.cpp:33
std::shared_ptr< TriangleMesh > CreateMeshCylinder(double radius=1.0, double height=2.0, int resolution=20, int split=4)
Definition: TriangleMeshFactory.cpp:207
virtual void RemoveDegenerateTriangles()
Definition: TriangleMesh.cpp:800
std::vector< Eigen::Vector3d > vertex_normals_
Definition: TriangleMesh.h:285
bool HasTriangles() const
Definition: TriangleMesh.h:162
TriangleMesh operator+(const TriangleMesh &mesh) const
Definition: TriangleMesh.cpp:211
std::shared_ptr< TriangleMesh > SimplifyQuadricDecimation(const TriangleMesh &input, int target_number_of_triangles)
Definition: TriangleMeshSimplification.cpp:268
std::shared_ptr< TriangleMesh > CreateMeshBox(double width=1.0, double height=1.0, double depth=1.0)
Definition: TriangleMeshFactory.cpp:120
std::shared_ptr< TriangleMesh > SubdivideLoop(const TriangleMesh &input, int number_of_iterations)
Definition: TriangleMeshSubdivide.cpp:112
bool OrientTriangles()
Definition: TriangleMesh.cpp:1008
virtual void RemoveNonManifoldEdges()
Definition: TriangleMesh.cpp:824
char type
Definition: FilePCD.cpp:56
bool HasAdjacencyList() const
Definition: TriangleMesh.h:180
std::shared_ptr< TriangleMesh > CreateMeshCoordinateFrame(double size=1.0, const Eigen::Vector3d &origin=Eigen::Vector3d(0.0, 0.0, 0.0))
Definition: TriangleMeshFactory.cpp:424
void FilterSmoothTaubin(int number_of_iterations, double lambda=0.5, double mu=-0.53, FilterScope scope=FilterScope::All)
Definition: TriangleMesh.cpp:492
Definition: PinholeCameraIntrinsic.cpp:34
double GetTriangleArea(size_t triangle_idx) const
Definition: TriangleMesh.cpp:1046
std::vector< Eigen::Vector2i > GetNonManifoldEdges(bool allow_boundary_edges=true) const
Definition: TriangleMesh.cpp:1122
GeometryType
Definition: Geometry.h:34
~TriangleMesh() override
Definition: TriangleMesh.h:63
int height
Definition: FilePCD.cpp:68
Eigen::Vector4d ComputeTrianglePlane(const Eigen::Vector3d &p0, const Eigen::Vector3d &p1, const Eigen::Vector3d &p2)
Definition: TriangleMesh.cpp:1074
int EulerPoincareCharacteristic() const
Definition: TriangleMesh.cpp:1098
std::vector< std::unordered_set< int > > adjacency_list_
Definition: TriangleMesh.h:289
std::vector< Eigen::Vector3d > triangle_normals_
Definition: TriangleMesh.h:288
bool HasVertexColors() const
Definition: TriangleMesh.h:171
bool HasVertexNormals() const
Definition: TriangleMesh.h:166
TriangleMesh(Geometry::GeometryType type)
Definition: TriangleMesh.h:157
Eigen::Vector3d GetMinBound() const override
Definition: TriangleMesh.cpp:55
bool HasTriangleNormals() const
Definition: TriangleMesh.h:176
Definition: TriangleMesh.h:43
double GetSurfaceArea() const
Definition: TriangleMesh.cpp:1054
TriangleMesh & Translate(const Eigen::Vector3d &translation) override
Definition: TriangleMesh.cpp:123
void ComputeAdjacencyList()
Function to compute adjacency list, call before adjacency list is needed.
Definition: TriangleMesh.cpp:244
std::shared_ptr< TriangleMesh > CreateMeshTorus(double torus_radius=1.0, double tube_radius=0.5, int radial_resolution=30, int tubular_resolution=20)
Definition: TriangleMeshFactory.cpp:319
std::shared_ptr< TriangleMesh > SubdivideMidpoint(const TriangleMesh &input, int number_of_iterations)
Definition: TriangleMeshSubdivide.cpp:38
std::shared_ptr< PointCloud > SamplePointsPoissonDisk(const TriangleMesh &input, size_t number_of_points, double init_factor, const std::shared_ptr< PointCloud > pcl_init)
Definition: TriangleMesh.cpp:522
std::shared_ptr< TriangleMesh > CreateMeshIcosahedron(double radius=1.0)
Definition: TriangleMeshFactory.cpp:78
void FilterSmoothLaplacian(int number_of_iterations, double lambda, FilterScope scope=FilterScope::All)
Definition: TriangleMesh.cpp:430
int width
Definition: FilePCD.cpp:67
SimplificationContraction
Definition: TriangleMesh.h:52