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

lmesh.H

Go to the documentation of this file.
00001 #ifndef LMESH_H_HAS_BEEN_INCLUDED
00002 #define LMESH_H_HAS_BEEN_INCLUDED
00003 
00004 #include "lstrip.H"
00005 #include "ledge_strip.H"
00006 #include "lvert_strip.H"
00007 #include "subdiv_calc.H"
00008 
00009 #define CLMESHptr const LMESHptr
00010 /*****************************************************************
00011  * LMESH:
00012  *
00013  *    Subdivision mesh based on rules defined in subdiv_calc.H
00014  *****************************************************************/
00015 MAKE_PTR_SUBC(LMESH,BMESH);
00016 class LMESH : public BMESH {
00017 
00018   public:
00019    //******** MANAGERS ********
00020    LMESH(int num_v=0, int num_e=0, int num_f=0);
00021 
00022    virtual ~LMESH();
00023 
00024    //******** RUN-TIME TYPE IDENTIFICATION ********
00025    DEFINE_RTTI_METHODS3("LMESH", LMESH*, BMESH, CDATA_ITEM*);
00026 
00027    // XXX - Should be protected, here for debugging:
00028 
00029    // Blow away subdivision mesh
00030    void delete_subdiv_mesh();
00031 
00032    // Put all vertices in the dirty list:
00033    void mark_all_dirty();
00034 
00035    // verts whose subdiv verts need recalculating:
00036    CBvert_list& dirty_verts() const { return _dirty_verts; }
00037 
00038    //******** CONVENIENT UPCASTS ********
00039    Lvert* lv(int k) const { return (Lvert*) _verts[k]; }
00040    Ledge* le(int k) const { return (Ledge*) _edges[k]; }
00041    Lface* lf(int k) const { return (Lface*) _faces[k]; }
00042 
00043    Lvert* dv(int k) const { return (Lvert*) _dirty_verts[k]; }
00044 
00045    //******** ACCESSORS ********
00046 
00047    // Control mesh:
00048    LMESH* control_mesh() const {
00049       return (LMESH*) (_parent_mesh ? _parent_mesh->control_mesh() : this);
00050    }
00051 
00052    bool   is_control_mesh()     const   { return (_parent_mesh == 0); }
00053 
00054    // Subdivision child of this mesh:
00055    LMESH* subdiv_mesh()         const   { return (LMESH*)_subdiv_mesh; }
00056 
00057    // Parent of this mesh
00058    LMESH* parent_mesh()         const  { return (LMESH*)_parent_mesh; }
00059 
00060    // Subdivision child at level k relative to this one:
00061    // (k == 1 refers to immediate child)
00062    LMESH* subdiv_mesh(int k) const {
00063       if (k == 0)
00064          return (LMESH*)this;
00065       else if (k < 0)
00066          return parent_mesh(-k);
00067       else
00068          return _subdiv_mesh ? _subdiv_mesh->subdiv_mesh(k-1) : 0;
00069    }
00070 
00071    // Parent at level k relative to this mesh:
00072    // (k == 1 refers to immediate parent)
00073    LMESH* parent_mesh(int k) const {
00074       if (k == 0)
00075          return (LMESH*)this;
00076       else if (k < 0)
00077          return subdiv_mesh(-k);
00078       else
00079          return _parent_mesh ? _parent_mesh->parent_mesh(k-1) : 0;
00080    }
00081 
00082    // Generate the subdivision mesh,
00083    // unless a system error prevents it:
00084    bool allocate_subdiv_mesh();
00085 
00086    // The currently drawn mesh in the whole subdivision hierarchy:
00087    LMESH* cur_mesh() const { return control_mesh()->_cur_mesh; }
00088 
00089    bool is_cur_mesh() const { return cur_mesh() == this; }
00090 
00091    // Returns 4^k, where k is the current subdivision level.
00092    // (Scale factor relating num faces in ctrl mesh to cur subdiv mesh).
00093    int subdiv_face_scale() const { return (1 << 2*cur_level()); }
00094 
00095    // Returns 2^k, where k is the current subdivision level.
00096    // (Scale factor relating num edges in ctrl mesh to cur subdiv mesh).
00097    int subdiv_edge_scale() const { return (1 << cur_level()); }   
00098 
00099    //******** SUBDIVION CALCULATION RULES ********
00100    SubdivLocCalc*   loc_calc()   const { return _loc_calc; }
00101    SubdivColorCalc* color_calc() const { return _color_calc; }
00102 
00103    void set_subdiv_loc_calc(SubdivLocCalc* c);
00104    void set_subdiv_color_calc(SubdivColorCalc* c);
00105 
00106    Wpt   limit_loc   (CBvert* v) const { return _loc_calc->limit_val(v); }
00107    Wpt   subdiv_loc  (CBvert* v) const { return _loc_calc->subdiv_val(v); }
00108    Wpt   subdiv_loc  (CBedge* e) const { return _loc_calc->subdiv_val(e); }
00109    COLOR subdiv_color(CBvert* v) const { return _color_calc->subdiv_val(v); }
00110    COLOR subdiv_color(CBedge* e) const { return _color_calc->subdiv_val(e); }
00111 
00112    //******** SUBDIVISION ********
00113    void refine();       // switch to finer subdivision mesh
00114    void unrefine();     // switch to coarser subdivision mesh
00115 
00116    // Ensure subdiv meshes are updated to the given level,
00117    // and set the current level to the given one:
00118    // (returns true if anything happened):
00119    bool update_subdivision(int level);
00120 
00121    // update a selected region down to desired level k.
00122    // faces must all belong to the same LMESH. corresponding
00123    // faces/edges/verts down to level k will be updated.
00124    static bool update_subdivision(CBface_list& faces, int k=1);
00125 
00126    // XXX - shouldn't have to update 1-ring faces...
00127    static bool update_subdivision(CBvert_list& verts, int k=1) {
00128       return update_subdivision(verts.one_ring_faces(), k);
00129    }
00130 
00131    // Ensure subdiv meshes are updated to CURRENT level:
00132    void update() {
00133       if (_cur_mesh != this)
00134          update_subdivision(cur_level());
00135    }
00136 
00137    // subdivide, replacing control mesh with the refined mesh:
00138    void subdivide_in_place();
00139 
00140    // Keeping track of vertices whose subdivision verts are out of
00141    // date (A.K.A. "dirty" vertices):
00142    void add_dirty_vert(Lvert* v) {
00143       if (v && v->is_clear(Lvert::DIRTY_VERT_LIST_BIT)) {
00144          v->set_bit(Lvert::DIRTY_VERT_LIST_BIT);
00145          _dirty_verts += v;
00146       }
00147    }
00148    void rem_dirty_vert(Lvert* v) {
00149       if (v && v->is_set(Lvert::DIRTY_VERT_LIST_BIT)) {
00150          v->clear_bit(Lvert::DIRTY_VERT_LIST_BIT);
00151          _dirty_verts -= v;
00152       }
00153    }
00154 
00155    static void fit(ARRAY<Lvert*>& verts, bool do_gauss_seidel=1);
00156 
00157    // Merging two meshes:
00158    //    Convenience method -- same as BMESH::merge() but
00159    //    returns an LMESHptr.
00160    static LMESHptr merge(LMESHptr m1, LMESHptr m2) {
00161       BMESHptr ret = BMESH::merge(m1, m2);
00162       return ret ? (LMESH*)&*ret : 0;
00163    }
00164 
00165    // Given a set of vertices from the same LMESH, return
00166    // the set of vertices of the parent LMESH that affect
00167    // the subdivision locations of the given vertices.
00168    static Bvert_list get_subdiv_inputs(CBvert_list& verts);
00169 
00170    //******** I/O - READ ********
00171 
00172    // Read an LMESH from a file and return it.  
00173    // Handles new .jot or .sm formats. 
00174    static LMESHptr read_jot_file  (char* filename);
00175    static LMESHptr read_jot_stream(istream& is);
00176 
00177    //******** BMESH methods ********
00178 
00179    // The level of the currently drawn mesh:
00180    virtual int cur_level() const { return cur_mesh()->_subdiv_level; }
00181 
00182    // The level of this mesh in the hierarchy
00183    // (0 == control mesh, next level is 1, etc.):
00184    virtual int subdiv_level() const { return _subdiv_level; }
00185 
00186    // Return the number of levels for which _subdiv_mesh is already
00187    // allocated (starting with the control mesh):
00188    int max_cur_level() const { return control_mesh()->_max_cur_level(); }
00189 
00190    // Vertices, edges and faces of the current subdiv mesh:
00191    virtual CBvert_list& cur_verts() const { return cur_mesh()->verts(); }
00192    virtual CBedge_list& cur_edges() const { return cur_mesh()->edges(); }
00193    virtual CBface_list& cur_faces() const { return cur_mesh()->faces(); }
00194 
00195    // creating elements
00196    virtual Bvert*    new_vert(CWpt& p = mlib::Wpt::Origin()) const;
00197    virtual Bedge*    new_edge(Bvert* u, Bvert* v) const;
00198    virtual Bface*    new_face(Bvert*,Bvert*,Bvert*,Bedge*,Bedge*,Bedge*) const;
00199 
00200    // XXX - in transition:
00201    virtual TriStrip*  new_tri_strip()  const { return new TriStrip; }
00202 
00203    virtual EdgeStrip* new_edge_strip() const { return new LedgeStrip; }
00204    virtual VertStrip* new_vert_strip() const { return new LvertStrip; }
00205    virtual Patch*     new_patch();
00206 
00207    // adding elements
00208    virtual Bvert* add_vertex(Bvert* v);
00209    virtual Bvert* add_vertex(CWpt& loc=mlib::Wpt::Origin());
00210 
00211    // removing elements
00212    virtual int remove_vertex(Bvert* v);
00213    virtual int remove_edge(Bedge* e);
00214    virtual int remove_face(Bface* f);
00215 
00216    // geometric ops:
00217    virtual double volume() const;
00218    virtual double area()   const;
00219    virtual void clear_creases();
00220 
00221    // freeing elements
00222    virtual void   delete_elements();
00223 
00224    // assigning
00225    virtual BMESH& operator =(CBMESH& m);
00226    virtual BMESH& operator =(CLMESH& m);
00227    virtual BMESH& operator =(BODY& b);
00228 
00229    // setting the geom
00230    virtual void set_geom(GEOM *geom);
00231 
00232    // I/O
00233    virtual int write_patches(ostream& os) const;
00234 
00235    // Edit level -
00236    //   Tells what level of subdivision is active for editing.
00237    //   The value is only meaningful in the control mesh.
00238    //
00239    virtual int edit_level() const {
00240       return control_mesh()->BMESH::edit_level();
00241    }
00242 
00243    virtual void inc_edit_level();
00244    virtual void dec_edit_level();
00245    
00246    // specify edit level for current mesh,
00247    // only operate on control mesh ... john
00248    virtual bool set_edit_level(int level);
00249 
00250    virtual void changed(change_t);
00251    virtual void changed() { changed(TOPOLOGY_CHANGED); }
00252 
00253    //******** DIAGNOSTIC ********
00254 
00255    // Return the approximate memory used for this mesh.
00256    virtual int  size()  const;
00257    virtual void print() const;
00258 
00259    //******** RENDERING STYLE ********
00260 
00261    // The rendering style is only set on a mesh when you want to
00262    // override the current rendering style of the view. i.e., almost
00263    // never. Virtual methods over-rode in LMESH to deflect calls to
00264    // the control mesh.
00265    virtual void set_render_style(Cstr_ptr& s) {
00266       control_mesh()->BMESH::set_render_style(s);
00267    }
00268    virtual void push_render_style(Cstr_ptr& s) {
00269       control_mesh()->BMESH::push_render_style(s);
00270    }
00271    virtual void pop_render_style() {
00272       control_mesh()->BMESH::pop_render_style();
00273    }
00274    virtual Cstr_ptr& render_style() const {
00275       return control_mesh()->BMESH::render_style();
00276    }
00277 
00278    //**************** BODY methods ****************
00279    // missing: copy, vertices
00280    virtual int    draw(CVIEWptr &v);
00281    virtual int    intersect(RAYhit&, CWtransf&, mlib::Wpt&,
00282                             Wvec&, double&, double&,mlib::XYpt&) const;
00283    virtual void   transform(CWtransf &xform, CMOD& m);
00284    virtual BODY  *subtract (BODYptr &subtractor)   { return 0; }
00285    virtual BODY  *combine (BODYptr &combiner)      { return 0; }
00286    virtual BODY  *intersect (BODYptr &intersector) { return 0; }
00287    virtual CBBOX &get_bb();
00288 
00289    //**************** DATA_ITEM methods ****************
00290    
00291    virtual CTAGlist &tags() const;
00292 
00293    virtual DATA_ITEM   *dup()  const { return new LMESH(0,0,0);}
00294 
00295  //*******************************************************
00296  // PROTECTED
00297  //*******************************************************
00298  protected:
00299    LMESH*       _parent_mesh;  // subdivision parent
00300    LMESH*       _cur_mesh;     // current subdivision mesh
00301    LMESHptr     _subdiv_mesh;  // subdivision child
00302    int          _subdiv_level; // level of this mesh (control mesh = level 0)
00303    Bvert_list   _dirty_verts;  // verts whose subdiv verts need recalculating
00304 
00305    // engines of subdivision calculation:
00306    SubdivLocCalc*       _loc_calc;
00307    SubdivColorCalc*     _color_calc;
00308 
00309    //******** INTERNAL METHODS ********
00310 
00311    void set_parent(LMESH* parent) { 
00312       _parent_mesh = parent; 
00313       _subdiv_level = parent->subdiv_level() + 1; 
00314    }
00315 
00316    void set_cur_mesh(LMESH* cur);
00317 
00318    // Return the number of levels finer than this mesh
00319    // for which _subdiv_mesh is already allocated:
00320    int _max_cur_level() const {
00321       return _subdiv_mesh ? _subdiv_mesh->_max_cur_level() + 1 : 0;
00322    }
00323 
00324    virtual void send_update_notification();
00325 
00326    // Merge the elements of the given mesh into this one:
00327    virtual void _merge(BMESH*);
00328 
00329    //******** I/O ********
00330    TAGlist*             _lmesh_tags;
00331 };
00332 
00333 /*****************************************************************
00334  * inlines
00335  *****************************************************************/
00336 
00337 // Convenient "upcast" (though GEL actually may contain an LMESH)
00338 inline LMESHptr 
00339 gel_to_lmesh(CGELptr &gel) 
00340 {
00341    BMESHptr mesh = gel_to_bmesh(gel);
00342    return mesh ? LMESH::upcast(&*mesh) : 0;
00343 }
00344 
00345 inline BMESH*
00346 get_ctrl_mesh(CBMESH* m)
00347 {
00348    return (LMESH::isa(m)) ? ((LMESH*)m)->control_mesh() : (BMESH*)m;
00349 }
00350 
00351 inline BMESH*
00352 get_cur_mesh(CBMESH* m)
00353 {
00354    return (LMESH::isa(m)) ? ((LMESH*)m)->control_mesh()->cur_mesh() :
00355       (BMESH*)m;
00356 }
00357 
00358 // Return the LMESH that owns the simplex, if it exists:
00359 inline LMESH*
00360 get_lmesh(CBsimplex* s)
00361 {
00362    return s ? LMESH::upcast(s->mesh()) : 0;
00363 }
00364 
00365 inline int
00366 subdiv_level(CBsimplex* s)
00367 {
00368    if (!s) return -1;
00369    LMESH* m = LMESH::upcast(s->mesh());
00370    return m ? m->subdiv_level() : -1;
00371 }
00372 
00373 inline Bface*
00374 get_ctrl_face(CBface* f)
00375 {
00376    if (!f)
00377       return 0;
00378    return LMESH::isa(f->mesh()) ? ((Lface*)f)->control_face() : (Bface*)f;
00379 }
00380 
00381 inline Bface*
00382 get_parent_face(CBface* f)
00383 {
00384    return (f && LMESH::isa(f->mesh())) ? ((Lface*)f)->parent() : 0;
00385 }
00386 
00387 inline Bsimplex*
00388 get_parent_simplex(CBedge* e)
00389 {
00390    return (e && LMESH::isa(e->mesh())) ? ((Ledge*)e)->parent() : 0;
00391 }
00392 
00393 inline Bsimplex*
00394 get_parent_simplex(CBvert* v)
00395 {
00396    return (v && LMESH::isa(v->mesh())) ? ((Lvert*)v)->parent() : 0;
00397 }
00398 
00399 inline Bsimplex*
00400 get_parent_simplex(CBsimplex* s)
00401 {
00402    return (!(s && LMESH::isa(s->mesh())) ? 0 :
00403            is_vert(s) ? get_parent_simplex((Bvert*)s) :
00404            is_edge(s) ? get_parent_simplex((Bedge*)s) :
00405            is_face(s) ? (Bsimplex*)get_parent_face((Bface*)s) :
00406            0);
00407 }
00408 
00409 inline void
00410 claim_edit_level(LMESHptr m)
00411 {
00412    // make the mesh m the "current" one in its
00413    // subdivision hierarchy, and set the edit level
00414    // to the level of m.
00415    if (m) {
00416       m->control_mesh()->update_subdivision(m->subdiv_level());
00417       set_edit_level(m, m->subdiv_level());
00418    }
00419 }
00420 
00421 inline void
00422 update_subdivision(CBMESHptr& mesh, int level)
00423 {
00424    if (mesh && LMESH::isa(&*mesh)) {
00425       LMESH* ctrl = ((LMESH*)&*mesh)->control_mesh();
00426       if (ctrl)
00427          ctrl->update_subdivision(level);
00428    }
00429 }
00430 
00431 inline LMESH*
00432 get_lmesh(CBface_list& faces)
00433 {
00434    return LMESH::upcast(faces.mesh());
00435 }
00436 
00437 inline LMESH*
00438 get_subdiv_mesh(BMESH* m, int level)
00439 {
00440    // XXX -- could handle negative levels but not doing it now
00441    if ( level < 0 || !LMESH::isa(m) )
00442       return 0;
00443 
00444    LMESH* lm = (LMESH*)m;
00445 
00446      for ( int i=0; lm && i<level; i++ ) {
00447        lm = lm->subdiv_mesh();
00448      }
00449 
00450    return lm;
00451 }
00452 
00453 // Return faces at given level relative to these faces.
00454 // Assumes these faces are from the same LMESH.
00455 inline Bface_list 
00456 get_subdiv_faces(CBface_list& faces, int level)
00457 {
00458    Bface_list ret;
00459    LMESH* m = LMESH::upcast(faces.mesh());
00460    if (!(level >= 0 && m && m->subdiv_mesh(level)))
00461       return ret;
00462    for (int i=0; i<faces.num(); i++)
00463       ((Lface*)faces[i])->append_subdiv_faces(level, ret);
00464    return ret;
00465 }
00466 
00467 // Return parent faces at given level up from the given ones.
00468 // Assumes these faces are from the same LMESH.
00469 inline Bface_list
00470 get_parent_faces(CBface_list& faces, int level=1)
00471 {
00472    Bface_list ret;
00473    LMESH* m = LMESH::upcast(faces.mesh());
00474    if (!(level >= 0 && m && m->parent_mesh(level)))
00475       return ret;
00476 
00477    // first clear the flag of each parental face
00478    Lface* p = 0;
00479    int i;
00480    for (i = 0; i<faces.num(); i++) {
00481       if ((p = ((Lface*)faces[i])->parent()))
00482          p->clear_flag();
00483    }
00484 
00485    // now store each parent face that hasn't yet been reached:
00486    for (i = 0; i<faces.num(); i++) {
00487       if ((p = ((Lface*)faces[i])->parent()) && !p->flag()) {
00488          p->set_flag(1);
00489          ret += p;
00490       }
00491    }
00492    return ret;
00493 }
00494 
00495 inline Bface_list
00496 remap_level(CBface_list& faces, int k)
00497 {
00498    // Given a set of faces from the same LMESH,
00499    // remap to corresponding faces at the given level k,
00500    // relative to the original mesh.
00501 
00502    if (k == 0)
00503       return faces;
00504    else if (k < 0)
00505       return get_parent_faces(faces, -k);
00506    else
00507       return get_subdiv_faces(faces, k);
00508 }
00509 
00510 inline Bface_list
00511 get_top_level(CBface_list& faces)
00512 {
00513    Bface_list ret = faces;
00514    
00515    for (Bface_list p = get_parent_faces(faces);
00516         !p.empty();
00517         p = get_parent_faces(p))
00518       ret = p;
00519    return ret;
00520 }
00521 
00522 inline bool
00523 has_secondary_any_level(CBface_list& faces)
00524 {
00525    for (Bface_list sub = faces; !sub.empty(); sub = get_subdiv_faces(sub,1))
00526       if (sub.has_any_secondary())
00527          return true;
00528    return false;
00529 }
00530 
00531 template <class L, class S>
00532 inline Bvert_list
00533 child_verts(const L& list)
00534 {
00535    // L can be Bvert_list or Bedge_list.
00536    // S must then be Lvert or Ledge, respectively.
00537    // 
00538    // Return the child vertices of the given list.
00539    // list elements must all belong to the same LMESH.
00540    // Child vertices must already exist.
00541    // We aren't creating them, just returning a list of them.
00542 
00543    Bvert_list ret(list.num());
00544 
00545    if (list.empty())
00546       return ret;
00547 
00548    assert(LMESH::isa(list.mesh()));
00549 
00550    for (int i=0; i<list.num(); i++) {
00551       Lvert* v = ((S*)list[i])->subdiv_vertex();
00552       assert(v);
00553       ret += v;
00554    }
00555    return ret;
00556 }
00557 
00558 #endif  // LMESH_H_HAS_BEEN_INCLUDED
00559 
00560 // end of file lmesh.H

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