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

hybrid.H

Go to the documentation of this file.
00001 /*****************************************************************
00002  * hybrid.H
00003  *****************************************************************/
00004 #ifndef HYBRID_H_IS_INCLUDED
00005 #define HYBRID_H_IS_INCLUDED
00006 
00007 #include "subdiv_calc.H"
00008 
00009 //
00010 // A Bface is a triangle if it is non-null and
00011 // isn't part of a quad
00012 //
00013 inline bool
00014 is_tri(CBface* f)
00015 {
00016    return f && !f->is_quad();
00017 }
00018 
00019 //
00020 // A Bedge is adjacent to a triangle if it belongs
00021 // to a face that is a triangle
00022 //
00023 inline bool
00024 is_adjacent_tri(CBedge* e)
00025 {
00026    return e && (is_tri(e->f1()) || is_tri(e->f2()));
00027 }
00028 
00029 //
00030 // A Bvert is adjacent to a triangle if it belongs
00031 // to an edge that is adjacent to a triangle
00032 //
00033 inline bool
00034 is_adjacent_tri(CBvert* v)
00035 {
00036    if (!v) return 0;
00037    for (int i=0; i<v->degree(); i++)
00038       if (is_adjacent_tri(v->e(i)))
00039          return 1;
00040    return 0;
00041 }
00042 
00043 
00044 //
00045 // A Bvert is near a triangle if any of its
00046 // neighboring vertices is adjacent to a triangle
00047 //
00048 inline bool
00049 is_near_tri(CBvert* v)
00050 {
00051    if (!v) return 0;
00052    if (is_adjacent_tri(v))
00053       return 1;
00054    for (int i=0; i<v->degree(); i++)
00055       if (is_adjacent_tri(v->nbr(i)))
00056          return 1;
00057    return 0;
00058 }
00059 
00060 /*
00061 //
00062 //                  v2                              
00063 //                /  | \                            
00064 //              /    |   \                          
00065 //        vf2 /      |     \ vf1                    
00066 //            \  f2  | f1  /                        
00067 //              \    |   /                          
00068 //                \  | /                            
00069 //                  v1                              
00070 //
00071 // A Bedge is near a triangle if any of the 4
00072 // vertices v1, v2, vf1, vf2 (see above) are
00073 // adjacent to a triangle. I.e., the edge is in
00074 // the 1-ring (maybe on the boundary) of a vertex
00075 // that is adjacent to a triangle.
00076 //
00077 */
00078 inline bool
00079 is_near_tri(CBedge* e)
00080 {
00081    return (
00082       e && (is_adjacent_tri(e->v1()) ||
00083             is_adjacent_tri(e->v2()) ||
00084             is_adjacent_tri(e->opposite_vert1()) ||
00085             is_adjacent_tri(e->opposite_vert2()))
00086       );
00087 }
00088 
00089 /*****************************************************************
00090  * HybridCalc2:
00091  *
00092  *   Scheme that is a hybrid of the Loop scheme and the
00093  *   Catmull-Clark scheme. In regions near triangles it uses the
00094  *   Loop masks. In regions of quads it uses the Catmull-clark
00095  *   masks. The "near-triangle" region of the quads keeps shrinking
00096  *   with each subdivision.
00097  *****************************************************************/
00098 template <class T>
00099 class HybridCalc2 : public SubdivCalc<T> {
00100  public:
00101    //******** MANAGERS ********
00102    HybridCalc2<T>() {
00103       _loop_calc.set_boss(this);
00104       _cc_calc.set_boss(this);
00105    }
00106 
00107    //******** SubdivCalc VIRTUAL METHODS ********
00108    virtual str_ptr name() const {
00109       static str_ptr ret("Nouveau Hybrid Subdivision");
00110       return ret;
00111    }
00112 
00113    //******** SUBDIVISION CALCULATION ********
00114    virtual T subdiv_val(CBvert* v) const {
00115       if (is_near_tri(v))
00116          return(_loop_calc.subdiv_val(v));
00117       return(_cc_calc.subdiv_val(v));
00118    }
00119 
00120    virtual T subdiv_val(CBedge* e) const {
00121       if (is_near_tri(e))
00122          return _loop_calc.subdiv_val(e);
00123       return (_cc_calc.subdiv_val(e));  // All Catmull-Clark
00124    }
00125 
00126    virtual T limit_val (CBvert* v) const {
00127       // actually we don't know the limit value in a region
00128       // near the boundary of quads and triangles.
00129       if (is_near_tri(v))
00130          return _loop_calc.limit_val(v);
00131       return _cc_calc.limit_val(v);
00132    }
00133 
00134  protected:
00135    LoopCalc<T>          _loop_calc;  // Computes Loop scheme
00136    CatmullClarkCalc<T>  _cc_calc;    // Computes Catmull-clark scheme
00137 };
00138 
00139 class Hybrid2Loc : public HybridCalc2<Wpt> {
00140  public:
00141    //******** VALUE ACCESSORS ********
00142    virtual Wpt get_val(CBvert* v)   const { return v->loc(); }
00143 
00144    //******** DUPLICATING ********
00145    virtual SubdivCalc<Wpt> *dup() const { return new Hybrid2Loc(); }
00146 };
00147 
00148 typedef VolPreserve<Hybrid2Loc> Hybrid2VolPreserve;
00149 
00150 #endif // HYBRID_H_IS_INCLUDED
00151 
00152 /* end of file hybrid.H */

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