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 */