Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

bedge.H

Go to the documentation of this file.
00001 /**********************************************************************
00002  * bedge.H
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  * Bedge:
00019  *
00020  *      An edge joining two vertices, bordering one or two faces.
00021  *      The order of vertices is arbitrary.
00022  **********************************************************************/
00023 class Bedge : public Bsimplex {
00024  public:
00025 
00026    //******** FLAG BITS ********
00027 
00028    // Used to store boolean states (see Bsimplex class):
00029    enum {
00030       CREASE_BIT = Bsimplex::NEXT_AVAILABLE_BIT, // it's a crease
00031       PATCH_BOUNDARY_BIT,                        // it's a patch boundary
00032       CONVEX_BIT,                                // it's convex
00033       CONVEX_VALID_BIT,                          // previous bit is believable
00034       WEAK_BIT,                                  // edge is labelled "weak"
00035       NEXT_AVAILABLE_BIT                         // derived classes start here
00036    };
00037 
00038    //******** MANAGERS ********
00039 
00040    Bedge(Bvert* u, Bvert* v);
00041    virtual ~Bedge();
00042 
00043    //******** ACCESSORS ********
00044 
00045    Bvert* v1()                  const   { return _v1; }
00046    Bvert* v2()                  const   { return _v2; }
00047    Bvert* v(int k)              const   { return (&_v1)[k-1]; } // k in [1..2]
00048 
00049    // Return primary face 1 or 2:
00050    Bface* f1()                  const   { return _f1; } 
00051    Bface* f2()                  const   { return _f2; }
00052 
00053    // Return number of non-NULL primary faces (f1 or f2):
00054    // XXX - ignores multi faces at this time:
00055    int    nfaces()              const;
00056 
00057    // Number of faces, including multi faces:
00058    // (For more info, see comment below about NON-MANIFOLD MESHES)
00059    int    num_all_faces()       const;
00060 
00061    // return a list of all adjacent faces, including f1 and f2
00062    // (but not if they are null):
00063    Bface_list get_all_faces() const;
00064 
00065    // Return face k, starting from 1, including "multi" faces:
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    // Clear flag of this edge and adjacent faces:
00074    // (clearing propagates from dim 0 to dim 2)
00075    void clear_flag02(); // defined in bface.H
00076    
00077    //******** GEOMETRIC MEASURES ********
00078 
00079    Wvec    vec()          const;  // vector from vertex 1 to vertex 2
00080    double  length()       const   { return vec().length(); }
00081    Wline   line()         const;  // mlib::Wline defined by endpoints
00082    PIXELline pix_line() const; //returns a line in screen space
00083    Wpt     mid_pt()       const;  // returns midpoint of edge
00084    Wpt&    mid_pt(mlib::Wpt& v) const;  // same as above, but returns reference
00085    Wvec    norm()         const;  // unit-length average of 2 face normals
00086    double  dot()          const;  // dot product of 2 face normals
00087    double  avg_area()     const;  // average area of 2 faces
00088 
00089    // Angle (in radians) between two adjacent face normals
00090    // (or 0, if < 2 faces):
00091    // XXX - name problem: it is not actually the dihedral angle!
00092    double dihedral_angle() const { return Acos(dot()); }
00093 
00094    Wpt interp(double s) const;
00095 
00096    // returns true if the edge is convex (uses cached value):
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    //******** ADJACENCY ********
00104 
00105    // Only meaningful for primary faces:
00106    // Return the other vertex of the other face.
00107    // E.g., if f is _f1, return the other vertex of _f2;
00108    // and vice versa:
00109    Bvert* opposite_vert(CBface* f) const; // Defined in bface.H:
00110 
00111    // Opposite vertex on face 1 or 2, respectively:
00112    Bvert* opposite_vert1() const { return opposite_vert(_f2); }
00113    Bvert* opposite_vert2() const { return opposite_vert(_f1); }
00114 
00115    // If v is a vertex of this edge, return the other vertex:
00116    Bvert* other_vertex(CBvert* v) const {
00117       return (v==_v1)?_v2:(v==_v2)?_v1:0;
00118    }
00119 
00120    // Return the vertex's "index." i.e., 1 or 2
00121    // whether it is vertex _v1 or _v2 respectively:
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    // tell whether this edge is adjacent to to the given vertex or face:
00133    bool contains(CBvert* v)   const   { return (_v1 == v || _v2 == v); }
00134    bool contains(CBface* f)   const;    // defined in bface.H
00135 
00136    // does this edge connect the given vertices?
00137    bool same_verts(CBvert* u, CBvert* v)  const {
00138       return contains(u) && contains(v);
00139    }
00140 
00141    // If f is a primary adjacent face, return the other primary adjacent face:
00142    Bface* other_face(CBface *f)  const   { return (f==_f1)?_f2:(f==_f2)?_f1:0;} 
00143 
00144 
00145    // Return a front-facing face, if any:
00146    // XXX - ignores secondary faces
00147    Bface* frontfacing_face()     const;
00148 
00149    // Return an adjacent face containing a given vertex or edge
00150    Bface* lookup_face(CBvert *v) const;
00151    Bface* lookup_face(CBedge *e) const;
00152 
00153    // Given vertex v belonging to this edge, return the adjacent
00154    // face (_f1 or _f2) for which this edge follows v in CCW
00155    // order within the face.
00156    Bface* ccw_face(CBvert* v) const;
00157    Bface*  cw_face(CBvert* v) const { return ccw_face(other_vertex(v)); }
00158 
00159    // Return the face (f1 or f2) for which _v2 follows _v1
00160    // in CCW or CW order, respectively:
00161    Bface* ccw_face() const { return ccw_face(_v1); }
00162    Bface* cw_face()  const { return ccw_face(_v2); }
00163 
00164    // Return the number of quads adjacent to the edge:
00165    int num_quads() const;
00166 
00167    // Count the number of adjacent faces (including secondary ones)
00168    // satisfied by the given filter:
00169    int nfaces_satisfy(CSimplexFilter& f) const;
00170 
00171    //******** NON-MANIFOLD MESHES ********
00172 
00173    // A "multi" edge has additional adjacent faces besides the 2
00174    // primary ones. (I.e. the surface is non-manifold at that edge).
00175    // A face is a "multi" face (WRT a given edge) if the face
00176    // is one of the additional adjacent faces of that edge.
00177 
00178    // Additional faces (usually null unless the edge is non-manifold):
00179    Bface_list*  adj() const { return _adj; }
00180 
00181  protected:
00182    // Allocate the list of secondary faces ("adjacent faces")
00183    void allocate_adj();
00184 
00185    // Add the face as a secondary (or "multi") face.
00186    // In Ledge, do the same for the appropriate child faces.
00187    virtual bool add_multi(Bface* f); 
00188 
00189    // Add the face as a primary face (in slot _f1 or _f2).
00190    // In Ledge, do the same for the appropriate child faces.
00191    virtual bool add_primary(Bface* f); 
00192 
00193  public:
00194 
00195    // Returns true if there is at least one available primary slot (_f1 or _f2).
00196    // In Ledge, all child edges must also have available slots.
00197    virtual bool can_promote() const;
00198 
00199    // Move f from the _adj list to _f1 or _f2:
00200    // It's up to the caller to check Bedge::can_promote().
00201    bool promote(Bface* f);
00202 
00203    // Move f from _f1 or _f2 to the _adj list:
00204    bool demote(Bface* f);
00205 
00206    // Is the edge a non-manifold ("multi") edge?
00207    bool is_multi() const;
00208 
00209    // Is the face a secondary face of this edge?
00210    bool is_multi(CBface* f) const;
00211 
00212    // If any faces in the _adj listed are labelled "primary",
00213    // then move them to a primary slot (_f1 or _f2). Used when
00214    // reading a mesh from file, when primary/secondary face
00215    // labels are specified only after all faces are created.
00216    void fix_multi(); 
00217 
00218    // Return true if at least one adjacent face is primary
00219    bool is_primary() const;
00220 
00221    // The edge is labelled "secondary" if it is not adjacent
00222    // to a primary face. This means "polyline" edges are
00223    // also considered secondary.
00224    bool is_secondary() const { return !is_primary(); }
00225 
00226    //******** EDGE TESTS ********
00227    // various tests that can be applied to an edge:
00228    //   border edge:   just 1 adjacent face.
00229    //   polyline edge: no adjacent faces
00230    //   crease edge:
00231    //      an edge can be labelled a "crease," which does 2 things:
00232    //      (1) normals are not blended across the edge in gouraud shading,
00233    //      (2) for subdivision meshes (LMESHes), separate crease rules 
00234    //          are used so the edge retains its sharpness.
00235    //   patch boundary:
00236    //      adjacent faces are in different patches; or they're in the same
00237    //      patch but the edge is considered to mark a patch boundary anyway, as
00238    //      when texture coordinates exhibit a seam running down a cylinder.
00239    //   sil edge:
00240    //      silhouette edge (for the current view / frame)
00241    //   stressed edge:
00242    //      has a pretty sharp dihedral angle.
00243    //   crossable edge:
00244    //      a triangle strip can pass across the edge -- i.e., the
00245    //      edge is not a patch boundary or a crease edge.
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    // Returns true if the 2 adjacent faces have a consistent orientation:
00263    bool consistent_orientation() const;
00264    bool oriented_ccw(Bface* =0)  const;
00265 
00266    // Returns true if either vertex has an odd number of adjacent
00267    // polyline edges (or crease edges, respectively). Used in
00268    // finding long edge strips of a given type:
00269    bool is_polyline_end()                       const;
00270    bool is_crease_end()                         const;
00271    bool is_chain_tip(CSimplexFilter& filter)      const;
00272 
00273    //******** EDGE LABELS ********
00274    void set_patch_boundary(int b=1) { set_bit(PATCH_BOUNDARY_BIT,b); }
00275 
00276    // labels this edge as a "crease" if passed-in value exceeds the
00277    // dot product of the 2 adjacent faces:
00278    void compute_crease(double dot); 
00279 
00280    // these take on more meaning in Ledge, which supports variable
00281    // sharpness creases for subdivision:
00282    virtual void set_crease(unsigned short = USHRT_MAX);
00283    virtual unsigned short crease_val() const { return is_crease() ? 1 : 0; }
00284 
00285    // The following increment and decrement the crease val,
00286    // respectively. 'max_val' represents a "large" value; if you try to
00287    // increment past max_val, it goes straight to USHRT_MAX. If you
00288    // try to decrement when the current value is USHRT_MAX, it goes
00289    // straight to max_val (not USHRT_MAX - 1). E.g. if max_val is 5,
00290    // then possible crease values are: { 0, 1, 2, 3, 4, 5, USHRT_MAX }.
00291    void inc_crease(ushort max_val = USHRT_MAX);
00292    void dec_crease(ushort max_val = USHRT_MAX);
00293 
00294    //******** SUBDIVISION ********
00295 
00296    // Difference between subdiv level of this edge and its control element
00297    // (See Ledge):
00298    virtual uint rel_level() const { return 0; }
00299 
00300    //******** BUILDING/REDEFINING ********
00301 
00302    bool operator +=(Bface* face);       // add adjacent face
00303    bool operator -=(Bface* face);       // remove adjacent face
00304    int  detach();                       // tell verts good-bye (pre-suicide)
00305 
00306    // Redefine this edge, replacing v with u:
00307    virtual int  redefine(Bvert *v, Bvert *u);
00308 
00309    // Redefine this edge, replacing both vertices w/ 2 new ones:
00310    virtual void set_new_vertices(Bvert *v1, Bvert *v2);
00311 
00312    // return true if performing an "edge swap" operation is both legal
00313    // and desirable:
00314    bool  swapable(Bface*&, Bface*&, Bvert*&, Bvert*&, Bvert*&, Bvert*&,
00315                          bool favor_degree_six=0);
00316 
00317    // NEW VERSIONS (12/2004)
00318 
00319    // Return true if edge swap does not violate topology requirements:
00320    bool swap_is_legal() const;
00321 
00322    // Carry out swap if it is legal:
00323    virtual bool do_swap();
00324 
00325    // 2nd version of redefine, should replace redefine() above, after testing:
00326    virtual bool redef2(Bvert *v, Bvert *u);
00327 
00328    //******** INTERSECTION ********
00329 
00330    bool    ndc_intersect(CNDCpt& p, mlib::CNDCpt& q, mlib::NDCpt& ret) const;
00331    int     which_side(CWplane& plane) const;
00332 
00333    //******** HANDLING CACHED VALUES ********
00334 
00335    virtual void notify_split(Bsimplex*);
00336    virtual void geometry_changed();  // Bsimplex method - notify SimplexData
00337    virtual void normal_changed();    // adjacent face changes its normal
00338    virtual void crease_changed();    // called when crease status changes
00339    virtual void faces_changed();    // called when faces are added or deleted
00340 
00341    //******** I/O ********
00342 
00343    friend ostream &operator <<(ostream &os, CBedge &e);
00344 
00345    //******** Bsimplex VIRTUAL METHODS ********
00346 
00347    // dimension
00348    virtual int    dim()              const { return 1; }
00349 
00350    // index in BMESH Bedge array:
00351    virtual int  index() const;
00352    
00353    // (Bsimplex virtual method):
00354    // Intersection w/ ray from given screen point -- returns the point
00355    // on the Bedge that is nearest to the given screen space point.
00356    // Note: the returned "near point" and "normal" are both
00357    //       transformed to world space.
00358    virtual bool view_intersect(
00359       CNDCpt&,  // Given screen point. Following are returned:
00360       Wpt&,     // Near point on the simplex IN WORLD SPACE (not object space)
00361       double&,  // Distance from camera to near point
00362       double&,  // Screen distance (in PIXELs) from given point
00363       Wvec& n   // "normal" vector at intersection point IN WORLD SPACE
00364       ) const;
00365 
00366    // faces
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    // Return the first face accepted by the filter:
00371    Bface* screen_face(CSimplexFilter& filter) const;
00372 
00373    // compute barycentric coords of a point wrt this edge
00374    virtual void project_barycentric(CWpt &p, mlib::Wvec &bc)  const;
00375 
00376    // given barycentric coords, return a position
00377    virtual void bc2pos(CWvec& bc, mlib::Wpt& pos)             const;    
00378  
00379    // given barycentric coords, return a simplex 
00380    // (endpoint vertex, or this edge):
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    // Return a list of adjacent Bsimplexes:
00387    // (returns v1, v2, f1 and f2, if not null)
00388    virtual Bsimplex_list neighbors() const;
00389 
00390    //******** XXX - OBSOLETE -- OLD TESSELLATOR STUFF
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  // PROTECTED
00399  //*******************************************************
00400  protected:
00401    // order of verts/faces is not significant
00402    Bvert*       _v1;    // first vertex
00403    Bvert*       _v2;    // 2nd vertex
00404    Bface*       _f1;    // first adjacent face
00405    Bface*       _f2;    // 2nd one
00406    Bface_list*  _adj;   // additional faces
00407 
00408    // last frame number when this edge was checked to see if it was a
00409    // silhouette:
00410    uint     _sil_stamp; 
00411 
00412    //******** INTERNAL METHODS ********
00413    // methods for recomputing cached values when needed:
00414    void  set_convex();  
00415 };
00416 
00417 
00418 /*****************************************************************
00419  * Bedge inline methods
00420  *****************************************************************/
00421 inline Bedge*
00422 bedge(Bsimplex* sim)
00423 {
00424    return is_edge(sim) ? (Bedge*)sim : 0;
00425 }
00426 
00427 /*****************************************************************
00428  * Bedge filters
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    // accept edges with sufficiently large angle between
00439    // adjacent face normals
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;   // max acceptable dot() value
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 // Accept an edge if it has an adjacent front-facing triangle
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    // Accepts edges with <= 2 adjacent faces of a given type.
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;       // accepts faces of the given type
00595 };
00596 
00597 class BoundaryEdgeFilter : public SimplexFilter {
00598  public:
00599    BoundaryEdgeFilter(CSimplexFilter& f) : _filter(f) {}
00600 
00601    // Accepts edges along the boundary between faces of a
00602    // given type and faces not of that type.
00603    virtual bool accept(CBsimplex* s) const;
00604 
00605  protected:
00606    CSimplexFilter& _filter;       // accepts faces of the given type
00607 };
00608 
00609 /*****************************************************************
00610  * NewSilEdgeFilter:
00611  *
00612  *   Accepts silhouette edges that have not been detected already
00613  *   in the current frame.
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))                          // reject if non-edge
00622          return false;
00623       Bedge* e = (Bedge*)s;
00624       if (e->sil_stamp() == _stamp)             // reject if previously checked
00625          return 0;
00626       e->set_sil_stamp(_stamp);                 // mark as checked this frame
00627       if (_skip_secondary && e->is_secondary()) // reject secondary edges as needed
00628          return false;
00629       return e->is_sil();                       // accept if silhouette
00630    }
00631 
00632  protected:
00633    uint  _stamp;                // frame number of current frame
00634    bool  _skip_secondary;       // if true, skip "secondary" edges
00635 };
00636 
00637 /*****************************************************************
00638  * ChainTipEdgeFilter:
00639  *
00640  *   Given a kind of filter, screens edges for those that match the
00641  *   filter and also do not lie in the middle of a chain of edges
00642  *   that match the filter. I.e. finds edges at the tips of chains.
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  * Bedge_list
00657  ************************************************************/
00658 typedef const Bedge_list CBedge_list;
00659 class Bedge_list : public SimplexArray<Bedge_list,Bedge*> {
00660  public:
00661 
00662    //******** MANAGERS ********
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    //******** EDGE FLAGS ********
00669 
00670    void clear_flag02() const {
00671       for (int i=0; i<_num; i++)
00672          _array[i]->clear_flag02();
00673    }
00674 
00675    //******** EDGE LENGTHS ********
00676 
00677    // Returns the sum of the edge lengths:
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    // Returns average length of the edges:
00686    double avg_len() const { return empty() ? 0 : total_length()/_num; }
00687 
00688    // minimum edge length
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    // Return true if all edges have the same number of adjacent
00699    // primary faces:
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    // Returns list of verts contained in these edges:
00720    Bvert_list get_verts() const;
00721 
00722    // Returns list of faces adjacent to these edges:
00723    Bface_list get_faces() const;
00724 
00725    // Returns list of primary faces adjacent to these edges:
00726    // (defined inline in Bface.H)
00727    Bface_list get_primary_faces() const;        
00728 
00729    // Returns Bverts of this edge list that are "fold"
00730    // vertices WRT these edges (see bedge.C):
00731    Bvert_list fold_verts() const;
00732 
00733    // Check to see if a set of edges is simple,
00734    // i.e. it doesn't contain any self-intersections
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    //******** PRIMARY/SECONDARY EDGES ********
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    //******** PROTECTED METHODS ********
00750    void clear_vert_flags() const;
00751 
00752    // Set the flag of each edge to 1, and clear the flags of
00753    // each edge around the boundary of this set of edges:
00754    void mark_edges() const;
00755 };
00756 
00757 #endif  // BEDGE_H_HAS_BEEN_INCLUDED
00758 
00759 // end of file bedge.H

Generated on Mon Sep 18 11:39:28 2006 for jot by  doxygen 1.4.4