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

#include "MeshRepairPlugin.hh"

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 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
  // Check if a face is selected
  for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end() ; ++f_it)
    if ( _mesh.status(f_it).selected() ) {
      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;

      for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(v_it); !tagged && vf_it; ++vf_it)
        if (_mesh.status(vf_it).selected())
          tagged = true;

      _mesh.status(v_it).set_tagged(tagged);
    }

    // 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) {

      typename MeshT::VertexHandle vh = v_it.handle();

      if (_mesh.status(v_it).tagged() )
        for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(v_it); vf_it; ++vf_it)

          if (!_mesh.status(vf_it).tagged()) {

            typename MeshT::Point tmpPoint = _mesh.point(v_it);

            // 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!
            _mesh.status(v_it).set_tagged(false);
            break;
          }

      _mesh.property(vmap, v_it) = vh;
    }
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

75 76 77 78 79 80 81 82 83 84 85 86 87
      if (_mesh.status(f_it).selected()) {

        // Collect vertex handles
        typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(f_it);

        valence.push_back(_mesh.valence(f_it));
        while (fv_it) {
          vhandles.push_back(fv_it.handle());
          ++fv_it;
        }

        // delete the corresponding face
        _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 116
    // store vertices
    points.reserve(_mesh.n_vertices() );
    for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
      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

126
      valence.push_back( _mesh.valence(f_it) );
127

128 129
      for (typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(f_it); fv_it; ++fv_it)
        vhandles.push_back(fv_it.handle());
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

162 163
//-----------------------------------------------------------------------------