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