10 #include <Eigen/Dense>
23 std::shared_ptr<cloudViewer::geometry::TetraMesh> tetra_mesh,
24 std::vector<size_t>* pt_map) {
25 std::vector<size_t> pt_map_computed;
26 if (tetra_mesh ==
nullptr) {
28 "[CreateFromPointCloudAlphaShape] "
29 "ComputeDelaunayTetrahedralization");
30 std::tie(tetra_mesh, pt_map_computed) =
33 pt_map = &pt_map_computed;
35 "[CreateFromPointCloudAlphaShape] done "
36 "ComputeDelaunayTetrahedralization");
40 "[CreateFromPointCloudAlphaShape] init triangle mesh");
47 auto mesh = std::make_shared<ccMesh>(baseVertices);
48 mesh->addChild(baseVertices);
50 baseVertices->
addPoints(tetra_mesh->vertices_);
53 for (
size_t idx = 0; idx < (*pt_map).size(); ++idx) {
55 static_cast<unsigned>(idx),
61 for (
size_t idx = 0; idx < (*pt_map).size(); ++idx) {
63 static_cast<unsigned>(idx),
68 "[CreateFromPointCloudAlphaShape] done init triangle mesh");
70 std::vector<double> vsqn(tetra_mesh->vertices_.size());
71 for (
size_t vidx = 0; vidx < vsqn.size(); ++vidx) {
72 vsqn[vidx] = tetra_mesh->vertices_[vidx].squaredNorm();
76 "[CreateFromPointCloudAlphaShape] add triangles from tetras that "
77 "satisfy constraint");
78 const auto& verts = tetra_mesh->vertices_;
79 for (
size_t tidx = 0; tidx < tetra_mesh->tetras_.size(); ++tidx) {
80 const auto& tetra = tetra_mesh->tetras_[tidx];
83 tmp << verts[tetra(0)](0), verts[tetra(0)](1), verts[tetra(0)](2), 1,
84 verts[tetra(1)](0), verts[tetra(1)](1), verts[tetra(1)](2), 1,
85 verts[tetra(2)](0), verts[tetra(2)](1), verts[tetra(2)](2), 1,
86 verts[tetra(3)](0), verts[tetra(3)](1), verts[tetra(3)](2), 1;
87 double a = tmp.determinant();
88 tmp << vsqn[tetra(0)], verts[tetra(0)](0), verts[tetra(0)](1), verts[tetra(0)](2),
89 vsqn[tetra(1)], verts[tetra(1)](0), verts[tetra(1)](1), verts[tetra(1)](2),
90 vsqn[tetra(2)], verts[tetra(2)](0), verts[tetra(2)](1), verts[tetra(2)](2),
91 vsqn[tetra(3)], verts[tetra(3)](0), verts[tetra(3)](1), verts[tetra(3)](2);
92 double c = tmp.determinant();
93 tmp << vsqn[tetra(0)], verts[tetra(0)](1), verts[tetra(0)](2), 1,
94 vsqn[tetra(1)], verts[tetra(1)](1), verts[tetra(1)](2), 1,
95 vsqn[tetra(2)], verts[tetra(2)](1), verts[tetra(2)](2), 1,
96 vsqn[tetra(3)], verts[tetra(3)](1), verts[tetra(3)](2), 1;
97 double dx = tmp.determinant();
98 tmp << vsqn[tetra(0)], verts[tetra(0)](0), verts[tetra(0)](2), 1,
99 vsqn[tetra(1)], verts[tetra(1)](0), verts[tetra(1)](2), 1,
100 vsqn[tetra(2)], verts[tetra(2)](0), verts[tetra(2)](2), 1,
101 vsqn[tetra(3)], verts[tetra(3)](0), verts[tetra(3)](2), 1;
102 double dy = tmp.determinant();
103 tmp << vsqn[tetra(0)], verts[tetra(0)](0), verts[tetra(0)](1), 1,
104 vsqn[tetra(1)], verts[tetra(1)](0), verts[tetra(1)](1), 1,
105 vsqn[tetra(2)], verts[tetra(2)](0), verts[tetra(2)](1), 1,
106 vsqn[tetra(3)], verts[tetra(3)](0), verts[tetra(3)](1), 1;
107 double dz = tmp.determinant();
111 "[CreateFromPointCloudAlphaShape] invalid tetra in "
114 double r = std::sqrt(dx * dx + dy * dy + dz * dz - 4 *
a * c) /
129 "[CreateFromPointCloudAlphaShape] done add triangles from tetras "
130 "that satisfy constraint");
133 "[CreateFromPointCloudAlphaShape] remove triangles within "
138 for (
size_t tidx = 0; tidx < mesh->size(); ++tidx) {
140 if (triangle_count.count(triangle) == 0) {
141 triangle_count[triangle] = 1;
143 triangle_count[triangle] += 1;
148 for (
size_t tidx = 0; tidx < mesh->size(); ++tidx) {
150 if (triangle_count[triangle] == 1) {
151 mesh->setTriangle(to_idx, triangle);
155 mesh->resize(to_idx);
157 "[CreateFromPointCloudAlphaShape] done remove triangles within "
161 "[CreateFromPointCloudAlphaShape] remove duplicate triangles and "
162 "unreferenced vertices");
172 mesh->RemoveDuplicatedTriangles();
173 mesh->RemoveUnreferencedVertices();
177 "[CreateFromPointCloudAlphaShape] done remove duplicate triangles "
178 "and unreferenced vertices");
Array of compressed 3D normals (single index)
static cloudViewer::VerticesIndexes GetOrderedTriangle(int vidx0, int vidx1, int vidx2)
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 ...
virtual void setLocked(bool state)
Sets the "enabled" property.
virtual void setEnabled(bool state)
Sets the "enabled" property.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool resizeTheNormsTable()
Resizes the compressed normals array.
bool hasNormals() const override
Returns whether normals are enabled or not.
bool resizeTheRGBTable(bool fillWithWhite=false)
Resizes the RGB colors array.
bool hasColors() const override
Returns whether colors are enabled or not.
void setPointColor(size_t pointIndex, const ecvColor::Rgb &col)
Sets a particular point color.
void setPointNormal(size_t pointIndex, const CCVector3 &N)
Sets a particular point normal (shortcut)
const CCVector3 & getPointNormal(unsigned pointIndex) const override
Returns normal corresponding to a given point.
void shrinkToFit()
Removes unused capacity.
const ecvColor::Rgb & getPointColor(unsigned pointIndex) const override
Returns color corresponding to a given point.
std::vector< CCVector3 > & getPoints()
void addPoints(const std::vector< CCVector3 > &points)
static std::tuple< std::shared_ptr< TetraMesh >, std::vector< size_t > > ComputeDelaunayTetrahedralization(const std::vector< Eigen::Vector3d > &points)
Eigen::Matrix< Index, 3, 1 > Vector3i