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

bsimplex.H

Go to the documentation of this file.
00001 /*****************************************************************
00002  * bsimplex.H
00003  *****************************************************************/
00004 #ifndef BSIMPLEX_H_IS_INCLUDED
00005 #define BSIMPLEX_H_IS_INCLUDED
00006 
00007 #include "simplex_data.H"
00008 
00009 class Bsimplex;
00010 class Bvert;
00011 class Bedge;
00012 class Bface;
00013 
00014 typedef const Bsimplex CBsimplex;
00015 typedef const Bvert CBvert;
00016 typedef const Bedge CBedge;
00017 typedef const Bface CBface;
00018 
00019 class BMESH;
00020 class Bsimplex_list;
00021 /*****************************************************************
00022  * SimplexFilter:
00023  *
00024  *      Accepts or rejects a simplex based on some criteria.
00025  *      Other filters are defined in bsimplex.H and bedge.H
00026  *      (and elsewhere).
00027  *****************************************************************/
00028 class SimplexFilter {
00029  public:
00030    //******** MANAGERS ********
00031    SimplexFilter() {}
00032    virtual ~SimplexFilter() {}
00033 
00034    //******** SOLE JOB ********
00035    virtual bool accept(CBsimplex* s) const { return s != 0; }
00036 };
00037 typedef const SimplexFilter CSimplexFilter;
00038 
00039 /*****************************************************************
00040  * Bsimplex:
00041  *
00042  *      Base class for BMESH vertices, edges and faces.
00043  *****************************************************************/
00044 class Bsimplex;
00045 typedef const Bsimplex CBsimplex;
00046 class Bsimplex {
00047  public:
00048 
00049    //******** FLAG BITS ********
00050 
00051    // For accessing bits in member variable _flag.
00052    // First 2 bits are used in graph searches; remaining
00053    // bits are available for recording boolean states.
00054    enum {
00055       FLAG_BITS = 2,            // first 2 bits store flag value
00056       SELECTED_BIT,             // simplex is currently selected
00057       NEXT_AVAILABLE_BIT        // next available bit for derived classes
00058    };
00059 
00060    //******** MANAGERS ********
00061 
00062    Bsimplex() : _key(0), _flag(0), _mesh(0), _data_list(0) {}
00063    virtual ~Bsimplex();
00064 
00065    //******** ACCESSORS ********
00066 
00067    void   set_mesh(BMESH* mesh)         { _mesh = mesh; }
00068    BMESH* mesh()                const   { return _mesh; }
00069 
00070    //******** KEY/LOOKUP ********
00071 
00072    uint  key() const { return _key ? _key : ((Bsimplex*)this)->generate_key();}
00073    static Bsimplex* lookup(uint k) {
00074       return (k<(uint)_table.num()) ? _table[k] : 0;
00075    }
00076 
00077    //******** DIMENSION ********
00078    //   vertex: 0
00079    //     edge: 1
00080    //     face: 2
00081    virtual int dim() const = 0;
00082 
00083    //******** INDEX ********
00084 
00085    // index in BMESH Bvert, Bedge, or Bface array:
00086    virtual int  index() const = 0;
00087    
00088    //******** FLAGS/BITS ********
00089 
00090    // "flag" value that can store values 0..3:
00091    uint flag()                  const   { return _flag & FLAG_MASK; }
00092    void clear_flag()                    { _flag &= ~FLAG_MASK; }
00093    void set_flag(uchar b=1)             { clear_flag(); _flag |= b; }
00094 
00095    // increment the flag value (mod 4):
00096    void inc_flag(uint i) {
00097       set_flag(uchar((flag() + i) % (1 << FLAG_BITS)));
00098    }
00099 
00100    bool is_set(uint b)          const   { return (_flag & mask(b)) ? 1 : 0; }
00101    bool is_clear(uint b)        const   { return !is_set(b); }
00102 
00103    void clear_bit(uint b)               { _flag &= ~mask(b); }
00104    void set_bit(uint b, int x=1) {
00105       clear_bit(b); if(x) _flag |= mask(b);
00106    }
00107 
00108    //******** SELECTION ********
00109 
00110    //  To change the selection status of a Bsimplex, use
00111    //  MeshGlobal::select() and MeshGlobal::deselect().
00112 
00113    // Is it selected?
00114    bool is_selected()   const   { return is_set(SELECTED_BIT); }
00115 
00116    //******** SIMPLEX DATA ********
00117 
00118    SimplexData* find_data(uint key) const {
00119       return _data_list ? _data_list->get_item(key) : 0;
00120    }
00121 
00122    SimplexData* find_data(Cstr_ptr& s) const { return find_data((uint)**s);}
00123    SimplexData* find_data(void *key)   const { return find_data((uint)key);}
00124    
00125    void add_simplex_data(SimplexData* sd);
00126    void rem_simplex_data(SimplexData* sd) {
00127       if (_data_list)
00128          _data_list->rem(sd);
00129    }
00130 
00131    // For debugging only
00132    const SimplexDataList* data_list() const { return _data_list;  }
00133 
00134    //******** NOTIFICATIONS ********
00135 
00136    virtual void notify_split(Bsimplex *new_simp);
00137    virtual void notify_xform(CWtransf& xf);
00138    virtual void geometry_changed(); // vert moved, edge changed length, etc
00139    virtual void normal_changed();   // a vert's neighbor moved, etc
00140 
00141    //******** PROJECTIONS ********
00142 
00143    virtual void project_barycentric(CWpt &loc, mlib::Wvec &bc) const = 0;
00144    virtual void bc2pos(CWvec& bc, mlib::Wpt& pos) const = 0;
00145 
00146    Wpt bc2pos(mlib::CWvec& bc) const {
00147       Wpt ret;
00148       bc2pos(bc, ret);
00149       return ret;
00150    }
00151 
00152    Wpt& project_to_simplex(mlib::CWpt &pos, mlib::Wpt &ret) {
00153       Wvec bc;
00154       project_barycentric(pos, bc);
00155       clamp_barycentric(bc);
00156       bc2pos(bc, ret);
00157       return ret;
00158    }
00159 
00160    virtual Bsimplex* bc2sim(CWvec& bc) const = 0;
00161 
00162    static void clamp_barycentric(Wvec &bc) {
00163       bc.set(max(bc[0],0.0), max(bc[1],0.0), max(bc[2],0.0));
00164       bc /= (bc[0] + bc[1] + bc[2]);
00165    }
00166 
00167    //******** INTERSECTION ********
00168 
00169    // Intersection w/ ray from given screen point -- returns the point
00170    // on the Bsimplex that is nearest to the given screen space point.
00171    // Note: the returned "near point" and "normal" are both
00172    //       transformed to world space.
00173    virtual bool view_intersect(
00174       CNDCpt&,  // Given screen point. Following are returned:
00175       Wpt&,     // Near point on the simplex IN WORLD SPACE (not object space)
00176       double&,  // Distance from camera to near point
00177       double&,  // Screen distance (in PIXELs) from given point
00178       Wvec& n   // "normal" vector at intersection point IN WORLD SPACE
00179       ) const = 0;
00180 
00181    // Convenience, when you just want the hit point:
00182    virtual bool near_point(CNDCpt& p, mlib::Wpt& hit) const {
00183       double d, d2d; Wvec n;
00184       return view_intersect(p, hit, d, d2d, n);
00185    }
00186 
00187    //******** LOCAL SEARCH AND NEAREST POINTS ********
00188 
00189    //**** NEW VERSION ****
00190 
00191    // Do a local search over the mesh, starting from this Bsimplex,
00192    // crossing to neighboring Bsimplexes as long as they are closer to
00193    // the target point and they are accepted by the filter. Stop when
00194    // reaching a Bsimplex that is locally closest (no neighbors are
00195    // closer), and return that one.
00196    Bsimplex* walk_to_target(
00197       CWpt& target, CSimplexFilter& filter = SimplexFilter()
00198       ) const;
00199    Bsimplex* walk_to_target(
00200       CWpt& target,
00201       Wpt&  near_pt,    // return val
00202       Wvec& near_bc,    // return val
00203       CSimplexFilter& filter = SimplexFilter()
00204       ) const {
00205       Bsimplex* ret = walk_to_target(target, filter);
00206       assert(ret);
00207       near_pt = ret->nearest_pt(target, near_bc);
00208       return ret;
00209    }
00210 
00211    // return a list of adjacent Bsimplexes:
00212    virtual Bsimplex_list neighbors() const = 0;
00213 
00214    // Distance from this Bsimplex to the given point:
00215    double dist(CWpt& p)           const { return nearest_pt(p   ).dist(p); }
00216    double dist(CWpt& p, mlib::Wvec& bc) const { return nearest_pt(p,bc).dist(p); }
00217 
00218    //**** OLD VERSION ****
00219 
00220    virtual bool local_search(
00221       Bsimplex *&end, Wvec &final_bc,
00222       CWpt &target, mlib::Wpt &reached,
00223       Bsimplex *repeater = 0, int iters = 30
00224       ) = 0;
00225 
00226    virtual NDCpt nearest_pt_ndc(mlib::CNDCpt&, mlib::Wvec&, int&)               const = 0;
00227    virtual Wpt   nearest_pt(mlib::CWpt& p, mlib::Wvec &bc, bool &is_on_simplex) const = 0;
00228    virtual Wpt   nearest_pt(mlib::CWpt& p, mlib::Wvec& bc) const {
00229       bool b;
00230       return nearest_pt(p,bc,b);
00231    }
00232    virtual Wpt nearest_pt(mlib::CWpt& p) const {
00233       Wvec bc;
00234       return nearest_pt(p,bc);
00235    }
00236 
00237    // probably should be replaced:
00238    virtual bool   on_face(const Bface* f)       const = 0;
00239    virtual Bface* get_face()                    const = 0;
00240 
00241  //*******************************************************
00242  // PROTECTED
00243  //*******************************************************
00244  protected:
00245    uint              _key;       // unique id for looking up this simplex
00246    uint              _flag;      // for graph searching and boolean states
00247    BMESH*            _mesh;      // mesh containing this simplex
00248    SimplexDataList*  _data_list; // optional simplex data list
00249 
00250    //******** INTERNAL METHODS ********
00251 
00252    // called once (first time _key is accessed):
00253    uint generate_key();
00254 
00255    // Table for looking up a Bsimplex from its "key" value. First slot
00256    // contains a null item, so index of 0 always looks up a null item.
00257  public:
00258    class IDtable : public ARRAY<Bsimplex*> {
00259     public:
00260       IDtable(int max) : ARRAY<Bsimplex*>(max) { *this += (Bsimplex*)0; }
00261    };
00262  protected:
00263    static IDtable       _table;
00264 
00265    enum { FLAG_MASK = ((1 << FLAG_BITS) - 1) };
00266 
00267    // convert a bit number to corresponding mask:
00268    static uint mask(uint b) { return (1 << (b - 1)); }
00269 };
00270 
00271 inline bool
00272 is_vert(CBsimplex* s)
00273 {
00274    return (s && (s->dim() == 0));
00275 }
00276 
00277 inline bool
00278 is_edge(CBsimplex* s)
00279 {
00280    return (s && (s->dim() == 1));
00281 }
00282 
00283 inline bool
00284 is_face(CBsimplex* s)
00285 {
00286    return (s && (s->dim() == 2));
00287 }
00288 
00289 inline BMESH*
00290 get_mesh(CBsimplex* s) 
00291 {
00292    return s ? s->mesh() : (BMESH*)0;
00293 }
00294 
00295 inline Bface*
00296 get_bface(CBsimplex* s) 
00297 {
00298    return s ? s->get_face() : (Bface*)0;
00299 }
00300 
00301 #endif // BSIMPLEX_H_IS_INCLUDED
00302 
00303 // end of file bsimplex.H

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