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

ledge.H

Go to the documentation of this file.
00001 #ifndef LEDGE_H_HAS_BEEN_INCLUDED
00002 #define LEDGE_H_HAS_BEEN_INCLUDED
00003 
00004 #include <climits>
00005 #include "bmesh.H"
00006 
00007 class Lvert;
00008 class Lface;
00009 class LMESH;
00010 
00011 #define CLvert const Lvert
00012 #define CLedge const Ledge
00013 #define CLface const Lface
00014 #define CLMESH const LMESH
00015 /**********************************************************************
00016  * Ledge:
00017  *
00018  *    An edge of an LMESH (subdivision mesh)
00019  **********************************************************************/
00020 class Ledge : public Bedge {
00021    friend class REPARENT_CMD;
00022  public:
00023 
00024    //******** ENUMS ********
00025 
00026    enum mask_t {
00027       REGULAR_SMOOTH_EDGE = 0,
00028       REGULAR_CREASE_EDGE,
00029       NON_REGULAR_CREASE_EDGE
00030    };
00031 
00032    enum {
00033       SUBDIV_LOC_VALID_BIT = Bedge::NEXT_AVAILABLE_BIT,
00034       SUBDIV_COLOR_VALID_BIT,
00035       SUBDIV_CREASE_VALID_BIT,
00036       MASK_VALID_BIT,
00037       SUBDIV_ALLOCATED_BIT,
00038       NEXT_AVAILABLE_BIT
00039    };
00040 
00041 
00042    //******** MANAGERS ********
00043 
00044    Ledge(Lvert* u, Lvert* v) :
00045       Bedge((Bvert*)u,(Bvert*)v),
00046       _subdiv_vertex(0),
00047       _crease(0),
00048       _mask(REGULAR_SMOOTH_EDGE),
00049       _parent(0) {}
00050    
00051    virtual ~Ledge();
00052 
00053    //******** ACCESSORS ********
00054 
00055    LMESH*  lmesh()      const   { return (LMESH*)mesh(); }
00056    Lvert*  lv(int k)    const   { return (Lvert*) v(k); }
00057    Lface*  lf(int k)    const   { return (Lface*) f(k); }
00058 
00059    //******** SUBDIVISION ELEMENTS ********
00060 
00061    Lvert*  subdiv_vertex()const   { return _subdiv_vertex; }
00062 
00063    // child edges
00064    Ledge*  subdiv_edge1() const;
00065    Ledge*  subdiv_edge2() const;
00066 
00067    // child edge of adjacent face (1 or 2) that is parallel to this:
00068    Ledge*  parallel_sub_edge(int k) const;
00069 
00070    void    allocate_subdiv_elements();
00071    void    set_subdiv_elements(Lvert* subv);
00072    void    delete_subdiv_elements();
00073    void    update_subdivision();
00074 
00075    // Return an ordered list of edges at the given subdiv level
00076    // *relative* to the level of this edge. (Level must be >= 0).
00077    // E.g. level 1 means one level down the subdivision hierarchy.
00078    // The returned edges run in the direction of v1 to v2.
00079    bool append_subdiv_edges(int lev, ARRAY<Bedge *> &edges); 
00080 
00081    // Similar to append_subdiv_edges(), but returns the
00082    // ordered list of subdiv verts at the given level lev >= 0:
00083    bool get_subdiv_verts(int lev, Bvert_list& ret);
00084 
00085    // not for public use, to be called by the child
00086    void    subdiv_vert_deleted();
00087 
00088    //******** NON-MANIFOLD MESHES ********
00089 
00090  protected:
00091    // Add the face as a secondary (or "multi") face.
00092    // Then do the same for the appropriate child faces.
00093    virtual bool add_multi(Bface* f); 
00094 
00095    // Add the face as a primary face (in slot _f1 or _f2).
00096    // In Ledge, do the same for the appropriate child faces.
00097    virtual bool add_primary(Bface* f); 
00098 
00099  public:
00100 
00101    // Bedge::can_promote() returns true if there is at least one
00102    // available primary slot (_f1 or _f2).  In Ledge, all child
00103    // edges must also have available slots.
00104    virtual bool can_promote() const {
00105       Ledge* s = 0;
00106       return (Bedge::can_promote() &&
00107               (!(s = subdiv_edge1()) || s->can_promote()) &&
00108               (!(s = subdiv_edge2()) || s->can_promote()));
00109    }
00110 
00111    // The following is used in Lface::allocate_subdiv_elements()
00112    // and also in Ledge::add_multi().  If the given face is a
00113    // secondary face WRT this edge, then ensure its children have
00114    // the same relationship WRT the child edges of this edge.
00115    void push_multi(Bface* f);
00116 
00117    // Used in Ledge::add_primary(); similar to above.
00118    void push_primary(Bface* f);
00119 
00120    //******** CONTROL ELEMENTS ********
00121 
00122    // proper parent
00123    // (it's null for edges of the control mesh):
00124    Bsimplex* parent() const { return _parent; }
00125 
00126    // Get parent edge (it it exists) at the given relative
00127    // level up from this edge
00128    Ledge* parent_edge(int rel_level) const;
00129 
00130    // control element
00131    // (it's the edge itself in the control mesh):
00132    Bsimplex* ctrl_element() const;
00133 
00134    // convenience method - casts control element to Ledge if valid:
00135    Ledge* ctrl_edge() const {
00136       Bsimplex* sim = ctrl_element();
00137       return is_edge(sim) ? (Ledge*)sim : (Ledge*)0;
00138    }
00139    Lface* ctrl_face() const;    // defined in bface.H
00140 
00141    void set_parent(Bsimplex* p) { _parent = p; }
00142 
00143    // Difference between subdiv level of this edge and its control element
00144    // (See Ledge):
00145    // XXX - move to Bsimplex?
00146    virtual uint rel_level() const;
00147 
00148    //******** SUBDIVISION MASK ********
00149 
00150    void set_mask();
00151    unsigned short subdiv_mask() const;
00152    int is_smooth() const { return !is_crease(); }
00153 
00154    //******** CACHED DATA ********
00155 
00156    void    subdiv_loc_changed()    { clear_bit(SUBDIV_LOC_VALID_BIT);   }
00157    void    subdiv_color_changed()  { clear_bit(SUBDIV_COLOR_VALID_BIT); }
00158 
00159    //******** Bedge VIRTUAL METHODS ********
00160 
00161    // crease management
00162    virtual void set_crease(unsigned short c = USHRT_MAX);
00163    virtual unsigned short crease_val() const { return _crease; }
00164 
00165    // cached data management
00166    virtual void normal_changed();
00167    virtual void geometry_changed();
00168    virtual void color_changed();
00169    virtual void crease_changed();
00170    virtual void faces_changed();    // called when faces are added or deleted
00171 
00172    virtual void mask_changed();
00173 
00174    // building/redefining
00175    virtual int  redefine(Bvert *v, Bvert *u);
00176    virtual void set_new_vertices(Bvert *v1, Bvert *v2);
00177 
00178    // Carry out swap if it is legal:
00179    virtual bool do_swap();
00180 
00181  protected:
00182    Lvert*         _subdiv_vertex; // vertex generated by subdivision
00183    unsigned short _crease;        // variable sharpness crease
00184    unsigned short _mask;          // subdivision mask id
00185    Bsimplex*      _parent;        // face or an edge that created this edge
00186 
00187    //******** PROTECTED METHODS ********
00188 
00189    // Helper functions used in Ledge::allocate_subdiv_elements() and
00190    // Ledge::set_subdiv_elements().
00191    //
00192    // Record this edge as parent of given child element, and propagate
00193    // attributes to the child.
00194    //
00195    // It's protected because we assume child legitimately
00196    // belongs to this edge.
00197    void claim_child(Ledge* child);
00198    void claim_child(Lvert* child);
00199 
00200    // Used in push_multi() and push_primary().
00201    // Full comments in ledge.C:
00202    void get_sub_faces(Bface* f, Bedge* &e1, Bface* &sf1, Bedge* &e2, Bface* &sf2);
00203 
00204  private:
00205    // In rare cases, certain people can do the following.
00206    // However, you are not one of them.
00207    void assign_subdiv_vert(Lvert* v) { _subdiv_vertex = v; }
00208 };
00209 
00210 /*****************************************************************
00211  *  get_subdiv_chain:
00212  *
00213  *     Given vertices v1 and v2 joined by an Ledge, recursively
00214  *     extract chain of subdivision vertices generated along the
00215  *     edge at the given level (relative to the original edge):
00216  *****************************************************************/
00217 bool get_subdiv_chain(Bvert* v1, Bvert* v2, int level, Bvert_list& ret);
00218 
00219 /*****************************************************************
00220  *  get_subdiv_chain:
00221  *
00222  *     Given a connected chain of vertices, recursively extract
00223  *     the corresponding chain of subdivision vertices at the
00224  *     given level (relative to the original chain). On failure
00225  *     returns the empty list.
00226  *****************************************************************/
00227 bool get_subdiv_chain(CBvert_list& chain, int level, Bvert_list& ret);
00228 
00229 
00230 /*****************************************************************
00231  * EdgeChildFilter:
00232  *
00233  *   Accepts an edge that was generated in subdivision by an edge
00234  *   in the next coarser-level mesh.
00235  *
00236  *   NB: Only use this with class Ledge.
00237  *****************************************************************/
00238 class EdgeChildFilter : public SimplexFilter {
00239  public:
00240    virtual bool accept(CBsimplex* s) const {
00241       return is_edge(s) && is_edge(((Ledge*)s)->parent());
00242    }
00243 };
00244 
00245 #endif  // LEDGE_H_HAS_BEEN_INCLUDED
00246 
00247 // end of file ledge.H

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