MeshRepairPluginT.cc 7.79 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
*                                                                            *
\*===========================================================================*/

Jan Möbius's avatar
Jan Möbius committed
42

Jan Möbius's avatar
Jan Möbius committed
43

44 45 46 47
#define MESHREPAIRPLUGINT_CC

#include "MeshRepairPlugin.hh"

Matthias Möller's avatar
Matthias Möller committed
48
//-----------------------------------------------------------------------------
49 50

template<typename MeshT>
51
void MeshRepairPlugin::flipOrientation(MeshT& _mesh)
52 53 54
{


55 56
  std::vector< unsigned int >                 valence;
  std::vector< typename MeshT::VertexHandle > vhandles;
Jan Möbius's avatar
Jan Möbius committed
57

58 59


60
  bool selected = false;
61

62 63
  // 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
64
    if ( _mesh.status(*f_it).selected() ) {
65 66 67 68 69 70 71 72 73 74 75 76 77
      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
78 79
      for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(*v_it); !tagged && vf_it.is_valid(); ++vf_it)
        if (_mesh.status(*vf_it).selected())
80 81
          tagged = true;

Jan Möbius's avatar
Jan Möbius committed
82
      _mesh.status(*v_it).set_tagged(tagged);
83 84 85 86 87 88 89 90 91
    }

    // 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
92
      typename MeshT::VertexHandle vh = *v_it;
93

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

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

Jan Möbius's avatar
Jan Möbius committed
99
            typename MeshT::Point tmpPoint = _mesh.point(*v_it);
100 101 102 103 104 105 106 107

            // 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
108
            _mesh.status(*v_it).set_tagged(false);
109 110 111
            break;
          }

Jan Möbius's avatar
Jan Möbius committed
112
      _mesh.property(vmap, *v_it) = vh;
113
    }
114

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

Jan Möbius's avatar
Jan Möbius committed
118
      if (_mesh.status(*f_it).selected()) {
119 120

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

Jan Möbius's avatar
Jan Möbius committed
123 124 125
        valence.push_back(_mesh.valence(*f_it));
        while (fv_it.is_valid()) {
          vhandles.push_back(*fv_it);
126 127 128 129
          ++fv_it;
        }

        // delete the corresponding face
Jan Möbius's avatar
Jan Möbius committed
130
        _mesh.delete_face(*f_it, false);
131 132 133
      }

    }
134 135 136 137 138 139 140 141 142 143 144 145 146

    // 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]) );

Jan Möbius's avatar
Jan Möbius committed
147
      _mesh.add_face(faceVertices);
148
    }
149

150
    _mesh.remove_property(vmap);
151

152
  } else {
153

154
    std::vector < typename MeshT::Point > points;
155

156 157 158
    // 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
159
      points.push_back(_mesh.point(*v_it));
160

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

164 165 166 167
    // 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) {
168

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

Jan Möbius's avatar
Jan Möbius committed
171 172
      for (typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(*f_it); fv_it.is_valid(); ++fv_it)
        vhandles.push_back(*fv_it);
173 174
    }

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
    // 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]);

Jan Möbius's avatar
Jan Möbius committed
195
      _mesh.add_face(faceVertices);
196
    }
197

198 199
  }

200 201 202

  _mesh.garbage_collection();
  _mesh.update_normals();
203
}
204

Matthias Möller's avatar
Matthias Möller committed
205 206
//-----------------------------------------------------------------------------