Open3D (C++ API)
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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  TriangleMesh &Clear() override;
67  bool IsEmpty() const override;
68  Eigen::Vector3d GetMinBound() const override;
69  Eigen::Vector3d GetMaxBound() const override;
70  Eigen::Vector3d GetCenter() const override;
73  TriangleMesh &Transform(const Eigen::Matrix4d &transformation) override;
74  TriangleMesh &Translate(const Eigen::Vector3d &translation,
75  bool relative = true) override;
76  TriangleMesh &Scale(const double scale, bool center = true) override;
77  TriangleMesh &Rotate(const Eigen::Vector3d &rotation,
78  bool center = true,
80 
81 public:
82  TriangleMesh &operator+=(const TriangleMesh &mesh);
83  TriangleMesh operator+(const TriangleMesh &mesh) const;
84 
86  TriangleMesh &ComputeTriangleNormals(bool normalized = true);
87 
89  TriangleMesh &ComputeVertexNormals(bool normalized = true);
90 
93 
97 
101 
105 
110 
115 
122  std::shared_ptr<TriangleMesh> FilterSharpen(
123  int number_of_iterations,
124  double strength,
125  FilterScope scope = FilterScope::All) const;
126 
133  std::shared_ptr<TriangleMesh> FilterSmoothSimple(
134  int number_of_iterations,
135  FilterScope scope = FilterScope::All) const;
136 
145  std::shared_ptr<TriangleMesh> FilterSmoothLaplacian(
146  int number_of_iterations,
147  double lambda,
148  FilterScope scope = FilterScope::All) const;
149 
157  std::shared_ptr<TriangleMesh> FilterSmoothTaubin(
158  int number_of_iterations,
159  double lambda = 0.5,
160  double mu = -0.53,
161  FilterScope scope = FilterScope::All) const;
162 
163  bool HasVertices() const { return vertices_.size() > 0; }
164 
165  bool HasTriangles() const {
166  return vertices_.size() > 0 && triangles_.size() > 0;
167  }
168 
169  bool HasVertexNormals() const {
170  return vertices_.size() > 0 &&
171  vertex_normals_.size() == vertices_.size();
172  }
173 
174  bool HasVertexColors() const {
175  return vertices_.size() > 0 &&
176  vertex_colors_.size() == vertices_.size();
177  }
178 
179  bool HasTriangleNormals() const {
180  return HasTriangles() && triangles_.size() == triangle_normals_.size();
181  }
182 
183  bool HasAdjacencyList() const {
184  return vertices_.size() > 0 &&
185  adjacency_list_.size() == vertices_.size();
186  }
187 
189  for (size_t i = 0; i < vertex_normals_.size(); i++) {
190  vertex_normals_[i].normalize();
191  if (std::isnan(vertex_normals_[i](0))) {
192  vertex_normals_[i] = Eigen::Vector3d(0.0, 0.0, 1.0);
193  }
194  }
195  for (size_t i = 0; i < triangle_normals_.size(); i++) {
196  triangle_normals_[i].normalize();
197  if (std::isnan(triangle_normals_[i](0))) {
198  triangle_normals_[i] = Eigen::Vector3d(0.0, 0.0, 1.0);
199  }
200  }
201  return *this;
202  }
203 
205  TriangleMesh &PaintUniformColor(const Eigen::Vector3d &color) {
207  return *this;
208  }
209 
213  int EulerPoincareCharacteristic() const;
214 
218  std::vector<Eigen::Vector2i> GetNonManifoldEdges(
219  bool allow_boundary_edges = true) const;
220 
225  bool IsEdgeManifold(bool allow_boundary_edges = true) const;
226 
230  std::vector<int> GetNonManifoldVertices() const;
231 
235  bool IsVertexManifold() const;
236 
239  std::vector<Eigen::Vector2i> GetSelfIntersectingTriangles() const;
240 
243  bool IsSelfIntersecting() const;
244 
247  bool IsBoundingBoxIntersecting(const TriangleMesh &other) const;
248 
251  bool IsIntersecting(const TriangleMesh &other) const;
252 
256  bool IsOrientable() const;
257 
261  bool IsWatertight() const;
262 
266  bool OrientTriangles();
267 
270  std::unordered_map<Eigen::Vector2i,
271  std::vector<int>,
273  GetEdgeToTrianglesMap() const;
274 
276  static double ComputeTriangleArea(const Eigen::Vector3d &p0,
277  const Eigen::Vector3d &p1,
278  const Eigen::Vector3d &p2);
279 
282  double GetTriangleArea(size_t triangle_idx) const;
283 
286  double GetSurfaceArea() const;
287 
290  double GetSurfaceArea(std::vector<double> &triangle_areas) const;
291 
295  static Eigen::Vector4d ComputeTrianglePlane(const Eigen::Vector3d &p0,
296  const Eigen::Vector3d &p1,
297  const Eigen::Vector3d &p2);
298 
301  Eigen::Vector4d GetTrianglePlane(size_t triangle_idx) const;
302 
304  std::shared_ptr<TriangleMesh> ComputeConvexHull() const;
305 
308  std::shared_ptr<PointCloud> SamplePointsUniformlyImpl(
309  size_t number_of_points,
310  std::vector<double> &triangle_areas,
311  double surface_area) const;
312 
315  std::shared_ptr<PointCloud> SamplePointsUniformly(
316  size_t number_of_points) const;
317 
324  std::shared_ptr<PointCloud> SamplePointsPoissonDisk(
325  size_t number_of_points,
326  double init_factor = 5,
327  const std::shared_ptr<PointCloud> pcl_init = nullptr) const;
328 
332  std::shared_ptr<TriangleMesh> SubdivideMidpoint(
333  int number_of_iterations) const;
334 
338  std::shared_ptr<TriangleMesh> SubdivideLoop(int number_of_iterations) const;
339 
342  std::shared_ptr<TriangleMesh> SimplifyVertexClustering(
343  double voxel_size,
346 
349  std::shared_ptr<TriangleMesh> SimplifyQuadricDecimation(
350  int target_number_of_triangles) const;
351 
355  std::shared_ptr<TriangleMesh> SelectDownSample(
356  const std::vector<size_t> &indices) const;
357 
361  std::shared_ptr<TriangleMesh> Crop(const Eigen::Vector3d &min_bound,
362  const Eigen::Vector3d &max_bound) const;
363 
373  static std::shared_ptr<TriangleMesh> CreateFromPointCloudBallPivoting(
374  const PointCloud &pcd, const std::vector<double> &radii);
375 
379  static std::shared_ptr<TriangleMesh> CreateTetrahedron(double radius = 1.0);
380 
384  static std::shared_ptr<TriangleMesh> CreateOctahedron(double radius = 1.0);
385 
389  static std::shared_ptr<TriangleMesh> CreateIcosahedron(double radius = 1.0);
390 
395  static std::shared_ptr<TriangleMesh> CreateBox(double width = 1.0,
396  double height = 1.0,
397  double depth = 1.0);
398 
404  static std::shared_ptr<TriangleMesh> CreateSphere(double radius = 1.0,
405  int resolution = 20);
406 
412  static std::shared_ptr<TriangleMesh> CreateCylinder(double radius = 1.0,
413  double height = 2.0,
414  int resolution = 20,
415  int split = 4);
416 
421  static std::shared_ptr<TriangleMesh> CreateCone(double radius = 1.0,
422  double height = 2.0,
423  int resolution = 20,
424  int split = 1);
425 
431  static std::shared_ptr<TriangleMesh> CreateTorus(
432  double torus_radius = 1.0,
433  double tube_radius = 0.5,
434  int radial_resolution = 30,
435  int tubular_resolution = 20);
436 
447  static std::shared_ptr<TriangleMesh> CreateArrow(
448  double cylinder_radius = 1.0,
449  double cone_radius = 1.5,
450  double cylinder_height = 5.0,
451  double cone_height = 4.0,
452  int resolution = 20,
453  int cylinder_split = 4,
454  int cone_split = 1);
455 
460  static std::shared_ptr<TriangleMesh> CreateCoordinateFrame(
461  double size = 1.0,
462  const Eigen::Vector3d &origin = Eigen::Vector3d(0.0, 0.0, 0.0));
463 
472  static std::shared_ptr<TriangleMesh> CreateMoebius(int length_split = 70,
473  int width_split = 15,
474  int twists = 1,
475  double radius = 1,
476  double flatness = 1,
477  double width = 1,
478  double scale = 1);
479 
480 protected:
481  // Forward child class type to avoid indirect nonvirtual base
483 
485  std::shared_ptr<TriangleMesh> &mesh,
486  const std::vector<Eigen::Vector3d> &prev_vertices,
487  const std::vector<Eigen::Vector3d> &prev_vertex_normals,
488  const std::vector<Eigen::Vector3d> &prev_vertex_colors,
489  const std::vector<std::unordered_set<int>> &adjacency_list,
490  double lambda,
491  bool filter_vertex,
492  bool filter_normal,
493  bool filter_color) const;
494 
495 public:
496  std::vector<Eigen::Vector3d> vertices_;
497  std::vector<Eigen::Vector3d> vertex_normals_;
498  std::vector<Eigen::Vector3d> vertex_colors_;
499  std::vector<Eigen::Vector3i> triangles_;
500  std::vector<Eigen::Vector3d> triangle_normals_;
501  std::vector<std::unordered_set<int>> adjacency_list_;
502 };
503 
504 } // namespace geometry
505 } // namespace open3d
static std::shared_ptr< TriangleMesh > CreateFromPointCloudBallPivoting(const PointCloud &pcd, const std::vector< double > &radii)
Definition: SurfaceReconstructionBallPivoting.cpp:748
std::vector< Eigen::Vector3d > vertex_colors_
Definition: TriangleMesh.h:498
bool IsSelfIntersecting() const
Definition: TriangleMesh.cpp:1281
std::shared_ptr< PointCloud > SamplePointsUniformlyImpl(size_t number_of_points, std::vector< double > &triangle_areas, double surface_area) const
Definition: TriangleMesh.cpp:474
std::vector< Eigen::Vector3i > triangles_
Definition: TriangleMesh.h:499
TriangleMesh & RemoveDuplicatedTriangles()
Definition: TriangleMesh.cpp:744
bool IsOrientable() const
Definition: TriangleMesh.cpp:1039
Eigen::Vector3d GetMaxBound() const override
Definition: TriangleMesh.cpp:61
Definition: Helper.h:90
std::shared_ptr< TriangleMesh > SubdivideLoop(int number_of_iterations) const
Definition: TriangleMeshSubdivide.cpp:111
std::shared_ptr< TriangleMesh > SelectDownSample(const std::vector< size_t > &indices) const
Definition: DownSample.cpp:168
Definition: Geometry.h:32
std::vector< int > GetNonManifoldVertices() const
Definition: TriangleMesh.cpp:1189
std::vector< Eigen::Vector3d > vertices_
Definition: TriangleMesh.h:496
std::shared_ptr< TriangleMesh > FilterSmoothSimple(int number_of_iterations, FilterScope scope=FilterScope::All) const
Definition: TriangleMesh.cpp:271
OrientedBoundingBox GetOrientedBoundingBox() const override
Definition: TriangleMesh.cpp:73
std::shared_ptr< TriangleMesh > ComputeConvexHull() const
Function that computes the convex hull of the triangle mesh using qhull.
Definition: TriangleMesh.cpp:1312
static std::shared_ptr< TriangleMesh > CreateMoebius(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:471
Definition: BoundingVolume.h:90
std::shared_ptr< TriangleMesh > SimplifyVertexClustering(double voxel_size, TriangleMesh::SimplificationContraction contraction=TriangleMesh::SimplificationContraction::Average) const
Definition: TriangleMeshSimplification.cpp:92
std::unordered_map< Eigen::Vector2i, std::vector< int >, utility::hash_eigen::hash< Eigen::Vector2i > > GetEdgeToTrianglesMap() const
Definition: TriangleMesh.cpp:1058
bool IsBoundingBoxIntersecting(const TriangleMesh &other) const
Definition: TriangleMesh.cpp:1285
TriangleMesh()
Definition: TriangleMesh.h:62
bool HasVertices() const
Definition: TriangleMesh.h:163
std::shared_ptr< TriangleMesh > FilterSharpen(int number_of_iterations, double strength, FilterScope scope=FilterScope::All) const
Definition: TriangleMesh.cpp:200
Definition: BoundingVolume.h:38
Definition: TriangleMeshSimplification.cpp:42
TriangleMesh & PaintUniformColor(const Eigen::Vector3d &color)
Assigns each vertex in the TriangleMesh the same color.
Definition: TriangleMesh.h:205
Definition: PointCloud.h:50
bool IsEdgeManifold(bool allow_boundary_edges=true) const
Definition: TriangleMesh.cpp:1176
TriangleMesh & ComputeVertexNormals(bool normalized=true)
Function to compute vertex normals, usually called before rendering.
Definition: TriangleMesh.cpp:169
static std::shared_ptr< TriangleMesh > CreateSphere(double radius=1.0, int resolution=20)
Definition: TriangleMeshFactory.cpp:163
static 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:1077
static std::shared_ptr< TriangleMesh > CreateBox(double width=1.0, double height=1.0, double depth=1.0)
Definition: TriangleMeshFactory.cpp:123
Eigen::Vector4d GetTrianglePlane(size_t triangle_idx) const
Definition: TriangleMesh.cpp:1130
bool IsEmpty() const override
Definition: TriangleMesh.cpp:55
static std::shared_ptr< TriangleMesh > CreateCoordinateFrame(double size=1.0, const Eigen::Vector3d &origin=Eigen::Vector3d(0.0, 0.0, 0.0))
Definition: TriangleMeshFactory.cpp:429
std::vector< Eigen::Vector2i > GetSelfIntersectingTriangles() const
Definition: TriangleMesh.cpp:1249
RotationType
Definition: Geometry3D.h:43
TriangleMesh & Rotate(const Eigen::Vector3d &rotation, bool center=true, RotationType type=RotationType::XYZ) override
Definition: TriangleMesh.cpp:95
TriangleMesh & operator+=(const TriangleMesh &mesh)
Definition: TriangleMesh.cpp:104
std::shared_ptr< TriangleMesh > FilterSmoothLaplacian(int number_of_iterations, double lambda, FilterScope scope=FilterScope::All) const
Definition: TriangleMesh.cpp:387
static std::shared_ptr< TriangleMesh > CreateCylinder(double radius=1.0, double height=2.0, int resolution=20, int split=4)
Definition: TriangleMeshFactory.cpp:210
int size
Definition: FilePCD.cpp:55
TriangleMesh & RemoveDegenerateTriangles()
Definition: TriangleMesh.cpp:834
TriangleMesh & Scale(const double scale, bool center=true) override
Definition: TriangleMesh.cpp:90
static std::shared_ptr< TriangleMesh > CreateTetrahedron(double radius=1.0)
Definition: TriangleMeshFactory.cpp:33
bool IsVertexManifold() const
Definition: TriangleMesh.cpp:1245
FilterScope
Definition: TriangleMesh.h:60
bool IsIntersecting(const TriangleMesh &other) const
Definition: TriangleMesh.cpp:1290
TriangleMesh & ComputeAdjacencyList()
Function to compute adjacency list, call before adjacency list is needed.
Definition: TriangleMesh.cpp:186
bool IsWatertight() const
Definition: TriangleMesh.cpp:1044
TriangleMesh & NormalizeNormals()
Definition: TriangleMesh.h:188
Definition: Geometry3D.h:41
TriangleMesh & Transform(const Eigen::Matrix4d &transformation) override
Definition: TriangleMesh.cpp:77
TriangleMesh & Clear() override
Definition: TriangleMesh.cpp:45
std::vector< Eigen::Vector3d > vertex_normals_
Definition: TriangleMesh.h:497
bool HasTriangles() const
Definition: TriangleMesh.h:165
TriangleMesh operator+(const TriangleMesh &mesh) const
Definition: TriangleMesh.cpp:150
static Eigen::Vector4d ComputeTrianglePlane(const Eigen::Vector3d &p0, const Eigen::Vector3d &p1, const Eigen::Vector3d &p2)
Definition: TriangleMesh.cpp:1114
bool OrientTriangles()
Definition: TriangleMesh.cpp:1048
TriangleMesh & RemoveNonManifoldEdges()
Definition: TriangleMesh.cpp:859
static std::shared_ptr< TriangleMesh > CreateTorus(double torus_radius=1.0, double tube_radius=0.5, int radial_resolution=30, int tubular_resolution=20)
Definition: TriangleMeshFactory.cpp:323
char type
Definition: FilePCD.cpp:56
std::shared_ptr< TriangleMesh > SubdivideMidpoint(int number_of_iterations) const
Definition: TriangleMeshSubdivide.cpp:38
void FilterSmoothLaplacianHelper(std::shared_ptr< TriangleMesh > &mesh, const std::vector< Eigen::Vector3d > &prev_vertices, const std::vector< Eigen::Vector3d > &prev_vertex_normals, const std::vector< Eigen::Vector3d > &prev_vertex_colors, const std::vector< std::unordered_set< int >> &adjacency_list, double lambda, bool filter_vertex, bool filter_normal, bool filter_color) const
Definition: TriangleMesh.cpp:337
static std::shared_ptr< TriangleMesh > 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)
Definition: TriangleMeshFactory.cpp:379
bool HasAdjacencyList() const
Definition: TriangleMesh.h:183
std::shared_ptr< TriangleMesh > Crop(const Eigen::Vector3d &min_bound, const Eigen::Vector3d &max_bound) const
Definition: DownSample.cpp:489
static std::shared_ptr< TriangleMesh > CreateOctahedron(double radius=1.0)
Definition: TriangleMeshFactory.cpp:56
Definition: PinholeCameraIntrinsic.cpp:34
double GetTriangleArea(size_t triangle_idx) const
Definition: TriangleMesh.cpp:1086
std::vector< Eigen::Vector2i > GetNonManifoldEdges(bool allow_boundary_edges=true) const
Definition: TriangleMesh.cpp:1162
GeometryType
Definition: Geometry.h:34
~TriangleMesh() override
Definition: TriangleMesh.h:63
std::shared_ptr< PointCloud > SamplePointsPoissonDisk(size_t number_of_points, double init_factor=5, const std::shared_ptr< PointCloud > pcl_init=nullptr) const
Definition: TriangleMesh.cpp:551
static std::shared_ptr< TriangleMesh > CreateIcosahedron(double radius=1.0)
Definition: TriangleMeshFactory.cpp:80
int height
Definition: FilePCD.cpp:68
int EulerPoincareCharacteristic() const
Definition: TriangleMesh.cpp:1138
void ResizeAndPaintUniformColor(std::vector< Eigen::Vector3d > &colors, const size_t size, const Eigen::Vector3d &color) const
Definition: Geometry3D.cpp:71
std::vector< std::unordered_set< int > > adjacency_list_
Definition: TriangleMesh.h:501
std::vector< Eigen::Vector3d > triangle_normals_
Definition: TriangleMesh.h:500
Eigen::Vector3d GetCenter() const override
Definition: TriangleMesh.cpp:65
bool HasVertexColors() const
Definition: TriangleMesh.h:174
bool HasVertexNormals() const
Definition: TriangleMesh.h:169
TriangleMesh(Geometry::GeometryType type)
Definition: TriangleMesh.h:482
Eigen::Vector3d GetMinBound() const override
Definition: TriangleMesh.cpp:57
TriangleMesh & RemoveUnreferencedVertices()
Definition: TriangleMesh.cpp:791
bool HasTriangleNormals() const
Definition: TriangleMesh.h:179
Definition: TriangleMesh.h:43
TriangleMesh & ComputeTriangleNormals(bool normalized=true)
Function to compute triangle normals, usually called before rendering.
Definition: TriangleMesh.cpp:154
TriangleMesh & RemoveDuplicatedVertices()
Definition: TriangleMesh.cpp:700
double GetSurfaceArea() const
Definition: TriangleMesh.cpp:1094
TriangleMesh & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Definition: TriangleMesh.cpp:84
AxisAlignedBoundingBox GetAxisAlignedBoundingBox() const override
Definition: TriangleMesh.cpp:69
static std::shared_ptr< TriangleMesh > CreateCone(double radius=1.0, double height=2.0, int resolution=20, int split=1)
Definition: TriangleMeshFactory.cpp:266
std::shared_ptr< TriangleMesh > SimplifyQuadricDecimation(int target_number_of_triangles) const
Definition: TriangleMeshSimplification.cpp:266
std::shared_ptr< TriangleMesh > FilterSmoothTaubin(int number_of_iterations, double lambda=0.5, double mu=-0.53, FilterScope scope=FilterScope::All) const
Definition: TriangleMesh.cpp:426
std::shared_ptr< PointCloud > SamplePointsUniformly(size_t number_of_points) const
Definition: TriangleMesh.cpp:531
int width
Definition: FilePCD.cpp:67
SimplificationContraction
Definition: TriangleMesh.h:52