MVE - Multi-View Environment mve-devel
Loading...
Searching...
No Matches
mesh_tools.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015, Simon Fuhrmann
3 * TU Darmstadt - Graphics, Capture and Massively Parallel Computing
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD 3-Clause license. See the LICENSE.txt file for details.
8 */
9
10#include <vector>
11#include <stdexcept>
12#include <algorithm>
13#include <list>
14#include <limits>
15#include <fstream>
16#include <cerrno>
17#include <cstring>
18
19#include "math/algo.h"
20#include "math/vector.h"
21#include "mve/mesh_info.h"
22#include "mve/mesh_tools.h"
23
26
28template <typename T, int D>
29struct foreach_hmatrix_mult
30{
31 typedef math::Matrix<T,D,D> MatrixType;
32 typedef math::Vector<T,D-1> VectorType;
33 typedef T ValueType;
34
35 MatrixType mat;
36 ValueType val;
37
38 foreach_hmatrix_mult (MatrixType const& matrix, ValueType const& value)
39 : mat(matrix), val(value) {}
40 void operator() (VectorType& vec) { vec = mat.mult(vec, val); }
41};
42
43/* ---------------------------------------------------------------- */
44
45void
47{
48 if (mesh == nullptr)
49 throw std::invalid_argument("Null mesh given");
50
51 mve::TriangleMesh::VertexList& verts(mesh->get_vertices());
52 mve::TriangleMesh::NormalList& vnorm(mesh->get_vertex_normals());
53 mve::TriangleMesh::NormalList& fnorm(mesh->get_face_normals());
54
56 std::for_each(verts.begin(), verts.end(), func);
57 std::for_each(fnorm.begin(), fnorm.end(), func);
58 std::for_each(vnorm.begin(), vnorm.end(), func);
59}
60
61/* ---------------------------------------------------------------- */
62
63void
65{
66 if (mesh == nullptr)
67 throw std::invalid_argument("Null mesh given");
68
69 mve::TriangleMesh::VertexList& verts(mesh->get_vertices());
70 mve::TriangleMesh::NormalList& vnorm(mesh->get_vertex_normals());
71 mve::TriangleMesh::NormalList& fnorm(mesh->get_face_normals());
72
73 foreach_hmatrix_mult<float, 4> vfunc(trans, 1.0f);
74 foreach_hmatrix_mult<float, 4> nfunc(trans, 0.0f);
75 std::for_each(verts.begin(), verts.end(), vfunc);
76 std::for_each(fnorm.begin(), fnorm.end(), nfunc);
77 std::for_each(vnorm.begin(), vnorm.end(), nfunc);
78}
79
80/* ---------------------------------------------------------------- */
81// FIXME: Find a way to abstract from the mesh attributes.
82
83void
85{
86 mve::TriangleMesh::VertexList const& verts1 = mesh1->get_vertices();
87 mve::TriangleMesh::VertexList& verts2 = mesh2->get_vertices();
88 mve::TriangleMesh::ColorList const& color1 = mesh1->get_vertex_colors();
89 mve::TriangleMesh::ColorList& color2 = mesh2->get_vertex_colors();
90 mve::TriangleMesh::ConfidenceList const& confs1 = mesh1->get_vertex_confidences();
91 mve::TriangleMesh::ConfidenceList& confs2 = mesh2->get_vertex_confidences();
92 mve::TriangleMesh::ValueList const& values1 = mesh1->get_vertex_values();
93 mve::TriangleMesh::ValueList& values2 = mesh2->get_vertex_values();
94 mve::TriangleMesh::NormalList const& vnorm1 = mesh1->get_vertex_normals();
95 mve::TriangleMesh::NormalList& vnorm2 = mesh2->get_vertex_normals();
96 mve::TriangleMesh::TexCoordList const& vtex1 = mesh1->get_vertex_texcoords();
97 mve::TriangleMesh::TexCoordList& vtex2 = mesh2->get_vertex_texcoords();
98 mve::TriangleMesh::NormalList const& fnorm1 = mesh1->get_face_normals();
99 mve::TriangleMesh::NormalList& fnorm2 = mesh2->get_face_normals();
100 mve::TriangleMesh::FaceList const& faces1 = mesh1->get_faces();
101 mve::TriangleMesh::FaceList& faces2 = mesh2->get_faces();
102
103 verts2.reserve(verts1.size() + verts2.size());
104 color2.reserve(color1.size() + color2.size());
105 confs2.reserve(confs1.size() + confs2.size());
106 values2.reserve(values1.size() + values2.size());
107 vnorm2.reserve(vnorm1.size() + vnorm2.size());
108 vtex2.reserve(vtex1.size() + vtex2.size());
109 fnorm2.reserve(fnorm1.size() + fnorm2.size());
110 faces2.reserve(faces1.size() + faces2.size());
111
112 std::size_t const offset = verts2.size();
113 verts2.insert(verts2.end(), verts1.begin(), verts1.end());
114 color2.insert(color2.end(), color1.begin(), color1.end());
115 confs2.insert(confs2.end(), confs1.begin(), confs1.end());
116 values2.insert(values2.end(), values1.begin(), values1.end());
117 vnorm2.insert(vnorm2.end(), vnorm1.begin(), vnorm1.end());
118 vtex2.insert(vtex2.end(), vtex1.begin(), vtex1.end());
119 fnorm2.insert(fnorm2.end(), fnorm1.begin(), fnorm1.end());
120
121 for (std::size_t i = 0; i < faces1.size(); ++i)
122 faces2.push_back(faces1[i] + offset);
123}
124
125/* ---------------------------------------------------------------- */
126
127void
128mesh_components (TriangleMesh::Ptr mesh, std::size_t vertex_threshold)
129{
130 MeshInfo mesh_info(mesh);
131 std::size_t const num_vertices = mesh->get_vertices().size();
132 std::vector<int> component_per_vertex(num_vertices, -1);
133 int current_component = 0;
134 for (std::size_t i = 0; i < num_vertices; ++i)
135 {
136 /* Start with a vertex that has no component yet. */
137 if (component_per_vertex[i] >= 0)
138 continue;
139
140 /* Starting from this face, collect faces and assign component ID. */
141 std::list<std::size_t> queue;
142 queue.push_back(i);
143 while (!queue.empty())
144 {
145 std::size_t vid = queue.front();
146 queue.pop_front();
147
148 /* Skip vertices with a componenet already assigned. */
149 if (component_per_vertex[vid] >= 0)
150 continue;
151 component_per_vertex[vid] = current_component;
152
153 /* Add all adjacent vertices to queue. */
154 MeshInfo::AdjacentVertices const& adj_verts = mesh_info[vid].verts;
155 queue.insert(queue.end(), adj_verts.begin(), adj_verts.end());
156 }
157 current_component += 1;
158 }
159 mesh_info.clear();
160
161 /* Create a list of components and count vertices per component. */
162 std::vector<std::size_t> components_size(current_component, 0);
163 for (std::size_t i = 0; i < component_per_vertex.size(); ++i)
164 components_size[component_per_vertex[i]] += 1;
165
166 /* Mark vertices to be deleted if part of a small component. */
167 TriangleMesh::DeleteList delete_list(num_vertices, false);
168 for (std::size_t i = 0; i < component_per_vertex.size(); ++i)
169 if (components_size[component_per_vertex[i]] <= vertex_threshold)
170 delete_list[i] = true;
171
172 /* Delete vertices and faces indexing deleted vertices. */
173 mesh->delete_vertices_fix_faces(delete_list);
174}
175
176/* ---------------------------------------------------------------- */
177
178void
179mesh_scale_and_center (TriangleMesh::Ptr mesh, bool scale, bool center)
180{
181 if (mesh == nullptr)
182 throw std::invalid_argument("Null mesh given");
183
184 TriangleMesh::VertexList& verts(mesh->get_vertices());
185
186 if (verts.empty() || (!scale && !center))
187 return;
188
189 /* Calculate the AABB of the model. */
190 math::Vec3f min(std::numeric_limits<float>::max());
191 math::Vec3f max(-std::numeric_limits<float>::max());
192 for (std::size_t i = 0; i < verts.size(); ++i)
193 for (std::size_t j = 0; j < 3; ++j)
194 {
195 min[j] = std::min(min[j], verts[i][j]);
196 max[j] = std::max(max[j], verts[i][j]);
197 }
198
199 math::Vec3f move((min + max) / 2.0);
200
201 /* Prepare scaling of model to fit in the einheits cube. */
202 math::Vec3f sizes(max - min);
203 float max_xyz = sizes.maximum();
204
205 /* Translate and scale. */
206 if (scale && center)
207 {
208 for (std::size_t i = 0; i < verts.size(); ++i)
209 verts[i] = (verts[i] - move) / max_xyz;
210 }
211 else if (scale && !center)
212 {
213 for (std::size_t i = 0; i < verts.size(); ++i)
214 verts[i] /= max_xyz;
215 }
216 else if (!scale && center)
217 {
218 for (std::size_t i = 0; i < verts.size(); ++i)
219 verts[i] -= move;
220 }
221}
222
223/* ---------------------------------------------------------------- */
224
225void
227{
228 if (mesh == nullptr)
229 throw std::invalid_argument("Null mesh given");
230
231 TriangleMesh::FaceList& faces(mesh->get_faces());
232
233 for (std::size_t i = 0; i < faces.size(); i += 3)
234 std::swap(faces[i + 1], faces[i + 2]);
235 mesh->recalc_normals(true, true);
236}
237
238/* ---------------------------------------------------------------- */
239
240void
242 math::Vec3f& aabb_min, math::Vec3f& aabb_max)
243{
244 if (mesh == nullptr)
245 throw std::invalid_argument("Null mesh given");
246
247 TriangleMesh::VertexList const& verts(mesh->get_vertices());
248 if (verts.empty())
249 throw std::invalid_argument("Mesh without vertices given");
250
251 aabb_min = math::Vec3f(std::numeric_limits<float>::max());
252 aabb_max = math::Vec3f(-std::numeric_limits<float>::max());
253 for (std::size_t i = 0; i < verts.size(); ++i)
254 for (int j = 0; j < 3; ++j)
255 {
256 if (verts[i][j] < aabb_min[j])
257 aabb_min[j] = verts[i][j];
258 if (verts[i][j] > aabb_max[j])
259 aabb_max[j] = verts[i][j];
260 }
261}
262
263/* ---------------------------------------------------------------- */
264
265std::size_t
267{
268 if (mesh == nullptr)
269 throw std::invalid_argument("Null mesh given");
270
271 MeshInfo mesh_info(mesh);
272 TriangleMesh::DeleteList dlist(mesh_info.size(), false);
273 std::size_t num_deleted = 0;
274 for (std::size_t i = 0; i < mesh_info.size(); ++i)
275 {
276 if (mesh_info[i].vclass == MeshInfo::VERTEX_CLASS_UNREF)
277 {
278 dlist[i] = true;
279 num_deleted += 1;
280 }
281 }
282
283 mesh->delete_vertices_fix_faces(dlist);
284 return num_deleted;
285}
286
Matrix class for arbitrary dimensions and types.
Definition matrix.h:54
Vector class for arbitrary dimensions and types.
Definition vector.h:87
T maximum(void) const
Returns the largest element in the vector.
Definition vector.h:404
std::vector< math::Vec3f > VertexList
Definition mesh.h:33
std::vector< float > ConfidenceList
Definition mesh.h:35
std::vector< math::Vec4f > ColorList
Definition mesh.h:34
std::vector< float > ValueList
Definition mesh.h:36
std::vector< std::size_t > AdjacentVertices
Definition mesh_info.h:38
std::size_t size(void) const
Definition mesh_info.h:128
void clear(void)
Definition mesh_info.h:134
std::vector< math::Vec3f > NormalList
Definition mesh.h:95
std::vector< bool > DeleteList
Definition mesh.h:99
std::vector< math::Vec2f > TexCoordList
Definition mesh.h:96
std::shared_ptr< TriangleMesh > Ptr
Definition mesh.h:92
std::vector< VertexID > FaceList
Definition mesh.h:97
std::shared_ptr< TriangleMesh const > ConstPtr
Definition mesh.h:93
#define MVE_NAMESPACE_BEGIN
Definition defines.h:13
#define MVE_NAMESPACE_END
Definition defines.h:14
#define MVE_GEOM_NAMESPACE_END
Definition defines.h:20
#define MVE_GEOM_NAMESPACE_BEGIN
Definition defines.h:19
Vector< float, 3 > Vec3f
Definition vector.h:31
void mesh_transform(mve::TriangleMesh::Ptr mesh, math::Matrix3f const &rot)
Transforms the vertices and normals of the mesh using the specified rotation matrix.
Definition mesh_tools.cc:46
void mesh_invert_faces(TriangleMesh::Ptr mesh)
Inverts the orientation of all faces in the mesh.
std::size_t mesh_delete_unreferenced(TriangleMesh::Ptr mesh)
Cleans unreferenced vertices from the mesh.
void mesh_components(TriangleMesh::Ptr mesh, std::size_t vertex_threshold)
Discards isolated components with a vertex count below a threshold.
void mesh_find_aabb(TriangleMesh::ConstPtr mesh, math::Vec3f &aabb_min, math::Vec3f &aabb_max)
Calculates the mesh axis-aligned bounding box (AABB).
void mesh_scale_and_center(TriangleMesh::Ptr mesh, bool scale, bool center)
Scales the mesh such that it fits into a cube with length 1 and centers the mesh in the coordinate or...
void mesh_merge(TriangleMesh::ConstPtr mesh1, TriangleMesh::Ptr mesh2)
Merges the first given mesh with the second one, modifying the second one.
Definition mesh_tools.cc:84
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.
Definition image.h:478
for-each functor: matrix-vector multiplication.
Definition algo.h:268