58#define OPENMESH_MESHFIXING_CC
62#include "MeshFixingT.hh"
71 epsilon_(_epsilon * _epsilon)
77 if ((_v0 - _v1).sqrnorm() <= epsilon_)
93 vertices_.push_back(
Vertex(_p) );
94 return vertices_.size()-1;
105 for (
unsigned int i=0; i<3; ++i) {
108 it = vmap_.find(p[i]);
112 if ( it == vmap_.end() ) {
113 v[i] = add_vertex( p[i] );
121 if (v[0]==v[1] || v[0]==v[2] || v[1]==v[2])
126 faces_.push_back(
Face(v[0], v[1], v[2]) );
128 unsigned int newFace = faces_.size()- 1;
129 for (
unsigned int i = 0; i < 3; ++i)
130 vertices_[v[i]].faces.push_back( newFace );
145 const unsigned int numberOfVertices = vertices_.size();
148 for (
unsigned int v = 0; v < numberOfVertices; ++v) {
151 const std::vector<unsigned int>& vfaces = vertices_[v].faces;
152 std::vector<unsigned int>::const_iterator f_it, f_end(vfaces.end());
153 std::vector<unsigned int> todo;
155 todo.reserve(vfaces.size());
158 for (
auto f_it : vfaces)
159 faces_[f_it].component = -1;
162 for (component = 0;; ++component) {
165 for (
auto f_it : vfaces) {
167 if (faces_[f_it].component == -1) {
170 todo.push_back(f_it);
173 faces_[f_it].component = component;
186 while (!todo.empty()) {
189 const unsigned int currentFace = todo.back();
193 for (
unsigned int i = 0; i < 3; ++i) {
196 if (faces_[currentFace].v[i] != v) {
199 const int neighbourFace = neighbor(currentFace, v, faces_[currentFace].v[i]);
200 if ( neighbourFace != -1) {
203 if (faces_[neighbourFace].component == -1) {
204 faces_[neighbourFace].component = component;
205 todo.push_back(neighbourFace);
215 for (
int c = 1; c < component; ++c) {
219 unsigned int newVertex = add_vertex(p);
222 std::vector<unsigned int>& vfaces = vertices_[v].faces;
223 std::vector<unsigned int>::iterator f_it, f_end(vfaces.end());
226 bool finished =
false;
230 for (f_it = vfaces.begin(), f_end = vfaces.end(); f_it != f_end; ++f_it) {
234 if (faces_[*f_it].component == c) {
237 for (
unsigned int i = 0; i < 3; ++i) {
240 if (faces_[*f_it].v[i] == v) {
241 faces_[*f_it].v[i] = newVertex;
242 vertices_[newVertex].faces.push_back(*f_it);
273 const std::vector<unsigned int>& v0faces = vertices_[_v0].faces;
275 int neighborFace = -1;
278 for (
auto f_it : v0faces) {
284 for (
unsigned int j = 0; j < 3; ++j)
287 if (faces_[f_it].v[j] == _v1) {
289 if (neighborFace != -1)
308 if (faces_.empty())
return;
312 std::vector<int> todo;
313 todo.reserve( (
int) sqrt( (
double) faces_.size()) );
315 const unsigned int faceCount = faces_.size();
318 for (
unsigned int i = 0; i < faceCount; ++i)
319 faces_[i].component = -1;
323 for (
int component = 0;; ++component) {
325 unsigned int start = 0 ;
328 for (; start < faceCount; ++start) {
331 if (faces_[start].component == -1) {
334 faces_[fh].component = component;
341 if (start == faceCount)
345 while (!todo.empty()) {
352 for (
unsigned int i = 0; i < 3; ++i) {
353 unsigned int i0 = faces_[fh].v[i];
354 unsigned int i1 = faces_[fh].v[(i + 1) % 3];
356 int neighborFace = neighbor(fh, i0, i1);
357 if (neighborFace != -1 && faces_[neighborFace].component == -1) {
360 for (nextVertex = 0; nextVertex < 3; ++nextVertex)
361 if (faces_[neighborFace].v[nextVertex] == i1)
365 if (faces_[neighborFace].v[(nextVertex + 2) % 3] == i0)
366 std::swap(faces_[neighborFace].v[1], faces_[neighborFace].v[2]);
368 faces_[neighborFace].component = component;
369 todo.push_back(neighborFace);
388 typename MeshT::FaceVertexIter fv_it;
390 std::cerr <<
"Setup data structure" << std::endl;
393 for (
auto f_it : mesh_.faces())
395 fv_it = mesh_.fv_iter(f_it);
396 const ACG::Vec3d p0 = mesh_.point( *(fv_it) );
397 const ACG::Vec3d p1 = mesh_.point(*(++fv_it));
398 const ACG::Vec3d p2 = mesh_.point(*(++fv_it));
400 add_face(p0, p1, p2);
406 std::cerr <<
"Fix topology" << std::endl;
409 std::cerr <<
"Fix orientation" << std::endl;
413 std::cerr <<
"Copy back to mesh" << std::endl;
419 unsigned int vertexCount(vertices_.size());
420 unsigned int faceCount(faces_.size());
423 std::vector<typename MeshT::VertexHandle> vh;
424 typename MeshT::VertexHandle v0, v1, v2;
425 typename MeshT::FaceHandle fh;
430 vh.resize(vertexCount);
431 for (
unsigned int i = 0; i < vertexCount; ++i)
435 for (
unsigned int i = 0; i < faceCount; ++i) {
438 if (!(fh = mesh_.add_face(vh[faces_[i].v[0]], vh[faces_[i].v[1]], vh[faces_[i].v[2]])).is_valid()) {
440 v0 = mesh_.
add_vertex((
typename MeshT::Point) vertices_[faces_[i].v[0]].p);
441 v1 = mesh_.
add_vertex((
typename MeshT::Point) vertices_[faces_[i].v[1]].p);
442 v2 = mesh_.
add_vertex((
typename MeshT::Point) vertices_[faces_[i].v[2]].p);
443 fh = mesh_.add_face(v0, v1, v2);
CompareVectors(double _eps=FLT_MIN)
Constructor.
bool operator()(const ACG::Vec3d &_v0, const ACG::Vec3d &_v1) const
comparison operator
int neighbor(unsigned int _f, unsigned int _v0, unsigned int _v1)
void fix_topology()
Fix the mesh topology.
int add_vertex(const ACG::Vec3d &_p)
void add_face(const ACG::Vec3d &_p0, const ACG::Vec3d &_p1, const ACG::Vec3d &_p2)
Add a face to the fixing data.
SmartVertexHandle add_vertex(const Point _p)
Kernel::Point Point
Coordinate type.