00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00046
00047
00048
00049
00050
00051
00052 #define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC
00053
00054
00055
00056
00057 #include <OpenMesh/Core/System/config.hh>
00058 #include <OpenMesh/Core/System/omstream.hh>
00059 #include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh>
00060 #include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh>
00061
00062
00063
00064
00065 namespace OpenMesh {
00066 namespace Subdivider {
00067 namespace Adaptive {
00068
00069
00070
00071
00072
00073 template<class M>
00074 bool
00075 CompositeT<M> ::
00076 initialize( void )
00077 {
00078 typename Mesh::VertexIter v_it;
00079 typename Mesh::FaceIter f_it;
00080 typename Mesh::EdgeIter e_it;
00081 const typename Mesh::Point zero_point(0.0, 0.0, 0.0);
00082
00083
00084 for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
00085 {
00086 mesh_.data(v_it).set_state(0);
00087 mesh_.data(v_it).set_final();
00088 mesh_.data(v_it).set_position(0, mesh_.point(v_it.handle()));
00089 }
00090
00091
00092 for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
00093 {
00094 mesh_.data(f_it).set_state(0);
00095 mesh_.data(f_it).set_final();
00096 mesh_.data(f_it).set_position(0, zero_point);
00097 }
00098
00099
00100 for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
00101 {
00102 mesh_.data(e_it).set_state(0);
00103 mesh_.data(e_it).set_final();
00104 mesh_.data(e_it).set_position(0, zero_point);
00105 }
00106
00107
00108
00109
00110 int n_subdiv_rules_ = 0;
00111
00112
00113
00114 for (size_t i=0; i < n_rules(); ++i) {
00115
00116 if (rule_sequence_[i]->type()[0] == 'T' ||
00117 rule_sequence_[i]->type()[0] == 't')
00118 {
00119 ++n_subdiv_rules_;
00120 subdiv_rule_ = rule_sequence_[i];
00121 subdiv_type_ = rule_sequence_[i]->subdiv_type();
00122 }
00123 }
00124
00125
00126
00127 assert(n_subdiv_rules_ == 1);
00128
00129 if (n_subdiv_rules_ != 1)
00130 {
00131 std::cerr << "Error! More than one subdivision rules not allowed!\n";
00132 return false;
00133 }
00134
00135
00136 assert(subdiv_type_ == 3 || subdiv_type_ == 4);
00137
00138 if (subdiv_type_ != 3 && subdiv_type_ != 4)
00139 {
00140 ::omerr() << "Error! Unknown subdivision type in sequence!" << std::endl;
00141 return false;
00142 }
00143
00144
00145
00146
00147
00148
00149 for (size_t i = 0; i < n_rules(); ++i)
00150 {
00151 rule_sequence_[i]->set_subdiv_type(subdiv_type_);
00152 rule_sequence_[i]->set_n_rules(n_rules());
00153 rule_sequence_[i]->set_number(i);
00154 rule_sequence_[i]->set_prev_rule(rule_sequence_[(i+n_rules()-1)%n_rules()]);
00155 rule_sequence_[i]->set_subdiv_rule(subdiv_rule_);
00156 }
00157
00158 return true;
00159 }
00160
00161
00162
00163 #define MOBJ mesh_.deref
00164 #define TVH to_vertex_handle
00165 #define HEH halfedge_handle
00166 #define NHEH next_halfedge_handle
00167 #define PHEH prev_halfedge_handle
00168 #define OHEH opposite_halfedge_handle
00169
00170
00171
00172 template<class M>
00173 void CompositeT<M>::refine(typename Mesh::FaceHandle& _fh)
00174 {
00175 std::vector<typename Mesh::HalfedgeHandle> hh_vector;
00176
00177
00178 int new_face_level =
00179 t_rule()->number() + 1 +
00180 ((int)floor((float)(mesh_.data(_fh).state() - t_rule()->number() - 1)/n_rules()) + 1) * n_rules();
00181
00182 int new_vertex_level =
00183 new_face_level + l_rule()->number() - t_rule()->number();
00184
00185
00186
00187 typename Mesh::VertexHandle vh[3];
00188
00189 vh[0] = mesh_.TVH(mesh_.HEH(_fh));
00190 vh[1] = mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh)));
00191 vh[2] = mesh_.TVH(mesh_.PHEH(mesh_.HEH(_fh)));
00192
00193
00194
00195 if (subdiv_type_ == 4)
00196 {
00197 hh_vector.clear();
00198
00199
00200 if (mesh_.data(_fh).final())
00201 {
00202 typename Mesh::FaceHalfedgeIter fh_it(mesh_.fh_iter(_fh));
00203
00204 for (; fh_it; ++fh_it)
00205 {
00206 hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(fh_it.handle())));
00207 }
00208 }
00209
00210
00211 else
00212 {
00213
00214 typename Mesh::HalfedgeHandle red_hh(mesh_.data(_fh).red_halfedge());
00215
00216 hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.NHEH(red_hh))));
00217 hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.PHEH(mesh_.OHEH(red_hh)))));
00218 }
00219 }
00220
00221
00222
00223 if (t_rule()->number() > 0)
00224 t_rule()->prev_rule()->raise(_fh, new_face_level-1);
00225
00226
00227 t_rule()->raise(_fh, new_face_level);
00228
00229 #if 0 // original code
00230 assert(MOBJ(_fh).state() >=
00231 subdiv_rule_->number()+1+(int) (MOBJ(_fh).state()/n_rules())*n_rules());
00232 #else // improved code (use % operation and avoid floating point division)
00233 assert( mesh_.data(_fh).state() >= ( t_rule()->number()+1+generation(_fh) ) );
00234 #endif
00235
00236
00237 if (subdiv_type_ == 3)
00238 {
00239 typename Mesh::VertexHandle new_vh(mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh))));
00240
00241
00242 l_rule()->raise(new_vh, new_vertex_level);
00243 }
00244
00245 if (subdiv_type_ == 4)
00246 {
00247 typename Mesh::HalfedgeHandle hh;
00248 typename Mesh::VertexHandle new_vh;
00249
00250 while (!hh_vector.empty()) {
00251
00252 hh = hh_vector.back();
00253 hh_vector.pop_back();
00254
00255
00256 new_vh = mesh_.TVH(mesh_.NHEH(hh));
00257
00258
00259 l_rule()->raise(new_vh, new_vertex_level);
00260 }
00261 }
00262
00263
00264 l_rule()->raise(vh[0], new_vertex_level);
00265 l_rule()->raise(vh[1], new_vertex_level);
00266 l_rule()->raise(vh[2], new_vertex_level);
00267 }
00268
00269
00270
00271
00272
00273 template<class M>
00274 void CompositeT<M>::refine(typename Mesh::VertexHandle& _vh)
00275 {
00276
00277 int new_vertex_state = generation(_vh) + l_rule()->number() + 1;
00278
00279 assert( new_vertex_state == mesh_.data(_vh).state()+1 );
00280
00281
00282 l_rule()->raise(_vh, new_vertex_state);
00283 }
00284
00285
00286
00287
00288
00289 template <class M>
00290 std::string CompositeT<M>::rules_as_string(const std::string& _sep) const
00291 {
00292 std::string seq;
00293 typename RuleSequence::const_iterator it = rule_sequence_.begin();
00294
00295 if ( it != rule_sequence_.end() )
00296 {
00297 seq = (*it)->type();
00298 for (++it; it != rule_sequence_.end(); ++it )
00299 {
00300 seq += _sep;
00301 seq += (*it)->type();
00302 }
00303 }
00304 return seq;
00305 }
00306
00307
00308 #undef MOBJ
00309 #undef TVH
00310 #undef HEH
00311 #undef NHEH
00312 #undef PHEH
00313 #undef OHEH
00314
00315 }
00316 }
00317 }
00318