00001
00002
00003
00004 #ifndef BEDGE_H_HAS_BEEN_INCLUDED
00005 #define BEDGE_H_HAS_BEEN_INCLUDED
00006
00007 #include "net/data_item.H"
00008 #include "simplex_filter.H"
00009 #include "simplex_array.H"
00010
00011
00012 class Patch;
00013
00014 class BMESH;
00015 typedef const BMESH CBMESH;
00016
00017
00018
00019
00020
00021
00022
00023 class Bedge : public Bsimplex {
00024 public:
00025
00026
00027
00028
00029 enum {
00030 CREASE_BIT = Bsimplex::NEXT_AVAILABLE_BIT,
00031 PATCH_BOUNDARY_BIT,
00032 CONVEX_BIT,
00033 CONVEX_VALID_BIT,
00034 WEAK_BIT,
00035 NEXT_AVAILABLE_BIT
00036 };
00037
00038
00039
00040 Bedge(Bvert* u, Bvert* v);
00041 virtual ~Bedge();
00042
00043
00044
00045 Bvert* v1() const { return _v1; }
00046 Bvert* v2() const { return _v2; }
00047 Bvert* v(int k) const { return (&_v1)[k-1]; }
00048
00049
00050 Bface* f1() const { return _f1; }
00051 Bface* f2() const { return _f2; }
00052
00053
00054
00055 int nfaces() const;
00056
00057
00058
00059 int num_all_faces() const;
00060
00061
00062
00063 Bface_list get_all_faces() const;
00064
00065
00066 Bface* f(int k) const;
00067
00068 Patch* patch() const;
00069
00070 uint sil_stamp() const { return _sil_stamp; }
00071 void set_sil_stamp(uint s) { _sil_stamp = s; }
00072
00073
00074
00075 void clear_flag02();
00076
00077
00078
00079 Wvec vec() const;
00080 double length() const { return vec().length(); }
00081 Wline line() const;
00082 PIXELline pix_line() const;
00083 Wpt mid_pt() const;
00084 Wpt& mid_pt(mlib::Wpt& v) const;
00085 Wvec norm() const;
00086 double dot() const;
00087 double avg_area() const;
00088
00089
00090
00091
00092 double dihedral_angle() const { return Acos(dot()); }
00093
00094 Wpt interp(double s) const;
00095
00096
00097 bool is_convex() const {
00098 if (!is_set(CONVEX_VALID_BIT))
00099 ((Bedge*)this)->set_convex();
00100 return is_set(CONVEX_BIT);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 Bvert* opposite_vert(CBface* f) const;
00110
00111
00112 Bvert* opposite_vert1() const { return opposite_vert(_f2); }
00113 Bvert* opposite_vert2() const { return opposite_vert(_f1); }
00114
00115
00116 Bvert* other_vertex(CBvert* v) const {
00117 return (v==_v1)?_v2:(v==_v2)?_v1:0;
00118 }
00119
00120
00121
00122 int vindex(CBvert* v) const { return (v==_v1) ? 1 : (v==_v2) ? 2 : -1; }
00123
00124 Bvert* shared_vert(CBedge* e) const {
00125 return (
00126 (e == 0 || e == this) ? 0 :
00127 e->contains(_v1) ? _v1 :
00128 e->contains(_v2) ? _v2 : 0
00129 );
00130 }
00131
00132
00133 bool contains(CBvert* v) const { return (_v1 == v || _v2 == v); }
00134 bool contains(CBface* f) const;
00135
00136
00137 bool same_verts(CBvert* u, CBvert* v) const {
00138 return contains(u) && contains(v);
00139 }
00140
00141
00142 Bface* other_face(CBface *f) const { return (f==_f1)?_f2:(f==_f2)?_f1:0;}
00143
00144
00145
00146
00147 Bface* frontfacing_face() const;
00148
00149
00150 Bface* lookup_face(CBvert *v) const;
00151 Bface* lookup_face(CBedge *e) const;
00152
00153
00154
00155
00156 Bface* ccw_face(CBvert* v) const;
00157 Bface* cw_face(CBvert* v) const { return ccw_face(other_vertex(v)); }
00158
00159
00160
00161 Bface* ccw_face() const { return ccw_face(_v1); }
00162 Bface* cw_face() const { return ccw_face(_v2); }
00163
00164
00165 int num_quads() const;
00166
00167
00168
00169 int nfaces_satisfy(CSimplexFilter& f) const;
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 Bface_list* adj() const { return _adj; }
00180
00181 protected:
00182
00183 void allocate_adj();
00184
00185
00186
00187 virtual bool add_multi(Bface* f);
00188
00189
00190
00191 virtual bool add_primary(Bface* f);
00192
00193 public:
00194
00195
00196
00197 virtual bool can_promote() const;
00198
00199
00200
00201 bool promote(Bface* f);
00202
00203
00204 bool demote(Bface* f);
00205
00206
00207 bool is_multi() const;
00208
00209
00210 bool is_multi(CBface* f) const;
00211
00212
00213
00214
00215
00216 void fix_multi();
00217
00218
00219 bool is_primary() const;
00220
00221
00222
00223
00224 bool is_secondary() const { return !is_primary(); }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 bool is_interior() const { return nfaces() == 2; }
00248 bool is_border() const { return nfaces() == 1; }
00249 bool is_polyline() const { return nfaces() == 0; }
00250 bool is_crease() const { return is_set(CREASE_BIT); }
00251 bool is_weak() const { return is_set(WEAK_BIT); }
00252 bool is_strong() const { return !is_weak(); }
00253 bool is_poly_crease() const { return is_crease() || (nfaces()<2);}
00254 bool is_strong_poly_crease() const { return is_strong() &&
00255 is_poly_crease(); }
00256 bool is_patch_boundary() const;
00257 bool is_texture_seam() const;
00258 bool is_sil() const;
00259 bool is_stressed() const;
00260 bool is_crossable() const;
00261
00262
00263 bool consistent_orientation() const;
00264 bool oriented_ccw(Bface* =0) const;
00265
00266
00267
00268
00269 bool is_polyline_end() const;
00270 bool is_crease_end() const;
00271 bool is_chain_tip(CSimplexFilter& filter) const;
00272
00273
00274 void set_patch_boundary(int b=1) { set_bit(PATCH_BOUNDARY_BIT,b); }
00275
00276
00277
00278 void compute_crease(double dot);
00279
00280
00281
00282 virtual void set_crease(unsigned short = USHRT_MAX);
00283 virtual unsigned short crease_val() const { return is_crease() ? 1 : 0; }
00284
00285
00286
00287
00288
00289
00290
00291 void inc_crease(ushort max_val = USHRT_MAX);
00292 void dec_crease(ushort max_val = USHRT_MAX);
00293
00294
00295
00296
00297
00298 virtual uint rel_level() const { return 0; }
00299
00300
00301
00302 bool operator +=(Bface* face);
00303 bool operator -=(Bface* face);
00304 int detach();
00305
00306
00307 virtual int redefine(Bvert *v, Bvert *u);
00308
00309
00310 virtual void set_new_vertices(Bvert *v1, Bvert *v2);
00311
00312
00313
00314 bool swapable(Bface*&, Bface*&, Bvert*&, Bvert*&, Bvert*&, Bvert*&,
00315 bool favor_degree_six=0);
00316
00317
00318
00319
00320 bool swap_is_legal() const;
00321
00322
00323 virtual bool do_swap();
00324
00325
00326 virtual bool redef2(Bvert *v, Bvert *u);
00327
00328
00329
00330 bool ndc_intersect(CNDCpt& p, mlib::CNDCpt& q, mlib::NDCpt& ret) const;
00331 int which_side(CWplane& plane) const;
00332
00333
00334
00335 virtual void notify_split(Bsimplex*);
00336 virtual void geometry_changed();
00337 virtual void normal_changed();
00338 virtual void crease_changed();
00339 virtual void faces_changed();
00340
00341
00342
00343 friend ostream &operator <<(ostream &os, CBedge &e);
00344
00345
00346
00347
00348 virtual int dim() const { return 1; }
00349
00350
00351 virtual int index() const;
00352
00353
00354
00355
00356
00357
00358 virtual bool view_intersect(
00359 CNDCpt&,
00360 Wpt&,
00361 double&,
00362 double&,
00363 Wvec& n
00364 ) const;
00365
00366
00367 virtual Bface* get_face() const { return _f1?_f1:_f2?_f2:0; }
00368 virtual bool on_face(CBface* f) const { return contains(f); }
00369
00370
00371 Bface* screen_face(CSimplexFilter& filter) const;
00372
00373
00374 virtual void project_barycentric(CWpt &p, mlib::Wvec &bc) const;
00375
00376
00377 virtual void bc2pos(CWvec& bc, mlib::Wpt& pos) const;
00378
00379
00380
00381 virtual Bsimplex* bc2sim(CWvec& bc) const
00382 { return ((bc[0] >= 1) ? (Bsimplex*)_v1 :
00383 (bc[1] >= 1) ? (Bsimplex*)_v2 :
00384 (Bsimplex*)this); }
00385
00386
00387
00388 virtual Bsimplex_list neighbors() const;
00389
00390
00391 virtual bool local_search(Bsimplex *&end, Wvec &final_bc,
00392 CWpt &target, mlib::Wpt &reached,
00393 Bsimplex *repeater = 0, int iters = 30);
00394 virtual NDCpt nearest_pt_ndc(mlib::CNDCpt& p, mlib::Wvec &bc, int &is_on_simplex) const;
00395 virtual Wpt nearest_pt(mlib::CWpt& p, mlib::Wvec &bc, bool &is_on_simplex) const;
00396
00397
00398
00399
00400 protected:
00401
00402 Bvert* _v1;
00403 Bvert* _v2;
00404 Bface* _f1;
00405 Bface* _f2;
00406 Bface_list* _adj;
00407
00408
00409
00410 uint _sil_stamp;
00411
00412
00413
00414 void set_convex();
00415 };
00416
00417
00418
00419
00420
00421 inline Bedge*
00422 bedge(Bsimplex* sim)
00423 {
00424 return is_edge(sim) ? (Bedge*)sim : 0;
00425 }
00426
00427
00428
00429
00430 class CreaseEdgeFilter : public SimplexFilter {
00431 public:
00432 virtual bool accept(CBsimplex* s) const {
00433 return is_edge(s) && ((Bedge*)s)->is_crease();
00434 }
00435 };
00436
00437 class SharpEdgeFilter : public SimplexFilter {
00438
00439
00440 public:
00441 SharpEdgeFilter(double min_angle_deg=60) : _max_dot(0) {
00442 set_angle(min_angle_deg);
00443 }
00444
00445 void set_angle(double min_angle_deg) {
00446 _max_dot = cos(deg2rad(min_angle_deg));
00447 }
00448
00449 virtual bool accept(CBsimplex* s) const {
00450 return is_edge(s) && (((Bedge*)s)->dot() < _max_dot);
00451 }
00452
00453 protected:
00454 double _max_dot;
00455 };
00456
00457 class InteriorEdgeFilter : public SimplexFilter {
00458 public:
00459 virtual bool accept(CBsimplex* s) const {
00460 return is_edge(s) && ((Bedge*)s)->is_interior();
00461 }
00462 };
00463
00464 class BorderEdgeFilter : public SimplexFilter {
00465 public:
00466 virtual bool accept(CBsimplex* s) const {
00467 return is_edge(s) && ((Bedge*)s)->is_border();
00468 }
00469 };
00470
00471 class PolylineEdgeFilter : public SimplexFilter {
00472 public:
00473 virtual bool accept(CBsimplex* s) const {
00474 return is_edge(s) && ((Bedge*)s)->is_polyline();
00475 }
00476 };
00477
00478 class MultiEdgeFilter : public SimplexFilter {
00479 public:
00480 virtual bool accept(CBsimplex* s) const {
00481 return is_edge(s) && ((Bedge*)s)->is_multi();
00482 }
00483 };
00484
00485 class CanPromoteEdgeFilter : public SimplexFilter {
00486 public:
00487 virtual bool accept(CBsimplex* s) const {
00488 return is_edge(s) && ((Bedge*)s)->can_promote();
00489 }
00490 };
00491
00492 class CrossableEdgeFilter : public SimplexFilter {
00493 public:
00494 virtual bool accept(CBsimplex* s) const {
00495 return is_edge(s) && ((Bedge*)s)->is_crossable();
00496 }
00497 };
00498
00499 class UncrossableEdgeFilter : public SimplexFilter {
00500 public:
00501 virtual bool accept(CBsimplex* s) const {
00502 return is_edge(s) && !((Bedge*)s)->is_crossable();
00503 }
00504 };
00505
00506 class PrimaryEdgeFilter : public SimplexFilter {
00507 public:
00508 virtual bool accept(CBsimplex* s) const {
00509 return is_edge(s) && ((Bedge*)s)->is_primary();
00510 }
00511 };
00512
00513 class SecondaryEdgeFilter : public SimplexFilter {
00514 public:
00515 virtual bool accept(CBsimplex* s) const {
00516 return is_edge(s) && ((Bedge*)s)->is_secondary();
00517 }
00518 };
00519
00520 class ConvexEdgeFilter : public SimplexFilter {
00521 public:
00522 virtual bool accept(CBsimplex* s) const {
00523 return is_edge(s) && ((Bedge*)s)->is_convex();
00524 }
00525 };
00526
00527 class ConcaveEdgeFilter : public SimplexFilter {
00528 public:
00529 virtual bool accept(CBsimplex* s) const {
00530 return is_edge(s) && !((Bedge*)s)->is_convex();
00531 }
00532 };
00533
00534 class WeakEdgeFilter : public SimplexFilter {
00535 public:
00536 virtual bool accept(CBsimplex* s) const {
00537 return is_edge(s) && ((Bedge*)s)->is_weak();
00538 }
00539 };
00540
00541 class StrongEdgeFilter : public SimplexFilter {
00542 public:
00543 virtual bool accept(CBsimplex* s) const {
00544 return is_edge(s) && ((Bedge*)s)->is_strong();
00545 }
00546 };
00547
00548
00549 class FrontFacingEdgeFilter : public SimplexFilter {
00550 public:
00551 virtual bool accept(CBsimplex* s) const {
00552 return is_edge(s) && (((Bedge*)s)->frontfacing_face() != 0);
00553 }
00554 };
00555
00556 class StressedEdgeFilter : public SimplexFilter {
00557 public:
00558 virtual bool accept(CBsimplex* s) const {
00559 return is_edge(s) && ((Bedge*)s)->is_stressed();
00560 }
00561 };
00562
00563 class ConsistentEdgeFilter : public SimplexFilter {
00564 public:
00565 virtual bool accept(CBsimplex* s) const {
00566 return is_edge(s) && ((Bedge*)s)->consistent_orientation();
00567 }
00568 };
00569
00570 class SilEdgeFilter : public SimplexFilter {
00571 public:
00572 virtual bool accept(CBsimplex* s) const {
00573 return is_edge(s) && ((Bedge*)s)->is_sil();
00574 }
00575 };
00576
00577 class StrongPolyCreaseEdgeFilter : public SimplexFilter {
00578 public:
00579 virtual bool accept(CBsimplex* s) const {
00580 return is_edge(s) && ((Bedge*)s)->is_strong_poly_crease();
00581 }
00582 };
00583
00584 class ManifoldEdgeFilter : public SimplexFilter {
00585 public:
00586 ManifoldEdgeFilter(CSimplexFilter& f) : _filter(f) {}
00587
00588
00589 virtual bool accept(CBsimplex* s) const {
00590 return is_edge(s) && ((Bedge*)s)->nfaces_satisfy(_filter) <= 2;
00591 }
00592
00593 protected:
00594 CSimplexFilter& _filter;
00595 };
00596
00597 class BoundaryEdgeFilter : public SimplexFilter {
00598 public:
00599 BoundaryEdgeFilter(CSimplexFilter& f) : _filter(f) {}
00600
00601
00602
00603 virtual bool accept(CBsimplex* s) const;
00604
00605 protected:
00606 CSimplexFilter& _filter;
00607 };
00608
00609
00610
00611
00612
00613
00614
00615 class NewSilEdgeFilter : public SimplexFilter {
00616 public:
00617 NewSilEdgeFilter(uint frame_number, bool skip_sec=true) :
00618 _stamp(frame_number), _skip_secondary(skip_sec) {}
00619
00620 virtual bool accept(CBsimplex* s) const {
00621 if (!is_edge(s))
00622 return false;
00623 Bedge* e = (Bedge*)s;
00624 if (e->sil_stamp() == _stamp)
00625 return 0;
00626 e->set_sil_stamp(_stamp);
00627 if (_skip_secondary && e->is_secondary())
00628 return false;
00629 return e->is_sil();
00630 }
00631
00632 protected:
00633 uint _stamp;
00634 bool _skip_secondary;
00635 };
00636
00637
00638
00639
00640
00641
00642
00643
00644 class ChainTipEdgeFilter : public SimplexFilter {
00645 public:
00646 ChainTipEdgeFilter(CSimplexFilter& f) : _filter(f) {}
00647
00648 virtual bool accept(CBsimplex* s) const {
00649 return is_edge(s) && ((Bedge*)s)->is_chain_tip(_filter);
00650 }
00651 protected:
00652 CSimplexFilter& _filter;
00653 };
00654
00655
00656
00657
00658 typedef const Bedge_list CBedge_list;
00659 class Bedge_list : public SimplexArray<Bedge_list,Bedge*> {
00660 public:
00661
00662
00663
00664 Bedge_list(CARRAY<Bedge*>& list) : SimplexArray<Bedge_list,Bedge*>(list) {}
00665 explicit Bedge_list(int n=0) : SimplexArray<Bedge_list,Bedge*>(n) {}
00666 explicit Bedge_list(Bedge* e) : SimplexArray<Bedge_list,Bedge*>(e) {}
00667
00668
00669
00670 void clear_flag02() const {
00671 for (int i=0; i<_num; i++)
00672 _array[i]->clear_flag02();
00673 }
00674
00675
00676
00677
00678 double total_length() const {
00679 double ret = 0;
00680 for (int i=0; i<_num; i++)
00681 ret += _array[i]->length();
00682 return ret;
00683 }
00684
00685
00686 double avg_len() const { return empty() ? 0 : total_length()/_num; }
00687
00688
00689 double min_edge_len() const {
00690 if (empty())
00691 return 0;
00692 double ret = first()->length();
00693 for(int i=1; i<_num; i++)
00694 ret = min(ret,_array[i]->length());
00695 return ret;
00696 }
00697
00698
00699
00700 bool nfaces_is_equal(int num_faces) const {
00701 if (empty())
00702 return false;
00703 for (int i=0; i<_num; i++)
00704 if (_array[i]->nfaces() != num_faces)
00705 return false;
00706 return true;
00707 }
00708
00709 void inc_crease_vals(ushort max_val = USHRT_MAX) const {
00710 for (int i=0; i<num(); i++)
00711 _array[i]->inc_crease(max_val);
00712 }
00713
00714 void dec_crease_vals(ushort max_val = USHRT_MAX) const {
00715 for (int i=0; i<num(); i++)
00716 _array[i]->dec_crease(max_val);
00717 }
00718
00719
00720 Bvert_list get_verts() const;
00721
00722
00723 Bface_list get_faces() const;
00724
00725
00726
00727 Bface_list get_primary_faces() const;
00728
00729
00730
00731 Bvert_list fold_verts() const;
00732
00733
00734
00735 bool is_simple() const;
00736
00737 Bedge_list strong_edges() const { return filter(StrongEdgeFilter()); }
00738 Bedge_list weak_edges() const { return filter(WeakEdgeFilter()); }
00739
00740
00741
00742 Bedge_list primary_edges() const { return filter(PrimaryEdgeFilter()); }
00743 Bedge_list secondary_edges() const { return filter(SecondaryEdgeFilter()); }
00744
00745 bool is_primary() const { return all_satisfy(PrimaryEdgeFilter()); }
00746 bool is_secondary() const { return all_satisfy(SecondaryEdgeFilter());}
00747
00748 protected:
00749
00750 void clear_vert_flags() const;
00751
00752
00753
00754 void mark_edges() const;
00755 };
00756
00757 #endif // BEDGE_H_HAS_BEEN_INCLUDED
00758
00759