![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsFEMTetrahedron.cpp 00003 ******************************************************************************/ 00007 /****************************************************************************** 00008 SUKITTI PUNAK (12/15/2009) 00009 UPDATE (05/01/2010) 00010 ******************************************************************************/ 00011 #include "TAPsFEMTetrahedron.hpp" 00012 // Using Inclusion Model (i.e. definitions are included in declarations) 00013 // (this name.cpp is included in name.hpp) 00014 // Each friend is defined directly inside its declaration. 00015 00016 BEGIN_NAMESPACE_TAPs__FEM 00017 //============================================================================= 00018 // Constructors 00019 //----------------------------------------------------------------------------- 00020 template <typename T> 00021 Tetrahedron<T>::Tetrahedron ( 00022 std::vector< Vector3<T> > * deformedNodes, 00023 std::vector< Vector3<T> > * undeformedNodes, 00024 T YoungModulus, 00025 T PoissionRatio, 00026 unsigned int globalNode0, 00027 unsigned int globalNode1, 00028 unsigned int globalNode2, 00029 unsigned int globalNode3 00030 ) : Element( deformedNodes, undeformedNodes, YoungModulus, PoissionRatio ) 00031 { 00032 ids[0] = globalNode0; 00033 ids[1] = globalNode1; 00034 ids[2] = globalNode2; 00035 ids[3] = globalNode3; 00036 CalUndeformedVolume(); // the result volume is stored in Volume (the property (undeformed) for volume) 00037 UpdateElasticMatrixElements(); // update the elastic matrix due to Young's modulus, Poisson's ratio, and (undeformed) volume 00038 UpdateStrainDisplacementMatrixElements(); // update the elements of the strain-displacement matrix 00039 UpdateStiffnessMatrixElements(); // update all 16 sub stiffness matrices of this element 00040 } 00041 //----------------------------------------------------------------------------- 00042 //template <typename T> 00043 //Tetrahedron<T>::Tetrahedron ( Tetrahedron<T> const &orig ) 00044 //{} 00045 //----------------------------------------------------------------------------- 00046 template <typename T> 00047 Tetrahedron<T>::~Tetrahedron () 00048 {} 00049 //----------------------------------------------------------------------------- 00050 template <typename T> 00051 std::string Tetrahedron<T>::StrInfo () const 00052 { 00053 std::stringstream ss; 00054 ss << "FEM::Tetrahedron<" << typeid(T).name() << ">:\n" 00055 << "\tDeformed - Undeformed Node 0: " << (*pX)[ids[0]] << " - " << (*pU)[ids[0]] << "\n" 00056 << "\tDeformed - Undeformed Node 1: " << (*pX)[ids[1]] << " - " << (*pU)[ids[1]] << "\n" 00057 << "\tDeformed - Undeformed Node 2: " << (*pX)[ids[2]] << " - " << (*pU)[ids[2]] << "\n" 00058 << "\tDeformed - Undeformed Node 3: " << (*pX)[ids[3]] << " - " << (*pU)[ids[3]] << "\n" 00059 << "\tDeformed - Undeformed Volume: " << CalDeformedVolume() << " - " << Volume << "\n"; 00060 return ss.str(); 00061 } 00062 //----------------------------------------------------------------------------- 00063 //============================================================================= 00064 // Assignment Operator 00065 //----------------------------------------------------------------------------- 00066 //template <typename T> 00067 //Tetrahedron<T> & Tetrahedron<T>::operator= ( Tetrahedron<T> const &orig ) 00068 //{} 00069 //----------------------------------------------------------------------------- 00070 //============================================================================= 00071 // Get/Set Functions 00072 //----------------------------------------------------------------------------- 00073 template <typename T> 00074 Matrix3x3<T> const & Tetrahedron<T>::GetStiffnessMatrix ( unsigned int n, unsigned int m ) const 00075 { 00076 assert( 0 <= n && n <= 3 ); 00077 assert( 0 <= m && m <= 3 ); 00078 return Ke[n][m]; 00079 } 00080 //----------------------------------------------------------------------------- 00081 //============================================================================= 00082 // Operations 00083 //----------------------------------------------------------------------------- 00084 template <typename T> 00085 void Tetrahedron<T>::SetNode ( unsigned int i, unsigned int globalNodeNumber ) 00086 { 00087 assert( 0 <= i && i <= 3 ); 00088 ids[i] = globalNodeNumber; 00089 } 00090 //----------------------------------------------------------------------------- 00091 //template <typename T> 00092 //void Tetrahedron<T>::ResetToDeformedState () 00093 //{ 00094 //} 00095 //----------------------------------------------------------------------------- 00096 template <typename T> 00097 void Tetrahedron<T>::ResetToUndeformedState () 00098 { 00099 (*pU)[ids[0]] = (*pX)[ids[0]]; 00100 (*pU)[ids[1]] = (*pX)[ids[1]]; 00101 (*pU)[ids[2]] = (*pX)[ids[2]]; 00102 (*pU)[ids[3]] = (*pX)[ids[3]]; 00103 } 00104 //----------------------------------------------------------------------------- 00105 template <typename T> 00106 Vector3<T> * const Tetrahedron<T>::DeformedNode ( unsigned int i ) 00107 { 00108 assert( 0 <= i && i <= 3 ); 00109 return &(*pU)[ids[i]]; 00110 } 00111 //----------------------------------------------------------------------------- 00112 template <typename T> 00113 Vector3<T> * const Tetrahedron<T>::UndeformedNode ( unsigned int i ) 00114 { 00115 assert( 0 <= i && i <= 3 ); 00116 return &(*pX)[ids[i]]; 00117 } 00118 //----------------------------------------------------------------------------- 00119 template <typename T> 00120 Vector3<T> Tetrahedron<T>::ComputeDeformedPositionBasedOnCoordinates ( T coord0, T coord1, T coord2, T coord3 ) 00121 { 00122 Vector3<T> & T0 = (*pX)[ids[0]]; 00123 Vector3<T> T10 = (*pX)[ids[1]] - T0; 00124 Vector3<T> T20 = (*pX)[ids[2]] - T0; 00125 Vector3<T> T30 = (*pX)[ids[3]] - T0; 00126 00127 T x = T10[0]*coord1 + T20[0]*coord2 + T30[0]*coord3 + T0[0]; 00128 T y = T10[1]*coord1 + T20[1]*coord2 + T30[1]*coord3 + T0[1]; 00129 T z = T10[2]*coord1 + T20[2]*coord2 + T30[2]*coord3 + T0[2]; 00130 00131 return Vector3<T>( x, y, z ); 00132 } 00133 //----------------------------------------------------------------------------- 00134 template <typename T> 00135 Vector3<T> Tetrahedron<T>::ComputeUndeformedPositionBasedOnCoordinates ( T coord0, T coord1, T coord2, T coord3 ) 00136 { 00137 Vector3<T> & T0 = (*pU)[ids[0]]; 00138 Vector3<T> T10 = (*pU)[ids[1]] - T0; 00139 Vector3<T> T20 = (*pU)[ids[2]] - T0; 00140 Vector3<T> T30 = (*pU)[ids[3]] - T0; 00141 00142 T x = T10[0]*coord1 + T20[0]*coord2 + T30[0]*coord3 + T0[0]; 00143 T y = T10[1]*coord1 + T20[1]*coord2 + T30[1]*coord3 + T0[1]; 00144 T z = T10[2]*coord1 + T20[2]*coord2 + T30[2]*coord3 + T0[2]; 00145 00146 return Vector3<T>( x, y, z ); 00147 } 00148 //----------------------------------------------------------------------------- 00149 template <typename T> 00150 T Tetrahedron<T>::CalDeformedVolume () const 00151 { 00152 return ((((*pU)[ids[1]]-(*pU)[ids[0]]) ^ ((*pU)[ids[2]]-(*pU)[ids[0]])) * ((*pU)[ids[3]]-(*pU)[ids[0]])) / T(6); 00153 } 00154 //----------------------------------------------------------------------------- 00155 template <typename T> 00156 T Tetrahedron<T>::CalUndeformedVolume () 00157 { 00158 Volume = ((((*pX)[ids[1]]-(*pX)[ids[0]]) ^ ((*pX)[ids[2]]-(*pX)[ids[0]])) * ((*pX)[ids[3]]-(*pX)[ids[0]])) / T(6); 00159 return Volume; 00160 } 00161 //----------------------------------------------------------------------------- 00162 template <typename T> 00163 void Tetrahedron<T>::UpdateStrainDisplacementMatrixElements () 00164 { 00165 // B = [ B0 B1 B2 B3 ] 00166 // where Bn (n = 0,1,2,3) are 00167 // | bn 0 0 | 00168 // | 0 cn 0 | 00169 // Bn = | 0 0 dn | 00170 // | cn bn 0 | 00171 // | 0 dn cn | 00172 // | dn 0 bn | 00173 // 00174 // bn, cn, and dn are 00175 // | a0 b0 c0 d0 | | 1 1 1 1 | 00176 // | a1 b1 c1 d1 | = the inverse of | x0 x1 x2 x3 | 00177 // | a2 b2 c2 d2 | | y1 y2 y3 y4 | 00178 // | a3 b3 c3 d3 | | z1 z2 z3 z4 | 00179 // 00180 00181 // bn, cn, and dn, where n = 1,2,3, can be computed more efficiently as 00182 // | b1 c1 d1 | | x1-x0 x2-x0 x3-x0 | 00183 // | b2 c2 d2 | = the inverse of | y1-y0 y2-y0 y3-y0 | 00184 // | b3 c3 d3 | | z1-z0 z2-z0 z3-z0 | 00185 // 00186 T e[9] = { 00187 ((*pX)[ids[1]])[0]-((*pX)[ids[0]])[0], ((*pX)[ids[2]])[0]-((*pX)[ids[0]])[0], ((*pX)[ids[3]])[0]-((*pX)[ids[0]])[0], 00188 ((*pX)[ids[1]])[1]-((*pX)[ids[0]])[1], ((*pX)[ids[2]])[1]-((*pX)[ids[0]])[1], ((*pX)[ids[3]])[1]-((*pX)[ids[0]])[1], 00189 ((*pX)[ids[1]])[2]-((*pX)[ids[0]])[2], ((*pX)[ids[2]])[2]-((*pX)[ids[0]])[2], ((*pX)[ids[3]])[2]-((*pX)[ids[0]])[2] 00190 }; 00191 b[1] = e[4]*e[8] - e[5]*e[7]; 00192 c[1] = e[2]*e[7] - e[1]*e[8]; 00193 d[1] = e[1]*e[5] - e[2]*e[4]; 00194 T detInv = T(1) / (e[0]*b[1] + e[3]*c[1] + e[6]*d[1]); 00195 b[1] *= detInv; 00196 c[1] *= detInv; 00197 d[1] *= detInv; 00198 b[2] = -( e[3]*e[8] - e[6]*e[5] ) * detInv; 00199 c[2] = ( e[0]*e[8] - e[6]*e[2] ) * detInv; 00200 d[2] = -( e[0]*e[5] - e[3]*e[2] ) * detInv; 00201 b[3] = ( e[3]*e[7] - e[6]*e[4] ) * detInv; 00202 c[3] = -( e[0]*e[7] - e[6]*e[1] ) * detInv; 00203 d[3] = ( e[0]*e[4] - e[3]*e[1] ) * detInv; 00204 00205 // Compute b0, c0, and d0 from 00206 // b0 = -b1-b2-b3 00207 // c0 = -c1-c2-c3 00208 // d0 = -d1-d2-d3 00209 b[0] = -(b[1]+b[2]+b[3]); 00210 c[0] = -(c[1]+c[2]+c[3]); 00211 d[0] = -(d[1]+d[2]+d[3]); 00212 00213 /* 00214 // DEBUG 00215 std::cout << "B:\n" 00216 << "\t" << b[0] << "\t" << c[0] << "\t" << d[0] << "\n" 00217 << "\t" << b[1] << "\t" << c[1] << "\t" << d[1] << "\n" 00218 << "\t" << b[2] << "\t" << c[2] << "\t" << d[2] << "\n" 00219 << "\t" << b[3] << "\t" << c[3] << "\t" << d[3] << "\n"; 00220 00221 //* 00222 Matrix3x3<T> test1( e ); 00223 00224 Matrix4x4<T> test2( 00225 1, 1, 1, 1, 00226 ((*pX)[ids[0]])[0], ((*pX)[ids[1]])[0], ((*pX)[ids[2]])[0], ((*pX)[ids[3]])[0], 00227 ((*pX)[ids[0]])[1], ((*pX)[ids[1]])[1], ((*pX)[ids[2]])[1], ((*pX)[ids[3]])[1], 00228 ((*pX)[ids[0]])[2], ((*pX)[ids[1]])[2], ((*pX)[ids[2]])[2], ((*pX)[ids[3]])[2] 00229 ); 00230 00231 std::cout << test2.Inversed() << "\n"; 00232 std::cout << test1.Inversed() << "\n"; 00233 00234 std::cout << "b[0] checked: " << test2[ 1] - b[0] << "\n"; 00235 std::cout << "c[0] checked: " << test2[ 2] - c[0] << "\n"; 00236 std::cout << "d[0] checked: " << test2[ 3] - d[0] << "\n"; 00237 std::cout << "b[1] checked: " << test2[ 5] - b[1] << "\n"; 00238 std::cout << "c[1] checked: " << test2[ 6] - c[1] << "\n"; 00239 std::cout << "d[1] checked: " << test2[ 7] - d[1] << "\n"; 00240 std::cout << "b[2] checked: " << test2[ 9] - b[2] << "\n"; 00241 std::cout << "c[2] checked: " << test2[10] - c[2] << "\n"; 00242 std::cout << "d[2] checked: " << test2[11] - d[2] << "\n"; 00243 std::cout << "b[3] checked: " << test2[13] - b[3] << "\n"; 00244 std::cout << "c[3] checked: " << test2[14] - c[3] << "\n"; 00245 std::cout << "d[3] checked: " << test2[15] - d[3] << "\n"; 00246 00247 //std::cout << "\n4x4 - 3x3 RESULTS:\n"; 00248 //std::cout << "b[1] checked: " << test2[ 5] - test1[0] << "\n"; 00249 //std::cout << "c[1] checked: " << test2[ 6] - test1[1] << "\n"; 00250 //std::cout << "d[1] checked: " << test2[ 7] - test1[2] << "\n"; 00251 //std::cout << "b[2] checked: " << test2[ 9] - test1[3] << "\n"; 00252 //std::cout << "c[2] checked: " << test2[10] - test1[4] << "\n"; 00253 //std::cout << "d[2] checked: " << test2[11] - test1[5] << "\n"; 00254 //std::cout << "b[3] checked: " << test2[13] - test1[6] << "\n"; 00255 //std::cout << "c[3] checked: " << test2[14] - test1[7] << "\n"; 00256 //std::cout << "d[3] checked: " << test2[15] - test1[8] << "\n"; 00257 00258 std::cout << "b[0] + b[1] + b[2] + b[3] = 0 = " << b[0]+b[1]+b[2]+b[3] << "\n"; 00259 std::cout << "c[0] + c[1] + c[2] + c[3] = 0 = " << c[0]+c[1]+c[2]+c[3] << "\n"; 00260 std::cout << "d[0] + d[1] + d[2] + d[3] = 0 = " << d[0]+d[1]+d[2]+d[3] << "\n"; 00261 std::cout << "-----------------------------------------\n\n"; 00262 //*/ 00263 } 00264 //----------------------------------------------------------------------------- 00265 template <typename T> 00266 void Tetrahedron<T>::UpdateStiffnessMatrixElements () 00267 { 00268 // K^e_{nm} = 00269 // | bn 0 0 | | e f f | | bm 0 0 | | cn 0 dn | | g 0 0 | | cm bm 0 | 00270 // | 0 cn 0 |*| f e f |*| 0 cm 0 | + | bn dn 0 |*| 0 g 0 |*| 0 dm cm | 00271 // | 0 0 dn | | f f e | | 0 0 dm | | 0 cn bn | | 0 0 g | | dm 0 bm | 00272 // = 00273 // | bn*e*bm + cn*g*cm + dn*g*dm bn*f*cm + cn*g*bm bn*f*dm + dn*g*bm | 00274 // | cn*f*bm + bn*g*cm cn*e*cm + bn*g*bm + dn*g*dm cn*f*dm + dn*g*cm | 00275 // | dn*f*bm + bn*g*dm dn*f*cm + cn*g*dm dn*e*dm + cn*g*cm + bn*g*bm | 00276 00277 T be[4] = { b[0]*Ee, b[1]*Ee, b[2]*Ee, b[3]*Ee }; 00278 T bf[4] = { b[0]*Ef, b[1]*Ef, b[2]*Ef, b[3]*Ef }; 00279 T bg[4] = { b[0]*Eg, b[1]*Eg, b[2]*Eg, b[3]*Eg }; 00280 00281 T ce[4] = { c[0]*Ee, c[1]*Ee, c[2]*Ee, c[3]*Ee }; 00282 T cf[4] = { c[0]*Ef, c[1]*Ef, c[2]*Ef, c[3]*Ef }; 00283 T cg[4] = { c[0]*Eg, c[1]*Eg, c[2]*Eg, c[3]*Eg }; 00284 00285 T de[4] = { d[0]*Ee, d[1]*Ee, d[2]*Ee, d[3]*Ee }; 00286 T df[4] = { d[0]*Ef, d[1]*Ef, d[2]*Ef, d[3]*Ef }; 00287 T dg[4] = { d[0]*Eg, d[1]*Eg, d[2]*Eg, d[3]*Eg }; 00288 00289 for ( int n = 0; n < 4; ++n ) { 00290 for ( int m = 0; m < 4; ++m ) { 00291 if ( n <= m ) { 00292 // 1st row 00293 Ke[n][m](0,0) = be[n]*b[m] + cg[n]*c[m] + dg[n]*d[m]; 00294 Ke[n][m](0,1) = bf[n]*c[m] + cg[n]*b[m]; 00295 Ke[n][m](0,2) = bf[n]*d[m] + dg[n]*b[m]; 00296 // 2nd row 00297 Ke[n][m](1,0) = cf[n]*b[m] + bg[n]*c[m]; 00298 Ke[n][m](1,1) = ce[n]*c[m] + bg[n]*b[m] + dg[n]*d[m]; 00299 Ke[n][m](1,2) = cf[n]*d[m] + dg[n]*c[m]; 00300 // 3rd row 00301 Ke[n][m](2,0) = df[n]*b[m] + bg[n]*d[m]; 00302 Ke[n][m](2,1) = df[n]*c[m] + cg[n]*d[m]; 00303 Ke[n][m](2,2) = de[n]*d[m] + cg[n]*c[m] + bg[n]*b[m]; 00304 } 00305 // due to the symmetry of the linear tetrahedron's stiffness sub-matrices 00306 else { 00307 Ke[n][m] = Ke[m][n].GetTranspose(); 00308 } 00309 } 00310 } 00311 } 00312 //----------------------------------------------------------------------------- 00313 //============================================================================= 00314 00315 00316 00317 00318 //============================================================================= 00319 // OpenGL 00320 #if defined(__gl_h_) || defined(__GL_H__) 00321 //----------------------------------------------------------------------------- 00323 template <typename T> 00324 void Tetrahedron<T>::Draw () 00325 { 00326 glPushAttrib( GL_LINE_BIT ); 00327 00328 // Draw the undeformed element 00329 glLineWidth( 1 ); 00330 glBegin( GL_LINE_LOOP ); 00331 glColor3f( 1.0f, 0.0f, 0.0f ); 00332 glVertex3fv( (*pX)[ids[0]].GetDataFloat() ); 00333 glVertex3fv( (*pX)[ids[1]].GetDataFloat() ); 00334 glVertex3fv( (*pX)[ids[3]].GetDataFloat() ); 00335 glEnd(); 00336 glBegin( GL_LINE_STRIP ); 00337 glColor3f( 0.0f, 1.0f, 0.0f ); 00338 glVertex3fv( (*pX)[ids[1]].GetDataFloat() ); 00339 glVertex3fv( (*pX)[ids[2]].GetDataFloat() ); 00340 glVertex3fv( (*pX)[ids[3]].GetDataFloat() ); 00341 glEnd(); 00342 glBegin( GL_LINES ); 00343 glColor3f( 0.0f, 0.0f, 1.0f ); 00344 glVertex3fv( (*pX)[ids[2]].GetDataFloat() ); 00345 glVertex3fv( (*pX)[ids[0]].GetDataFloat() ); 00346 //glVertex3fv( (*pX)[ids[3]].GetDataFloat() ); 00347 glEnd(); 00348 00349 // Draw the deformed element 00350 glLineWidth( 3 ); 00351 glBegin( GL_LINE_LOOP ); 00352 glColor3f( 1.0f, 0.0f, 0.0f ); 00353 glVertex3fv( (*pU)[ids[0]].GetDataFloat() ); 00354 glVertex3fv( (*pU)[ids[1]].GetDataFloat() ); 00355 glVertex3fv( (*pU)[ids[3]].GetDataFloat() ); 00356 glEnd(); 00357 glBegin( GL_LINE_STRIP ); 00358 glColor3f( 0.0f, 1.0f, 0.0f ); 00359 glVertex3fv( (*pU)[ids[1]].GetDataFloat() ); 00360 glVertex3fv( (*pU)[ids[2]].GetDataFloat() ); 00361 glVertex3fv( (*pU)[ids[3]].GetDataFloat() ); 00362 glEnd(); 00363 glBegin( GL_LINES ); 00364 glColor3f( 0.0f, 0.0f, 1.0f ); 00365 glVertex3fv( (*pU)[ids[2]].GetDataFloat() ); 00366 glVertex3fv( (*pU)[ids[0]].GetDataFloat() ); 00367 //glVertex3fv( (*pU)[ids[3]].GetDataFloat() ); 00368 glEnd(); 00369 00370 glPopAttrib(); 00371 } 00372 00373 00374 //------------------------------------------------------------------- 00375 template <typename T> 00376 void Tetrahedron<T>::DrawUndeformedMesh () 00377 { 00378 glPushAttrib( GL_LINE_BIT ); 00379 // Draw the undeformed element 00380 glLineWidth( 1 ); 00381 glBegin( GL_LINE_LOOP ); 00382 glColor3f( 1.0f, 0.0f, 0.0f ); 00383 glVertex3fv( (*pX)[ids[0]].GetDataFloat() ); 00384 glVertex3fv( (*pX)[ids[1]].GetDataFloat() ); 00385 glVertex3fv( (*pX)[ids[3]].GetDataFloat() ); 00386 glEnd(); 00387 glBegin( GL_LINE_STRIP ); 00388 glColor3f( 0.0f, 1.0f, 0.0f ); 00389 glVertex3fv( (*pX)[ids[1]].GetDataFloat() ); 00390 glVertex3fv( (*pX)[ids[2]].GetDataFloat() ); 00391 glVertex3fv( (*pX)[ids[3]].GetDataFloat() ); 00392 glEnd(); 00393 glBegin( GL_LINES ); 00394 glColor3f( 0.0f, 0.0f, 1.0f ); 00395 glVertex3fv( (*pX)[ids[2]].GetDataFloat() ); 00396 glVertex3fv( (*pX)[ids[0]].GetDataFloat() ); 00397 //glVertex3fv( (*pX)[ids[3]].GetDataFloat() ); 00398 glEnd(); 00399 glPopAttrib(); 00400 } 00401 00402 00403 //------------------------------------------------------------------- 00405 template <typename T> 00406 void Tetrahedron<T>::DrawDeformedMesh () 00407 { 00408 glPushAttrib( GL_LINE_BIT ); 00409 // Draw the deformed element 00410 glLineWidth( 1 ); 00411 glBegin( GL_LINE_LOOP ); 00412 glColor3f( 1.0f, 0.0f, 0.0f ); 00413 glVertex3fv( (*pU)[ids[0]].GetDataFloat() ); 00414 glVertex3fv( (*pU)[ids[1]].GetDataFloat() ); 00415 glVertex3fv( (*pU)[ids[3]].GetDataFloat() ); 00416 glEnd(); 00417 glBegin( GL_LINE_STRIP ); 00418 glColor3f( 0.0f, 1.0f, 0.0f ); 00419 glVertex3fv( (*pU)[ids[1]].GetDataFloat() ); 00420 glVertex3fv( (*pU)[ids[2]].GetDataFloat() ); 00421 glVertex3fv( (*pU)[ids[3]].GetDataFloat() ); 00422 glEnd(); 00423 glBegin( GL_LINES ); 00424 glColor3f( 0.0f, 0.0f, 1.0f ); 00425 glVertex3fv( (*pU)[ids[2]].GetDataFloat() ); 00426 glVertex3fv( (*pU)[ids[0]].GetDataFloat() ); 00427 //glVertex3fv( (*pU)[ids[3]].GetDataFloat() ); 00428 glEnd(); 00429 glPopAttrib(); 00430 } 00431 00432 00433 //----------------------------------------------------------------------------- 00434 #endif // OpenGL 00435 //============================================================================= 00436 //----------------------------------------------------------------------------- 00437 //============================================================================= 00438 END_NAMESPACE_TAPs__FEM 00439 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00440 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----