00001
00015 #ifndef _TENSORMANIFOLD_H
00016 #define _TENSORMANIFOLD_H
00017
00018 #include <TensorArray.H>
00019 #include <Model.H>
00020 #include <tensormanifold_type_def.H>
00021 #include <KnotVector.H>
00022
00023 namespace xchen
00024 {
00026 template<int dims = 2, int sp_dims = 3>
00027 class TensorManifold : public Model
00028 {
00029 friend class glModel;
00030 def_type_name_for_tensor_manifold(dims, sp_dims);
00031 public:
00032 TensorManifold() : rational(false), sbd_initialized(false) { }
00033 TensorManifold(mesh_t const& m) : ctl_msh(m), rational(false), sbd_initialized(false) { }
00034
00035 TensorManifold(TensorManifold const& rhs, Transform const&);
00036
00037 mesh_t& ControlMesh() { return ctl_msh; }
00038 bool& IsRational() { return rational; }
00039
00040 virtual void Subdivide(int depth=1)const = 0;
00041
00042 friend ostream& operator<< <>(ostream& os, TensorManifold const& m);
00043
00044 protected:
00045 void GenerateUI();
00046 void DrawBrief() const;
00047 void Draw() const;
00048 void draw(mesh_t& mesh) const;
00049
00050 mesh_t ctl_msh;
00051 int deg[dims];
00052 bool rational;
00053
00054 mesh_t sbd_msh;
00055 Nmesh_t Nmsh;
00056 mesh_t Dmsh[dims];
00057 bool sbd_initialized;
00058
00059
00060
00061 enum { bzr_surface, bsp_surface, sbd_surface } srf_type;
00062 void set2bzr_srf_type() { srf_type = bzr_surface; }
00063 void set2bsp_srf_type() { srf_type = bsp_surface; }
00064 void set2sbd_srf_type() { srf_type = sbd_surface; }
00065
00066 void init_sbd() { sbd_msh = ctl_msh; }
00067 void clean_sbd() { sbd_msh.Clear(); Nmsh.Clear(); ForEachIofDims Dmsh[i].Clear(); sbd_initialized = false; }
00068
00069 private:
00070 bool force_draw_vertext_stride_to_1;
00071 void draw_grid2D(int row_dir, int other_dir, row_iterator itr1) const;
00072 void draw_grid2D(int row_dir, int other_dir, row_iterator v_itr1, row_Niterator n_itr1) const;
00073 void draw_grid3D(mesh_t&) const;
00074 void drawNormalInPlace() const;
00075 void drawNormalSurface() const;
00076 };
00077
00078 template<int dims, int sp_dims>
00079 inline TensorManifold<dims, sp_dims> ::
00080 TensorManifold(TensorManifold<dims,sp_dims>const& rhs, Transform const& trans) : ctl_msh(trans * rhs.ctl_msh), rational(rhs.rational), sbd_initialized(false)
00081 {
00082 copy(&(rhs.deg[0]), &(rhs.deg[0]) + dims, deg);
00083 }
00084
00085
00086 template<int dims, int sp_dims>
00087 inline void TensorManifold<dims, sp_dims> :: GenerateUI()
00088 {
00089 Model::GenerateUI();
00090 ui->AddboolControl("Draw Polygon Model", 'p', true);
00091 ui->AddboolControl("Draw Original Control Mesh", 'm');
00092 ui->AddboolControl("Draw Normal In Place", 'N');
00093 ui->AddboolControl("Draw Normal Surface", 'n');
00094 ui->AddboolControl("Subdivide", 's');
00095 }
00096 template<int dims, int sp_dims>
00097 inline void TensorManifold<dims, sp_dims> :: DrawBrief() const
00098 {
00099 (bool&)force_draw_vertext_stride_to_1 = true;
00100 {
00101 glPushAttrib(GL_POLYGON_BIT | GL_LIGHTING_BIT);
00102 glDisable(GL_LIGHTING);
00103 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00104 glColor3f(1.0,1.0,1.0);
00105
00106 draw( (mesh_t&)ctl_msh );
00107
00108 glPopAttrib();
00109 }
00110 (bool&)force_draw_vertext_stride_to_1 = false;
00111 }
00112
00113 template<int dims, int sp_dims>
00114 inline void TensorManifold<dims, sp_dims> :: Draw() const
00115 {
00116 if(ui->GetboolControl("Subdivide"))
00117 {
00118 Subdivide();
00119 ui->SetboolControl("Subdivide", false);
00120 }
00121
00122 if( ui->GetboolControl("Draw Original Control Mesh") ) DrawBrief();
00123
00124 if(ui->GetboolControl("Draw Polygon Model"))
00125 {
00126 if(sbd_msh.Empty())
00127 DrawBrief();
00128 else
00129 {
00130
00131 draw((mesh_t&) sbd_msh );
00132
00133 if(dims==2 && !Nmsh.Empty())
00134 {
00135 if(ui->GetboolControl("Draw Normal In Place"))
00136 drawNormalInPlace();
00137 if(ui->GetboolControl("Draw Normal Surface"))
00138 drawNormalSurface();
00139 }
00140 }
00141 }
00142 }
00143
00144
00145 template<int dims, int sp_dims>
00146 inline void TensorManifold<dims, sp_dims> :: drawNormalInPlace() const
00147 {
00148 row_iterator row_itr = ((mesh_t&)sbd_msh).RowIterate(0);
00149 linear_Niterator Nitr = ((Nmesh_t&)Nmsh).LinearIterate();
00150 for(; !row_itr.PastEnd(); row_itr += deg[1])
00151 {
00152 for(element_iterator itr = row_itr.Begin(); itr < row_itr.End(); itr += deg[0], ++Nitr)
00153 {
00154
00155 }
00156 }
00157 }
00158 template<int dims, int sp_dims>
00159 inline void TensorManifold<dims, sp_dims> :: drawNormalSurface() const
00160 {
00161 glPushAttrib(GL_LIGHTING_BIT | GL_CURRENT_BIT);
00162 glDisable(GL_LIGHTING);
00163 glColor3f(1,0,0);
00164 {
00165 row_Niterator itr1 = ((Nmesh_t&)Nmsh).RowIterate(0);
00166 for(row_Niterator itr2 = itr1+1; !itr2.PastEnd(); ++itr1, ++itr2)
00167 {
00168 element_Niterator itr11 = itr1.Begin();
00169 element_Niterator itr22 = itr2.Begin();
00170 glBegin(GL_QUAD_STRIP);
00171 {
00172 for(; itr11 < itr1.End(); ++itr11, ++itr22)
00173 {
00174 wglVertex(*itr22);
00175 wglVertex(*itr11);
00176 }
00177 }
00178 glEnd();
00179 }
00180 }
00181 glPopAttrib();
00182 }
00183
00184
00185
00186
00187 template<int dims, int sp_dims>
00188 inline void TensorManifold<dims, sp_dims> :: draw(mesh_t& mesh) const
00189 {
00190 {
00191 switch(dims)
00192 {
00193 case 1:
00194 {
00195 glEnableClientState(GL_VERTEX_ARRAY);
00196 {
00197 int stride = 1;
00198 if(!force_draw_vertext_stride_to_1 && (srf_type == bzr_surface || srf_type == bsp_surface) )
00199 stride = deg[0];
00200
00201 glVertexPointer(sp_dims, GL_DOUBLE, sizeof(point_t) * stride, &mesh[0][0]);
00202 glDrawArrays(GL_LINE_STRIP, 0, (mesh.GetSize(0)-1) / stride + 1);
00203 }
00204 glDisableClientState(GL_VERTEX_ARRAY);
00205 break;
00206 }
00207 case 2:
00208 {
00209 if(Nmsh.Empty())
00210 draw_grid2D(0, 1, mesh.RowIterate(0));
00211 else
00212 {
00213 glEnable(GL_NORMALIZE);
00214 draw_grid2D(0, 1, mesh.RowIterate(0), ((Nmesh_t&)Nmsh).RowIterate(0));
00215 glDisable(GL_NORMALIZE);
00216 }
00217 break;
00218 }
00219 case 3:
00220 {
00221 draw_grid3D(mesh); break;
00222 }
00223
00224 }
00225 }
00226 }
00227
00228 template<int dims, int sp_dims>
00229 inline void TensorManifold<dims, sp_dims> :: draw_grid3D(mesh_t& mesh) const
00230 {
00231 int sz, start[dims], end[dims];
00232 mesh.GetSize(end);
00233 bzero(start, sizeof(int) * dims);
00234
00235 bool deg_stride = !force_draw_vertext_stride_to_1 && (srf_type == bzr_surface || srf_type == bsp_surface);
00236
00237 sz = end[2];
00238 for(int i=0; i<sz; i += (deg_stride? deg[2] : 1) )
00239 {
00240 start[2] = i;
00241 end[2] = i+1;
00242 draw_grid2D(0, 1, mesh.RowIterate(0, start, end));
00243 }
00244 start[2] = 0;
00245 end[2] = sz;
00246
00247 sz = end[1];
00248 for(int i=0; i<sz; i += (deg_stride? deg[1] : 1))
00249 {
00250 start[1] = i;
00251 end[1] = i+1;
00252 draw_grid2D(2, 0, mesh.RowIterate(2, start, end));
00253 }
00254 start[1] = 0;
00255 end[1] = sz;
00256
00257 sz = end[0];
00258 for(int i=0; i<sz; i += (deg_stride? deg[0] : 1))
00259 {
00260 start[0] = i;
00261 end[0] = i+1;
00262 draw_grid2D(1, 2, mesh.RowIterate(1, start, end));
00263 }
00264 }
00265
00266
00267 template<int dims, int sp_dims>
00268 inline void TensorManifold<dims, sp_dims> :: draw_grid2D(int row_dir, int other_dir, row_iterator v_itr1, row_Niterator n_itr1) const
00269 {
00270 int step1 = 1, step2 = 1;
00271 if(!force_draw_vertext_stride_to_1 && (srf_type == bzr_surface || srf_type == bsp_surface))
00272 {
00273 step1 = deg[row_dir];
00274 step2 = deg[other_dir];
00275 }
00276
00277 row_Niterator n_itr2 = n_itr1+1;
00278 row_iterator v_itr2 = v_itr1+step2;
00279 for(; !v_itr2.PastEnd(); v_itr1 += step2, v_itr2 += step2, ++n_itr1, ++n_itr2)
00280 {
00281 element_iterator v_itr11 = v_itr1.Begin();
00282 element_iterator v_itr22 = v_itr2.Begin();
00283 element_Niterator n_itr11 = n_itr1.Begin();
00284 element_Niterator n_itr22 = n_itr2.Begin();
00285 glBegin(GL_QUAD_STRIP);
00286 {
00287 for(; v_itr11 < v_itr1.End(); v_itr11 += step1, v_itr22 += step1, ++n_itr11, ++n_itr22)
00288 {
00289 wglNormal(*n_itr22);
00290 wglVertex(*v_itr22);
00291 wglNormal(*n_itr11);
00292 wglVertex(*v_itr11);
00293 }
00294 }
00295 glEnd();
00296 }
00297 }
00298
00299
00300 template<int dims, int sp_dims>
00301 inline void TensorManifold<dims, sp_dims> :: draw_grid2D(int row_dir, int other_dir, row_iterator itr1) const
00302 {
00303 int step1 = 1, step2 = 1;
00304 if(!force_draw_vertext_stride_to_1 && (srf_type == bzr_surface || srf_type == bsp_surface))
00305 {
00306 step1 = deg[row_dir];
00307 step2 = deg[other_dir];
00308 }
00309
00310 for(row_iterator itr2 = itr1+step2; !itr2.PastEnd(); itr1 += step2, itr2 += step2)
00311 {
00312 element_iterator itr11 = itr1.Begin();
00313 element_iterator itr22 = itr2.Begin();
00314 glBegin(GL_QUAD_STRIP);
00315 {
00316 for(; itr11 < itr1.End(); itr11 += step1, itr22 += step1)
00317 {
00318 wglVertex(*itr22);
00319 wglVertex(*itr11);
00320 }
00321 }
00322 glEnd();
00323 }
00324 }
00325
00326
00327 template<int dims, int sp_dims>
00328 ostream& operator<<(ostream& os, TensorManifold<dims, sp_dims> const& m)
00329 {
00330 return os << (m.ctl_msh);
00331 }
00332
00333
00334
00335
00336 }
00337
00338
00339 #endif