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

lface.H

Go to the documentation of this file.
00001 #ifndef LFACE_H_HAS_BEEN_INCLUDED
00002 #define LFACE_H_HAS_BEEN_INCLUDED
00003 
00004 #include "lvert.H"
00005 class LMESH;
00006 /**********************************************************************
00007  * Lface:
00008  *    A face for LMESH, a subdivision mesh
00009  **********************************************************************/
00010 class Lface : public Bface {
00011  public:
00012    //******** ENUMS ********
00013    enum {
00014       SUBDIV_ALLOCATED_BIT = Bface::NEXT_AVAILABLE_BIT,
00015       NEXT_AVAILABLE_BIT
00016    };
00017 
00018 
00019    //******** MANAGERS ********
00020    Lface(Lvert* u, Lvert* v, Lvert* w, Ledge* e, Ledge* f, Ledge* g) :
00021       Bface(u,v,w,e,f,g), _parent(0) {}
00022 
00023    virtual ~Lface() { delete_subdiv_elements(); }
00024 
00025    //******** ACCESSORS ********
00026    LMESH* lmesh()       const   { return (LMESH*)mesh(); }
00027    Lvert* lv(int k)     const   { return (Lvert*) v(k); }
00028    Ledge* le(int k)     const   { return (Ledge*) e(k); }
00029    
00030 
00031    //******** CONTROL ELEMENTS ********
00032    Lface* parent() const { return _parent; }
00033 
00034    void   set_parent(Lface* f) { _parent = f; }
00035 
00036    // Return the parent face at the given subdivision level
00037    // relative to this face.
00038    //   rel_level <= 0: this face
00039    //   rel_level == 1: immediate parent
00040    //   rel_level == 2: parent of parent,
00041    //   etc.
00042    //
00043    // If there is no parent at the requested level,
00044    // return the parent at the highest available level.
00045    Lface* parent(int rel_level);
00046 
00047    Lface* control_face() const {
00048       return _parent ? _parent->control_face() : (Lface*)this;
00049    }
00050 
00051    //******** BARYCENTRIC COORDINATE CONVERSION ********
00052    // Convert barycentric coordinates WRT this face to
00053    // corresponding coords WRT parent or child face:
00054    Lface* parent_bc(CWvec& bc, mlib::Wvec& ret) const;
00055    Lface* parent_bc(Wvec& bc) const { return parent_bc(bc,bc); }
00056 
00057    Lface* child_bc (CWvec& bc, mlib::Wvec& ret) const;
00058    Lface* child_bc (Wvec& bc) const { return child_bc(bc,bc); }
00059 
00060    // Find the parent or child Lface at the desired mesh level, return
00061    // that face, and convert the given barycentric coords WRT this
00062    // face to corresponding coords WRT the returned face.
00063    //
00064    // If the desired level isn't available, returns the Lface* and
00065    // barycentric coordinates of the closest level to it we can reach.
00066    //
00067    Lface* bc_to_level(int level, CWvec& bc, mlib::Wvec& ret)  const;
00068    Lface* bc_to_level(int level, Wvec& bc)  const {
00069       return bc_to_level(level, bc, bc);
00070    }
00071 
00072    // Similar to above, using the mesh edit level:
00073    Lface* bc_to_edit_level(Wvec& bc)  const {
00074       return bc_to_level(_mesh->edit_level(), bc);
00075    }
00076    
00077    //******** SUBDIVISION ELEMENTS ********
00078    bool subdiv_dirty()  const   { return is_clear(SUBDIV_ALLOCATED_BIT); }
00079    void allocate_subdiv_elements();
00080    void set_subdiv_elements();
00081    void delete_subdiv_elements();
00082 
00083    // subdiv edges
00084    Ledge *subdiv_edge1() const {
00085       return (Ledge*)lookup_edge(le(1)->subdiv_vertex(),
00086                                  le(2)->subdiv_vertex());
00087    }
00088    Ledge *subdiv_edge2() const {
00089       return (Ledge*)lookup_edge(le(2)->subdiv_vertex(),
00090                                  le(3)->subdiv_vertex());
00091    }
00092    Ledge *subdiv_edge3() const {
00093       return (Ledge*)lookup_edge(le(3)->subdiv_vertex(),
00094                                  le(1)->subdiv_vertex());
00095    }
00096 
00097    // subdiv faces
00098    Lface *subdiv_face_center() const {
00099       return (Lface*) lookup_face(subdiv_edge1(), subdiv_edge2());
00100    }
00101    Lface *subdiv_face1() const {
00102       return (Lface*) lookup_face(subdiv_edge3(),lv(1)->subdiv_vertex());
00103    }
00104    Lface *subdiv_face2() const {
00105       return (Lface*) lookup_face(subdiv_edge1(),lv(2)->subdiv_vertex());
00106    }
00107    Lface *subdiv_face3() const {
00108       return (Lface*) lookup_face(subdiv_edge2(),lv(3)->subdiv_vertex());
00109    }
00110    
00111    void append_subdiv_faces(int lev, ARRAY<Bface *> &faces);
00112 
00113    virtual void color_changed();
00114 
00115    //******** NON-MANIFOLD MESHES ********
00116 
00117    // Label the face as "primary" or "secondary." I.e., as being
00118    // in the primary layer or not, respectively. In Lface, the
00119    // same action is passed down to all child faces.
00120    virtual void make_primary();
00121    virtual void make_secondary();
00122 
00123    // Set the layer number and pass it down to any children that exist:
00124    virtual void set_layer(ushort l);
00125 
00126    //******** BUILDING/REDEFINING ********
00127 
00128    virtual int  detach();
00129    virtual void reverse();
00130 
00131  protected:
00132    Lface* _parent;
00133 
00134    //******** PROTECTED METHODS ********
00135    virtual void set_patch(Patch* p);
00136 
00137    // Helper function used in Lface::set_patch():
00138    void set_child_patch(Lface* subface, Patch*& child);
00139 
00140    // Protected helper function used in Lface::gen_child_face()
00141    // and Lface::set_subdiv_elements().
00142    //
00143    // Record this face as parent of given child face, and
00144    // propagate attributes to the child.
00145    //
00146    // 'center_face' is true for the center face, whose edges
00147    // consider this face to be their parent.
00148    //
00149    // It's protected because we assume child legitimately
00150    // belongs to this face.
00151    void claim_child(Lface* child, bool center_face=false);
00152 
00153    // Helper function used in Lface::allocate_subdiv_elements().
00154    // Creat a child face and copy selected attributes from the
00155    // parent to the child.
00156    Lface* gen_child_face(Bvert* v1, Bvert* v2, Bvert* v3,
00157                          Patch* p, LMESH* m, bool center_face=false);
00158 };
00159 
00160 /*****************************************************************
00161  * inlines
00162  *****************************************************************/
00163 inline Lface*
00164 get_child(Lface* f, int level)
00165 {
00166    // Return f's child face at the given level
00167    // (relative to the level of f).
00168    //
00169    // XXX - chooses the center child at each step.
00170 
00171    while (f && level > 0) {
00172       f->allocate_subdiv_elements();
00173       f = f->subdiv_face_center();
00174       level--;
00175    }
00176    return f;
00177 }
00178 
00179 inline Lface*
00180 get_parent(Lface* f, int level)
00181 {   
00182    // Return f's parent face at the given level
00183    // (relative to the level of f).
00184 
00185    return f ? f->parent(level) : 0;
00186 }
00187 
00188 inline Lface* 
00189 remap(Lface* f, int level)
00190 {
00191    // Given a face, remap to a corresponding face at a
00192    // given subdivision level RELATIVE TO the given face.
00193    //
00194    // E.g. remap(f, 1) yields the center child face one
00195    // subdivision level finer than the given face.
00196    // remap(f, -1) yields the immediate parent, and
00197    // remap(f, -2) yields the parent of the parent, etc.
00198    // However, if the face is already at the control
00199    // level, and 'level' < 0, then remap(f, level) just
00200    // returns f.
00201 
00202    if (!f)
00203       return 0;                         // bad input
00204    if (level == 0)
00205       return f;                         // nothing to do
00206    if (level > 0)
00207       return get_child(f, level);       // go to finer level
00208 
00209    return get_parent(f, -level);        // go to coarser level:
00210 }
00211 
00212 inline Lface* 
00213 Ledge::ctrl_face() const 
00214 {
00215    Bsimplex* sim = ctrl_element();
00216    return is_face(sim) ? (Lface*)sim : (Lface*)0;
00217 }
00218 
00219 #endif  // LFACE_H_HAS_BEEN_INCLUDED
00220 
00221 // end of file lface.H

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