59 #define OPENMESH_MESHFIXING_CC
63 #include "MeshFixingT.hh"
72 epsilon_(_epsilon * _epsilon)
78 if ((_v0 - _v1).sqrnorm() <= epsilon_)
94 vertices_.push_back(
Vertex(_p) );
95 return vertices_.size()-1;
106 for (
unsigned int i=0; i<3; ++i) {
109 it = vmap_.find(p[i]);
113 if ( it == vmap_.end() ) {
114 v[i] = add_vertex( p[i] );
122 if (v[0]==v[1] || v[0]==v[2] || v[1]==v[2])
127 faces_.push_back(
Face(v[0], v[1], v[2]) );
129 unsigned int newFace = faces_.size()- 1;
130 for (
unsigned int i = 0; i < 3; ++i)
131 vertices_[v[i]].faces.push_back( newFace );
141 template<
class MeshT>
146 const unsigned int numberOfVertices = vertices_.size();
149 for (
unsigned int v = 0; v < numberOfVertices; ++v) {
152 const std::vector<unsigned int>& vfaces = vertices_[v].faces;
153 std::vector<unsigned int>::const_iterator f_it, f_end(vfaces.end());
154 std::vector<unsigned int> todo;
156 todo.reserve(vfaces.size());
159 for (f_it = vfaces.begin(); f_it != f_end; ++f_it)
160 faces_[*f_it].component = -1;
163 for (component = 0;; ++component) {
166 for (f_it = vfaces.begin(); f_it != f_end; ++f_it) {
168 if (faces_[*f_it].component == -1) {
171 todo.push_back(*f_it);
174 faces_[*f_it].component = component;
187 while (!todo.empty()) {
190 const unsigned int currentFace = todo.back();
194 for (
unsigned int i = 0; i < 3; ++i) {
197 if (faces_[currentFace].v[i] != v) {
200 const int neighbourFace = neighbor(currentFace, v, faces_[currentFace].v[i]);
201 if ( neighbourFace != -1) {
204 if (faces_[neighbourFace].component == -1) {
205 faces_[neighbourFace].component = component;
206 todo.push_back(neighbourFace);
216 for (
int c = 1; c < component; ++c) {
220 unsigned int newVertex = add_vertex(p);
223 std::vector<unsigned int>& vfaces = vertices_[v].faces;
224 std::vector<unsigned int>::iterator f_it, f_end(vfaces.end());
227 bool finished =
false;
231 for (f_it = vfaces.begin(), f_end = vfaces.end(); f_it != f_end; ++f_it) {
235 if (faces_[*f_it].component == c) {
238 for (
unsigned int i = 0; i < 3; ++i) {
241 if (faces_[*f_it].v[i] == v) {
242 faces_[*f_it].v[i] = newVertex;
243 vertices_[newVertex].faces.push_back(*f_it);
270 template<
class MeshT>
274 const std::vector<unsigned int>& v0faces = vertices_[_v0].faces;
275 std::vector<unsigned int>::const_iterator f_it, f_end = v0faces.end();
278 int neighborFace = -1;
281 for (f_it = v0faces.begin(); f_it != f_end; ++f_it) {
287 for (
unsigned int j = 0; j < 3; ++j)
290 if (faces_[*f_it].v[j] == _v1) {
292 if (neighborFace != -1)
295 neighborFace = *f_it;
307 template<
class MeshT>
311 if (faces_.empty())
return;
315 std::vector<int> todo;
316 todo.reserve( (
int) sqrt( (
double) faces_.size()) );
318 const unsigned int faceCount = faces_.size();
321 for (
unsigned int i = 0; i < faceCount; ++i)
322 faces_[i].component = -1;
326 for (
int component = 0;; ++component) {
328 unsigned int start = 0 ;
331 for (; start < faceCount; ++start) {
334 if (faces_[start].component == -1) {
337 faces_[fh].component = component;
344 if (start == faceCount)
348 while (!todo.empty()) {
355 for (
unsigned int i = 0; i < 3; ++i) {
356 unsigned int i0 = faces_[fh].v[i];
357 unsigned int i1 = faces_[fh].v[(i + 1) % 3];
359 int neighborFace = neighbor(fh, i0, i1);
360 if (neighborFace != -1 && faces_[neighborFace].component == -1) {
363 for (nextVertex = 0; nextVertex < 3; ++nextVertex)
364 if (faces_[neighborFace].v[nextVertex] == i1)
368 if (faces_[neighborFace].v[(nextVertex + 2) % 3] == i0)
369 std::swap(faces_[neighborFace].v[1], faces_[neighborFace].v[2]);
371 faces_[neighborFace].component = component;
372 todo.push_back(neighborFace);
380 template<
class MeshT>
391 typename MeshT::FaceVertexIter fv_it;
393 std::cerr <<
"Setup data structure" << std::endl;
396 for (
typename MeshT::FaceIter f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
398 fv_it = mesh_.fv_iter(*f_it);
399 const ACG::Vec3d p0 = mesh_.point( *(fv_it) );
400 const ACG::Vec3d p1 = mesh_.point(*(++fv_it));
401 const ACG::Vec3d p2 = mesh_.point(*(++fv_it));
403 add_face(p0, p1, p2);
409 std::cerr <<
"Fix topology" << std::endl;
412 std::cerr <<
"Fix orientation" << std::endl;
416 std::cerr <<
"Copy back to mesh" << std::endl;
422 unsigned int vertexCount(vertices_.size());
423 unsigned int faceCount(faces_.size());
426 std::vector<typename MeshT::VertexHandle> vh;
427 typename MeshT::VertexHandle v0, v1, v2;
428 typename MeshT::FaceHandle fh;
433 vh.resize(vertexCount);
434 for (
unsigned int i = 0; i < vertexCount; ++i)
435 vh[i] = mesh_.
add_vertex((
typename TriMesh::Point) vertices_[i].p);
438 for (
unsigned int i = 0; i < faceCount; ++i) {
441 if (!(fh = mesh_.add_face(vh[faces_[i].v[0]], vh[faces_[i].v[1]], vh[faces_[i].v[2]])).is_valid()) {
443 v0 = mesh_.
add_vertex((
typename MeshT::Point) vertices_[faces_[i].v[0]].p);
444 v1 = mesh_.
add_vertex((
typename MeshT::Point) vertices_[faces_[i].v[1]].p);
445 v2 = mesh_.
add_vertex((
typename MeshT::Point) vertices_[faces_[i].v[2]].p);
446 fh = mesh_.add_face(v0, v1, v2);
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
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.
bool operator()(const ACG::Vec3d &_v0, const ACG::Vec3d &_v1) const
comparison operator
int neighbor(unsigned int _f, unsigned int _v0, unsigned int _v1)
CompareVectors(double _eps=FLT_MIN)
Constructor.