MeshRepairPluginT.cc 8.26 KB
Newer Older
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 42 43 44 45 46 47 48 49
/*===========================================================================*\
*                                                                            *
*                              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.              *
*                                                                            *
\*===========================================================================*/

/*===========================================================================*\
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
\*===========================================================================*/

50 51 52 53
#define MESHREPAIRPLUGINT_CC

#include "MeshRepairPlugin.hh"

Matthias Möller's avatar
Matthias Möller committed
54
//-----------------------------------------------------------------------------
55 56

template<typename MeshT>
57
void MeshRepairPlugin::flipOrientation(MeshT& _mesh)
58 59 60
{


61 62
  std::vector< unsigned int >                 valence;
  std::vector< typename MeshT::VertexHandle > vhandles;
Jan Möbius's avatar
Jan Möbius committed
63

64 65


66
  bool selected = false;
67

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

Jan Möbius's avatar
Jan Möbius committed
88
      _mesh.status(*v_it).set_tagged(tagged);
89 90 91 92 93 94 95 96 97
    }

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

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

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

Jan Möbius's avatar
Jan Möbius committed
105
            typename MeshT::Point tmpPoint = _mesh.point(*v_it);
106 107 108 109 110 111 112 113

            // 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
114
            _mesh.status(*v_it).set_tagged(false);
115 116 117
            break;
          }

Jan Möbius's avatar
Jan Möbius committed
118
      _mesh.property(vmap, *v_it) = vh;
119
    }
120

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

Jan Möbius's avatar
Jan Möbius committed
124
      if (_mesh.status(*f_it).selected()) {
125 126

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

Jan Möbius's avatar
Jan Möbius committed
129 130 131
        valence.push_back(_mesh.valence(*f_it));
        while (fv_it.is_valid()) {
          vhandles.push_back(*fv_it);
132 133 134 135
          ++fv_it;
        }

        // delete the corresponding face
Jan Möbius's avatar
Jan Möbius committed
136
        _mesh.delete_face(*f_it, false);
137 138 139
      }

    }
140 141 142 143 144 145 146 147 148 149 150 151 152

    // 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
153
      _mesh.add_face(faceVertices);
154
    }
155

156
    _mesh.remove_property(vmap);
157

158
  } else {
159

160
    std::vector < typename MeshT::Point > points;
161

162 163 164
    // 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
165
      points.push_back(_mesh.point(*v_it));
166

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

170 171 172 173
    // 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) {
174

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

Jan Möbius's avatar
Jan Möbius committed
177 178
      for (typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(*f_it); fv_it.is_valid(); ++fv_it)
        vhandles.push_back(*fv_it);
179 180
    }

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
    // 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
201
      _mesh.add_face(faceVertices);
202
    }
203

204 205
  }

206 207 208

  _mesh.garbage_collection();
  _mesh.update_normals();
209
}
210

Matthias Möller's avatar
Matthias Möller committed
211 212
//-----------------------------------------------------------------------------