ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
trianglemesh.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 <Image.h>
9 #include <Logging.h>
10 #include <ecvHObjectCaster.h>
11 #include <ecvMesh.h>
12 #include <ecvPointCloud.h>
13 #include <ecvPolyline.h>
14 #include <ecvTetraMesh.h>
15 
16 #include "pybind/docstring.h"
19 
20 namespace cloudViewer {
21 namespace geometry {
22 
23 void pybind_trianglemesh(py::module& m) {
24  py::native_enum<ccMesh::MESH_SCALAR_FIELD_PROCESS>(
25  m, "MeshScalarFieldProcessType", "enum.Enum",
26  "Method for mesh scalar field process.")
27  .value("SMOOTH_MESH_SF",
28  ccMesh::MESH_SCALAR_FIELD_PROCESS::SMOOTH_MESH_SF,
29  "Smooth Scalar fields.")
30  .value("ENHANCE_MESH_SF",
31  ccMesh::MESH_SCALAR_FIELD_PROCESS::ENHANCE_MESH_SF,
32  "Enhance Scalar fields.")
33  .export_values()
34  .finalize();
35 
36  py::class_<ccMesh, PyGeometry<ccMesh>, std::shared_ptr<ccMesh>,
38  trianglemesh(m, "ccMesh", py::multiple_inheritance(),
39  "ccMesh class. Triangle mesh contains vertices "
40  "and triangles represented by the indices to the "
41  "vertices. Optionally, the mesh may also contain "
42  "triangle normals, vertex normals and vertex colors.");
43  py::detail::bind_default_constructor<ccMesh>(trianglemesh);
44  py::detail::bind_copy_functions<ccMesh>(trianglemesh);
45  trianglemesh
46  .def(py::init<const std::vector<Eigen::Vector3d>&,
47  const std::vector<Eigen::Vector3i>&>(),
48  "Create a triangle mesh from vertices and triangle indices",
49  "vertices"_a, "triangles"_a)
50  .def(py::init([](std::shared_ptr<ccGenericPointCloud> cloud) {
51  if (cloud) {
52  if (!cloud->isKindOf(CV_TYPES::POINT_CLOUD)) {
53  return new ccMesh(nullptr);
54  }
55  ccPointCloud* vertices =
56  ccHObjectCaster::ToPointCloud(cloud.get());
57  return new ccMesh(vertices->cloneThis());
58  } else {
59  return new ccMesh(nullptr);
60  }
61  }),
62  "Create a triangle mesh from vertices", "cloud"_a = nullptr)
63  .def(py::init([](std::shared_ptr<cloudViewer::GenericIndexedMesh>
64  index_mesh,
65  std::shared_ptr<ccGenericPointCloud> cloud) {
66  cloudViewer::GenericIndexedMesh* indexMesh = nullptr;
67  if (index_mesh) {
68  indexMesh = index_mesh.get();
69  }
70 
71  if (cloud) {
72  if (!cloud->isKindOf(CV_TYPES::POINT_CLOUD)) {
73  return new ccMesh(indexMesh, nullptr);
74  }
75  ccPointCloud* vertices =
76  ccHObjectCaster::ToPointCloud(cloud.get());
77  return new ccMesh(indexMesh, vertices->cloneThis());
78  } else {
79  return new ccMesh(indexMesh, nullptr);
80  }
81  }),
82  "Create a triangle mesh from index_mesh and cloud",
83  "index_mesh"_a, "cloud"_a)
84  .def("__repr__",
85  [](const ccMesh& mesh) {
86  std::string info = fmt::format(
87  "ccMesh with {} points and {} triangles",
88  mesh.getVerticeSize(), mesh.size());
89 
90  if (mesh.hasEigenTextures()) {
91  info += fmt::format(", and textures of size ");
92  for (auto& tex : mesh.textures_) {
93  info += fmt::format("({}, {}) ", tex.width_,
94  tex.height_);
95  }
96  } else {
97  info += ".";
98  }
99  return info;
100  })
101  .def(py::self + py::self)
102  .def(py::self += py::self)
103  .def(
104  "clone_mesh",
105  [](ccMesh& mesh,
106  std::shared_ptr<ccGenericPointCloud> cloud) {
107  if (!cloud) {
108  return std::shared_ptr<ccMesh>(mesh.cloneMesh());
109  }
110  return std::shared_ptr<ccMesh>(
111  mesh.cloneMesh(cloud.get()));
112  },
113  "Returns a complete clone of the mesh.",
114  "cloud"_a = nullptr)
115  .def(
116  "partial_clone",
117  [](const ccMesh& mesh,
118  const std::vector<unsigned>& triangle_indices) {
119  int warnings = 0;
120  ccMesh* result =
121  mesh.partialClone(triangle_indices, &warnings);
122  if (warnings != 0) {
124  "partialClone completed with warnings: {}",
125  warnings);
126  }
127  return std::shared_ptr<ccMesh>(result);
128  },
129  "Creates a partial clone from selected triangles. "
130  "Automatically handles vertex remapping, normals, "
131  "materials, "
132  "and texture coordinates.",
133  "triangle_indices"_a)
134  .def(
135  "merge",
136  [](ccMesh& mesh, const ccMesh& input_mesh,
137  bool create_submesh) {
138  return mesh.merge(&input_mesh, create_submesh);
139  },
140  "Returns vertices number.", "input_mesh"_a,
141  "create_submesh"_a)
142  .def("clear", &ccMesh::clear, "Release internal memory.")
143  .def("shift_triangle_indexes", &ccMesh::shiftTriangleIndexes,
144  "Shifts all triangles indexes.", "shift"_a)
145  .def("reserve", &ccMesh::reserve,
146  "Reserves the memory to store the vertex indexes (3 per "
147  "triangle).",
148  "triangles_number"_a)
149  .def("resize", &ccMesh::resize,
150  "If the new number of elements is smaller than the actual "
151  "size,"
152  "the overflooding elements will be deleted.",
153  "triangles_number"_a)
154  .def("flip_triangles", &ccMesh::flipTriangles,
155  "Flips the triangle.")
156  .def("shrink_triangles", &ccMesh::shrinkToFit,
157  "Removes unused triangle capacity.")
158  .def("shrink_vertexes", &ccMesh::shrinkVertexToFit,
159  "Removes unused vertex capacity.")
160  .def("clear_triangle_normals", &ccMesh::clearTriNormals,
161  "Removes per-triangle normals.")
162  .def("are_triangle_normals_enabled",
164  "Returns whether per triangle normals are enabled.")
165  .def("reserve_triangle_normal_indexes",
167  "Reserves memory to store per-triangle triplets of normal "
168  "indexes.")
169  .def("add_triangle_normal_indexes",
171  "Adds a triplet of normal indexes for next triangle.")
172  .def("set_triangle_normal_indexes",
173  py::overload_cast<std::size_t, CompressedNormType>(
175  "Adds a triplet of normal indexes for next triangle.",
176  "triangle_index"_a, "value"_a)
177  .def("set_triangle_normal_indexes",
178  py::overload_cast<unsigned, int, int, int>(
180  "Adds a triplet of normal indexes for next triangle.",
181  "triangle_index"_a, "i1"_a, "i2"_a, "i3"_a)
182  .def("get_triangle_normal_indexes",
183  py::overload_cast<std::size_t>(
185  "Returns a compressed normal indexes for a given triangle "
186  "index (if any).",
187  "triangle_index"_a)
188  .def("remove_triangle_normal_indexes",
190  "Removes any per-triangle triplets of normal indexes.")
191  .def("convert_materials_to_vertex_colors",
193  "Converts materials to vertex colors.")
194  .def("has_material_indexes", &ccMesh::hasPerTriangleMtlIndexes,
195  "Returns whether this mesh as per-triangle material index.")
196  .def("reserve_material_indexes",
198  "Reserves memory to store per-triangle material index.")
199  .def("remove_material_indexes",
201  "Removes any per-triangle material indexes.")
202  .def("add_material_index", &ccMesh::addTriangleMtlIndex,
203  "Adds triangle material index for next triangle.",
204  "material_index"_a)
205  .def("set_material_index", &ccMesh::setTriangleMtlIndex,
206  "Adds triangle material index for next triangle.",
207  "triangle_index"_a, "material_index"_a)
208  .def("reserve_texture_coord_indexes",
210  "Reserves memory to store per-triangle triplets of tex coords "
211  "indexes.")
212  .def("remove_texture_coord_indexes",
214  "Remove per-triangle tex coords indexes.")
215  .def("add_texture_coord_indexes",
217  "Adds a triplet of tex coords indexes for next triangle.",
218  "i1"_a, "i2"_a, "i3"_a)
219  .def("set_texture_coord_indexes",
221  "Sets a triplet of tex coords indexes for a given triangle.",
222  "triangle_index"_a, "i1"_a, "i2"_a, "i3"_a)
223  .def("compute_normals", &ccMesh::computeNormals,
224  "Computes normals.", "per_vertex"_a)
225  .def(
226  "laplacian_smooth",
227  [](ccMesh& mesh, unsigned iterations,
228  PointCoordinateType factor) {
229  return mesh.laplacianSmooth(iterations, factor,
230  nullptr);
231  },
232  "Laplacian smoothing.", "iterations"_a = 100,
233  "factor"_a = 0.01f)
234  .def("process_scalar_field", &ccMesh::processScalarField,
235  "Applies process to the mesh scalar field (the one associated "
236  "to its vertices in fact).",
237  "process_type"_a)
238  .def(
239  "subdivide",
240  [](const ccMesh& mesh, PointCoordinateType max_area) {
241  return std::shared_ptr<ccMesh>(
242  mesh.subdivide(max_area));
243  },
244  "Subdivides mesh (so as to ensure that all triangles are "
245  "falls below 'max_area').",
246  "max_area"_a)
247  .def(
248  "create_mesh_from_selection",
249  [](ccMesh& mesh, bool remove_selected_faces) {
250  return std::shared_ptr<ccMesh>(
252  remove_selected_faces));
253  },
254  "Creates a new mesh with the selected vertices only.",
255  "remove_selected_faces"_a)
256  .def("swap_triangles", &ccMesh::swapTriangles,
257  "Swaps two triangles.", "first_index"_a, "second_index"_a)
258  .def("remove_triangles", &ccMesh::removeTriangles,
259  "Removes triangles.", "index"_a)
260  .def(
261  "transform_triangle_normals",
262  [](ccMesh& mesh, const Eigen::Matrix4d& transformation) {
263  mesh.transformTriNormals(
264  ccGLMatrix::FromEigenMatrix(transformation));
265  },
266  "Transforms the mesh per-triangle normals.",
267  "transformation"_a)
268  .def("get_triangle_area", &ccMesh::GetTriangleArea,
269  "Function that computes the area of a mesh triangle "
270  "identified by the triangle index.",
271  "triangle_index"_a)
272  .def("is_bbox_intersecting", &ccMesh::IsBoundingBoxIntersecting,
273  "Function that tests if the bounding boxes of the triangle "
274  "meshes are intersecting.",
275  "other"_a)
276  .def("get_edge_to_triangles_map", &ccMesh::GetEdgeToTrianglesMap,
277  "Function that returns a map from edges (vertex0, vertex1) to "
278  "the"
279  " triangle indices the given edge belongs to.")
280  .def("get_edge_to_vertices_map", &ccMesh::GetEdgeToVerticesMap,
281  "Function that returns a map from edges (vertex0, vertex1) to "
282  "the"
283  " vertex (vertex2) indices the given edge belongs to.")
284  .def("get_triangle_plane", &ccMesh::GetTrianglePlane,
285  "Function that computes the plane equation of a mesh triangle "
286  "identified by the triangle index."
287  "triangle_index"_a)
288 
289  .def("vertice_size", &ccMesh::getVerticeSize,
290  "Returns vertices number.")
291  .def(
292  "set_associated_cloud",
293  [](ccMesh& mesh, ccGenericPointCloud& cloud) {
294  if (cloud.isKindOf(CV_TYPES::POINT_CLOUD)) {
295  ccPointCloud* vertices =
297  mesh.setAssociatedCloud(vertices->cloneThis());
298  }
299  },
300  "Sets the associated vertices cloud (warning)", "cloud"_a)
301  .def("create_internal_cloud", &ccMesh::CreateInternalCloud,
302  "Sets the associated vertices cloud (warning)")
303  .def("compute_triangle_normals", &ccMesh::ComputeTriangleNormals,
304  "Function to compute triangle normals, usually called before "
305  "rendering",
306  "normalized"_a = true)
307  .def("compute_vertex_normals", &ccMesh::ComputeVertexNormals,
308  "Function to compute vertex normals, usually called before "
309  "rendering",
310  "normalized"_a = true)
311  .def("compute_adjacency_list", &ccMesh::ComputeAdjacencyList,
312  "Function to compute adjacency list, call before adjacency "
313  "list is needed")
314  .def("remove_duplicated_vertices",
316  "Function that removes duplicated verties, i.e., vertices "
317  "that have identical coordinates.")
318  .def("remove_duplicated_triangles",
320  "Function that removes duplicated triangles, i.e., removes "
321  "triangles that reference the same three vertices, "
322  "independent of their order.")
323  .def("remove_unreferenced_vertices",
325  "This function removes vertices from the triangle mesh that "
326  "are not referenced in any triangle of the mesh.")
327  .def("remove_degenerate_triangles",
329  "Function that removes degenerate triangles, i.e., triangles "
330  "that references a single vertex multiple times in a single "
331  "triangle. They are usually the product of removing "
332  "duplicated vertices.")
333  .def("remove_non_manifold_edges", &ccMesh::RemoveNonManifoldEdges,
334  "Function that removes all non-manifold edges, by "
335  "successively deleting triangles with the smallest surface "
336  "area adjacent to the non-manifold edge until the number of "
337  "adjacent triangles to the edge is `<= 2`.")
338  .def("merge_close_vertices", &ccMesh::MergeCloseVertices,
339  "Function that will merge close by vertices to a single one. "
340  "The vertex position, "
341  "normal and color will be the average of the vertices. The "
342  "parameter eps "
343  "defines the maximum distance of close by vertices. This "
344  "function might help to "
345  "close triangle soups.",
346  "eps"_a)
347  .def("filter_sharpen", &ccMesh::FilterSharpen,
348  "Function to sharpen triangle mesh. The output value "
349  "(:math:`v_o`) is the input value (:math:`v_i`) plus strength "
350  "times the input value minus he sum of he adjacent values. "
351  ":math:`v_o = v_i x strength (v_i * |N| - \\sum_{n \\in N} "
352  "v_n)`",
353  "number_of_iterations"_a = 1, "strength"_a = 1,
354  "filter_scope"_a = ccMesh::FilterScope::All)
355  .def("filter_smooth_simple", &ccMesh::FilterSmoothSimple,
356  "Function to smooth triangle mesh with simple neighbor "
357  "average. :math:`v_o = \\frac{v_i + \\sum_{n \\in N} "
358  "v_n)}{|N| + 1}`, with :math:`v_i` being the input value, "
359  ":math:`v_o` the output value, and :math:`N` is the set of "
360  "adjacent neighbours.",
361  "number_of_iterations"_a = 1,
362  "filter_scope"_a = ccMesh::FilterScope::All)
363  .def("filter_smooth_laplacian", &ccMesh::FilterSmoothLaplacian,
364  "Function to smooth triangle mesh using Laplacian. :math:`v_o "
365  "= v_i \\cdot \\lambda (sum_{n \\in N} w_n v_n - v_i)`, with "
366  ":math:`v_i` being the input value, :math:`v_o` the output "
367  "value, :math:`N` is the set of adjacent neighbours, "
368  ":math:`w_n` is the weighting of the neighbour based on the "
369  "inverse distance (closer neighbours have higher weight), and "
370  "lambda is the smoothing parameter.",
371  "number_of_iterations"_a = 1, "lambda"_a = 0.5,
372  "filter_scope"_a = ccMesh::FilterScope::All)
373  .def("filter_smooth_taubin", &ccMesh::FilterSmoothTaubin,
374  "Function to smooth triangle mesh using method of Taubin, "
375  "\"Curve and Surface Smoothing Without Shrinkage\", 1995. "
376  "Applies in each iteration two times filter_smooth_laplacian, "
377  "first with filter parameter lambda and second with filter "
378  "parameter mu as smoothing parameter. This method avoids "
379  "shrinkage of the triangle mesh.",
380  "number_of_iterations"_a = 1, "lambda"_a = 0.5, "mu"_a = -0.53,
381  "filter_scope"_a = ccMesh::FilterScope::All)
382  .def("has_vertices", &ccMesh::HasVertices,
383  "Returns ``True`` if the mesh contains vertices.")
384  .def("has_triangles", &ccMesh::hasTriangles,
385  "Returns ``True`` if the mesh contains triangles.")
386  .def("has_vertex_normals", &ccMesh::hasNormals,
387  "Returns ``True`` if the mesh contains vertex normals.")
388  .def("has_vertex_colors", &ccMesh::hasColors,
389  "Returns ``True`` if the mesh contains vertex colors.")
390  .def("set_triangle", &ccMesh::setTriangle,
391  "set triangle indices by index", "index"_a, "triangle"_a)
392  .def("get_triangle", &ccMesh::getTriangle,
393  "get triangle indices by index", "index"_a)
394  .def("triangle", &ccMesh::getTriangle,
395  "get triangle indices by index", "index"_a)
396  .def("add_triangles", &ccMesh::addTriangles,
397  "``int`` array of shape ``(num_triangles, 3)``, use "
398  "``numpy.asarray()`` to access data: List of "
399  "triangles denoted by the index of points forming "
400  "the triangle.",
401  "triangles"_a)
402  .def("set_triangles", &ccMesh::setTriangles,
403  "``int`` array of shape ``(num_triangles, 3)``, use "
404  "``numpy.asarray()`` to access data: List of "
405  "triangles denoted by the index of points forming "
406  "the triangle.",
407  "triangles"_a)
408  .def("get_triangles", &ccMesh::getTriangles,
409  "``int`` array of shape ``(num_triangles, 3)``, use "
410  "``numpy.asarray()`` to access data: List of "
411  "triangles denoted by the index of points forming "
412  "the triangle.")
413  .def("triangles", &ccMesh::getTriangles,
414  "``int`` array of shape ``(num_triangles, 3)``, use "
415  "``numpy.asarray()`` to access data: List of "
416  "triangles denoted by the index of points forming "
417  "the triangle.")
418  .def("set_triangle_normal", &ccMesh::setTriangleNorm,
419  "set triangle normal by index", "index"_a, "triangle_normal"_a)
420  .def("get_triangle_normal", &ccMesh::getTriangleNorm,
421  "get triangle indices by index", "index"_a)
422  .def("triangle_normal", &ccMesh::getTriangleNorm,
423  "get triangle indices by index", "index"_a)
424  .def("set_triangle_normals", &ccMesh::setTriangleNorms,
425  "``int`` array of shape ``(num_triangles, 3)``, use "
426  "``numpy.asarray()`` to access data: List of "
427  "triangles denoted by the index of points forming "
428  "the triangle.",
429  "triangle_normals"_a)
430  .def("get_triangle_normals", &ccMesh::getTriangleNorms,
431  "``int`` array of shape ``(num_triangles, 3)``, use "
432  "``numpy.asarray()`` to access data: List of "
433  "triangles denoted by the index of points forming "
434  "the triangle.")
435  .def("triangle_normals", &ccMesh::getTriangleNorms,
436  "``int`` array of shape ``(num_triangles, 3)``, use "
437  "``numpy.asarray()`` to access data: List of "
438  "triangles denoted by the index of points forming "
439  "the triangle.")
440  .def("set_vertice", &ccMesh::setVertice,
441  "set vertex coordinate by given index.", "index"_a,
442  "vertice"_a)
443  .def("get_vertice", &ccMesh::getVertice,
444  "get vertex coordinate by given index.", "index"_a)
445  .def("vertice", &ccMesh::getVertice,
446  "get vertex coordinate by given index.", "index"_a)
447  .def("set_vertices", &ccMesh::addEigenVertices,
448  "``float64`` array of shape ``(num_vertices, 3)``, "
449  "use ``numpy.asarray()`` to access data: Vertex "
450  "coordinates.",
451  "vertices"_a)
452  .def("get_vertices", &ccMesh::getEigenVertices,
453  "``float64`` array of shape ``(num_vertices, 3)``, "
454  "use ``numpy.asarray()`` to access data: Vertex "
455  "coordinates.")
456  .def("vertices", &ccMesh::getEigenVertices,
457  "``float64`` array of shape ``(num_vertices, 3)``, "
458  "use ``numpy.asarray()`` to access data: Vertex "
459  "coordinates.")
460  .def("set_vertex_normal", &ccMesh::setVertexNormal,
461  "set vertex normal by given index.", "index"_a, "normal"_a)
462  .def("get_vertex_normal", &ccMesh::getVertexNormal,
463  "get vertex normal by given index.", "index"_a)
464  .def("vertex_normal", &ccMesh::getVertexNormal,
465  "get vertex normal by given index.", "index"_a)
466  .def("set_vertex_normals", &ccMesh::addVertexNormals,
467  "``float64`` array of shape ``(num_vertices, 3)``, "
468  "use ``numpy.asarray()`` to access data: Vertex "
469  "normals.",
470  "normals"_a)
471  .def("get_vertex_normals", &ccMesh::getVertexNormals,
472  "``float64`` array of shape ``(num_vertices, 3)``, "
473  "use ``numpy.asarray()`` to access data: Vertex "
474  "normals.")
475  .def("vertex_normals", &ccMesh::getVertexNormals,
476  "``float64`` array of shape ``(num_vertices, 3)``, "
477  "use ``numpy.asarray()`` to access data: Vertex "
478  "normals.")
479  .def("set_vertex_color", &ccMesh::setVertexColor,
480  "set vertex color by given index.", "index"_a, "color"_a)
481  .def("get_vertex_color", &ccMesh::getVertexColor,
482  "get vertex color by given index.", "index"_a)
483  .def("vertex_color", &ccMesh::getVertexColor,
484  "get vertex color by given index.", "index"_a)
485  .def("set_vertex_colors", &ccMesh::addVertexColors,
486  "``float64`` array of shape ``(num_vertices, 3)``, "
487  "range ``[0, 1]`` , use ``numpy.asarray()`` to access "
488  "data: RGB colors of vertices.",
489  "colors"_a)
490  .def(
491  "set_vertex_colors",
492  [](ccMesh& mesh, const Eigen::Vector3d& color) {
493  ccPointCloud* vertices =
495  if (!vertices) {
496  throw std::runtime_error(
497  "empty vertex found in mesh.");
498  }
499  std::vector<Eigen::Vector3d> color_vec;
500  color_vec.resize(vertices->size(), color);
501  mesh.setVertexColors(color_vec);
502  },
503  "Sets the associated vertices cloud (warning)", "cloud"_a)
504  .def("get_vertex_colors", &ccMesh::getVertexColors,
505  "``float64`` array of shape ``(num_vertices, 3)``, "
506  "range ``[0, 1]`` , use ``numpy.asarray()`` to access "
507  "data: RGB colors of vertices.")
508  .def("vertex_colors", &ccMesh::getVertexColors,
509  "``float64`` array of shape ``(num_vertices, 3)``, "
510  "range ``[0, 1]`` , use ``numpy.asarray()`` to access "
511  "data: RGB colors of vertices.")
512  .def("has_adjacency_list", &ccMesh::hasAdjacencyList,
513  "Returns ``True`` if the mesh contains adjacency normals.")
514  .def("has_triangle_uvs", &ccMesh::hasTriangleUvs,
515  "Returns ``True`` if the mesh contains uv coordinates.")
516  .def("has_triangle_material_ids", &ccMesh::hasTriangleMaterialIds,
517  "Returns ``True`` if the mesh contains material ids.")
518  .def("has_textures", &ccMesh::hasEigenTextures,
519  "Returns ``True`` if the mesh contains a texture image.")
520  .def("normalize_normals", &ccMesh::NormalizeNormals,
521  "Normalize both triangle normals and vertex normals to length "
522  "1.")
523  .def("paint_uniform_color", &ccMesh::PaintUniformColor,
524  "Assigns each vertex in the TriangleMesh the same color.")
525  .def("euler_poincare_characteristic",
527  "Function that computes the Euler-Poincaré characteristic, "
528  "i.e., V + F - E, where V is the number of vertices, F is the "
529  "number of triangles, and E is the number of edges.")
530  .def("get_non_manifold_edges", &ccMesh::GetNonManifoldEdges,
531  "Get list of non-manifold edges.",
532  "allow_boundary_edges"_a = true)
533  .def("is_edge_manifold", &ccMesh::IsEdgeManifold,
534  "Tests if the triangle mesh is edge manifold.",
535  "allow_boundary_edges"_a = true)
536  .def("get_non_manifold_vertices", &ccMesh::GetNonManifoldVertices,
537  "Returns a list of indices to non-manifold vertices.")
538  .def("is_vertex_manifold", &ccMesh::IsVertexManifold,
539  "Tests if all vertices of the triangle mesh are manifold.")
540  .def("is_self_intersecting", &ccMesh::IsSelfIntersecting,
541  "Tests if the triangle mesh is self-intersecting.")
542  .def("get_self_intersecting_triangles",
544  "Returns a list of indices to triangles that intersect the "
545  "mesh.")
546  .def("is_intersecting", &ccMesh::IsIntersecting,
547  "Tests if the triangle mesh is intersecting the other "
548  "triangle mesh.")
549  .def("is_orientable", &ccMesh::IsOrientable,
550  "Tests if the triangle mesh is orientable.")
551  .def("is_watertight", &ccMesh::IsWatertight,
552  "Tests if the triangle mesh is watertight.")
553  .def("orient_triangles", &ccMesh::OrientTriangles,
554  "If the mesh is orientable this function orients all "
555  "triangles such that all normals point towards the same "
556  "direction.")
557  .def("select_by_index", &ccMesh::SelectByIndex,
558  "Function to select mesh from input triangle mesh into output "
559  "triangle mesh. ``input``: The input triangle mesh. "
560  "``indices``: "
561  "Indices of vertices to be selected.",
562  "indices"_a, "cleanup"_a = true)
563  .def("crop",
564  (std::shared_ptr<ccMesh>(ccMesh::*)(const ccBBox&) const) &
565  ccMesh::Crop,
566  "Function to crop input TriangleMesh into output TriangleMesh",
567  "bounding_box"_a)
568  .def("crop",
569  (std::shared_ptr<ccMesh>(ccMesh::*)(const ecvOrientedBBox&)
570  const) &
571  ccMesh::Crop,
572  "Function to crop input TriangleMesh into output TriangleMesh",
573  "bounding_box"_a)
574  .def("get_surface_area",
575  py::overload_cast<>(&ccMesh::GetSurfaceArea, py::const_),
576  "Function that computes the surface area of the mesh, i.e. "
577  "the sum of the individual triangle surfaces.")
578  .def("get_surface_area",
579  py::overload_cast<std::vector<double>&>(
580  &ccMesh::GetSurfaceArea, py::const_),
581  "Function that computes the surface area of the mesh, i.e. "
582  "the sum of the individual triangle surfaces.",
583  "triangle_areas"_a)
584  .def("get_volume", (double(ccMesh::*)() const) & ccMesh::GetVolume,
585  "Function that computes the volume of the mesh, under the "
586  "condition that it is watertight and orientable.")
587  .def("sample_points_uniformly", &ccMesh::SamplePointsUniformly,
588  "Function to uniformly sample points from the mesh.",
589  "number_of_points"_a = 100, "use_triangle_normal"_a = false,
590  "seed"_a = -1)
591  .def("sample_points_poisson_disk", &ccMesh::SamplePointsPoissonDisk,
592  "Function to sample points from the mesh, where each point "
593  "has "
594  "approximately the same distance to the neighbouring points "
595  "(blue "
596  "noise). Method is based on Yuksel, \"Sample Elimination for "
597  "Generating Poisson Disk Sample Sets\", EUROGRAPHICS, 2015.",
598  "number_of_points"_a, "init_factor"_a = 5, "pcl"_a = nullptr,
599  "use_triangle_normal"_a = false, "seed"_a = -1)
600  .def("subdivide_midpoint", &ccMesh::SubdivideMidpoint,
601  "Function subdivide mesh using midpoint algorithm.",
602  "number_of_iterations"_a = 1)
603  .def("subdivide_loop", &ccMesh::SubdivideLoop,
604  "Function subdivide mesh using Loop's algorithm. Loop, "
605  "\"Smooth "
606  "subdivision surfaces based on triangles\", 1987.",
607  "number_of_iterations"_a = 1)
608  .def("simplify_vertex_clustering",
610  "Function to simplify mesh using vertex clustering.",
611  "voxel_size"_a,
613  .def("simplify_quadric_decimation",
615  "Function to simplify mesh using Quadric Error Metric "
616  "Decimation by "
617  "Garland and Heckbert",
618  "target_number_of_triangles"_a,
619  "maximum_error"_a = std::numeric_limits<double>::infinity(),
620  "boundary_weight"_a = 1.0)
621  .def("compute_convex_hull", &ccMesh::ComputeConvexHull,
622  "Computes the convex hull of the triangle mesh.")
623  .def("cluster_connected_triangles",
625  "Function that clusters connected triangles, i.e., triangles "
626  "that are connected via edges are assigned the same cluster "
627  "index. This function retuns an array that contains the "
628  "cluster index per triangle, a second array contains the "
629  "number of triangles per cluster, and a third vector contains "
630  "the surface area per cluster.")
631  .def("remove_triangles_by_index", &ccMesh::RemoveTrianglesByIndex,
632  "This function removes the triangles with index in "
633  "triangle_indices. Call remove_unreferenced_vertices to "
634  "clean up vertices afterwards.",
635  "triangle_indices"_a)
636  .def("remove_triangles_by_mask", &ccMesh::RemoveTrianglesByMask,
637  "This function removes the triangles where triangle_mask is "
638  "set to true. Call remove_unreferenced_vertices to clean up "
639  "vertices afterwards.",
640  "triangle_mask"_a)
641  .def("remove_vertices_by_index", &ccMesh::RemoveVerticesByIndex,
642  "This function removes the vertices with index in "
643  "vertex_indices. Note that also all triangles associated with "
644  "the vertices are removed.",
645  "vertex_indices"_a)
646  .def("remove_vertices_by_mask", &ccMesh::RemoveVerticesByMask,
647  "This function removes the vertices that are masked in "
648  "vertex_mask. Note that also all triangles associated with "
649  "the vertices are removed.",
650  "vertex_mask"_a)
651  .def("deform_as_rigid_as_possible",
653  "This function deforms the mesh using the method by Sorkine "
654  "and Alexa, "
655  "'As-Rigid-As-Possible Surface Modeling', 2007",
656  "constraint_vertex_indices"_a, "constraint_vertex_positions"_a,
657  "max_iter"_a,
658  "energy"_a = cloudViewer::GenericMesh::
659  DeformAsRigidAsPossibleEnergy::Spokes,
660  "smoothed_alpha"_a = 0.01)
661  .def_static("compute_triangle_area", &ccMesh::ComputeTriangleArea,
662  "Function that computes the area of a mesh triangle.",
663  "p0"_a, "p1"_a, "p2"_a)
664  .def_static("compute_triangle_plane", &ccMesh::ComputeTrianglePlane,
665  "Function that computes the plane equation from the "
666  "three points.",
667  "p0"_a, "p1"_a, "p2"_a)
668  .def_static("get_ordered_edge", &ccMesh::GetOrderedEdge,
669  "Helper function to get an edge with ordered vertex "
670  "indices.",
671  "vidx0"_a, "vidx1"_a)
672  .def_static("get_eigne_ordered_triangle",
674  "Returns eigne ordered triangle.", "vidx0"_a, "vidx1"_a,
675  "vidx2"_a)
676  .def_static(
677  "triangulate",
678  [](ccGenericPointCloud& cloud,
680  bool update_normals, PointCoordinateType max_edge_length,
681  unsigned char dim) {
682  return std::shared_ptr<ccMesh>(ccMesh::Triangulate(
683  &cloud, type, update_normals, max_edge_length,
684  dim));
685  },
686  "Creates a Delaunay 2.5D mesh from a point cloud \n"
687  "See "
688  "cloudViewer::PointProjectionTools::computeTriangulation.",
689  "cloud"_a, "type"_a, "update_normals"_a = false,
690  "max_edge_length"_a = 0, "dim"_a = 2)
691  .def_static(
692  "triangulate_two_polylines",
693  [](ccPolyline& poly1, ccPolyline& poly2) {
694  return std::shared_ptr<ccMesh>(
696  &poly2));
697  },
698  "Creates a Delaunay 2.5D mesh from two polylines.",
699  "poly1"_a, "poly2"_a)
700  .def_static(
701  "create_from_point_cloud_alpha_shape",
702  [](const ccPointCloud& pcd, double alpha) {
704  alpha);
705  },
706  "Alpha shapes are a generalization of the convex hull. "
707  "With decreasing alpha value the shape schrinks and "
708  "creates cavities. See Edelsbrunner and Muecke, "
709  "\"Three-Dimensional Alpha Shapes\", 1994.",
710  "pcd"_a, "alpha"_a)
711  .def_static("create_from_point_cloud_alpha_shape",
713  "Alpha shapes are a generalization of the convex hull. "
714  "With decreasing alpha value the shape schrinks and "
715  "creates cavities. See Edelsbrunner and Muecke, "
716  "\"Three-Dimensional Alpha Shapes\", 1994.",
717  "pcd"_a, "alpha"_a, "tetra_mesh"_a, "pt_map"_a)
718  .def_static(
719  "create_from_point_cloud_ball_pivoting",
721  "Function that computes a triangle mesh from a oriented "
722  "PointCloud. This implements the Ball Pivoting algorithm "
723  "proposed in F. Bernardini et al., \"The ball-pivoting "
724  "algorithm for surface reconstruction\", 1999. The "
725  "implementation is also based on the algorithms outlined "
726  "in Digne, \"An Analysis and Implementation of a Parallel "
727  "Ball Pivoting Algorithm\", 2014. The surface "
728  "reconstruction is done by rolling a ball with a given "
729  "radius over the point cloud, whenever the ball touches "
730  "three points a triangle is created.",
731  "pcd"_a, "radii"_a)
732  .def_static("create_from_point_cloud_poisson",
734  "Function that computes a triangle mesh from a "
735  "oriented PointCloud pcd. This implements the Screened "
736  "Poisson Reconstruction proposed in Kazhdan and Hoppe, "
737  "\"Screened Poisson Surface Reconstruction\", 2013. "
738  "This function uses the original implementation by "
739  "Kazhdan. See https://github.com/mkazhdan/PoissonRecon",
740  "pcd"_a, "depth"_a = 8, "width"_a = 0, "scale"_a = 1.1,
741  "linear_fit"_a = false, "point_weight"_a = 2.0,
742  "samples_per_node"_a = 1.5, "boundary_type"_a = 2,
743  "n_threads"_a = -1)
744  .def_static("create_plane", &ccMesh::CreatePlane,
745  "Factory function to create a plane. The center of "
746  "the plane will be placed at (0, 0, 0).",
747  "width"_a = 1.0, "height"_a = 1.0,
748  "create_uv_map"_a = false)
749  .def_static("create_box", &ccMesh::CreateBox,
750  "Factory function to create a box. The left bottom "
751  "corner on the "
752  "front will be placed at (0, 0, 0), and default UV "
753  "map, maps the entire texture to each face.",
754  "width"_a = 1.0, "height"_a = 1.0, "depth"_a = 1.0,
755  "create_uv_map"_a = false,
756  "map_texture_to_each_face"_a = false)
757  .def_static("create_tetrahedron", &ccMesh::CreateTetrahedron,
758  "Factory function to create a tetrahedron. The "
759  "centroid of the mesh "
760  "will be placed at (0, 0, 0) and the vertices have a "
761  "distance of "
762  "radius to the center.",
763  "radius"_a = 1.0, "create_uv_map"_a = false)
764  .def_static("create_octahedron", &ccMesh::CreateOctahedron,
765  "Factory function to create a octahedron. The centroid "
766  "of the mesh "
767  "will be placed at (0, 0, 0) and the vertices have a "
768  "distance of "
769  "radius to the center.",
770  "radius"_a = 1.0, "create_uv_map"_a = false)
771  .def_static("create_icosahedron", &ccMesh::CreateIcosahedron,
772  "Factory function to create a icosahedron. The "
773  "centroid of the mesh "
774  "will be placed at (0, 0, 0) and the vertices have a "
775  "distance of "
776  "radius to the center.",
777  "radius"_a = 1.0, "create_uv_map"_a = false)
778  .def_static("create_sphere", &ccMesh::CreateSphere,
779  "Factory function to create a sphere mesh centered at "
780  "(0, 0, 0).",
781  "radius"_a = 1.0, "resolution"_a = 20,
782  "create_uv_map"_a = false)
783  .def_static("create_cylinder", &ccMesh::CreateCylinder,
784  "Factory function to create a cylinder mesh.",
785  "radius"_a = 1.0, "height"_a = 2.0, "resolution"_a = 20,
786  "split"_a = 4, "create_uv_map"_a = false)
787  .def_static("create_cone", &ccMesh::CreateCone,
788  "Factory function to create a cone mesh.",
789  "radius"_a = 1.0, "height"_a = 2.0, "resolution"_a = 20,
790  "split"_a = 1, "create_uv_map"_a = false)
791  .def_static("create_torus", &ccMesh::CreateTorus,
792  "Factory function to create a torus mesh.",
793  "torus_radius"_a = 1.0, "tube_radius"_a = 0.5,
794  "radial_resolution"_a = 30, "tubular_resolution"_a = 20)
795  .def_static("create_arrow", &ccMesh::CreateArrow,
796  "Factory function to create an arrow mesh",
797  "cylinder_radius"_a = 1.0, "cone_radius"_a = 1.5,
798  "cylinder_height"_a = 5.0, "cone_height"_a = 4.0,
799  "resolution"_a = 20, "cylinder_split"_a = 4,
800  "cone_split"_a = 1)
801  .def_static(
802  "create_coordinate_frame", &ccMesh::CreateCoordinateFrame,
803  "Factory function to create a coordinate frame mesh. "
804  "The coordinate "
805  "frame will be centered at ``origin``. The x, y, z "
806  "axis will be "
807  "rendered as red, green, and blue arrows respectively.",
808  "size"_a = 1.0, "origin"_a = Eigen::Vector3d(0.0, 0.0, 0.0))
809  .def_static("create_mobius", &ccMesh::CreateMobius,
810  "Factory function to create a Mobius strip.",
811  "length_split"_a = 70, "width_split"_a = 15,
812  "twists"_a = 1, "radius"_a = 1, "flatness"_a = 1,
813  "width"_a = 1, "scale"_a = 1)
814  .def_readwrite(
815  "adjacency_list", &ccMesh::adjacency_list_,
816  "List of Sets: The set ``adjacency_list[i]`` contains the "
817  "indices of adjacent vertices of vertex i.")
818  .def_readwrite("triangle_uvs", &ccMesh::triangle_uvs_,
819  "``float64`` array of shape ``(3 * num_triangles, "
820  "2)``, use "
821  "``numpy.asarray()`` to access data: List of "
822  "uvs denoted by the index of points forming "
823  "the triangle.")
824  .def_readwrite("triangle_material_ids",
826  "`int` array of shape ``(num_trianges, 1)``, use "
827  "``numpy.asarray()`` to access data: material index "
828  "associated with each triangle")
829  .def_readwrite("textures", &ccMesh::textures_,
830  "cloudViewer.geometry.Image: The texture images.");
831 
832  docstring::ClassMethodDocInject(m, "ccMesh", "clone_mesh");
833  docstring::ClassMethodDocInject(m, "ccMesh", "merge");
834  docstring::ClassMethodDocInject(m, "ccMesh", "clear");
835  docstring::ClassMethodDocInject(m, "ccMesh", "shift_triangle_indexes");
836  docstring::ClassMethodDocInject(m, "ccMesh", "reserve");
837  docstring::ClassMethodDocInject(m, "ccMesh", "resize");
838  docstring::ClassMethodDocInject(m, "ccMesh", "flip_triangles");
839  docstring::ClassMethodDocInject(m, "ccMesh", "shrink_triangles");
840  docstring::ClassMethodDocInject(m, "ccMesh", "shrink_vertexes");
841  docstring::ClassMethodDocInject(m, "ccMesh", "clear_triangle_normals");
843  "are_triangle_normals_enabled");
845  "reserve_triangle_normal_indexes");
846  docstring::ClassMethodDocInject(m, "ccMesh", "add_triangle_normal_indexes");
847  docstring::ClassMethodDocInject(m, "ccMesh", "set_triangle_normal_indexes");
848  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangle_normal_indexes");
850  "remove_triangle_normal_indexes");
852  "convert_materials_to_vertex_colors");
853  docstring::ClassMethodDocInject(m, "ccMesh", "has_material_indexes");
854  docstring::ClassMethodDocInject(m, "ccMesh", "reserve_material_indexes");
855  docstring::ClassMethodDocInject(m, "ccMesh", "remove_material_indexes");
856  docstring::ClassMethodDocInject(m, "ccMesh", "add_material_index");
857  docstring::ClassMethodDocInject(m, "ccMesh", "set_material_index");
859  "reserve_texture_coord_indexes");
861  "remove_texture_coord_indexes");
862  docstring::ClassMethodDocInject(m, "ccMesh", "add_texture_coord_indexes");
863  docstring::ClassMethodDocInject(m, "ccMesh", "set_texture_coord_indexes");
864  docstring::ClassMethodDocInject(m, "ccMesh", "compute_normals");
865  docstring::ClassMethodDocInject(m, "ccMesh", "laplacian_smooth");
866  docstring::ClassMethodDocInject(m, "ccMesh", "process_scalar_field");
867  docstring::ClassMethodDocInject(m, "ccMesh", "subdivide");
868  docstring::ClassMethodDocInject(m, "ccMesh", "create_mesh_from_selection");
869  docstring::ClassMethodDocInject(m, "ccMesh", "swap_triangles");
870  docstring::ClassMethodDocInject(m, "ccMesh", "remove_triangles");
871  docstring::ClassMethodDocInject(m, "ccMesh", "transform_triangle_normals");
872  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangle_area");
873  docstring::ClassMethodDocInject(m, "ccMesh", "is_bbox_intersecting");
874  docstring::ClassMethodDocInject(m, "ccMesh", "get_edge_to_triangles_map");
875  docstring::ClassMethodDocInject(m, "ccMesh", "get_edge_to_vertices_map");
876  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangle_plane");
877  docstring::ClassMethodDocInject(m, "ccMesh", "vertice_size");
878  docstring::ClassMethodDocInject(m, "ccMesh", "create_internal_cloud");
879  docstring::ClassMethodDocInject(m, "ccMesh", "set_associated_cloud");
880  docstring::ClassMethodDocInject(m, "ccMesh", "compute_adjacency_list");
881  docstring::ClassMethodDocInject(m, "ccMesh", "compute_triangle_normals");
882  docstring::ClassMethodDocInject(m, "ccMesh", "compute_vertex_normals");
883  docstring::ClassMethodDocInject(m, "ccMesh", "has_adjacency_list");
884  docstring::ClassMethodDocInject(m, "ccMesh", "set_vertices");
885  docstring::ClassMethodDocInject(m, "ccMesh", "set_vertice");
886  docstring::ClassMethodDocInject(m, "ccMesh", "vertice");
887  docstring::ClassMethodDocInject(m, "ccMesh", "get_vertice");
888  docstring::ClassMethodDocInject(m, "ccMesh", "vertices");
889  docstring::ClassMethodDocInject(m, "ccMesh", "get_vertices");
890  docstring::ClassMethodDocInject(m, "ccMesh", "set_vertex_normal");
891  docstring::ClassMethodDocInject(m, "ccMesh", "set_vertex_normals");
892  docstring::ClassMethodDocInject(m, "ccMesh", "vertex_normal");
893  docstring::ClassMethodDocInject(m, "ccMesh", "get_vertex_normal");
894  docstring::ClassMethodDocInject(m, "ccMesh", "vertex_normals");
895  docstring::ClassMethodDocInject(m, "ccMesh", "get_vertex_normals");
896  docstring::ClassMethodDocInject(m, "ccMesh", "set_vertex_colors");
897  docstring::ClassMethodDocInject(m, "ccMesh", "set_vertex_color");
898  docstring::ClassMethodDocInject(m, "ccMesh", "vertex_color");
899  docstring::ClassMethodDocInject(m, "ccMesh", "get_vertex_color");
900  docstring::ClassMethodDocInject(m, "ccMesh", "vertex_colors");
901  docstring::ClassMethodDocInject(m, "ccMesh", "get_vertex_colors");
902  docstring::ClassMethodDocInject(m, "ccMesh", "set_triangle");
903  docstring::ClassMethodDocInject(m, "ccMesh", "set_triangles");
904  docstring::ClassMethodDocInject(m, "ccMesh", "triangle");
905  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangle");
906  docstring::ClassMethodDocInject(m, "ccMesh", "triangles");
907  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangles");
908  docstring::ClassMethodDocInject(m, "ccMesh", "add_triangles");
909  docstring::ClassMethodDocInject(m, "ccMesh", "set_triangle_normal");
910  docstring::ClassMethodDocInject(m, "ccMesh", "set_triangle_normals");
911  docstring::ClassMethodDocInject(m, "ccMesh", "triangle_normal");
912  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangle_normal");
913  docstring::ClassMethodDocInject(m, "ccMesh", "triangle_normals");
914  docstring::ClassMethodDocInject(m, "ccMesh", "get_triangle_normals");
915  docstring::ClassMethodDocInject(m, "ccMesh", "has_triangles");
916  docstring::ClassMethodDocInject(m, "ccMesh", "has_triangle_uvs");
917  docstring::ClassMethodDocInject(m, "ccMesh", "has_triangle_material_ids");
918  docstring::ClassMethodDocInject(m, "ccMesh", "has_textures");
919  docstring::ClassMethodDocInject(m, "ccMesh", "has_vertex_colors");
920  docstring::ClassMethodDocInject(m, "ccMesh", "normalize_normals");
922  m, "ccMesh", "has_vertex_normals",
923  {{"normalized",
924  "Set to ``True`` to normalize the normal to length 1."}});
925  docstring::ClassMethodDocInject(m, "ccMesh", "has_vertices");
927  m, "ccMesh", "paint_uniform_color",
928  {{"color", "RGB color for the PointCloud."}});
930  "euler_poincare_characteristic");
932  m, "ccMesh", "get_non_manifold_edges",
933  {{"allow_boundary_edges",
934  "If true, than non-manifold edges are defined as edges with more "
935  "than two adjacent triangles, otherwise each edge that is not "
936  "adjacent to two triangles is defined as non-manifold."}});
938  m, "ccMesh", "is_edge_manifold",
939  {{"allow_boundary_edges",
940  "If true, than non-manifold edges are defined as edges with more "
941  "than two adjacent triangles, otherwise each edge that is not "
942  "adjacent to two triangles is defined as non-manifold."}});
943  docstring::ClassMethodDocInject(m, "ccMesh", "is_vertex_manifold");
944  docstring::ClassMethodDocInject(m, "ccMesh", "get_non_manifold_vertices");
945  docstring::ClassMethodDocInject(m, "ccMesh", "is_self_intersecting");
947  "get_self_intersecting_triangles");
949  m, "ccMesh", "is_intersecting",
950  {{"other", "Other triangle mesh to test intersection with."}});
951  docstring::ClassMethodDocInject(m, "ccMesh", "is_orientable");
952  docstring::ClassMethodDocInject(m, "ccMesh", "is_watertight");
953  docstring::ClassMethodDocInject(m, "ccMesh", "orient_triangles");
954  docstring::ClassMethodDocInject(m, "ccMesh", "remove_duplicated_vertices");
955  docstring::ClassMethodDocInject(m, "ccMesh", "remove_duplicated_triangles");
957  "remove_unreferenced_vertices");
958  docstring::ClassMethodDocInject(m, "ccMesh", "remove_degenerate_triangles");
959  docstring::ClassMethodDocInject(m, "ccMesh", "remove_non_manifold_edges");
961  m, "ccMesh", "merge_close_vertices",
962  {{"eps",
963  "Parameter that defines the distance between close vertices."}});
965  m, "ccMesh", "filter_sharpen",
966  {{"number_of_iterations",
967  " Number of repetitions of this operation"},
968  {"strength", "Filter parameter."},
969  {"scope", "Mesh property that should be filtered."}});
971  m, "ccMesh", "filter_smooth_simple",
972  {{"number_of_iterations",
973  " Number of repetitions of this operation"},
974  {"scope", "Mesh property that should be filtered."}});
976  m, "ccMesh", "filter_smooth_laplacian",
977  {{"number_of_iterations",
978  " Number of repetitions of this operation"},
979  {"lambda", "Filter parameter."},
980  {"scope", "Mesh property that should be filtered."}});
982  m, "ccMesh", "filter_smooth_taubin",
983  {{"number_of_iterations",
984  " Number of repetitions of this operation"},
985  {"lambda", "Filter parameter."},
986  {"mu", "Filter parameter."},
987  {"scope", "Mesh property that should be filtered."}});
989  m, "ccMesh", "select_by_index",
990  {{"indices", "Indices of vertices to be selected."},
991  {"cleanup",
992  "If true calls number of mesh cleanup functions to remove "
993  "unreferenced vertices and degenerate triangles"}});
995  m, "ccMesh", "crop", {{"bounding_box", "ccBBox to crop points"}});
996  docstring::ClassMethodDocInject(m, "ccMesh", "get_volume");
998  m, "ccMesh", "sample_points_uniformly",
999  {{"number_of_points",
1000  "Number of points that should be uniformly sampled."},
1001  {"use_triangle_normal",
1002  "If True assigns the triangle normals instead of the "
1003  "interpolated vertex normals to the returned points. The "
1004  "triangle normals will be computed and added to the mesh if "
1005  "necessary."},
1006  {"seed",
1007  "Seed value used in the random generator, set to -1 to use a "
1008  "random seed value with each function call."}});
1010  m, "ccMesh", "sample_points_poisson_disk",
1011  {{"number_of_points", "Number of points that should be sampled."},
1012  {"init_factor",
1013  "Factor for the initial uniformly sampled PointCloud. This init "
1014  "PointCloud is used for sample elimination."},
1015  {"pcl",
1016  "Initial PointCloud that is used for sample elimination. If this "
1017  "parameter is provided the init_factor is ignored."},
1018  {"use_triangle_normal",
1019  "If True assigns the triangle normals instead of the "
1020  "interpolated vertex normals to the returned points. The "
1021  "triangle normals will be computed and added to the mesh if "
1022  "necessary."},
1023  {"seed",
1024  "Seed value used in the random generator, set to -1 to use a "
1025  "random seed value with each function call."}});
1027  m, "ccMesh", "subdivide_midpoint",
1028  {{"number_of_iterations",
1029  "Number of iterations. A single iteration splits each triangle "
1030  "into four triangles that cover the same surface."}});
1032  m, "ccMesh", "subdivide_loop",
1033  {{"number_of_iterations",
1034  "Number of iterations. A single iteration splits each triangle "
1035  "into four triangles."}});
1037  m, "ccMesh", "simplify_vertex_clustering",
1038  {{"voxel_size",
1039  "The size of the voxel within vertices are pooled."},
1040  {"contraction",
1041  "Method to aggregate vertex information. Average computes a "
1042  "simple average, Quadric minimizes the distance to the adjacent "
1043  "planes."}});
1045  m, "ccMesh", "simplify_quadric_decimation",
1046  {{"target_number_of_triangles",
1047  "The number of triangles that the simplified mesh should have. "
1048  "It is not guranteed that this number will be reached."},
1049  {"maximum_error",
1050  "The maximum error where a vertex is allowed to be merged"},
1051  {"boundary_weight",
1052  "A weight applied to edge vertices used to preserve "
1053  "boundaries"}});
1054  docstring::ClassMethodDocInject(m, "ccMesh", "compute_convex_hull");
1055  docstring::ClassMethodDocInject(m, "ccMesh", "cluster_connected_triangles");
1057  m, "ccMesh", "remove_triangles_by_index",
1058  {{"triangle_indices",
1059  "1D array of triangle indices that should be removed from the "
1060  "TriangleMesh."}});
1061  docstring::ClassMethodDocInject(m, "ccMesh", "remove_triangles_by_mask",
1062  {{"triangle_mask",
1063  "1D bool array, True values indicate "
1064  "triangles that should be removed."}});
1066  m, "ccMesh", "remove_vertices_by_index",
1067  {{"vertex_indices",
1068  "1D array of vertex indices that should be removed from the "
1069  "TriangleMesh."}});
1070  docstring::ClassMethodDocInject(m, "ccMesh", "remove_vertices_by_mask",
1071  {{"vertex_mask",
1072  "1D bool array, True values indicate "
1073  "vertices that should be removed."}});
1075  m, "ccMesh", "deform_as_rigid_as_possible",
1076  {{"constraint_vertex_indices",
1077  "Indices of the triangle vertices that should be constrained by "
1078  "the vertex positions "
1079  "in constraint_vertex_positions."},
1080  {"constraint_vertex_positions",
1081  "Vertex positions used for the constraints."},
1082  {"max_iter",
1083  "Maximum number of iterations to minimize energy functional."},
1084  {"energy",
1085  "Energy model that is minimized in the deformation process"},
1086  {"smoothed_alpha",
1087  "trade-off parameter for the smoothed energy functional for the "
1088  "regularization term."}});
1090  m, "ccMesh", "triangulate",
1091  {{"cloud", "a point cloud."},
1092  {"type", "the triangulation strategy."},
1093  {"update_normals", "compute per-vertex normals if true."},
1094  {"max_edge_length",
1095  "max edge length for output triangles (0 = ignored)."},
1096  {"dim", "projection dimension (for axis-aligned meshes)."}});
1098  m, "ccMesh", "create_from_point_cloud_alpha_shape",
1099  {{"pcd",
1100  "PointCloud from whicht the TriangleMesh surface is "
1101  "reconstructed."},
1102  {"alpha",
1103  "Parameter to controll the shape. A very big value will give a "
1104  "shape close to the convex hull."},
1105  {"tetra_mesh",
1106  "If not None, than uses this to construct the alpha shape. "
1107  "Otherwise, TetraMesh is computed from pcd."},
1108  {"pt_map",
1109  "Optional map from tetra_mesh vertex indices to pcd points."}});
1111  m, "ccMesh", "create_from_point_cloud_ball_pivoting",
1112  {{"pcd",
1113  "PointCloud from which the TriangleMesh surface is "
1114  "reconstructed. Has to contain normals."},
1115  {"radii",
1116  "The radii of the ball that are used for the surface "
1117  "reconstruction."}});
1119  m, "ccMesh", "create_from_point_cloud_poisson",
1120  {{"pcd",
1121  "PointCloud from which the TriangleMesh surface is "
1122  "reconstructed. Has to contain normals."},
1123  {"depth",
1124  "Maximum depth of the tree that will be used for surface "
1125  "reconstruction. Running at depth d corresponds to solving on a "
1126  "grid whose resolution is no larger than 2^d x 2^d x 2^d. Note "
1127  "that since the reconstructor adapts the octree to the sampling "
1128  "density, the specified reconstruction depth is only an upper "
1129  "bound."},
1130  {"width",
1131  "Specifies the target width of the finest level octree cells. "
1132  "This parameter is ignored if depth is specified"},
1133  {"scale",
1134  "Specifies the ratio between the diameter of the cube used for "
1135  "reconstruction and the diameter of the samples' bounding cube."},
1136  {"linear_fit",
1137  "If true, the reconstructor use linear interpolation to estimate "
1138  "the positions of iso-vertices."},
1139  {"point_weight",
1140  "The importance that interpolation of the point samples "
1141  "is given in the formulation of the screened Poisson equation."
1142  "The results of the original (unscreened) Poisson Reconstruction"
1143  "can be obtained by setting this value to 0"},
1144  {"samples_per_node",
1145  "The minimum number of sample points that should fall within"
1146  "an octree node as the octree construction is adapted to "
1147  "sampling density."
1148  "This parameter specifies the minimum number of points that "
1149  "should fall"
1150  "within an octree node. For noise-free samples, small values in "
1151  "the range [1.0 - 5.0]"
1152  "can be used. For more noisy samples, larger values in the range "
1153  "[15.0 - 20.0]"
1154  "may be needed to provide a smoother, noise-reduced, "
1155  "reconstruction."},
1156  {"boundary_type", "Boundary type for the finite elements"},
1157  {"n_threads",
1158  "Number of threads used for reconstruction. Set to -1 to "
1159  "automatically determine it."}});
1160 
1162  m, "ccMesh", "create_plane",
1163  {{"width", "The width of this plane."},
1164  {"height", "The height of this plane."},
1165  {"create_uv_map", "Add default uv map to the mesh."}});
1167  m, "ccMesh", "create_box",
1168  {{"width", "x-directional length."},
1169  {"height", "y-directional length."},
1170  {"depth", "z-directional length."},
1171  {"create_uv_map", "Add default uv map to the mesh."},
1172  {"map_texture_to_each_face", "Map entire texture to each face."}});
1174  m, "ccMesh", "create_tetrahedron",
1175  {{"radius", "Distance from centroid to mesh vetices."},
1176  {"create_uv_map", "Add default uv map to the mesh."}});
1178  m, "ccMesh", "create_octahedron",
1179  {{"radius", "Distance from centroid to mesh vetices."},
1180  {"create_uv_map", "Add default uv map to the mesh."}});
1182  m, "ccMesh", "create_icosahedron",
1183  {{"radius", "Distance from centroid to mesh vetices."},
1184  {"create_uv_map", "Add default uv map to the mesh."}});
1186  m, "ccMesh", "create_sphere",
1187  {{"radius", "The radius of the sphere."},
1188  {"resolution",
1189  "The resolution of the sphere. The longitues will be split into "
1190  "``resolution`` segments (i.e. there are ``resolution + 1`` "
1191  "latitude lines including the north and south pole). The "
1192  "latitudes will be split into ```2 * resolution`` segments (i.e. "
1193  "there are ``2 * resolution`` longitude lines.)"},
1194  {"create_uv_map", "Add default uv map to the mesh."}});
1196  m, "ccMesh", "create_cylinder",
1197  {{"radius", "The radius of the cylinder."},
1198  {"height",
1199  "The height of the cylinder. The axis of the cylinder will be "
1200  "from (0, 0, -height/2) to (0, 0, height/2)."},
1201  {"resolution",
1202  " The circle will be split into ``resolution`` segments"},
1203  {"split", "The ``height`` will be split into ``split`` segments."},
1204  {"create_uv_map", "Add default uv map to the mesh."}});
1206  m, "ccMesh", "create_cone",
1207  {{"radius", "The radius of the cone."},
1208  {"height",
1209  "The height of the cone. The axis of the cone will be from (0, "
1210  "0, 0) to (0, 0, height)."},
1211  {"resolution",
1212  "The circle will be split into ``resolution`` segments"},
1213  {"split", "The ``height`` will be split into ``split`` segments."},
1214  {"create_uv_map", "Add default uv map to the mesh."}});
1216  m, "ccMesh", "create_torus",
1217  {{"torus_radius",
1218  "The radius from the center of the torus to the center of the "
1219  "tube."},
1220  {"tube_radius", "The radius of the torus tube."},
1221  {"radial_resolution",
1222  "The number of segments along the radial direction."},
1223  {"tubular_resolution",
1224  "The number of segments along the tubular direction."}});
1226  m, "ccMesh", "create_arrow",
1227  {{"cylinder_radius", "The radius of the cylinder."},
1228  {"cone_radius", "The radius of the cone."},
1229  {"cylinder_height",
1230  "The height of the cylinder. The cylinder is from (0, 0, 0) to "
1231  "(0, 0, cylinder_height)"},
1232  {"cone_height",
1233  "The height of the cone. The axis of the cone will be from (0, "
1234  "0, cylinder_height) to (0, 0, cylinder_height + cone_height)"},
1235  {"resolution",
1236  "The cone will be split into ``resolution`` segments."},
1237  {"cylinder_split",
1238  "The ``cylinder_height`` will be split into ``cylinder_split`` "
1239  "segments."},
1240  {"cone_split",
1241  "The ``cone_height`` will be split into ``cone_split`` "
1242  "segments."}});
1244  m, "ccMesh", "create_coordinate_frame",
1245  {{"size", "The size of the coordinate frame."},
1246  {"origin", "The origin of the cooridnate frame."}});
1248  m, "ccMesh", "create_mobius",
1249  {{"length_split", "The number of segments along the Mobius strip."},
1250  {"width_split",
1251  "The number of segments along the width of the Mobius strip."},
1252  {"twists", "Number of twists of the Mobius strip."},
1253  {"radius", "The radius of the Mobius strip."},
1254  {"flatness", "Controls the flatness/height of the Mobius strip."},
1255  {"width", "Width of the Mobius strip."},
1256  {"scale", "Scale the complete Mobius strip."}});
1257 }
1258 
1259 void pybind_trianglemesh_methods(py::module& m) {}
1260 
1261 } // namespace geometry
1262 } // namespace cloudViewer
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
filament::Texture::InternalFormat format
char type
math::float4 color
core::Tensor result
Definition: VtkUtils.cpp:76
Bounding box structure.
Definition: ecvBBox.h:25
static ccGLMatrixTpl< float > FromEigenMatrix(const Eigen::Matrix< double, 4, 4 > &mat)
Generic mesh interface.
A 3D cloud interface with associated features (color, normals, octree, etc.)
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
Triangular mesh.
Definition: ecvMesh.h:35
bool IsIntersecting(const ccMesh &other) const
std::shared_ptr< ccMesh > Crop(const ccBBox &bbox) const
std::shared_ptr< ccMesh > FilterSmoothLaplacian(int number_of_iterations, double lambda, FilterScope scope=FilterScope::All) const
Function to smooth triangle mesh using Laplacian.
double GetTriangleArea(size_t triangle_idx) const
static std::tuple< std::shared_ptr< ccMesh >, std::vector< double > > CreateFromPointCloudPoisson(const ccPointCloud &pcd, size_t depth=8, size_t width=0, float scale=1.1f, bool linear_fit=false, float point_weight=2.f, float samples_per_node=1.5f, int boundary_type=2, int n_threads=-1)
Function that computes a triangle mesh from a oriented PointCloud pcd. This implements the Screened P...
static std::shared_ptr< ccMesh > CreateCylinder(double radius=1.0, double height=2.0, int resolution=20, int split=4, bool create_uv_map=false)
bool merge(const ccMesh *mesh, bool createSubMesh)
Merges another mesh into this one.
std::vector< int > GetNonManifoldVertices() const
ccMesh * cloneMesh(ccGenericPointCloud *vertices=nullptr, ccMaterialSet *clonedMaterials=nullptr, NormsIndexesTableType *clonedNormsTable=nullptr, TextureCoordsContainer *cloneTexCoords=nullptr)
Clones this entity.
void addEigenVertices(const std::vector< Eigen::Vector3d > &vertices)
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)
void getTriangleNormalIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns a triplet of normal indexes for a given triangle (if any)
std::shared_ptr< ccMesh > SimplifyVertexClustering(double voxel_size, SimplificationContraction contraction=SimplificationContraction::Average) const
std::shared_ptr< ccMesh > DeformAsRigidAsPossible(const std::vector< int > &constraint_vertex_indices, const std::vector< Eigen::Vector3d > &constraint_vertex_positions, size_t max_iter, DeformAsRigidAsPossibleEnergy energy=DeformAsRigidAsPossibleEnergy::Spokes, double smoothed_alpha=0.01) const
This function deforms the mesh using the method by Sorkine and Alexa, "As-Rigid-As-Possible Surface M...
ccMesh * partialClone(const std::vector< unsigned > &triangleIndices, int *warnings=nullptr) const
Creates a new mesh from a selection of triangles (partial clone)
ccMesh & RemoveDuplicatedTriangles()
Function that removes duplicated triangles, i.e., removes triangles that reference the same three ver...
void RemoveTrianglesByMask(const std::vector< bool > &triangle_mask)
This function removes the triangles that are masked in triangle_mask. Call RemoveUnreferencedVertices...
std::shared_ptr< ccMesh > SelectByIndex(const std::vector< size_t > &indices, bool cleanup=true) const
ccMesh * subdivide(PointCoordinateType maxArea) const
bool laplacianSmooth(unsigned nbIteration=100, PointCoordinateType factor=static_cast< PointCoordinateType >(0.01), ecvProgressDialog *progressCb=nullptr)
Laplacian smoothing.
bool hasAdjacencyList() const
Returns true if the mesh contains adjacency normals.
Definition: ecvMesh.h:712
std::tuple< std::vector< int >, std::vector< size_t >, std::vector< double > > ClusterConnectedTriangles() const
Function that clusters connected triangles, i.e., triangles that are connected via edges are assigned...
bool reservePerTriangleMtlIndexes()
Reserves memory to store per-triangle material index.
void flipTriangles()
Flips the triangle.
static std::shared_ptr< ccMesh > CreateCoordinateFrame(double size=1.0, const Eigen::Vector3d &origin=Eigen::Vector3d(0.0, 0.0, 0.0))
void setVertexNormal(size_t index, const Eigen::Vector3d &normal)
std::vector< Eigen::Vector3i > getTriangles() const
bool processScalarField(MESH_SCALAR_FIELD_PROCESS process)
void addTriangles(const std::vector< Eigen::Vector3i > &triangles)
Definition: ecvMesh.h:265
bool IsVertexManifold() const
bool setTriangleNorm(size_t index, const Eigen::Vector3d &triangle_normal)
static ccMesh * TriangulateTwoPolylines(ccPolyline *p1, ccPolyline *p2, CCVector3 *projectionDir=nullptr)
Creates a Delaunay 2.5D mesh from two polylines.
void removePerTriangleNormalIndexes()
Removes any per-triangle triplets of normal indexes.
std::vector< int > triangle_material_ids_
List of material ids.
Definition: ecvMesh.h:707
std::unordered_map< Eigen::Vector2i, std::vector< int >, cloudViewer::utility::hash_eigen< Eigen::Vector2i > > GetEdgeToTrianglesMap() const
int EulerPoincareCharacteristic() const
bool OrientTriangles()
bool convertMaterialsToVertexColors()
Converts materials to vertex colors.
double GetSurfaceArea() const
void setTriangle(size_t index, const Eigen::Vector3i &triangle)
ccMesh & RemoveDuplicatedVertices()
Function that removes duplicated verties, i.e., vertices that have identical coordinates.
static std::shared_ptr< ccMesh > CreateMobius(int length_split=70, int width_split=15, int twists=1, double radius=1, double flatness=1, double width=1, double scale=1)
static std::shared_ptr< ccMesh > CreateIcosahedron(double radius=1.0, bool create_uv_map=false)
std::vector< Eigen::Vector2d > triangle_uvs_
List of uv coordinates per triangle.
Definition: ecvMesh.h:625
void transformTriNormals(const ccGLMatrix &trans)
Transforms the mesh per-triangle normals.
void swapTriangles(unsigned index1, unsigned index2)
Swaps two triangles.
bool IsSelfIntersecting() const
Eigen::Vector3d getTriangleNorm(size_t index) const
std::vector< Eigen::Vector3d > getVertexColors() const
std::shared_ptr< ccMesh > FilterSmoothTaubin(int number_of_iterations, double lambda=0.5, double mu=-0.53, FilterScope scope=FilterScope::All) const
Function to smooth triangle mesh using method of Taubin, "Curve and Surface Smoothing Without Shrinka...
ccMesh & RemoveNonManifoldEdges()
Function that removes all non-manifold edges, by successively deleting triangles with the smallest su...
bool hasColors() const override
Returns whether colors are enabled or not.
void setAssociatedCloud(ccGenericPointCloud *cloud)
Sets the associated vertices cloud (warning)
static ccMesh * Triangulate(ccGenericPointCloud *cloud, cloudViewer::TRIANGULATION_TYPES type, bool updateNormals=false, PointCoordinateType maxEdgeLength=0, unsigned char dim=2)
Creates a Delaunay 2.5D mesh from a point cloud.
std::vector< Eigen::Vector3d > getTriangleNorms() const
std::vector< std::unordered_set< int > > adjacency_list_
Definition: ecvMesh.h:622
void addTriangleMtlIndex(int mtlIndex)
Adds triangle material index for next triangle.
void setTriangleMtlIndex(unsigned triangleIndex, int mtlIndex)
Sets triangle material indexes.
std::shared_ptr< ccMesh > SubdivideMidpoint(int number_of_iterations) const
void RemoveTrianglesByIndex(const std::vector< size_t > &triangle_indices)
This function removes the triangles with index in triangle_indices. Call RemoveUnreferencedVertices t...
void clearTriNormals()
Removes per-triangle normals.
Definition: ecvMesh.h:353
static std::shared_ptr< ccMesh > CreateBox(double width=1.0, double height=1.0, double depth=1.0, bool create_uv_map=false, bool map_texture_to_each_face=false)
void setTriangles(const std::vector< Eigen::Vector3i > &triangles)
std::unordered_map< Eigen::Vector2i, std::vector< int >, cloudViewer::utility::hash_eigen< Eigen::Vector2i > > GetEdgeToVerticesMap() const
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
void shiftTriangleIndexes(unsigned shift)
Shifts all triangles indexes.
static std::shared_ptr< ccMesh > CreateTetrahedron(double radius=1.0, bool create_uv_map=false)
double GetVolume() const
bool hasEigenTextures() const
Returns true if the mesh has texture.
Definition: ecvMesh.h:726
void addVertexColors(const std::vector< Eigen::Vector3d > &colors)
void addTriangleTexCoordIndexes(int i1, int i2, int i3)
Adds a triplet of tex coords indexes for next triangle.
std::vector< Eigen::Vector2i > GetSelfIntersectingTriangles() const
static std::shared_ptr< ccMesh > CreateCone(double radius=1.0, double height=2.0, int resolution=20, int split=1, bool create_uv_map=false)
std::shared_ptr< ccMesh > SubdivideLoop(int number_of_iterations) const
bool setTriangleNormalIndexes(size_t triangleIndex, CompressedNormType value)
static std::shared_ptr< ccMesh > CreateFromPointCloudBallPivoting(const ccPointCloud &pcd, const std::vector< double > &radii)
ccMesh & RemoveUnreferencedVertices()
This function removes vertices from the triangle mesh that are not referenced in any triangle of the ...
Eigen::Vector3d getVertice(size_t index) const
static Eigen::Vector4d ComputeTrianglePlane(const Eigen::Vector3d &p0, const Eigen::Vector3d &p1, const Eigen::Vector3d &p2)
std::vector< Eigen::Vector3d > getEigenVertices() const
Eigen::Vector4d GetTrianglePlane(size_t triangle_idx) const
void removePerTriangleTexCoordIndexes()
Remove per-triangle tex coords indexes.
bool reservePerTriangleNormalIndexes()
Reserves memory to store per-triangle triplets of normal indexes.
static std::shared_ptr< ccMesh > CreatePlane(double width=1.0, double height=1.0, bool create_uv_map=false)
bool HasVertices() const
Definition: ecvMesh.h:208
static Eigen::Vector3i GetEigneOrderedTriangle(int vidx0, int vidx1, int vidx2)
Definition: ecvMesh.h:965
ccMesh & PaintUniformColor(const Eigen::Vector3d &color)
Assigns each vertex in the ccMesh the same color.
std::shared_ptr< ccMesh > SimplifyQuadricDecimation(int target_number_of_triangles, double maximum_error=std::numeric_limits< double >::infinity(), double boundary_weight=1.0) const
unsigned int getVerticeSize() const
void RemoveVerticesByIndex(const std::vector< size_t > &vertex_indices)
This function removes the vertices with index in vertex_indices. Note that also all triangles associa...
std::shared_ptr< ccPointCloud > SamplePointsPoissonDisk(size_t number_of_points, double init_factor=5, const std::shared_ptr< ccPointCloud > pcl_init=nullptr, bool use_triangle_normal=false, int seed=-1)
void removeTriangles(size_t index)
static std::shared_ptr< ccMesh > CreateFromPointCloudAlphaShape(const ccPointCloud &pcd, double alpha, std::shared_ptr< cloudViewer::geometry::TetraMesh > tetra_mesh=nullptr, std::vector< size_t > *pt_map=nullptr)
Alpha shapes are a generalization of the convex hull. With decreasing alpha value the shape schrinks ...
ccMesh & ComputeAdjacencyList()
Function to compute adjacency list, call before adjacency list is.
bool resize(size_t n)
Resizes the array of vertex indexes (3 per triangle)
void setVertexColors(const std::vector< Eigen::Vector3d > &colors)
Eigen::Vector3d getVertexColor(size_t index) const
bool arePerTriangleNormalsEnabled() const
Returns whether per triangle normals are enabled.
std::shared_ptr< ccPointCloud > SamplePointsUniformly(size_t number_of_points, bool use_triangle_normal=false, int seed=-1)
static std::shared_ptr< ccMesh > CreateSphere(double radius=1.0, int resolution=20, bool create_uv_map=false)
void addTriangleNormalIndexes(int i1, int i2, int i3)
Adds a triplet of normal indexes for next triangle.
std::tuple< std::shared_ptr< ccMesh >, std::vector< size_t > > ComputeConvexHull() const
ccMesh & RemoveDegenerateTriangles()
Function that removes degenerate triangles, i.e., triangles that reference a single vertex multiple t...
bool reservePerTriangleTexCoordIndexes()
Reserves memory to store per-triangle triplets of tex coords indexes.
void setVertexColor(size_t index, const Eigen::Vector3d &color)
ccMesh * createNewMeshFromSelection(bool removeSelectedTriangles, std::vector< int > *newIndexesOfRemainingTriangles=nullptr, bool withChildEntities=false)
Creates a new mesh with the selected vertices only.
bool IsOrientable() const
bool hasNormals() const override
Returns whether normals are enabled or not.
void clear()
static std::shared_ptr< ccMesh > CreateTorus(double torus_radius=1.0, double tube_radius=0.5, int radial_resolution=30, int tubular_resolution=20)
bool IsWatertight() const
void RemoveVerticesByMask(const std::vector< bool > &vertex_mask)
This function removes the vertices that are masked in vertex_mask. Note that also all triangles assoc...
bool IsBoundingBoxIntersecting(const ccMesh &other) const
std::vector< Eigen::Vector3d > getVertexNormals() const
void setTriangleTexCoordIndexes(unsigned triangleIndex, int i1, int i2, int i3)
Sets a triplet of tex coords indexes for a given triangle.
virtual unsigned size() const override
Returns the number of triangles.
bool IsEdgeManifold(bool allow_boundary_edges=true) const
Eigen::Vector3i getTriangle(size_t index) const
void removePerTriangleMtlIndexes()
Removes any per-triangle material indexes.
bool setTriangleNorms(const std::vector< Eigen::Vector3d > &triangle_normals)
void setVertice(size_t index, const Eigen::Vector3d &vertice)
bool hasTriangleMaterialIds() const
Definition: ecvMesh.h:721
std::shared_ptr< ccMesh > FilterSmoothSimple(int number_of_iterations, FilterScope scope=FilterScope::All) const
Function to smooth triangle mesh with simple neighbour average.
std::vector< cloudViewer::geometry::Image > textures_
Textures of the image.
Definition: ecvMesh.h:709
static double ComputeTriangleArea(const Eigen::Vector3d &p0, const Eigen::Vector3d &p1, const Eigen::Vector3d &p2)
Function that computes the area of a mesh triangle.
void shrinkVertexToFit()
ccMesh & ComputeVertexNormals(bool normalized=true)
Function to compute vertex normals, usually called before rendering.
static Eigen::Vector2i GetOrderedEdge(int vidx0, int vidx1)
Helper function to get an edge with ordered vertex indices.
Definition: ecvMesh.h:1005
Eigen::Vector3d getVertexNormal(size_t index) const
std::shared_ptr< ccMesh > FilterSharpen(int number_of_iterations, double strength, FilterScope scope=FilterScope::All) const
Function to sharpen triangle mesh.
void addVertexNormals(const std::vector< Eigen::Vector3d > &normals)
void shrinkToFit()
Removes unused capacity.
Definition: ecvMesh.h:302
ccMesh & MergeCloseVertices(double eps)
Function that will merge close by vertices to a single one. The vertex position, normal and color wil...
bool hasPerTriangleMtlIndexes() const
Returns whether this mesh as per-triangle material index.
Definition: ecvMesh.h:421
bool hasTriangleUvs() const
Definition: ecvMesh.h:717
std::vector< Eigen::Vector2i > GetNonManifoldEdges(bool allow_boundary_edges=true) const
static std::shared_ptr< ccMesh > CreateOctahedron(double radius=1.0, bool create_uv_map=false)
ccMesh & ComputeTriangleNormals(bool normalized=true)
Function to compute triangle normals, usually called before rendering.
bool computeNormals(bool perVertex)
Computes normals.
ccMesh & NormalizeNormals()
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
ccPointCloud * cloneThis(ccPointCloud *destCloud=nullptr, bool ignoreChildren=false)
Clones this entity.
Colored polyline.
Definition: ecvPolyline.h:24
A generic mesh with index-based vertex access.
virtual bool hasTriangles() const
Definition: GenericMesh.h:60
unsigned size() const override
Definition: PointCloudTpl.h:38
#define LogWarning(...)
Definition: Logging.h:72
__device__ __forceinline__ float infinity()
Definition: result_set.h:36
@ POINT_CLOUD
Definition: CVTypes.h:104
void ClassMethodDocInject(py::module &pybind_module, const std::string &class_name, const std::string &function_name, const std::unordered_map< std::string, std::string > &map_parameter_body_docs)
Definition: docstring.cpp:27
void pybind_trianglemesh_methods(py::module &m)
void pybind_trianglemesh(py::module &m)
Generic file read and write utility for python interface.
TRIANGULATION_TYPES
Triangulation types.