File: crease_cut.h

package info (click to toggle)
meshlab 2020.09%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 45,124 kB
  • sloc: cpp: 400,238; ansic: 31,952; javascript: 1,578; sh: 387; yacc: 238; lex: 139; python: 86; makefile: 29
file content (138 lines) | stat: -rw-r--r-- 5,711 bytes parent folder | download | duplicates (3)
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/****************************************************************************
* VCGLib                                                            o o     *
* Visual and Computer Graphics Library                            o     o   *
*                                                                _   O  _   *
* Copyright(C) 2004-2017                                           \/)\/    *
* Visual Computing Lab                                            /\/|      *
* ISTI - Italian National Research Council                           |      *
*                                                                    \      *
* All rights reserved.                                                      *
*                                                                           *
* This program is free software; you can redistribute it and/or modify      *   
* it under the terms of the GNU General Public License as published by      *
* the Free Software Foundation; either version 2 of the License, or         *
* (at your option) any later version.                                       *
*                                                                           *
* This program is distributed in the hope that it will be useful,           *
* but WITHOUT ANY WARRANTY; without even the implied warranty of            *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
* for more details.                                                         *
*                                                                           *
****************************************************************************/

#ifndef __VCG_CREASE_CUT
#define __VCG_CREASE_CUT
#include<vcg/simplex/face/jumping_pos.h>
#include<vcg/complex/algorithms/update/normal.h>
#include<vcg/complex/algorithms/update/flag.h>
namespace vcg {
namespace tri {

/** \brief Open a mesh cutting all the edges where the two faces make an angle *larger* than the indicated threshold
 */

template<class MESH_TYPE>
void CreaseCut(MESH_TYPE &m, float angleRad)
{
  tri::UpdateFlags<MESH_TYPE>::FaceEdgeSelSignedCrease(m, -angleRad, angleRad);
  CutMeshAlongSelectedFaceEdges(m);
}

/**
 * \brief Open a mesh along non-faux edges
 * 
 * Duplicate exisiting vertices so that non-faux edges become boundary edges. 
 * It assume FF topology and manifoldness.
 * The idea is that we scan faces around each vertex duplicating it each time we encounter a marked edge. 
 * 
 */
template<class MESH_TYPE>
void CutMeshAlongSelectedFaceEdges(MESH_TYPE &m)
{
  typedef typename MESH_TYPE::FaceIterator FaceIterator;
  typedef typename MESH_TYPE::FaceType     FaceType;
  typedef typename face::Pos<FaceType> PosType;
  tri::Allocator<MESH_TYPE>::CompactVertexVector(m);
  tri::Allocator<MESH_TYPE>::CompactFaceVector(m);
  tri::RequireFFAdjacency(m);
  
  tri::UpdateFlags<MESH_TYPE>::VertexClearV(m);
  std::vector<int> indVec(m.fn*3,-1);
  int newVertexCounter=m.vn;
  int startVn=m.vn;
  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
  {
    for(int j=0;j<3;++j)
      if(!(*fi).V(j)->IsV() )  // foreach unvisited vertex we loop around it searching for creases.
      {
        (*fi).V(j)->SetV();
        
        PosType startPos(&*fi,j,(*fi).V(j));
        PosType curPos=startPos;
        bool borderVertexFlag=false;  // on border vertex swe startfrom border edges (so we are sure that we cross the crease once)
        do 
        {
          curPos.FlipF();curPos.FlipE();
          if(curPos.IsBorder()) {
            borderVertexFlag=true;
            break;
          }
        } while(curPos!=startPos);
        
        assert(borderVertexFlag == curPos.IsBorder());
        startPos=curPos;
        if(!borderVertexFlag) // on internal vertex we start on creases.
        {
          do  {
            curPos.FlipF();curPos.FlipE();
            if(curPos.IsEdgeS()) 
              break;           
          } while(curPos!=startPos);
          startPos=curPos;
        }        
        int locCreaseCounter=0;
        int curVertexCounter= Index(m, curPos.V());        
        
        // The real Loop; we assume that if there is border we are starting from a border pos;
        // the idea is that just before jumping on the next face, if we cross a crease, we increase the vertex counter.
        do {          
          size_t faceInd = Index(m,curPos.F());
          indVec[faceInd*3+ curPos.VInd()] = curVertexCounter;
          curPos.FlipE();
          if(curPos.IsEdgeS()) 
          { //qDebug("  Crease FOUND");
            ++locCreaseCounter;
            curVertexCounter=newVertexCounter;
            newVertexCounter++;
          }
          curPos.FlipF();
        } while (startPos!=curPos && !curPos.IsBorder());
      }
  } // end foreach face/vert 

  // Now the indVec vector contains for each face wedge the new index of each vertex (duplicated as necessary)
  // We do a second loop to copy split vertices into new positions
  tri::Allocator<MESH_TYPE>::AddVertices(m,newVertexCounter-m.vn);
  
  tri::UpdateFlags<MESH_TYPE>::VertexClearV(m);
  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
    for(int j=0;j<3;++j) 
    {
      size_t faceInd = Index(m, *fi);
      int curVertexInd = indVec[faceInd*3+ j];
      assert(curVertexInd != -1);
      assert(curVertexInd < m.vn);
      if(curVertexInd < startVn) { assert(size_t(curVertexInd) == Index(m, (*fi).V(j))); }
      if(curVertexInd >= startVn)
      {
        m.vert[curVertexInd].ImportData(*((*fi).V(j)));
        (*fi).V(j) = & m.vert[curVertexInd];
      }
    }
}

} // end namespace tri
} // end namespace vcg
#endif