MeshRepairPluginT.cc 4.76 KB
Newer Older
1
2
3
4
#define MESHREPAIRPLUGINT_CC

#include "MeshRepairPlugin.hh"

Matthias Möller's avatar
Matthias Möller committed
5
//-----------------------------------------------------------------------------
6
7

template<typename MeshT>
8
void MeshRepairPlugin::flipOrientation(MeshT& _mesh)
9
10
11
{


12
13
  std::vector< unsigned int >                 valence;
  std::vector< typename MeshT::VertexHandle > vhandles;
Jan Möbius's avatar
Jan Möbius committed
14

15
16


17
  bool selected = false;
18

19
20
  // Check if a face is selected
  for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end() ; ++f_it)
Jan Möbius's avatar
Jan Möbius committed
21
    if ( _mesh.status(*f_it).selected() ) {
22
23
24
25
26
27
28
29
30
31
32
33
34
      selected = true;
      break;
    }

  // Two ways to go
  // if something is selected, we have to duplicate some vertices in order to get a manifold mesh
  if ( selected ) {

    // Tag all vertices adjacent to selected faces
    for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it) {

      bool tagged = false;

Jan Möbius's avatar
Jan Möbius committed
35
36
      for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(*v_it); !tagged && vf_it.is_valid(); ++vf_it)
        if (_mesh.status(*vf_it).selected())
37
38
          tagged = true;

Jan Möbius's avatar
Jan Möbius committed
39
      _mesh.status(*v_it).set_tagged(tagged);
40
41
42
43
44
45
46
47
48
    }

    // Remember the vertex mapping for the duplication
    OpenMesh::VPropHandleT< typename MeshT::VHandle>  vmap;
    _mesh.add_property(vmap);

    // duplicate vertices that are incident to tagged and un-tagged faces
    for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it !=  _mesh.vertices_end(); ++v_it) {

Jan Möbius's avatar
Jan Möbius committed
49
      typename MeshT::VertexHandle vh = *v_it;
50

Jan Möbius's avatar
Jan Möbius committed
51
52
      if (_mesh.status(*v_it).tagged() )
        for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(*v_it); vf_it.is_valid(); ++vf_it)
53

Jan Möbius's avatar
Jan Möbius committed
54
          if (!_mesh.status(*vf_it).tagged()) {
55

Jan Möbius's avatar
Jan Möbius committed
56
            typename MeshT::Point tmpPoint = _mesh.point(*v_it);
57
58
59
60
61
62
63
64

            // Duplicate the vertex
            vh = _mesh.add_vertex( tmpPoint );

            // The next vertex should be tagged
            _mesh.status(vh).set_tagged(true);

            // The original vertex is already duplicated, so we don't need to do it again!
Jan Möbius's avatar
Jan Möbius committed
65
            _mesh.status(*v_it).set_tagged(false);
66
67
68
            break;
          }

Jan Möbius's avatar
Jan Möbius committed
69
      _mesh.property(vmap, *v_it) = vh;
70
    }
71

72
73
    // Delete the old faces and collect their information
    for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end(); ++f_it) {
74

Jan Möbius's avatar
Jan Möbius committed
75
      if (_mesh.status(*f_it).selected()) {
76
77

        // Collect vertex handles
Jan Möbius's avatar
Jan Möbius committed
78
        typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(*f_it);
79

Jan Möbius's avatar
Jan Möbius committed
80
81
82
        valence.push_back(_mesh.valence(*f_it));
        while (fv_it.is_valid()) {
          vhandles.push_back(*fv_it);
83
84
85
86
          ++fv_it;
        }

        // delete the corresponding face
Jan Möbius's avatar
Jan Möbius committed
87
        _mesh.delete_face(*f_it, false);
88
89
90
      }

    }
91
92
93
94
95
96
97
98
99
100
101
102
103
104

    // Rebuild the faces in the opposite order
    std::size_t pos = 0;
    for (std::size_t i = 0; i < valence.size(); i++) {

      std::vector<typename MeshT::VertexHandle> faceVertices;

      pos += valence[i];

      // add valence vertices in the inverse order
      for (unsigned int j = 1; j <= valence[i]; ++j)
        faceVertices.push_back(_mesh.property(vmap,vhandles[pos - j]) );

      typename MeshT::FaceHandle fh = _mesh.add_face(faceVertices);
105
    }
106

107
    _mesh.remove_property(vmap);
108

109
  } else {
110

111
    std::vector < typename MeshT::Point > points;
112

113
114
115
    // store vertices
    points.reserve(_mesh.n_vertices() );
    for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
Jan Möbius's avatar
Jan Möbius committed
116
      points.push_back(_mesh.point(*v_it));
117

118
119
    // Better approximation of vector size for storing the handles
    const unsigned int n_VerticesPerFace = _mesh.is_trimesh() ? 3 : 4;
120

121
122
123
124
    // Remember vertex handles for each face and its valence
    std::vector< typename MeshT::VertexHandle > vhandles;
    vhandles.reserve( _mesh.n_faces() * n_VerticesPerFace);
    for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end(); ++f_it) {
125

Jan Möbius's avatar
Jan Möbius committed
126
      valence.push_back( _mesh.valence(*f_it) );
127

Jan Möbius's avatar
Jan Möbius committed
128
129
      for (typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(*f_it); fv_it.is_valid(); ++fv_it)
        vhandles.push_back(*fv_it);
130
131
    }

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    // Remove all entities from the mesh
    _mesh.clean();

    // Restore vertices
    for (unsigned int i = 0; i < points.size(); ++i)
      _mesh.add_vertex(points[i]);


    // Add back the faces
    std::size_t pos = 0;
    for (std::size_t i = 0; i < valence.size(); i++) {

      std::vector<typename MeshT::VertexHandle> faceVertices;

      pos += valence[i];

      // add valence vertices in the inverse order
      for (unsigned int j = 1; j <= valence[i]; ++j)
        faceVertices.push_back(vhandles[pos - j]);

      typename MeshT::FaceHandle fh = _mesh.add_face(faceVertices);
    }
154

155
156
  }

157
158
159

  _mesh.garbage_collection();
  _mesh.update_normals();
160
}
161

Matthias Möller's avatar
Matthias Möller committed
162
163
//-----------------------------------------------------------------------------