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

bvert.H

Go to the documentation of this file.
00001  /**********************************************************************
00002  * bvert.H
00003  **********************************************************************/
00004 #ifndef BVERT_H_HAS_BEEN_INCLUDED
00005 #define BVERT_H_HAS_BEEN_INCLUDED
00006 
00007 #include "disp/color.H"
00008 #include "mesh/bedge.H"
00009 #include "mesh/bmesh_curvature.H"
00010 
00011 /**********************************************************************
00012  * Bvert:
00013  *
00014  *      A vertex of a mesh. Has position and knows its adjacent edges.
00015  *      Derived from Bsimplex.
00016  **********************************************************************/
00017 class Bvert : public Bsimplex {
00018  public:
00019    //******** BOOLEAN BIT FLAGS ********
00020    // used to store boolean states (see Bsimplex class):
00021    enum {
00022       VALID_COLOR_BIT = Bsimplex::NEXT_AVAILABLE_BIT, // color has been set
00023       VALID_NORMAL_BIT,       // normal is up-to-date
00024       VALID_CCW_BIT,          // edges are in CCW order
00025       NON_MANIFOLD_BIT,       // an adjacent edge is a multi-edge (cached value)
00026       VALID_NON_MANIFOLD_BIT, // previous bit is believable
00027       CREASE_BIT,             // some adjacent edge is a crease (cached value)
00028       VALID_CREASE_BIT,       // previous bit is believable
00029       STRESSED_BIT,           // some adjacent edge is stressed (cached value)
00030       VALID_STRESSED_BIT,     // previous bit is believable
00031       NEXT_AVAILABLE_BIT      // derived classes start here
00032    };
00033    
00034    //******** MANAGERS ********
00035    Bvert(CWpt& p=mlib::Wpt::Origin()) : _loc(p), _adj(6), _alpha(1) { }
00036    virtual ~Bvert();
00037 
00038    //******** ACCESSORS ********
00039 
00040    CWpt&   loc() const   { return _loc; }         ///< position (location)
00041    Wpt     wloc()const;                           ///< mesh->xf * loc()
00042    NDCZpt  ndc() const;                           ///< NDCZ position
00043    PIXEL   pix() const   { return mlib::PIXEL(wloc());} ///< position in mlib::PIXEL coords
00044 
00045    int     degree()    const   { return _adj.num(); }   ///< number of edges
00046    CCOLOR& color()     const   { return _color; }       ///< color
00047    double  alpha()     const   { return _alpha; }       ///< transparency
00048    bool    has_color() const   { return is_set(VALID_COLOR_BIT); }
00049 
00050    // list of adjacent edges:
00051    CBedge_list& get_adj() const { return _adj; }
00052 
00053    // Clear flag of this vertex and edges and faces containing it:
00054    // (clearing propagates from dim 0 to dim 2)
00055    void clear_flag02() {
00056       clear_flag();
00057       _adj.clear_flag02(); // edges propagate it to faces
00058    }
00059 
00060    //******** NORMALS ********
00061 
00062    // Computes an (angle-weighted) average normal from the given
00063    // set of faces, WRT this vertex. Any face that does not contain
00064    // this vertex makes no contribution to the final result.
00065    Wvec compute_normal(const ARRAY<Bface*>& faces) const;
00066 
00067    /// normal -- i.e. unit length average of adjacent faces:
00068    ///   (uses angle-weighted face normals)
00069    CWvec& norm() const {
00070       if (!is_set(VALID_NORMAL_BIT))
00071          ((Bvert*)this)->set_normal();
00072       return _norm;
00073    }
00074 
00075 
00076    // Assign a normal explicitly. Note that if vertices are moved,
00077    // nearby normals will be recomputed by averaging face normals.
00078    // XXX - does not apply to vertices on creases
00079    void set_norm(Wvec n) {
00080       _norm = n.normalized();
00081       set_bit(VALID_NORMAL_BIT); 
00082    }
00083 
00084    /// return a normal WRT faces accepted by the given filter:
00085    Wvec norm(CSimplexFilter& f) const;
00086 
00087    /// normal transformed to world space
00088    /// xf.inverse().transpose() * norm
00089    Wvec wnorm() const;
00090    
00091    /// for a vertex with adjacent crease edges, returns 1 normal
00092    /// for each set of adjacent faces bounded by crease edges:
00093    void get_normals(ARRAY<Wvec>& norms) const;
00094 
00095    //******** LOCATION, COLOR, CURVATURE, etc. ********
00096 
00097    // setting location:
00098    void set_loc(CWpt& p)        { _loc = p; geometry_changed(); }
00099    void offset_loc(CWvec& v)    { set_loc(_loc + v); }
00100    void transform(CWtransf& xf) { set_loc(xf*_loc); notify_xform(xf); }
00101 
00102    // setting color:
00103    void set_color(CCOLOR &c, double a=1) {
00104       _color = c;
00105       _alpha = a;
00106       set_bit(VALID_COLOR_BIT,1);
00107       color_changed();
00108    }
00109 
00110    /// Distance to another vert (ignoring modeling transform):
00111    double dist(CBvert* v)  { return v ? loc().dist(v->loc()) : 0.0; }
00112 
00113    /// Distance to another vert (computed in world space):
00114    double wdist(CBvert* v) { return v ? wloc().dist(v->wloc()) : 0.0; }
00115 
00116    //******** ADJACENCY ********
00117 
00118    // Adjacent edge number k:
00119    Bedge* e  (int k) const   { return _adj[k]; }
00120 
00121    // Neighboring vertex number k:
00122    Bvert* nbr(int k) const {
00123       return _adj.valid_index(k) ? _adj[k]->other_vertex(this) : 0;
00124    }
00125    // Neighboring vertex along given edge (which must be adjacent to this):
00126    Bvert* nbr(CBedge* e) const { return e ? e->other_vertex(this) : 0; }
00127 
00128    // Return a set of neighboring vertices from the
00129    // given set of edges, all of which must contain
00130    // this vertex (or an assertion failure will occur):
00131    Bvert_list get_nbrs(CBedge_list& edges) const;
00132 
00133    // Like previous 2 methods, but return neighbor location.
00134    // Must be valid or assertion fails:
00135    Wpt nbr_loc(int k)     const { Bvert* n = nbr(k); assert(n); return n->loc(); }
00136    Wpt nbr_loc(CBedge* e) const { Bvert* n = nbr(e); assert(n); return n->loc(); }
00137 
00138    // NB: The following methods for getting adjacent faces 
00139    //     select faces just from the primary layer of the mesh.
00140    //     The exception is get_all_faces().
00141 
00142    // Adjacent faces in star of this vertex:
00143    void get_faces(ARRAY<Bface*>& ret) const;
00144 
00145    // like above, but returns the list by copying
00146    // defined in bface.H
00147    Bface_list get_faces() const;
00148 
00149    // Return a list of quads in the star of this vertex.
00150    // (Each quad is represented by a single Bface -- the "quad rep").
00151    void get_quad_faces(ARRAY<Bface*>& ret) const;
00152 
00153    // Return a list of faces in the star of this vertex,
00154    // including both faces of every quad adjacent to this vertex.
00155    void get_q_faces(ARRAY<Bface*>& ret) const;
00156 
00157    // Return ALL faces incident to the vertex,
00158    // including faces adjacent to non-manifold ("multi") edges:
00159    void  get_all_faces(ARRAY<Bface*>& ret) const;
00160 
00161    Bface_list get_all_faces() const; // defined in bface.H
00162 
00163    int num_tris() const;
00164    int num_quads() const;
00165 
00166    // Return the edge connecting this to a given vertex:
00167    Bedge* lookup_edge(CBvert* v) const {
00168       if (v == this)
00169          return 0;  
00170       for(int k=0; k<_adj.num(); k++)
00171          if(_adj[k]->contains(v))
00172             return _adj[k];
00173       return 0;
00174    }
00175 
00176    // tell if this is adjacent to the given vertex:
00177    bool is_adjacent(CBvert* v) const {
00178       for(int k=0; k<_adj.num(); k++)
00179          if(v == _adj[k]->other_vertex(this))
00180             return 1;
00181       return 0;
00182    }
00183 
00184    // Return neighboring vertices in an array
00185    void get_nbrs(ARRAY<Bvert*>& nbrs) const;
00186 
00187    // The following assume edges can be put in CCW order,
00188    // meaning the vertex is either surrounded by faces, or
00189    // has exactly 2 border edges.
00190    //
00191    // XXX - not handling non-manifold surfaces yet
00192    //
00193    // Return list of edges in CCW order:
00194    // returns an empty list if the operation is invalid.
00195    Bedge_list get_ccw_edges() const;
00196 
00197    // Returns list of neighbor verts in CCW order:
00198    Bvert_list get_ccw_nbrs() const;
00199 
00200    // Return adjacent edges the normal way, unless it's a
00201    // "multi" vertex; then return primary edges. Used in
00202    // computing centroids, e.g. for subdivision.
00203    void get_manifold_edges(ARRAY<Bedge*>& ret) const;
00204 
00205    // Same as above but returns list by copying
00206    Bedge_list get_manifold_edges() const {
00207       Bedge_list ret;
00208       get_manifold_edges(ret);
00209       return ret;
00210    }
00211 
00212    Bedge_list strong_edges() const { return get_manifold_edges().strong_edges(); }
00213    double avg_strong_len()   const { return strong_edges().avg_len(); }
00214 
00215    // Return neighboring vertices from the "primary" layer.
00216    // I.e., neighboring vertices connected to this one by
00217    // an edge that has one or more adjacent faces with
00218    // Bface::SECONDARY_BIT not set in its flag.
00219    void get_primary_nbrs(ARRAY<Bvert*>& nbrs) const;
00220 
00221    // Get neighbors the normal way, unless it's a "multi"
00222    // (non-manifold) vertex; then get primary neighbors. Used in
00223    // computing centroids, e.g. for subdivision.
00224    void  get_p_nbrs(ARRAY<Bvert*>& nbrs) const;
00225 
00226    // Same as above but returns list by copying
00227    ARRAY<Bvert*> get_p_nbrs() const {
00228       ARRAY<Bvert*> ret;
00229       get_p_nbrs(ret);
00230       return ret;
00231    }
00232 
00233    int p_degree() const {
00234       return is_manifold() ? degree() : get_p_nbrs().num();
00235    }
00236 
00237    // Return "quad opposite vertices" in an array
00238    void get_q_nbrs(ARRAY<Bvert*>& q) const;
00239 
00240    // Given that this vertex lies on a chain of border edges,
00241    // (with exactly 2 adjacent border edges to this vertex),
00242    // return the next border edge when traversing the border
00243    // chain in CW order around the adjacent surface.
00244    Bedge* next_border_edge_cw();
00245 
00246    // Like above, but returns the next border vertex:
00247    Bvert* next_border_vert_cw() {
00248       Bedge* border = next_border_edge_cw();
00249       return border ? border->other_vertex(this) : 0;
00250    }               
00251 
00252    //******** BUILDING/REDEFINING ********
00253    void operator +=(Bedge* e);
00254    int  operator -=(Bedge* e);
00255 
00256    // The following assumes edges can be put in CCW order,
00257    // meaning the vertex is either surrounded by faces, or
00258    // has exactly 2 border edges.
00259    //
00260    // XXX - not handling non-manifold surfaces yet
00261    //
00262    // put edges of this vertex in CCW order:
00263    // returns true on success
00264    bool order_edges_ccw();
00265 
00266    //******** GEOMETRIC MEASURES ********
00267    // returns sum of "interior" angles of faces around vertex:
00268    double star_sum_angles() const;
00269 
00270    // returns sum of face areas around vertex:
00271    double star_area() const;
00272 
00273    double min_dot() const {
00274       double ret = 1;
00275       for (int i=0; i < degree(); i++)
00276          ret = min(ret, e(i)->dot());
00277       return ret;
00278    }   
00279 
00280    // minimum edge length
00281    double min_edge_len() const { return _adj.min_edge_len(); }
00282 
00283    // average edge length
00284    double avg_edge_len() const { return _adj.avg_len(); }
00285 
00286    //******** CENTROIDS ********
00287 
00288    // Return the average of neighboring vertices
00289    Wpt centroid() const;
00290 
00291    // Area weighted centroid:
00292    Wpt area_centroid() const;
00293 
00294    // Special kind of centroid that weights regular ("r")
00295    // neighbors differently from quad ("q") neighbors:
00296    Wpt  qr_centroid()   const;
00297    Wvec qr_delt()       const   { return qr_centroid() - loc(); }
00298    
00299    //******** CURVATURE ********
00300    
00301    BMESHcurvature_data::curv_tensor_t curv_tensor() const;
00302    BMESHcurvature_data::diag_curv_t diag_curv() const;
00303    double k1() const;
00304    double k2() const;
00305    Wvec pdir1() const;
00306    Wvec pdir2() const;
00307    BMESHcurvature_data::dcurv_tensor_t dcurv_tensor() const;
00308 
00309    //******** DEGREE FOR VARIOUS EDGE TESTS ********
00310 
00311    // Return "degree" of this vertex with respect to edges of a
00312    // given type
00313    int degree(CSimplexFilter& f) const { return _adj.num_satisfy(f); }
00314 
00315    int  crease_degree()   const { return degree(CreaseEdgeFilter()); }
00316    int  border_degree()   const { return degree(BorderEdgeFilter()); }
00317    int  polyline_degree() const { return degree(PolylineEdgeFilter()); }
00318    int  stressed_degree() const { return degree(StressedEdgeFilter()); }
00319    int  multi_degree()    const { return degree(MultiEdgeFilter()); }
00320 
00321    //******** VERTEX TESTS ********
00322 
00323    bool is_border()       const { return (border_degree() > 0); }
00324    bool is_polyline_end() const { return (polyline_degree() % 2) == 1; }
00325    bool is_crease_end()   const { return (crease_degree()   % 2) == 1; }
00326 
00327    bool is_stressed()     const { 
00328       if (!is_set(VALID_STRESSED_BIT)) {
00329          ((Bvert*)this)->set_bit(VALID_STRESSED_BIT);
00330          ((Bvert*)this)->set_bit(STRESSED_BIT, stressed_degree() > 0);
00331       }
00332       return is_set(STRESSED_BIT);
00333    }
00334    bool is_crease() const {
00335       if (!is_set(VALID_CREASE_BIT)) {
00336          ((Bvert*)this)->set_bit(VALID_CREASE_BIT,1);
00337          ((Bvert*)this)->set_bit(CREASE_BIT, crease_degree() > 0);
00338       }
00339       return is_set(CREASE_BIT);
00340    }
00341 
00342    /// camera (eye) location in local coordinates:
00343    Wpt eye_local() const;
00344 
00345    /// unit length vector to camera in local coordinates
00346    Wvec eye_vec() const { return (eye_local() - loc()).normalized(); }
00347 
00348    /// dot product of unit length vector toward camera
00349    /// and surface normal (ignoring creases):
00350    double eye_vec_dot_norm() const { return eye_vec() * norm(); }
00351 
00352    /// returns true if surface normal (ignoring creases) points toward camera:
00353    bool is_front_facing() const { return (eye_local() - loc()) * norm() > 0; }
00354 
00355    bool is_sharp_point(double sharpness=M_PI/2);
00356 
00357    bool is_non_manifold()       const { return multi_degree() > 0; }
00358    bool is_manifold()           const { return !is_non_manifold(); }
00359 
00360    // within the star of this vertex, return the number of
00361    // faces that satisify the given filter:
00362    int face_degree(CSimplexFilter& f) const;
00363 
00364    //******** MANAGING CACHED VALUES ********
00365    virtual void geometry_changed();
00366    virtual void normal_changed();
00367    virtual void degree_changed();
00368    virtual void star_changed()    { clear_bit(VALID_CCW_BIT); }
00369    virtual void crease_changed()  { clear_bit(VALID_CREASE_BIT); }
00370    virtual void color_changed()   { set_bit(VALID_COLOR_BIT); }
00371     
00372    //******** I/O ********
00373    friend ostream &operator <<(ostream &os, CBvert &v) {
00374       return os << v.loc()[0] << " "
00375                 << v.loc()[1] << " "
00376                 << v.loc()[2] << endl;
00377    }
00378    friend istream &operator >>(istream &is,  Bvert &v) {
00379       double x,y,z;
00380       is >> x >> y >> z;
00381       v.set_loc(Wpt(x,y,z));
00382       return is;
00383    }
00384    // shift operators for STDdstream
00385    friend STDdstream &operator <<(STDdstream &d, CBvert &v) {
00386       return d << v.loc()[0] << v.loc()[1] << v.loc()[2];
00387    }
00388    friend STDdstream &operator >>(STDdstream &d,  Bvert &v) {
00389       double x,y,z;
00390       d >> x >> y >> z;
00391       v.set_loc(Wpt(x,y,z));
00392       return d;
00393    }
00394 
00395    //******** Bsimplex VIRTUAL METHODS ********
00396 
00397    virtual int dim() const { return 0; }
00398 
00399    // index in BMESH Bedge array:
00400    virtual int  index() const;
00401    
00402    // (Bsimplex virtual method):
00403    // Intersection w/ ray from given screen point -- returns the point
00404    // on the Bvert that is nearest to the given screen space point.
00405    // Note: the returned "near point" and "normal" are both
00406    //       transformed to world space.
00407    virtual bool view_intersect(
00408       CNDCpt&,  // Given screen point. Following are returned:
00409       Wpt&,     // Near point on the simplex IN WORLD SPACE (not object space)
00410       double&,  // Distance from camera to near point
00411       double&,  // Screen distance (in PIXELs) from given point
00412       Wvec& n   // "normal" vector at intersection point IN WORLD SPACE
00413       ) const;
00414 
00415    virtual Bface* get_face()            const;
00416    virtual bool   on_face(CBface* f)    const;
00417 
00418    virtual void project_barycentric(CWpt&, mlib::Wvec& bc)  const {
00419       bc.set(1,0,0);
00420    }
00421    virtual void bc2pos(CWvec&, mlib::Wpt& pos) const { pos = _loc; }
00422 
00423    virtual Bsimplex* bc2sim(CWvec&) const { return (Bsimplex*)this; }
00424 
00425    // Return a list of adjacent Bsimplexes:
00426    // (returns edges and faces):
00427    virtual Bsimplex_list neighbors() const;
00428 
00429    //******** XXX - OBSOLETE -- OLD TESSELLATOR STUFF
00430    virtual bool local_search(Bsimplex *&end, Wvec &final_bc,
00431                              CWpt &target, mlib::Wpt &reached, 
00432                              Bsimplex *repeater = 0, int iters = 30);
00433    virtual NDCpt nearest_pt_ndc(mlib::CNDCpt& p, mlib::Wvec &bc, int &is_on_simplex) const;
00434    virtual Wpt   nearest_pt(mlib::CWpt& p, mlib::Wvec &bc, bool &is_on_simplex) const;
00435 
00436    //*******************************************************
00437    // PROTECTED
00438    //*******************************************************
00439  protected:
00440    Wpt          _loc;       // location in 3-space
00441    Bedge_list   _adj;       // list of adjacent edges
00442    COLOR        _color;     // color of vertex
00443    double       _alpha;     // alpha value for _color
00444    Wvec         _norm;      // unit-length average of face normals
00445   
00446 
00447    //******** INTERNAL METHODS ********
00448    // methods for recomputing cached values when needed:
00449    void set_normal();
00450 };
00451 
00452 inline Bedge*
00453 lookup_edge(CBvert* a, CBvert* b)
00454 {
00455    return (a && b) ? a->lookup_edge(b) : 0;
00456 }
00457 
00458 inline Bvert*
00459 bvert(Bsimplex* sim)
00460 {
00461    return is_vert(sim) ? (Bvert*)sim : 0;
00462 }
00463 
00464 inline Wpt 
00465 Bedge::interp(double s) const  
00466 {
00467    // s is the parameter varying from 0 to 1 along the edge from
00468    // _v1 to _v2. return corresponding point.
00469 
00470    return _v1->loc() + vec()*s; 
00471 }
00472 
00473 /************************************************************
00474  * Bvert_list
00475  ************************************************************/
00476 class Bvert_list : public SimplexArray<Bvert_list,Bvert*> {
00477  public:
00478 
00479    //******** MANAGERS ********
00480 
00481    explicit Bvert_list(int n=0)     : SimplexArray<Bvert_list,Bvert*>(n)    {}
00482    explicit Bvert_list(Bvert* v)    : SimplexArray<Bvert_list,Bvert*>(v)    {}
00483    Bvert_list(CARRAY<Bvert*>& list) : SimplexArray<Bvert_list,Bvert*>(list) {}
00484 
00485    //******** CONVENIENCE ********
00486 
00487    // Clear flags of vertices and adjacent edges and faces
00488    // (from dimension 0 to 2)
00489    void clear_flag02() const {
00490       for (int i=0; i<_num; i++)
00491          _array[i]->clear_flag02();
00492    }
00493 
00494    // Return corresponding list of Wpts (object space)
00495    Wpt_list pts() const {
00496       Wpt_list ret(_num);
00497       for (int i=0; i<_num; i++) 
00498          ret += _array[i]->loc();
00499       ret.update_length();
00500       return ret;
00501    }
00502 
00503    // Return corresponding list of Wpts (world space)
00504    Wpt_list wpts() const {
00505       Wpt_list ret(_num);
00506       for (int i=0; i<_num; i++) 
00507          ret += _array[i]->wloc();
00508       ret.update_length();
00509       return ret;
00510    }
00511 
00512    // Return average of point locations in object space
00513    Wpt center() const { return pts().average(); }
00514 
00515    // Return sum of point locations in object space
00516    Wpt sum() const { return pts().sum(); }
00517 
00518    //******** TOPOLOGY ********
00519 
00520    // Returns the 1-ring faces of a set of vertices:
00521    Bface_list one_ring_faces() const;
00522    
00523    // Returns the 2-ring faces of a set of vertices:
00524    Bface_list two_ring_faces() const;
00525 
00526    // Return the set of edges containing at least 1 vertex
00527    // from this set
00528    Bedge_list get_outer_edges() const;
00529 
00530    // Return the set of edges that connect 2 vertices
00531    // from this set
00532    Bedge_list get_inner_edges() const;
00533 
00534    void transform(CWtransf &xf) {
00535       for (int i=0; i<num(); i++)
00536          (*this)[i]->transform(xf);
00537    }
00538 
00539    //******** EDGE CHAINS ********
00540 
00541    // Convenience methods for when a list of vertices
00542    // actually forms a chain connected by edges.
00543 
00544    // Are the vertices joined sequentially by edges in a
00545    // connected chain?
00546    bool forms_chain()        const;
00547    bool forms_closed_chain() const;     // and first connects to last
00548 
00549    // Returns the chain of edges formed by the vertices
00550    // (or the empty list). If 'try_close' is true and there
00551    // is an edge from the last vertex to the first, that
00552    // edge is added to the output list.
00553    Bedge_list get_chain(bool try_close=false) const;
00554 
00555    // Same as get_chain(), but includes the edge joining first and
00556    // last vertices. Returns the empty list if it failed:
00557    Bedge_list get_closed_chain() const;
00558 };
00559 typedef const Bvert_list CBvert_list;
00560 
00561 #endif // BVERT_H_HAS_BEEN_INCLUDED
00562 
00563 /* end of file bvert.H */

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