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

lvert.H

Go to the documentation of this file.
00001 /**********************************************************************
00002  * lvert.H
00003  **********************************************************************/
00004 #ifndef LVERT_H_HAS_BEEN_INCLUDED
00005 #define LVERT_H_HAS_BEEN_INCLUDED
00006 
00007 #include "ledge.H"
00008 
00009 template <class T> class SubdivCalc;
00010 typedef SubdivCalc<Wpt> LocCalc;
00011 
00012 /**********************************************************************
00013  * Lvert:
00014  *
00015  *      Vertex class for LMESH -- subdivision meshes implementing the
00016  *      scheme of Charles Loop, with special rules for creases as
00017  *      described in:
00018  *
00019  *        Hugues Hoppe, Tony DeRose, Tom Duchamp, Mark Halstead,
00020  *        Hubert Jin, John McDonald, Jean Schweitzer, and Werner
00021  *        Stuetzle. Piecewise Smooth Surface Reconstruction,
00022  *        Proceedings of SIGGRAPH 94, Computer Graphics Proceedings,
00023  *        Annual Conference Series, pp. 295-302 (July 1994, Orlando,
00024  *        Florida). ACM Press. Edited by Andrew Glassner. ISBN
00025  *        0-89791-667-0.
00026  **********************************************************************/
00027 class Lvert : public Bvert {
00028    friend class REPARENT_CMD;
00029    friend class Ledge;
00030  public:
00031 
00032    //******** MASK VALUES ********
00033 
00034    enum mask_t {
00035       SMOOTH_VERTEX = 0,
00036       DART_VERTEX,
00037       REGULAR_CREASE_VERTEX,
00038       NON_REGULAR_CREASE_VERTEX,
00039       CORNER_VERTEX,
00040       CUSP_VERTEX
00041    };
00042 
00043    //******** BITS ********
00044 
00045    enum {
00046       SUBDIV_LOC_VALID_BIT = Bvert::NEXT_AVAILABLE_BIT,
00047       SUBDIV_COLOR_VALID_BIT,
00048       SUBDIV_CORNER_VALID_BIT,
00049       DIRTY_VERT_LIST_BIT,
00050       MASK_VALID_BIT,
00051       DEAD_BIT,
00052       DISPLACED_LOC_VALID,
00053       SUBDIV_ALLOCATED_BIT,
00054       NEXT_AVAILABLE_BIT
00055    };
00056 
00057    //******** MANAGERS ********
00058 
00059    Lvert(CWpt& p=mlib::Wpt::Origin()) :
00060       Bvert(p),
00061       _subdiv_vertex(0),
00062       _corner(0),
00063       _mask(SMOOTH_VERTEX),
00064       _parent(0),
00065       _offset(0) {}
00066 
00067    virtual ~Lvert();
00068 
00069    //******** ACCESSORS ********
00070 
00071    LMESH* lmesh()                 const   { return (LMESH*)mesh(); }
00072    Ledge* le(int k)               const   { return (Ledge*)_adj[k]; }
00073    Lvert* lv(int k)               const   { return (Lvert*)nbr(k); }
00074    Lvert* subdiv_vertex()         const   { return _subdiv_vertex; }
00075 
00076  public:
00077 
00078    //******** CONTROL ELEMENTS ********
00079 
00080    bool is_control() const { return _parent == 0; }
00081 
00082    // proper parent
00083    // (it's null for vertices of the control mesh):
00084    Bsimplex* parent() const { return _parent; }
00085 
00086    // control element
00087    // (it's the vertex itself in the control mesh):
00088    Bsimplex* ctrl_element() const;
00089 
00090    // convenience method - casts control element to Lvert if valid:
00091    Lvert* ctrl_vert() const {
00092       Bsimplex* sim = ctrl_element();
00093       return is_vert(sim) ? (Lvert*)sim : (Lvert*)0;
00094    }
00095    
00096    //******** SUBDIV VERTS ********
00097 
00098    // Return subdiv vertex at given level down,
00099    // relative to this:
00100    Lvert* subdiv_vert(int level=1);
00101 
00102    // Get parent vert (it it exists) at the given relative
00103    // level up from this vert
00104    Lvert* parent_vert(int rel_level) const;
00105 
00106    // Return subdiv vertex at current subdiv level of the mesh:
00107    Lvert* cur_subdiv_vert();
00108 
00109    void set_parent(Bsimplex* p) { _parent=p; }
00110 
00111    //******** SUBDIVISION MASKS ********
00112 
00113    unsigned short subdiv_mask() const {
00114       if (!is_set(MASK_VALID_BIT))
00115          ((Lvert*)this)->set_mask();
00116       return _mask;
00117    }
00118 
00119    void set_corner(unsigned short c = USHRT_MAX);
00120    unsigned short corner_value(void) const {return _corner;}
00121    bool is_smooth()         const { return subdiv_mask() <= DART_VERTEX; }
00122    bool is_regular_crease() const {
00123       return subdiv_mask() == REGULAR_CREASE_VERTEX;
00124    }
00125 
00126    //******** SUBDIVISION COMPUTATION ********
00127 
00128    Lvert* update_subdivision();
00129    Lvert* allocate_subdiv_vert();
00130    void   set_subdiv_vert(Lvert* subv);
00131    void   delete_subdiv_vert();
00132 
00133    // not for public use, to be called by the child
00134    void    subdiv_vert_deleted();
00135 
00136    Wpt&   limit_loc(mlib::Wpt&)       const;
00137    Wvec&  loop_normal(mlib::Wvec&)    const;
00138 
00139    // Used in volume-preserving subdivision:
00140    CWpt&  displaced_loc(LocCalc*);
00141 
00142    bool   has_offset()          const   { return _offset != 0; }
00143    double offset()              const   { return _offset; }
00144    void   add_offset(double d)          { set_offset(_offset + d); }
00145    void   clear_offset()                { set_offset(0); }
00146    void   set_offset(double d);
00147 
00148    // Return the smooth subdiv location (without the "detail")
00149    // that would be assigned to this vertex using the SubdivCalc
00150    // of the parent LMESH:
00151    Wpt smooth_loc_from_parent() const;
00152 
00153    // Return smooth_loc_from_parent() + added "detail" offset:
00154    Wpt detail_loc_from_parent() const;
00155 
00156    // Compute and store the offset needed to approximate the
00157    // given location via the smooth subdiv loc + detail offset.
00158    void fit_subdiv_offset(CWpt& detail_loc);
00159 
00160  protected:
00161    // Protected method called by the parent of this vertex
00162    // to set the smooth subdiv location.
00163    //
00164    // The given value base_loc is the smooth subdiv location
00165    // computed from the parent level; this vertex should now set
00166    // its location = base_loc + n*offset, where n is the normal
00167    // from the parent and offset is the subdiv offset ("detail").
00168    void set_subdiv_base_loc(CWpt& base_loc);
00169 
00170  public:
00171 
00172    //******** VALIDITY OF CACHED VALUES ********
00173 
00174    void mark_dirty(int bit = SUBDIV_LOC_VALID_BIT);
00175    void subdiv_color_changed()          { mark_dirty(SUBDIV_COLOR_VALID_BIT); }
00176    void subdiv_loc_changed() {
00177       clear_bit(DISPLACED_LOC_VALID);
00178       mark_dirty(SUBDIV_LOC_VALID_BIT);
00179    }
00180 
00181    //******** BVERT VIRTUAL METHODS ********
00182 
00183    virtual void geometry_changed();
00184    virtual void normal_changed();
00185    virtual void crease_changed();
00186    virtual void degree_changed();
00187    virtual void color_changed();
00188    virtual void mask_changed();
00189 
00190  //*******************************************************
00191  // PROTECTED
00192  //*******************************************************
00193  protected:
00194    Lvert*          _subdiv_vertex; // optional vertex generated by subdivision
00195    unsigned short  _corner;        // "variable sharpness" corner
00196    unsigned short  _mask;          // subdivision mask
00197    Bsimplex*       _parent;        // edge or vertex that has created this one
00198    double          _offset;        // subdivision "detail"
00199    Wpt             _displaced_loc; // x-perimental
00200 
00201    //******** PROTECTED METHODS ********
00202 
00203    void set_mask();
00204 
00205  private:
00206    // In rare cases, certain people can do the following.
00207    // However, you are not one of them.
00208    void assign_subdiv_vert(Lvert* v) { _subdiv_vertex = v; }
00209 };
00210 
00211 #endif  // LVERT_H_HAS_BEEN_INCLUDED
00212 
00213 // end of file lvert.H

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