00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_REFINE_LOOP
00025 #define __VCGLIB_REFINE_LOOP
00026
00027 #include <math.h>
00028 #include <vcg/complex/trimesh/base.h>
00029 #include <vcg/complex/trimesh/refine.h>
00030 #include <vcg/space/color4.h>
00031 #include <vcg/container/simple_temporary_data.h>
00032 #include <vcg/complex/trimesh/update/flag.h>
00033 #include <vcg/complex/trimesh/update/color.h>
00034
00035
00036 namespace vcg{
00037 namespace tri{
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 template<class MESH_TYPE>
00059 struct OddPointLoop : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00060 {
00061 void operator()(typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep) {
00062
00063 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
00064 typename MESH_TYPE::CoordType *l,*r,*u,*d;
00065 l = &he.v->P();
00066 he.FlipV();
00067 r = &he.v->P();
00068
00069 if( MESH_TYPE::HasPerVertexColor())
00070 nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f);
00071
00072 if (he.IsBorder()) {
00073 nv.P() = ((*l)*0.5 + (*r)*0.5);
00074
00075 }
00076 else {
00077 he.FlipE(); he.FlipV();
00078 u = &he.v->P();
00079 he.FlipV(); he.FlipE();
00080 assert(&he.v->P()== r);
00081 he.FlipF(); he.FlipE(); he.FlipV();
00082 d = &he.v->P();
00083
00084
00085
00086 nv.P()=((*l)*(3.0/8.0)+(*r)*(3.0/8.0)+(*d)*(1.0/8.0)+(*u)*(1.0/8.0));
00087 }
00088
00089 }
00090
00091 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00092 {
00093 Color4<typename MESH_TYPE::ScalarType> cc;
00094 return cc.lerp(c0,c1,0.5f);
00095 }
00096
00097 template<class FL_TYPE>
00098 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00099 {
00100 TexCoord2<FL_TYPE,1> tmp;
00101 tmp.n()=t0.n();
00102 tmp.t()=(t0.t()+t1.t())/2.0;
00103 return tmp;
00104 }
00105 };
00106
00107
00108 template<class MESH_TYPE>
00109 struct EvenPointLoop : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00110 {
00111
00112 void operator()(typename MESH_TYPE::CoordType &nP, face::Pos<typename MESH_TYPE::FaceType> ep) {
00113
00114 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
00115 typename MESH_TYPE::CoordType *r, *l, *curr;
00116 curr = &he.v->P();
00117
00118 if (he.IsBorder()) {
00119 he.FlipV();
00120 r = &he.v->P();
00121 he.FlipV();
00122 assert(&he.v->P()== curr);
00123 he.NextB();
00124 if (&he.v->P() == curr)
00125 he.FlipV();
00126 l = &he.v->P();
00127 nP = ( *(curr) * (3.0)/(4.0) + (*l)*(1.0/8.0) + (*r)*(1.0/8.0));
00128 }
00129 else {
00130
00131 int k = 0;
00132 face::Pos<typename MESH_TYPE::FaceType> heStart = he;
00133 std::vector<typename MESH_TYPE::CoordType> otherVertVec;
00134 if(he.v->IsB())return ;
00135 do {
00136 he.FlipV();
00137 otherVertVec.push_back(he.v->P());
00138 he.FlipV();
00139 he.FlipE(); he.FlipF();
00140 k++;
00141 } while(he.f!=heStart.f || he.z!=heStart.z || he.v!=heStart.v);
00142
00143
00144 float beta = 3.0 / 16.0;
00145 if(k > 3 )
00146 beta = (1.0/(float)k) * (5.0/8.0 - pow((3.0/8.0 + 0.25 * cos(2*M_PI/k)),2));
00147
00148 *curr = *curr * (1 - k * beta) ;
00149 typename std::vector<typename MESH_TYPE::CoordType>::iterator iter;
00150 for (iter = otherVertVec.begin();
00151 iter != otherVertVec.end();
00152 ++iter) {
00153 *curr = *curr + (*iter) * beta;
00154
00155 }
00156 nP = *curr;
00157 }
00158 }
00159
00160 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00161 {
00162 Color4<typename MESH_TYPE::ScalarType> cc;
00163 return cc.lerp(c0,c1,0.5f);
00164 }
00165 Color4b WedgeInterp(Color4b &c0, Color4b &c1)
00166 {
00167 Color4b cc;
00168 cc.lerp(c0,c1,0.5f);
00169 return cc;
00170 }
00171
00172 template<class FL_TYPE>
00173 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00174 {
00175 TexCoord2<FL_TYPE,1> tmp;
00176
00177 tmp.n()=t0.n();
00178 tmp.t()=(t0.t()+t1.t())/2.0;
00179 return tmp;
00180 }
00181
00182 };
00183
00184 template<class CoordType> struct EvenParam {
00185 CoordType sum;
00186 bool border;
00187 int k;
00188 } ;
00189
00190
00191 template<class MESH_TYPE,class ODD_VERT, class EVEN_VERT>
00192 bool RefineOddEven(MESH_TYPE &m, ODD_VERT odd, EVEN_VERT even,float length,
00193 bool RefineSelected=false, CallBackPos *cbOdd = 0, CallBackPos *cbEven = 0)
00194 {
00195 EdgeLen <MESH_TYPE, typename MESH_TYPE::ScalarType> ep(length);
00196 return RefineOddEvenE(m, odd, even, ep, RefineSelected, cbOdd, cbEven);
00197 }
00198
00199 template<class MESH_TYPE, class ODD_VERT, class EVEN_VERT, class PREDICATE>
00200 bool RefineOddEvenE(MESH_TYPE &m, ODD_VERT odd, EVEN_VERT even, PREDICATE edgePred,
00201 bool RefineSelected=false, CallBackPos *cbOdd = 0, CallBackPos *cbEven = 0)
00202 {
00203
00204
00205 int n = m.vn;
00206
00207
00208 RefineE< MESH_TYPE,OddPointLoop<MESH_TYPE> > (m, odd, edgePred, RefineSelected, cbOdd);
00209
00210 cbEven = cbOdd;
00211
00212 vcg::tri::UpdateFlags<MESH_TYPE>::FaceBorderFromFF(m);
00213
00214 vcg::tri::UpdateFlags<MESH_TYPE>::VertexBorderFromFace (m);
00215
00216
00217
00218 int evenFlag = MESH_TYPE::VertexType::NewBitFlag();
00219 for (int i = 0; i < n ; i++ ) {
00220 m.vert[i].SetUserBit(evenFlag);
00221 }
00222
00223
00224 int j = 0;
00225
00226
00227 typename MESH_TYPE::VertexIterator vi;
00228 typename MESH_TYPE::FaceIterator fi;
00229 for (fi = m.face.begin(); fi != m.face.end(); fi++) if(!(*fi).IsD()){
00230 for (int i = 0; i < 3; i++) {
00231 if ( (*fi).V(i)->IsUserBit(evenFlag) && ! (*fi).V(i)->IsD() ) {
00232 if (RefineSelected && !(*fi).V(i)->IsS() )
00233 break;
00234 face::Pos<typename MESH_TYPE::FaceType>aux (&(*fi),i);
00235 if( MESH_TYPE::HasPerVertexColor() ) {
00236 (*fi).V(i)->C().lerp((*fi).V0(i)->C() , (*fi).V1(i)->C(),0.5f);
00237 }
00238
00239 if (cbEven) {
00240 (*cbEven)(int(100.0f * (float)j / (float)m.fn),"Refining");
00241 j++;
00242 }
00243 even((*fi).V(i)->P(), aux);
00244 }
00245 }
00246 }
00247
00248 return true;
00249 }
00250
00251
00252
00253 }
00254 }
00255
00256
00257
00258
00259 #endif
00260
00261
00262