CompositeT.cc 10.3 KB
Newer Older
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen      *
5
6
 *                           www.openmesh.org                                *
 *                                                                           *
7
 *---------------------------------------------------------------------------*
8
9
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
10
 *  OpenMesh is free software: you can redistribute it and/or modify         *
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh 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 Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
33
\*===========================================================================*/
34
35

/*===========================================================================*\
36
 *                                                                           *
37
38
39
40
 *   $Revision$                                                         *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
Jan Möbius committed
41
42

/** \file Adaptive/Composite/CompositeT.cc
43

Jan Möbius's avatar
Jan Möbius committed
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 */

//=============================================================================
//
//  CLASS CompositeT - IMPLEMENTATION
//
//=============================================================================

#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC


//== INCLUDES =================================================================

#include <OpenMesh/Core/System/config.hh>
#include <OpenMesh/Core/System/omstream.hh>
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh>
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh>


//== NAMESPACE ================================================================

namespace OpenMesh   { // BEGIN_NS_OPENMESH
namespace Subdivider { // BEGIN_NS_DECIMATER
Jan Möbius's avatar
Jan Möbius committed
67
namespace Adaptive   { // BEGIN_NS_ADAPTIVE
Jan Möbius's avatar
Jan Möbius committed
68
69


70
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
Jan Möbius committed
71
72
73
74
75


template<class M>
bool
CompositeT<M> ::
76
initialize( void )
Jan Möbius's avatar
Jan Möbius committed
77
78
79
80
81
{
  typename Mesh::VertexIter  v_it;
  typename Mesh::FaceIter    f_it;
  typename Mesh::EdgeIter    e_it;
  const typename Mesh::Point zero_point(0.0, 0.0, 0.0);
82

Jan Möbius's avatar
Jan Möbius committed
83
  // ---------------------------------------- Init Vertices
84
  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
Jan Möbius's avatar
Jan Möbius committed
85
  {
Jan Möbius's avatar
Jan Möbius committed
86
87
88
    mesh_.data(*v_it).set_state(0);
    mesh_.data(*v_it).set_final();
    mesh_.data(*v_it).set_position(0, mesh_.point(*v_it));
Jan Möbius's avatar
Jan Möbius committed
89
  }
90

Jan Möbius's avatar
Jan Möbius committed
91
  // ---------------------------------------- Init Faces
92
  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
Jan Möbius's avatar
Jan Möbius committed
93
  {
Jan Möbius's avatar
Jan Möbius committed
94
95
96
    mesh_.data(*f_it).set_state(0);
    mesh_.data(*f_it).set_final();
    mesh_.data(*f_it).set_position(0, zero_point);
Jan Möbius's avatar
Jan Möbius committed
97
  }
98

Jan Möbius's avatar
Jan Möbius committed
99
  // ---------------------------------------- Init Edges
100
  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
Jan Möbius's avatar
Jan Möbius committed
101
  {
Jan Möbius's avatar
Jan Möbius committed
102
103
104
    mesh_.data(*e_it).set_state(0);
    mesh_.data(*e_it).set_final();
    mesh_.data(*e_it).set_position(0, zero_point);
Jan Möbius's avatar
Jan Möbius committed
105
  }
106
107


Jan Möbius's avatar
Jan Möbius committed
108
109
110
111
112
113
114
115
  // ---------------------------------------- Init Rules

  int n_subdiv_rules_ = 0;


  // look for subdivision rule(s)
  for (size_t i=0; i < n_rules(); ++i) {

116
117
118
    if (rule_sequence_[i]->type()[0] == 'T' ||
        rule_sequence_[i]->type()[0] == 't')
    {
Jan Möbius's avatar
Jan Möbius committed
119
120
121
122
123
124
125
126
127
128
129
      ++n_subdiv_rules_;
      subdiv_rule_ = rule_sequence_[i];
      subdiv_type_ = rule_sequence_[i]->subdiv_type();
    }
  }


  // check for correct number of subdivision rules
  assert(n_subdiv_rules_ == 1);

  if (n_subdiv_rules_ != 1)
130
  {
Jan Möbius's avatar
Jan Möbius committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    std::cerr << "Error! More than one subdivision rules not allowed!\n";
    return false;
  }

  // check for subdivision type
  assert(subdiv_type_ == 3 || subdiv_type_ == 4);

  if (subdiv_type_ != 3 && subdiv_type_ != 4)
  {
    ::omerr() << "Error! Unknown subdivision type in sequence!" << std::endl;
    return false;
  }

  // set pointer to last rule
//   first_rule_ = rule_sequence_.front();
//   last_rule_  = rule_sequence_.back(); //[n_rules() - 1];

  // set numbers and previous rule
149
  for (size_t i = 0; i < n_rules(); ++i)
Jan Möbius's avatar
Jan Möbius committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  {
    rule_sequence_[i]->set_subdiv_type(subdiv_type_);
    rule_sequence_[i]->set_n_rules(n_rules());
    rule_sequence_[i]->set_number(i);
    rule_sequence_[i]->set_prev_rule(rule_sequence_[(i+n_rules()-1)%n_rules()]);
    rule_sequence_[i]->set_subdiv_rule(subdiv_rule_);
  }

  return true;
}


// ----------------------------------------------------------------------------
#define MOBJ mesh_.deref
#define TVH  to_vertex_handle
#define HEH  halfedge_handle
#define NHEH next_halfedge_handle
#define PHEH prev_halfedge_handle
#define OHEH opposite_halfedge_handle
// ----------------------------------------------------------------------------


template<class M>
Isaak Lim's avatar
Isaak Lim committed
173
void CompositeT<M>::refine(typename M::FaceHandle& _fh)
Jan Möbius's avatar
Jan Möbius committed
174
175
176
177
{
  std::vector<typename Mesh::HalfedgeHandle> hh_vector;

  // -------------------- calculate new level for faces and vertices
178
179
  int new_face_level =
    t_rule()->number() + 1 +
Jan Möbius's avatar
Jan Möbius committed
180
181
    ((int)floor((float)(mesh_.data(_fh).state() - t_rule()->number() - 1)/n_rules()) + 1) * n_rules();

182
  int new_vertex_level =
Jan Möbius's avatar
Jan Möbius committed
183
184
185
186
187
188
189
190
191
192
    new_face_level + l_rule()->number() - t_rule()->number();

  // -------------------- store old vertices
  // !!! only triangle meshes supported!
  typename Mesh::VertexHandle vh[3];

  vh[0] = mesh_.TVH(mesh_.HEH(_fh));
  vh[1] = mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh)));
  vh[2] = mesh_.TVH(mesh_.PHEH(mesh_.HEH(_fh)));

193
  // save handles to incoming halfedges for getting the new vertices
Jan Möbius's avatar
Jan Möbius committed
194
  // after subdivision (1-4 split)
195
  if (subdiv_type_ == 4)
Jan Möbius's avatar
Jan Möbius committed
196
197
198
199
200
201
202
203
  {
    hh_vector.clear();

    // green face
    if (mesh_.data(_fh).final())
    {
      typename Mesh::FaceHalfedgeIter fh_it(mesh_.fh_iter(_fh));

Jan Möbius's avatar
Jan Möbius committed
204
      for (; fh_it.is_valid(); ++fh_it)
Jan Möbius's avatar
Jan Möbius committed
205
      {
Jan Möbius's avatar
Jan Möbius committed
206
        hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(*fh_it)));
Jan Möbius's avatar
Jan Möbius committed
207
208
209
210
      }
    }

    // red face
211
    else
Jan Möbius's avatar
Jan Möbius committed
212
    {
213

Jan Möbius's avatar
Jan Möbius committed
214
215
216
217
218
219
220
      typename Mesh::HalfedgeHandle red_hh(mesh_.data(_fh).red_halfedge());

      hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.NHEH(red_hh))));
      hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.PHEH(mesh_.OHEH(red_hh)))));
    }
  }

221

Jan Möbius's avatar
Jan Möbius committed
222
223
224
225
226
227
228
229
  // -------------------- Average rule before topo rule?
  if (t_rule()->number() > 0)
    t_rule()->prev_rule()->raise(_fh, new_face_level-1);

  // -------------------- Apply topological operator first
  t_rule()->raise(_fh, new_face_level);

#if 0 // original code
230
  assert(MOBJ(_fh).state() >=
Jan Möbius's avatar
Jan Möbius committed
231
232
233
234
235
236
         subdiv_rule_->number()+1+(int) (MOBJ(_fh).state()/n_rules())*n_rules());
#else // improved code (use % operation and avoid floating point division)
  assert( mesh_.data(_fh).state() >= ( t_rule()->number()+1+generation(_fh) ) );
#endif

  // raise new vertices to final levels
237
  if (subdiv_type_ == 3)
Jan Möbius's avatar
Jan Möbius committed
238
239
240
241
242
243
244
  {
    typename Mesh::VertexHandle new_vh(mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh))));

    // raise new vertex to final level
    l_rule()->raise(new_vh, new_vertex_level);
  }

245
  if (subdiv_type_ == 4)
Jan Möbius's avatar
Jan Möbius committed
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  {
    typename Mesh::HalfedgeHandle hh;
    typename Mesh::VertexHandle   new_vh;

    while (!hh_vector.empty()) {

      hh = hh_vector.back();
      hh_vector.pop_back();

      // get new vertex
      new_vh = mesh_.TVH(mesh_.NHEH(hh));

      // raise new vertex to final level
      l_rule()->raise(new_vh, new_vertex_level);
    }
  }

263
  // raise old vertices to final position
Jan Möbius's avatar
Jan Möbius committed
264
265
266
267
268
269
270
271
272
273
  l_rule()->raise(vh[0], new_vertex_level);
  l_rule()->raise(vh[1], new_vertex_level);
  l_rule()->raise(vh[2], new_vertex_level);
}


// ----------------------------------------------------------------------------


template<class M>
Isaak Lim's avatar
Isaak Lim committed
274
void CompositeT<M>::refine(typename M::VertexHandle& _vh)
Jan Möbius's avatar
Jan Möbius committed
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
{
  // calculate next final level for vertex
  int new_vertex_state = generation(_vh) + l_rule()->number() + 1;

  // raise vertex to final position
  l_rule()->raise(_vh, new_vertex_state);
}


// ----------------------------------------------------------------------------


template <class M>
std::string CompositeT<M>::rules_as_string(const std::string& _sep) const
{
  std::string seq;
  typename RuleSequence::const_iterator it = rule_sequence_.begin();

  if ( it != rule_sequence_.end() )
  {
    seq = (*it)->type();
    for (++it; it != rule_sequence_.end(); ++it )
    {
      seq += _sep;
299
      seq += (*it)->type();
Jan Möbius's avatar
Jan Möbius committed
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    }
  }
  return seq;
}

// ----------------------------------------------------------------------------
#undef MOBJ
#undef TVH
#undef HEH
#undef NHEH
#undef PHEH
#undef OHEH
//=============================================================================
} // END_NS_ADAPTIVE
} // END_NS_SUBDIVIDER
} // END_NS_OPENMESH
//=============================================================================