Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

TensorManifold.H

Go to the documentation of this file.
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();                                    // Hot key 'm' controls whether draw contol mesh or draw approximated manifold.
00046       void DrawBrief() const;                               // Draw original ctl_mesh when mouse transformation the model.
00047       void Draw() const;                                    // Either draw subidvided ctl mesh or its approximation to manifold(points not on it not drawn.)
00048       void draw(mesh_t& mesh) const;                        // call this directly to draw iso manifolds.
00049 
00050       mesh_t ctl_msh;        // defining dat: control mesh.
00051       int deg[dims];         // defining dat: degrees.
00052       bool rational;         // defining dat: polynomial or rational type.
00053 
00054       mesh_t sbd_msh;        // subdivision data: subdivided mesh.
00055       Nmesh_t Nmsh;          // subdivision data: normal mesh is defined for a n-manifold embedding in (n+1)-space. Currently only implemented for n=2.
00056       mesh_t Dmsh[dims];     // subdivision data: partial derivative along each domain component.
00057       bool sbd_initialized;  // are sbd data (including in inherited) initialized? reset by clean_sbd(), and set appropriately by Derived class.
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;  // with normals.
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         //      drawNormalSurface(); return;
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         //      wglDrawArrowAt(*Nitr, *itr);
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         //      default: break;
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) )    //slice i cut across direction 2.
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))    //slice i cut across direction 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))    //slice i cut across direction 0.
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;     // row_dir is direction 1, other_direction is direction 2.
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;     // row_dir is direction 1, other_direction is direction 2.
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 }//end namespace xchen
00337 
00338 
00339 #endif

Generated on Wed Apr 7 21:40:49 2004 by doxygen1.2.18