00001
00002
00003
00004 #include "std/config.H"
00005 #include "subdiv_calc.H"
00006 #include "lmesh.H"
00007 #include "mi.H"
00008
00009 Ledge::~Ledge()
00010 {
00011
00012
00013
00014
00015
00016
00017 if (_mesh) {
00018 if (_f1) _mesh->remove_face(_f1);
00019 if (_f2) _mesh->remove_face(_f2);
00020 if (_adj) {
00021 for (int i=0; i<_adj->num(); i++)
00022 _mesh->remove_face((*_adj)[i]);
00023 }
00024 }
00025
00026
00027 delete_subdiv_elements();
00028 }
00029
00030 Ledge*
00031 Ledge::subdiv_edge1() const
00032 {
00033 return (Ledge*)lookup_edge(lv(1)->subdiv_vertex(),_subdiv_vertex);
00034 }
00035
00036 Ledge*
00037 Ledge::subdiv_edge2() const
00038 {
00039 return (Ledge*)lookup_edge(lv(2)->subdiv_vertex(),_subdiv_vertex);
00040 }
00041
00042 Ledge*
00043 Ledge::parallel_sub_edge(int k) const
00044 {
00045 Lface* f = lf(k);
00046 if (!(f && (f = f->subdiv_face_center())))
00047 return 0;
00048 return (Ledge*)f->opposite_edge(_subdiv_vertex);
00049 }
00050
00051 Ledge*
00052 Ledge::parent_edge(int rel_level) const
00053 {
00054
00055
00056
00057 Ledge* e = (Ledge*)this;
00058 for (int i=0; e && i<rel_level; i++) {
00059 Bsimplex* p = e->parent();
00060 if (!is_edge(p))
00061 return 0;
00062 e = (Ledge*)p;
00063 }
00064
00065 return e;
00066 }
00067
00068 Bsimplex*
00069 Ledge::ctrl_element() const
00070 {
00071 if (!_parent)
00072 return (Bsimplex*)this;
00073 if (is_edge(_parent))
00074 return ((Ledge*)_parent)->ctrl_element();
00075 if (is_face(_parent))
00076 return ((Lface*)_parent)->control_face();
00077 return 0;
00078 }
00079
00080 uint
00081 Ledge::rel_level() const
00082 {
00083
00084
00085 Bsimplex* c = ctrl_element();
00086 return (mesh() && c && c->mesh()) ?
00087 mesh()->subdiv_level() - c->mesh()->subdiv_level() : 0;
00088 }
00089
00090 void
00091 Ledge::delete_subdiv_elements()
00092 {
00093
00094
00095
00096
00097
00098
00099
00100 if (!is_set(SUBDIV_ALLOCATED_BIT))
00101 return;
00102 clear_bit(SUBDIV_ALLOCATED_BIT);
00103
00104 if (_subdiv_vertex) {
00105 _subdiv_vertex->mesh()->remove_vertex(_subdiv_vertex);
00106
00107
00108
00109 lv(1)->mark_dirty();
00110 lv(2)->mark_dirty();
00111 }
00112 }
00113
00114 void
00115 Ledge::subdiv_vert_deleted()
00116 {
00117 _subdiv_vertex = 0;
00118
00119 clear_bit(SUBDIV_LOC_VALID_BIT);
00120 clear_bit(SUBDIV_COLOR_VALID_BIT);
00121 clear_bit(SUBDIV_CREASE_VALID_BIT);
00122 }
00123
00124
00125 int
00126 Ledge::redefine(Bvert *v, Bvert *u)
00127 {
00128 delete_subdiv_elements();
00129 return Bedge::redefine(v,u);
00130 }
00131
00132 void
00133 Ledge::set_new_vertices(Bvert *v1, Bvert *v2)
00134 {
00135 delete_subdiv_elements();
00136 Bedge::set_new_vertices(v1, v2);
00137 }
00138
00139 inline void
00140 swap_edge(Bedge* e)
00141 {
00142 if (e) e->do_swap();
00143 }
00144
00145 bool
00146 Ledge::do_swap()
00147 {
00148 if (!swap_is_legal())
00149 return false;
00150
00151 if (is_set(SUBDIV_ALLOCATED_BIT)) {
00152 Bedge* e1 = subdiv_edge1();
00153 Bedge* e2 = subdiv_edge2();
00154 Bedge* e3 = parallel_sub_edge(1);
00155 Bedge* e4 = parallel_sub_edge(2);
00156 swap_edge(e1);
00157 swap_edge(e2);
00158 swap_edge(e3);
00159 swap_edge(e4);
00160 }
00161 return Bedge::do_swap();
00162 }
00163
00164 bool
00165 Ledge::add_multi(Bface* f)
00166 {
00167 if (Bedge::add_multi(f)) {
00168 push_multi(f);
00169 return true;
00170 }
00171 return false;
00172 }
00173
00174 bool
00175 Ledge::add_primary(Bface* f)
00176 {
00177 if (Bedge::add_primary(f)) {
00178 push_primary(f);
00179 return true;
00180 }
00181 return false;
00182 }
00183
00184 void
00185 Ledge::get_sub_faces(Bface* f, Bedge* &e1, Bface* &sf1, Bedge* &e2, Bface* &sf2)
00186 {
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 e1 = e2 = 0;
00211 sf1 = sf2 = 0;
00212
00213 Lvert* sve = _subdiv_vertex;
00214
00215 if (!sve)
00216 return;
00217
00218
00219
00220 Lvert* pv1 = (Lvert*)f->leading_vert_ccw(this);
00221 Lvert* pv2 = (Lvert*)f->next_vert_ccw(pv1);
00222 assert(pv1 && pv2);
00223
00224 Lvert* sv1 = pv1->subdiv_vertex();
00225 if (sv1) {
00226 e1 = sv1->lookup_edge(sve);
00227 if (e1) {
00228 Lvert* sva = ((Ledge*)f->edge_before_vert(pv1))->subdiv_vertex();
00229 sf1 = ::lookup_face(sv1, sve, sva);
00230 }
00231 }
00232
00233 Lvert* sv2 = pv2->subdiv_vertex();
00234 if (sv2) {
00235 e2 = sv2->lookup_edge(sve);
00236 if (e2) {
00237 Lvert* svb = ((Ledge*)f->edge_from_vert(pv2))->subdiv_vertex();
00238 sf2 = ::lookup_face(sve, sv2, svb);
00239 }
00240 }
00241 }
00242
00243 void
00244 Ledge::push_multi(Bface* f)
00245 {
00246
00247
00248
00249
00250 if (!is_multi(f))
00251 return;
00252
00253
00254
00255 Bedge *e1=0, *e2=0;
00256 Bface *sf1=0, *sf2=0;
00257 get_sub_faces(f, e1, sf1, e2, sf2);
00258
00259 if (e1 && sf1)
00260 e1->demote(sf1);
00261 if (e2 && sf2)
00262 e2->demote(sf2);
00263 }
00264
00265 void
00266 Ledge::push_primary(Bface* f)
00267 {
00268
00269
00270
00271
00272 if (!(f == _f1 || f == _f2))
00273 return;
00274
00275
00276
00277 Bedge *e1=0, *e2=0;
00278 Bface *sf1=0, *sf2=0;
00279 get_sub_faces(f, e1, sf1, e2, sf2);
00280
00281 if (e1 && sf1)
00282 e1->promote(sf1);
00283 if (e2 && sf2)
00284 e2->promote(sf2);
00285 }
00286
00287 void
00288 Ledge::claim_child(Ledge* child)
00289 {
00290 if (!child)
00291 return;
00292
00293
00294 assert(child->parent() == NULL);
00295 child->set_parent(this);
00296
00297
00298 if (is_weak())
00299 child->set_bit(WEAK_BIT);
00300
00301
00302 }
00303
00304 void
00305 Ledge::claim_child(Lvert* child)
00306 {
00307 if (!child)
00308 return;
00309 assert(child->parent() == NULL);
00310
00311
00312 _subdiv_vertex = child;
00313 child->set_parent(this);
00314
00315
00316 }
00317
00318 void
00319 Ledge::set_subdiv_elements(Lvert* subv)
00320 {
00321 if (is_set(SUBDIV_ALLOCATED_BIT)) {
00322 err_msg("Ledge::set_subdiv_elements: elements already set");
00323 return;
00324 }
00325 set_bit(SUBDIV_ALLOCATED_BIT);
00326
00327 assert(_subdiv_vertex == NULL);
00328 if (!subv)
00329 return;
00330 assert(lmesh()->subdiv_mesh() == subv->lmesh());
00331
00332 claim_child(subv);
00333 claim_child(subdiv_edge1());
00334 claim_child(subdiv_edge2());
00335
00336
00337 if (_data_list)
00338 _data_list->notify_subdiv_gen();
00339 }
00340
00341 void
00342 Ledge::allocate_subdiv_elements()
00343 {
00344
00345
00346
00347
00348
00349
00350
00351 if (is_set(SUBDIV_ALLOCATED_BIT))
00352 return;
00353 set_bit(SUBDIV_ALLOCATED_BIT);
00354
00355 assert(!_subdiv_vertex);
00356
00357 LMESH* submesh = lmesh()->subdiv_mesh();
00358 assert(submesh);
00359
00360
00361 claim_child((Lvert*)submesh->add_vertex(mid_pt()));
00362
00363 if (!_subdiv_vertex)
00364 return;
00365
00366
00367
00368
00369
00370
00371
00372
00373 Bvert* u1 = lv(1)->allocate_subdiv_vert();
00374 if (u1) {
00375 claim_child((Ledge*)submesh->add_edge(u1, _subdiv_vertex));
00376 }
00377
00378 Bvert* u2 = lv(2)->allocate_subdiv_vert();
00379 if (u2) {
00380 claim_child((Ledge*)submesh->add_edge(_subdiv_vertex,u2));
00381 }
00382
00383
00384 if (_data_list)
00385 _data_list->notify_subdiv_gen();
00386 }
00387
00388
00389 inline bool
00390 get_subdiv_edges(Ledge* e, int lev, ARRAY<Bedge*>& edges)
00391 {
00392 return e ? e->append_subdiv_edges(lev, edges) : false;
00393 }
00394
00395 bool
00396 Ledge::append_subdiv_edges(int lev, ARRAY<Bedge*>& edges)
00397 {
00398
00399
00400
00401
00402
00403
00404
00405 if (lev < 0) {
00406 err_msg("Ledge::append_subdiv_edges: error: bad level: %d", lev);
00407 return false;
00408 } else if (lev == 0) {
00409 edges += this;
00410 return true;
00411 } else {
00412 return (
00413 get_subdiv_edges(subdiv_edge1(), lev - 1, edges) &&
00414 get_subdiv_edges(subdiv_edge2(), lev - 1, edges)
00415 );
00416 }
00417 }
00418
00419 bool
00420 Ledge::get_subdiv_verts(int lev, Bvert_list& ret)
00421 {
00422
00423
00424
00425 ret.clear();
00426 Bedge_list edges;
00427 if (!append_subdiv_edges(lev, edges))
00428 return false;
00429 Lvert* v = lv(1)->subdiv_vert(lev);
00430 assert(v && !edges.empty() && edges.first()->contains(v));
00431 ret += v;
00432 for (int i=0; i<edges.num(); i++) {
00433 ret += edges[i]->other_vertex(ret.last());
00434 }
00435 return true;
00436 }
00437
00438 inline void
00439 set_crease(Ledge* e, unsigned short c) { if (e) e->set_crease(c); }
00440
00441 void
00442 Ledge::update_subdivision()
00443 {
00444
00445 allocate_subdiv_elements();
00446
00447
00448
00449 if (!_subdiv_vertex)
00450 return;
00451
00452
00453 if (is_clear(SUBDIV_CREASE_VALID_BIT)) {
00454 set_bit(SUBDIV_CREASE_VALID_BIT);
00455 unsigned short subcrease = (_crease > 0) ? _crease - 1 : 0;
00456 ::set_crease(subdiv_edge1(), subcrease);
00457 ::set_crease(subdiv_edge2(), subcrease);
00458 }
00459
00460
00461 if (is_clear(SUBDIV_COLOR_VALID_BIT)) {
00462 set_bit(SUBDIV_COLOR_VALID_BIT);
00463 if (_v1->has_color())
00464 _subdiv_vertex->set_color(lmesh()->subdiv_color(this));
00465 }
00466
00467
00468 if (is_clear(SUBDIV_LOC_VALID_BIT)) {
00469 set_bit(SUBDIV_LOC_VALID_BIT);
00470
00471
00472 if (!_data_list || !_data_list->handle_subdiv_calc())
00473 _subdiv_vertex->set_subdiv_base_loc(lmesh()->subdiv_loc(this));
00474 }
00475 }
00476
00477 unsigned short
00478 Ledge::subdiv_mask() const
00479 {
00480
00481 if (!is_set(MASK_VALID_BIT))
00482 ((Ledge*)this)->set_mask();
00483 return _mask;
00484 }
00485
00486 void
00487 Ledge::set_mask()
00488 {
00489 set_bit(MASK_VALID_BIT);
00490
00491 if (is_interior() &&
00492 (!is_crease() || lv(1)->is_smooth() || lv(2)->is_smooth())) {
00493 _mask = REGULAR_SMOOTH_EDGE;
00494 } else {
00495 _mask = REGULAR_CREASE_EDGE;
00496 }
00497 }
00498
00499 void
00500 Ledge::set_crease(unsigned short c)
00501 {
00502 if (c != _crease) {
00503 Bedge::set_crease(_crease = c);
00504 if (c == 0)
00505 Bedge::clear_bit(CREASE_BIT);
00506 crease_changed();
00507 }
00508 }
00509
00510 void
00511 Ledge::crease_changed()
00512 {
00513 Bedge::crease_changed();
00514
00515 clear_bit(SUBDIV_CREASE_VALID_BIT);
00516 mask_changed();
00517 lv(1)->mask_changed();
00518 lv(2)->mask_changed();
00519 }
00520
00521 void
00522 Ledge::normal_changed()
00523 {
00524 Bedge::normal_changed();
00525
00526 subdiv_loc_changed();
00527 }
00528
00529 void
00530 Ledge::geometry_changed()
00531 {
00532 Bedge::geometry_changed();
00533
00534 subdiv_loc_changed();
00535 }
00536
00537 void
00538 Ledge::color_changed()
00539 {
00540
00541
00542 if (_f1) lf(1)->color_changed();
00543 if (_f2) lf(2)->color_changed();
00544 }
00545
00546 void
00547 Ledge::faces_changed()
00548 {
00549
00550
00551 mask_changed();
00552
00553 lv(1)->mask_changed();
00554 lv(2)->mask_changed();
00555 }
00556
00557 void
00558 Ledge::mask_changed()
00559 {
00560 clear_bit(MASK_VALID_BIT);
00561 subdiv_loc_changed();
00562 subdiv_color_changed();
00563 }
00564
00565
00566
00567
00568 bool
00569 get_subdiv_chain(Bvert* v1, Bvert* v2, int level, Bvert_list& ret)
00570 {
00571
00572
00573
00574
00575 static bool debug = Config::get_var_bool("DEBUG_GET_SUBDIV_CHAIN",false);
00576
00577 ret.clear();
00578
00579 if (!(v1 && v2)) {
00580 err_adv(debug, "get_subdiv_chain: null vertex (level %d)", level);
00581 return 0;
00582 }
00583
00584 if (!(v1->mesh() == v2->mesh() && LMESH::isa(v1->mesh()))){
00585 err_adv(debug, "get_subdiv_chain: non-LMESH (level %d)", level);
00586 return 0;
00587 }
00588
00589 if (level < 0){
00590 err_adv(debug, "get_subdiv_chain: negative level (%d)", level);
00591 return 0;
00592 }
00593
00594 Bedge* e = v1->lookup_edge(v2);
00595 if (!e){
00596 err_adv(debug, "get_subdiv_chain: verts don't form edge (level %d)",
00597 level);
00598 return 0;
00599 }
00600
00601 if (level == 0) {
00602 ret += v1;
00603 ret += v2;
00604 return true;
00605 }
00606
00607 Bvert* s1 = ((Lvert*)v1)->subdiv_vertex();
00608 Bvert* sv = ((Ledge*)e) ->subdiv_vertex();
00609 Bvert* s2 = ((Lvert*)v2)->subdiv_vertex();
00610
00611 Bvert_list l1;
00612 Bvert_list l2;
00613
00614 if (!(get_subdiv_chain(s1, sv, level-1, l1) &&
00615 get_subdiv_chain(sv, s2, level-1, l2))) {
00616 return 0;
00617 }
00618
00619 l1.pop();
00620 ret = l1 + l2;
00621 return true;
00622 }
00623
00624
00625
00626
00627 bool
00628 get_subdiv_chain(CBvert_list& chain, int level, Bvert_list& ret)
00629 {
00630
00631
00632
00633
00634
00635 static bool debug = Config::get_var_bool("DEBUG_GET_SUBDIV_CHAIN",false);
00636
00637 ret.clear();
00638
00639 if (level < 0) {
00640 err_adv(debug, "get_subdiv_chain: negative level (%d)", level);
00641 return 0;
00642 }
00643
00644 if (chain.empty()) {
00645 err_adv(debug, "get_subdiv_chain: empty chain passed in");
00646 return true;
00647 }
00648
00649 if (!chain.forms_chain()) {
00650 err_adv(debug, "get_subdiv_chain: non-chain passed in");
00651 return 0;
00652 }
00653
00654 ret.realloc(((chain.num()-1) * (1 << level)) + 1);
00655
00656 for (int i=1; i<chain.num(); i++) {
00657 Bvert_list segment;
00658 if (!get_subdiv_chain(chain[i-1], chain[i], level, segment))
00659 return false;
00660 if (!ret.empty())
00661 ret.pop();
00662 ret += segment;
00663 }
00664
00665 return true;
00666 }
00667
00668