00001
00002
00003
00004 #include "disp/ray.H"
00005 #include "mesh/bmesh.H"
00006 #include "mesh/patch.H"
00007 #include "std/run_avg.H"
00008 #include "std/config.H"
00009 #include "bfilters.H"
00010 #include "uv_data.H"
00011 #include "tex_coord_gen.H"
00012
00013 using namespace mlib;
00014
00015 Bedge::Bedge(Bvert* u, Bvert* v) :
00016 _v1(u),
00017 _v2(v),
00018 _f1(0),
00019 _f2(0),
00020 _adj(0),
00021 _sil_stamp(0)
00022 {
00023 *_v1 += this;
00024 *_v2 += this;
00025 }
00026
00027 Bedge::~Bedge()
00028 {
00029
00030 if (is_selected())
00031 MeshGlobal::deselect(this);
00032
00033
00034 if (_mesh) {
00035 if (_f1) _mesh->remove_face(_f1);
00036 if (_f2) _mesh->remove_face(_f2);
00037 if (_adj) {
00038 for (int i=0; i<_adj->num(); i++)
00039 _mesh->remove_face((*_adj)[i]);
00040 }
00041 }
00042
00043 if (!detach())
00044 err_msg("Bedge::~Bedge: can't detach");
00045 }
00046
00047 int
00048 Bedge::index() const
00049 {
00050
00051
00052 if (!_mesh) return -1;
00053 return _mesh->edges().get_index((Bedge*)this);
00054 }
00055
00056 int
00057 Bedge::num_all_faces() const
00058 {
00059
00060
00061 int ret = nfaces();
00062 if (_adj)
00063 ret += _adj->num();
00064 return ret;
00065 }
00066
00067 Bface_list
00068 Bedge::get_all_faces() const
00069 {
00070
00071
00072 Bface_list ret(num_all_faces());
00073 if (_adj) ret = *_adj;
00074 if (_f1) ret += _f1;
00075 if (_f2) ret += _f2;
00076 return ret;
00077 }
00078
00079 Bface*
00080 Bedge::f(int k) const
00081 {
00082 switch (k) {
00083 case 1: return _f1;
00084 case 2: return _f2;
00085 }
00086 k -= 3;
00087 return (_adj && _adj->valid_index(k)) ? (*_adj)[k] : 0;
00088 }
00089
00090 int
00091 Bedge::nfaces() const
00092 {
00093
00094
00095 return (_f1?1:0) + (_f2?1:0);
00096 }
00097
00098 Bface*
00099 Bedge::lookup_face(CBvert *v) const
00100 {
00101
00102
00103
00104 if (!v || this->contains(v))
00105 return 0;
00106
00107
00108 if (_f1 && _f1->contains(v))
00109 return _f1;
00110 if (_f2 && _f2->contains(v))
00111 return _f2;
00112 if (_adj) {
00113 for (int i=0; i<_adj->num(); i++) {
00114 Bface* f = (*_adj)[i];
00115 if (f->contains(v))
00116 return f;
00117 }
00118 }
00119 return 0;
00120 }
00121
00122 Bface*
00123 Bedge::lookup_face(CBedge *e) const
00124 {
00125
00126
00127 if (!e || this == e)
00128 return 0;
00129
00130
00131
00132 if (_f1 && _f1->contains(e))
00133 return _f1;
00134 if (_f2 && _f2->contains(e))
00135 return _f2;
00136 if (_adj) {
00137 for (int i=0; i<_adj->num(); i++) {
00138 Bface* f = (*_adj)[i];
00139 if (f->contains(e))
00140 return f;
00141 }
00142 }
00143 return 0;
00144 }
00145
00146 int
00147 Bedge::detach()
00148 {
00149 if (nfaces() > 0 || is_multi()) {
00150 err_msg("Bedge::detach: error: faces present");
00151 return 0;
00152 }
00153 int ret = (*_v1 -= this);
00154 return (*_v2 -= this) && ret;
00155 }
00156
00157 Wvec
00158 Bedge::vec() const
00159 {
00160
00161 return (_v2->loc() - _v1->loc());
00162 }
00163
00164 Wline
00165 Bedge::line() const
00166 {
00167 return Wline(_v1->loc(),_v2->loc());
00168 }
00169
00170 PIXELline
00171 Bedge::pix_line() const
00172 {
00173 return PIXELline(_v1->pix(), _v2->pix());
00174 }
00175
00176 bool
00177 Bedge::ndc_intersect(
00178 CNDCpt& p,
00179 CNDCpt& q,
00180 NDCpt& ret) const
00181 {
00182 return NDCline(_v1->ndc(), _v2->ndc()).intersect_segs(NDCline(p, q), ret);
00183 }
00184
00185 bool
00186 Bedge::view_intersect(
00187 CNDCpt& p,
00188 Wpt& nearpt,
00189 double& dist,
00190 double& d2d,
00191 Wvec& n
00192 ) const
00193 {
00194
00195
00196
00197
00198
00199
00200
00201
00202 Wline ray(NDCline(_v1->ndc(), _v2->ndc()).project_to_seg(p));
00203
00204
00205
00206 nearpt = Wline(_v1->wloc(), _v2->wloc()).project_to_seg(ray);
00207
00208
00209 dist = nearpt.dist(ray.point());
00210 d2d = PIXEL(nearpt).dist(PIXEL(ray.point()));
00211
00212
00213 Wvec n1;
00214 if (nfaces() == 2)
00215 n1 = norm();
00216 else if (nfaces() == 1)
00217 n1 = get_face()->norm();
00218 else
00219 n1 = (ray.point() - nearpt).normalized();
00220
00221
00222 n = (_mesh->inv_xform().transpose()*n1).normalized();
00223
00224 return 1;
00225 }
00226
00227 bool
00228 Bedge::operator +=(Bface* f)
00229 {
00230 if (!(f && f->contains(this))) {
00231 cerr << "Bedge::operator+=(Bface*): error: "
00232 << (f ? "face doesn't contain edge" : "null face")
00233 << endl;
00234 return 0;
00235 }
00236
00237
00238
00239 if (this->contains(f))
00240 return true;
00241
00242 if (_f1 && _f2) {
00243 if (_f2->is_secondary())
00244 demote(_f2);
00245 else if (_f1->is_secondary())
00246 demote(_f1);
00247 }
00248 if (_f1 && _f2) {
00249
00250 bool ret = add_multi(f);
00251 assert(ret);
00252 } else if (_f1) {
00253 _f2 = f;
00254 } else {
00255 _f1 = f;
00256 }
00257
00258 faces_changed();
00259 _v1->star_changed();
00260 _v2->star_changed();
00261
00262 return true;
00263 }
00264
00265 bool
00266 Bedge::operator -=(Bface* f)
00267 {
00268 if (f == _f1)
00269 _f1 = 0;
00270 else if (f == _f2)
00271 _f2 = 0;
00272 else if (is_multi(f))
00273 _adj->rem(f);
00274 else {
00275 err_msg("Bedge::operator-=(Bface*): error: unknown face");
00276 return 0;
00277 }
00278
00279 faces_changed();
00280 _v1->star_changed();
00281 _v2->star_changed();
00282
00283 return 1;
00284 }
00285
00286 bool
00287 Bedge::is_patch_boundary() const
00288 {
00289
00290
00291
00292
00293
00294
00295
00296
00297 static bool USE_UV = !Config::get_var_bool("SKIN_INHIBIT_UV",false);
00298
00299 return (
00300 (_f1 && _f2 && _f1->patch() != _f2->patch()) ||
00301 is_set(PATCH_BOUNDARY_BIT) ||
00302 (USE_UV && !UVdata::is_continuous(this))
00303 );
00304 }
00305
00306 Wpt&
00307 Bedge::mid_pt(Wpt& v) const
00308 {
00309 v = (_v1->loc() + _v2->loc())/2;
00310
00311 return v;
00312 }
00313
00314 double
00315 Bedge::avg_area() const
00316 {
00317 RunningAvg<double> avg(0);
00318 if (_f1) avg.add(_f1->area());
00319 if (_f2) avg.add(_f2->area());
00320 if (_adj) {
00321 for (int i=0; i<_adj->num(); i++)
00322 avg.add((*_adj)[i]->area());
00323 }
00324 return (avg.num() > 0) ? avg.val() : 0.0;
00325 }
00326
00327 Patch*
00328 Bedge::patch() const
00329 {
00330 Bface* f = frontfacing_face();
00331 f = f ? f : _f1 ? _f1 : _f2;
00332 return f ? f->patch() : 0;
00333 }
00334
00335 Wvec
00336 Bedge::norm() const
00337 {
00338
00339
00340 return ((_f1&&_f2) ? (_f1->qnorm()+_f2->qnorm()).normalized() :
00341 _f1 ? _f1->qnorm() :
00342 _f2 ? _f2->qnorm() :
00343 vec().perpend()
00344 );
00345 }
00346
00347
00348
00349 double
00350 Bedge::dot() const
00351 {
00352 return (_f1 && _f2) ? (_f1->norm() * _f2->norm()) : 1.0;
00353 }
00354
00355 void
00356 Bedge::allocate_adj()
00357 {
00358 if (!_adj) _adj = new Bface_list(1); assert(_adj);
00359 }
00360
00361 bool
00362 Bedge::is_multi() const
00363 {
00364
00365
00366 return (_adj && !_adj->empty());
00367 }
00368
00369 bool
00370 Bedge::is_multi(CBface* f) const
00371 {
00372
00373
00374 return (f && _adj && f->contains(this) && _adj->contains((Bface*)f));
00375 }
00376
00377 bool
00378 Bedge::demote(Bface* f)
00379 {
00380
00381
00382 static bool debug = Config::get_var_bool("DEBUG_NON_MANIFOLD",false);
00383 if (!(f && f->contains(this))) {
00384 if (debug)
00385 MeshGlobal::select(this);
00386 err_msg("Bedge::demote: error: %s face", f ? "unknown" : "null");
00387 return false;
00388 }
00389
00390
00391
00392 if (_f1 == f) {
00393 _f1 = 0;
00394 } else if (_f2 == f) {
00395 _f2 = 0;
00396 } else {
00397 assert(_adj && _adj->contains(f));
00398
00399
00400 return true;
00401 }
00402 bool ret = add_multi(f);
00403 assert(ret);
00404 return true;
00405 }
00406
00407 bool
00408 Bedge::add_multi(Bface* f)
00409 {
00410
00411
00412
00413
00414
00415 if (!(f && f->contains(this)))
00416 return false;
00417 if (f == _f1 || f == _f2) {
00418
00419
00420 return demote(f);
00421 } else {
00422 allocate_adj();
00423 _adj->add_uniquely(f);
00424 faces_changed();
00425 return true;
00426 }
00427 }
00428
00429 bool
00430 Bedge::can_promote() const
00431 {
00432
00433
00434
00435 return (!_f1 || _f1->is_secondary()) || (!_f2 || _f2->is_secondary());
00436 }
00437
00438 bool
00439 Bedge::promote(Bface* f)
00440 {
00441
00442
00443
00444 if (!(f && f->contains(this))) {
00445 if (Config::get_var_bool("DEBUG_NON_MANIFOLD",false))
00446 MeshGlobal::select(this);
00447 err_msg("Bedge::promote: error: %s face", f ? "unknown" : "null");
00448 return false;
00449 }
00450
00451 if (!(_adj && _adj->contains(f))) {
00452
00453
00454 assert(f == _f1 || f == _f2);
00455 return true;
00456 }
00457 _adj->rem(f);
00458 bool ret = add_primary(f);
00459 assert(ret);
00460 return ret;
00461 }
00462
00463 bool
00464 Bedge::add_primary(Bface* f)
00465 {
00466
00467
00468
00469 if (!(f && f->contains(this)))
00470 return false;
00471
00472
00473 assert(!this->contains(f));
00474
00475
00476 if (!_f1) {
00477 _f1 = f;
00478 } else if (!_f2) {
00479 _f2 = f;
00480 } else if (_f1->is_secondary()) {
00481 demote(_f1);
00482 _f1 = f;
00483 } else if (_f2->is_secondary()) {
00484 demote(_f2);
00485 _f2 = f;
00486 } else {
00487 return false;
00488 }
00489 return true;
00490 }
00491
00492 void
00493 Bedge::fix_multi()
00494 {
00495
00496
00497
00498
00499
00500 if (!_adj)
00501 return;
00502
00503
00504
00505 if (nfaces_satisfy(PrimaryFaceFilter()) > 2) {
00506 cerr << "Bedge::fix_multi: error: more than 2 primary faces" << endl;
00507 return;
00508 }
00509
00510
00511 for (int i=_adj->num()-1; i>=0; i--) {
00512 Bface *face = (*_adj)[i];
00513 if (face->is_primary()) {
00514 promote(face);
00515 }
00516 }
00517 }
00518
00519 Bface*
00520 Bedge::ccw_face(CBvert* v) const
00521 {
00522
00523
00524
00525
00526 return (!contains(v) ? 0 :
00527 (_f1 && _f1->edge_from_vert(v) == this) ? _f1 :
00528 (_f2 && _f2->edge_from_vert(v) == this) ? _f2 : 0
00529 );
00530 }
00531
00532 bool
00533 Bedge::consistent_orientation() const
00534 {
00535 return ((nfaces()<2) ? 1 :
00536 ((_f1->orientation(this) * _f2->orientation(this)) == -1) ? 1 : 0
00537 );
00538 }
00539
00540 bool
00541 Bedge::oriented_ccw(Bface* f) const
00542 {
00543
00544
00545
00546 if (!f && !(f = get_face()))
00547 return 0;
00548
00549 return f->orientation(this) == 1;
00550 }
00551
00552 void
00553 Bedge::bc2pos(CWvec& bc, Wpt& pos) const
00554 {
00555 pos = (bc[0]*_v1->loc()) + (bc[1]*_v2->loc());
00556 }
00557
00558 void
00559 Bedge::project_barycentric(CWpt &p, Wvec &bc) const
00560 {
00561 double t = ((p - _v1->loc()) * vec()) / sqr(length());
00562 bc.set(1.0 - t, t, 0);
00563 }
00564
00565 int
00566 Bedge::redefine(Bvert *v, Bvert *u)
00567 {
00568
00569
00570
00571
00572
00573
00574
00575
00576 assert(contains(v) && nfaces() == 0);
00577
00578 if (contains(u))
00579 return 0;
00580
00581 Bedge* dup = 0;
00582 if (v == _v1) {
00583 if ((dup = u->lookup_edge(_v2))) {
00584
00585
00586 if (is_crease())
00587 dup->set_crease(crease_val());
00588 return 0;
00589 }
00590
00591 *_v1 -= this;
00592 _v1 = u;
00593 *_v1 += this;
00594 } else if (v == _v2) {
00595
00596 if ((dup = u->lookup_edge(_v1))) {
00597 if (is_crease())
00598 dup->set_crease(crease_val());
00599 return 0;
00600 }
00601 *_v2 -= this;
00602 _v2 = u;
00603 *_v2 += this;
00604 } else assert(0);
00605
00606 geometry_changed();
00607
00608 return 1;
00609 }
00610
00611 bool
00612 Bedge::redef2(Bvert *v, Bvert *u)
00613 {
00614 static bool debug = Config::get_var_bool("DEBUG_MESH_OPS",false);
00615
00616
00617
00618
00619
00620
00621
00622
00623 if (!contains(v)) {
00624 err_adv(debug, "Bedge::redef2: error: edge doesn't contain v");
00625 return false;
00626 }
00627 if (contains(u)) {
00628 err_adv(debug, "Bedge::redef2: error: edge already contains u");
00629 return false;
00630 }
00631 Bvert* keeper = other_vertex(v);
00632 if (keeper->lookup_edge(u)) {
00633 err_adv(debug, "Bedge::redef2: error: would duplicate existing edge");
00634 return false;
00635 }
00636
00637 if (v == _v1) {
00638 *_v1 -= this;
00639 _v1 = u;
00640 *_v1 += this;
00641 } else if (v == _v2) {
00642 *_v2 -= this;
00643 _v2 = u;
00644 *_v2 += this;
00645 } else assert(0);
00646
00647 geometry_changed();
00648
00649 return true;
00650 }
00651
00652 void
00653 Bedge::set_new_vertices(
00654 Bvert *v1,
00655 Bvert *v2)
00656 {
00657
00658
00659 assert(nfaces() == 0 && !v1->lookup_edge(v2));
00660
00661 *_v1 -= this;
00662 *_v2 -= this;
00663 _v1 = v1;
00664 _v2 = v2;
00665
00666 *_v1 += this;
00667 *_v2 += this;
00668
00669 geometry_changed();
00670 }
00671
00672 void
00673 Bedge::notify_split(
00674 Bsimplex *new_simp)
00675 {
00676 Bsimplex::notify_split(new_simp);
00677 if (is_crease() && new_simp->dim() == 1)
00678 ((Bedge*)new_simp)->set_crease(crease_val());
00679 }
00680
00681 bool
00682 Bedge::is_polyline_end() const
00683 {
00684 return (is_polyline() && (_v1->is_polyline_end() || _v2->is_polyline_end()));
00685 }
00686
00687 bool
00688 Bedge::is_crease_end() const
00689 {
00690 return (is_crease() && (_v1->is_crease_end() || _v2->is_crease_end()));
00691 }
00692
00693 bool
00694 Bedge::is_chain_tip(CSimplexFilter& filter) const
00695 {
00696 return (filter.accept((Bedge*)this) &&
00697 (_v1->degree(filter) != 2 || _v2->degree(filter) != 2));
00698 }
00699
00700
00701
00702 bool
00703 Bedge::is_sil() const
00704 {
00705
00706 if (is_border())
00707 return true;
00708
00709
00710 if (!(_f1 || _f2))
00711 return false;
00712
00713
00714 if (!(_f1->norm().is_null() || _f2->norm().is_null()))
00715 return (_f1->front_facing() != _f2->front_facing());
00716
00717
00718 if (_f1->norm().is_null() && _f2->norm().is_null())
00719 return false;
00720
00721
00722
00723
00724
00725
00726
00727
00728 if (is_weak())
00729 return false;
00730
00731
00732 Bface* good_face = _f1;
00733 Bface* null_face = _f2;
00734 if (good_face->norm().is_null())
00735 swap(good_face, null_face);
00736 assert(null_face->norm().is_null());
00737
00738 if (null_face->is_quad() && !null_face->quad_partner()->norm().is_null())
00739 return (good_face->front_facing() !=
00740 null_face->quad_partner()->front_facing());
00741
00742
00743 return false;
00744 }
00745
00746 Bsimplex_list
00747 Bedge::neighbors() const
00748 {
00749 Bsimplex_list ret(4);
00750 ret += _v1;
00751 ret += _v2;
00752 if (_f1) ret += _f1;
00753 if (_f2) ret += _f2;
00754 if (_adj) {
00755 for (int j=0; j<_adj->num(); j++)
00756 ret += (*_adj)[j];
00757 }
00758 return ret;
00759 }
00760
00761 bool
00762 Bedge :: is_texture_seam()const
00763 {
00764
00765
00766
00767
00768 static bool USE_UV = !Config::get_var_bool("SKIN_INHIBIT_UV",false);
00769 if( USE_UV && !UVdata::is_continuous(this)) return true;
00770
00771
00772 if (_f1 && _f2 && !is_patch_boundary())
00773 {
00774
00775 TexCoordGen* tg = patch()->tex_coord_gen();
00776 if (tg)
00777 {
00778 UVpt tx1A = tg->uv_from_vert(_v1,_f1);
00779 UVpt tx1B = tg->uv_from_vert(_v1,_f2);
00780 UVpt tx2A = tg->uv_from_vert(_v2,_f1);
00781 UVpt tx2B = tg->uv_from_vert(_v2,_f2);
00782
00783 if ((tx1A!=tx1B) || (tx2A!=tx2B)) return true;
00784
00785 }
00786 }
00787
00788 return false;
00789 }
00790
00791 bool
00792 Bedge::is_crossable() const
00793 {
00794
00795 return (consistent_orientation() &&
00796 !(is_crease() || is_patch_boundary() || is_texture_seam()) );
00797 }
00798
00799 bool
00800 Bedge::is_stressed() const
00801 {
00802 return !is_crease() && _f1 && _f2 && (_f1->norm() * _f2->norm() < -.5);
00803 }
00804
00805 void
00806 Bedge::set_crease(ushort c)
00807 {
00808 set_bit(CREASE_BIT,c);
00809 crease_changed();
00810 }
00811
00812 void
00813 Bedge::inc_crease(ushort max_val)
00814 {
00815
00816
00817 ushort c = crease_val();
00818 if (c == USHRT_MAX)
00819 return;
00820 else if (c >= max_val)
00821 c = USHRT_MAX;
00822 else
00823 c++;
00824 set_crease(c);
00825 }
00826
00827 void
00828 Bedge::dec_crease(ushort max_val)
00829 {
00830
00831
00832 ushort c = crease_val();
00833 if (c == 0)
00834 return;
00835 else if (c <= max_val)
00836 c--;
00837 else
00838 c = max_val;
00839 set_crease(c);
00840 }
00841
00842 void
00843 Bedge::compute_crease(double d)
00844 {
00845
00846
00847 set_crease((dot() < d) ? USHRT_MAX : 0);
00848 }
00849
00850 void
00851 Bedge::set_convex()
00852 {
00853 set_bit(CONVEX_VALID_BIT);
00854 int b = (!_f1 || !_f2 ||
00855 ((_f1->norm() + _f2->norm()) *
00856 (_f1->other_vertex(_v1,_v2)->loc()-_v1->loc()) < 0));
00857 set_bit(CONVEX_BIT,b);
00858 }
00859
00860 Bface*
00861 Bedge::frontfacing_face() const
00862 {
00863
00864
00865 return ((_f1 && _f1->front_facing()) ? _f1 :
00866 (_f2 && _f2->front_facing()) ? _f2 :
00867 0);
00868 }
00869
00870 ostream& operator <<(ostream &os, CBedge &e)
00871 {
00872 return os << e.v(1)->index() << " " << e.v(2)->index() << " " ;
00873 }
00874
00875 bool
00876 Bedge::swapable(Bface*& face1,
00877 Bface*& face2,
00878 Bvert*& verta,
00879 Bvert*& vertb,
00880 Bvert*& vertc,
00881 Bvert*& vertd,
00882 bool favor_degree_six)
00883 {
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 static bool debug = Config::get_var_bool("DEBUG_EDGE_SWAP",false);
00907 if (is_patch_boundary() || is_crease() || is_multi()) {
00908 err_adv(debug, "Bedge::swapable: bad edge type");
00909 return 0;
00910 }
00911
00912
00913 face1 = ccw_face();
00914 face2 = other_face(face1);
00915
00916
00917 if (!(face1 && face2)) {
00918 err_adv(debug, "Bedge::swapable: need 2 faces");
00919 return 0;
00920 }
00921
00922
00923 static const double DOT_THRESH = cos(60.0 * M_PI / 180.0);
00924 if ((face1->norm() * face2->norm()) < DOT_THRESH) {
00925 err_adv(debug, "Bedge::swapable: too sharp");
00926 return 0;
00927 }
00928
00929
00930 verta = _v1;
00931 vertc = _v2;
00932 vertb = face2->other_vertex(verta, vertc);
00933 vertd = face1->other_vertex(verta, vertc);
00934
00935
00936
00937 if (!vertb || !vertd || vertb->lookup_edge(vertd)) {
00938 err_adv(debug, "Bedge::swapable: topology violation");
00939 return 0;
00940 }
00941
00942 CWpt& a=verta->loc();
00943 CWpt& b=vertb->loc();
00944 CWpt& c=vertc->loc();
00945 CWpt& d=vertd->loc();
00946
00947
00948 if ((cross(a-d,b-d).normalized() * cross(b-d,c-d).normalized()) <= DOT_THRESH) {
00949 err_adv(debug, "Bedge::swapable: new edge too sharp");
00950 return 0;
00951 }
00952
00953 Wvec ca = vec().normalized();
00954 Wvec ba = (b-a).normalized();
00955 Wvec da = (d-a).normalized();
00956 Wvec bc = (b-c).normalized();
00957 Wvec dc = (d-c).normalized();
00958
00959
00960
00961 double cur_max_dot = ca * ba;
00962 cur_max_dot = max(cur_max_dot, (ca * da));
00963 cur_max_dot = max(cur_max_dot,-(ca * bc));
00964 cur_max_dot = max(cur_max_dot,-(ca * dc));
00965
00966 Wvec bd = (b-d).normalized();
00967 double swap_max_dot = -(bd * da);
00968 swap_max_dot = max(swap_max_dot, -(bd * dc));
00969 swap_max_dot = max(swap_max_dot, (bd * ba));
00970 swap_max_dot = max(swap_max_dot, (bd * bc));
00971
00972
00973
00974 double cur_min_angle = Acos(cur_max_dot);
00975 double swap_min_angle = Acos(swap_max_dot);
00976
00977
00978 int k = 0;
00979 if (favor_degree_six) {
00980 k += ((verta->degree() <= 6) ? 1 : -1);
00981 k += ((vertc->degree() <= 6) ? 1 : -1);
00982 k += ((vertd->degree() >= 6) ? 1 : -1);
00983 k += ((vertb->degree() >= 6) ? 1 : -1);
00984 }
00985
00986
00987
00988 static const double handicap_unit = 8.0 / 180.0 * M_PI;
00989 return (swap_min_angle > (cur_min_angle + k*(handicap_unit)));
00990 }
00991
00992 bool
00993 Bedge::swap_is_legal() const
00994 {
00995 static bool debug = Config::get_var_bool("DEBUG_EDGE_SWAP",false);
00996
00997 if (!is_interior() || is_patch_boundary() || is_crease() || is_multi()) {
00998 err_adv(debug, "Bedge::swap_is_legal: bad edge type");
00999 return false;
01000 }
01001 if (!is_weak() && (_f1->is_quad() || _f2->is_quad())) {
01002 err_adv(debug, "Bedge::swap_is_legal: swap would wreck quad-ness");
01003 return false;
01004 }
01005 if ((UVdata::has_uv(_f1) || UVdata::has_uv(_f2)) &&
01006 !UVdata::is_continuous(this)) {
01007 err_adv(debug, "Bedge::swap_is_legal: can't swap uv-discontinuous edge");
01008 return false;
01009 }
01010 Bvert* o1 = opposite_vert1();
01011 Bvert* o2 = opposite_vert2();
01012 assert(o1 && o2);
01013
01014 return !lookup_edge(o1,o2);
01015 }
01016
01017 bool
01018 Bedge::do_swap()
01019 {
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 static bool debug = Config::get_var_bool("DEBUG_MESH_OPS",false);
01042
01043 if (!swap_is_legal()) {
01044 err_adv(debug, "Bedge::do_swap: illegal");
01045 return false;
01046 }
01047
01048
01049 Bface* g1 = ccw_face();
01050 Bface* g2 = cw_face();
01051 assert(g1 && g2);
01052
01053
01054 Bvert* o1 = g1->other_vertex(this);
01055 Bvert* o2 = g2->other_vertex(this);
01056 Bvert* v1 = _v1;
01057 Bvert* v2 = _v2;
01058
01059
01060 UVpt uvo1, uvo2, uvv1, uvv2;
01061 bool do_uv = false;
01062 if ((UVdata::has_uv(_f1) || UVdata::has_uv(_f2))) {
01063 assert(UVdata::has_uv(_f1) && UVdata::has_uv(_f2));
01064 assert(UVdata::is_continuous(this));
01065 do_uv = true;
01066 uvo1 = UVdata::get_uv(o1,g1);
01067 uvo2 = UVdata::get_uv(o2,g2);
01068 uvv1 = UVdata::get_uv(v1,g1);
01069 uvv2 = UVdata::get_uv(v2,g1);
01070 }
01071
01072
01073 g1->Bface::detach();
01074 g2->Bface::detach();
01075
01076
01077 Bedge::set_new_vertices(o2,o1);
01078
01079
01080 g1->Bface::redefine(v2,o2);
01081 g2->Bface::redefine(v1,o1);
01082
01083 if (do_uv) {
01084 UVdata::set(o1,g1,uvo1);
01085 UVdata::set(v1,g1,uvv1);
01086 UVdata::set(o2,g1,uvo2);
01087 UVdata::set(o2,g2,uvo2);
01088 UVdata::set(v2,g2,uvv2);
01089 UVdata::set(o1,g2,uvo1);
01090 }
01091
01092 if (!(g1->check() && g2->check())) {
01093 err_adv(debug, "Bedge::do_swap: check failed");
01094 }
01095
01096 return true;
01097 }
01098
01099 void
01100 Bedge::geometry_changed()
01101 {
01102
01103
01104 Bsimplex::geometry_changed();
01105 }
01106
01107 void
01108 Bedge::crease_changed()
01109 {
01110 _v1->crease_changed();
01111 _v2->crease_changed();
01112 }
01113
01114 void
01115 Bedge::normal_changed()
01116 {
01117 clear_bit(CONVEX_VALID_BIT);
01118 _sil_stamp = 0;
01119
01120 Bsimplex::normal_changed();
01121 }
01122
01123 void
01124 Bedge::faces_changed()
01125 {
01126
01127 normal_changed();
01128
01129
01130
01131
01132 _v1->clear_bit(Bvert::VALID_NON_MANIFOLD_BIT);
01133 _v2->clear_bit(Bvert::VALID_NON_MANIFOLD_BIT);
01134 }
01135
01136
01137
01138
01139 int
01140 Bedge::which_side(CWplane& plane) const
01141 {
01142 Wpt p = plane.origin();
01143 Wvec n = plane.normal();
01144 double dot1 = (p - _v1->loc()) * n;
01145 double dot2 = (p - _v2->loc()) * n;
01146 return dot1*dot2 < 1e-20 ? 0 : Sign(dot1);
01147 }
01148
01149
01150
01151
01152
01153 bool
01154 Bedge::local_search(Bsimplex *&end, Wvec &final_bc,
01155 CWpt &target, Wpt &reached,
01156 Bsimplex *repeater, int iters)
01157 {
01158 if (iters <= 0)
01159 return 0;
01160
01161 Wvec bc;
01162 bool is_on_sim = 0;
01163 Wpt nearpt = nearest_pt(target, bc, is_on_sim);
01164 Bsimplex* sim = bc2sim(bc);
01165
01166 if (!is_on_sim) {
01167
01168 if (sim == repeater)
01169 return 0;
01170
01171 if (sim != this) {
01172 assert(is_vert(sim));
01173 Bvert* v = (Bvert*)sim;
01174
01175 for (int i=0; i<v->degree(); i++) {
01176 int good_path = v->e(i)->local_search(end, final_bc, target,
01177 reached, sim, iters-1);
01178 if (good_path == 1)
01179 return 1;
01180 else if (good_path==-1)
01181 return repeater ? true : false;
01182
01183 }
01184 }
01185 }
01186
01187 reached = nearpt;
01188 end = this;
01189 final_bc = bc;
01190
01191 return 1;
01192 }
01193
01194 NDCpt
01195 Bedge::nearest_pt_ndc(CNDCpt& p, Wvec &bc, int &is_on_simplex) const
01196 {
01197 NDCpt a = _v1->ndc();
01198 NDCpt b = _v2->ndc();
01199
01200 NDCvec ab = b - a;
01201 NDCvec ac = p - a;
01202
01203 double dot = (ab * ac) / ab.length_sqrd();
01204 bc.set(1-dot, dot, 0);
01205
01206 if (dot < gEpsZeroMath) {
01207 bc.set(1, 0, 0);
01208 is_on_simplex = 0;
01209 } else if (1-dot < gEpsZeroMath) {
01210 bc.set(0, 1, 0);
01211 is_on_simplex = 0;
01212 }
01213
01214 return (bc[0] * a) + (bc[1] * b);
01215 }
01216
01217 Wpt
01218 Bedge::nearest_pt(CWpt& p, Wvec &bc, bool &is_on_simplex) const
01219 {
01220 Wvec ab = _v2->loc() - _v1->loc();
01221 Wvec ac = p - _v1->loc();
01222
01223 double dot = (ab * ac) / ab.length_sqrd();
01224 bc.set(1-dot, dot, 0);
01225
01226 if (dot < gEpsZeroMath) {
01227 bc.set(1, 0, 0);
01228 is_on_simplex = (dot >= 0);
01229 } else if (1-dot < gEpsZeroMath) {
01230 bc.set(0, 1, 0);
01231 is_on_simplex = (dot <= 1);
01232 }
01233
01234 return (bc[0] * _v1->loc()) + (bc[1] * _v2->loc());
01235 }
01236
01237 Wpt
01238 Bedge::mid_pt() const
01239 {
01240 return (_v1->loc() + _v2->loc())/2;
01241 }
01242
01243 int
01244 Bedge::nfaces_satisfy(CSimplexFilter& f) const
01245 {
01246 return ((f.accept(_f1) ? 1 : 0) +
01247 (f.accept(_f2) ? 1 : 0) +
01248 (_adj ? _adj->num_satisfy(f) : 0));
01249 }
01250
01251
01252
01253
01254
01255
01256
01257 bool
01258 BoundaryEdgeFilter::accept(CBsimplex* s) const
01259 {
01260
01261
01262
01263
01264
01265 if (!is_edge(s))
01266 return false;
01267 int n = ((Bedge*)s)->nfaces_satisfy(_filter);
01268 return (n > 0 && n != 2);
01269 }
01270
01271
01272
01273
01274
01275 void
01276 Bedge_list::clear_vert_flags() const
01277 {
01278
01279
01280 for (int i=0; i<_num; i++) {
01281 _array[i]->v1()->clear_flag();
01282 _array[i]->v2()->clear_flag();
01283 }
01284 }
01285
01286
01287 inline void
01288 screen(Bvert_list& list, Bvert* v)
01289 {
01290 if (v && !v->flag()) {
01291 v->set_flag();
01292 list += v;
01293 }
01294 }
01295
01296 Bvert_list
01297 Bedge_list::get_verts() const
01298 {
01299
01300
01301
01302 clear_vert_flags();
01303
01304
01305 Bvert_list ret;
01306 for (int i=0; i<_num; i++) {
01307 screen(ret, _array[i]->v1());
01308 screen(ret, _array[i]->v2());
01309 }
01310 return ret;
01311 }
01312
01313 inline void
01314 add_face(Bface* f, Bface_list& ret)
01315 {
01316
01317
01318
01319
01320
01321
01322 if (f && !f->flag()) {
01323 f->set_flag();
01324 ret += f;
01325 }
01326 }
01327
01328 inline void
01329 add_faces(Bface_list* faces, Bface_list& ret)
01330 {
01331
01332
01333 if (!faces)
01334 return;
01335 for (int i=0; i<faces->num(); i++)
01336 add_face((*faces)[i], ret);
01337 }
01338
01339 inline void
01340 add_faces(Bedge* e, Bface_list& ret)
01341 {
01342
01343
01344
01345
01346 if (e) {
01347 add_face(e->f1(), ret);
01348 add_face(e->f2(), ret);
01349 add_faces(e->adj(), ret);
01350 }
01351 }
01352
01353 Bface_list
01354 Bedge_list::get_faces() const
01355 {
01356
01357
01358
01359 clear_flag02();
01360
01361
01362 Bface_list ret;
01363 for (int i=0; i<_num; i++)
01364 add_faces(_array[i], ret);
01365 return ret;
01366 }
01367
01368 void
01369 Bedge_list::mark_edges() const
01370 {
01371
01372
01373
01374
01375
01376 get_verts().clear_flag02();
01377
01378
01379 set_flags(1);
01380 }
01381
01382 Bvert_list
01383 Bedge_list::fold_verts() const
01384 {
01385
01386 mark_edges();
01387
01388
01389
01390
01391
01392
01393 return get_verts().filter(FoldVertFilter(SimplexFlagFilter(1)));
01394 }
01395
01396 bool
01397 Bedge_list::is_simple() const
01398 {
01399 mark_edges();
01400 return
01401 get_verts().filter(
01402 !(VertDegreeFilter(2, SimplexFlagFilter(1)) ||
01403 VertDegreeFilter(1, SimplexFlagFilter(1)))).empty();
01404 }
01405
01406