cgma
|
00001 // 00002 // File: CubitQuadFacet.cpp 00003 // 00004 // Owner: sjowen 00005 // 00006 #include "CubitDefines.h" 00007 #include "CubitQuadFacet.hpp" 00008 #include "CubitFacetEdge.hpp" 00009 #include "CubitPoint.hpp" 00010 #include "CubitFacet.hpp" 00011 #include "CubitVector.hpp" 00012 #include "FacetEvalTool.hpp" 00013 00014 #define DETERM(p1,q1,p2,q2,p3,q3) ((q3)*((p2)-(p1)) + (q2)*((p1)-(p3)) + (q1)*((p3)-(p2))) 00015 00016 //=========================================================================== 00017 // Function: CubitQuadFacet 00018 // Purpose: constructor 00019 // Date: 4/11/01 00020 // Author: sjowen 00021 //=========================================================================== 00022 CubitQuadFacet::CubitQuadFacet() 00023 { 00024 } 00025 00026 //=========================================================================== 00027 // Function: CubitQuadFacet 00028 // Purpose: destructor 00029 // Date: 4/11/01 00030 // Author: sjowen 00031 //=========================================================================== 00032 CubitQuadFacet::~CubitQuadFacet() 00033 { 00034 } 00035 00036 //=========================================================================== 00037 // Function: evaluate 00038 // Purpose: evaluate the quad at a specified u,v coordinate 00039 // Notes: Uses the interpolation order previously set up for the 00040 // facet-based surface. The u,v system is based on the point 00041 // order and is defined as follows: 00042 // 00043 // [3] = (-1,1) *============* [2] = (1,1) 00044 // | | 00045 // | | 00046 // | | 00047 // | | 00048 // | | 00049 // [0] = (-1,-1) *============* [1] = (1,-1) 00050 // 00051 // Date: 4/11/01 00052 // Author: sjowen 00053 //=========================================================================== 00054 CubitStatus CubitQuadFacet::evaluate( double u, double v, 00055 CubitVector *eval_point, 00056 CubitVector *eval_normal, 00057 CubitVector *eval_du, 00058 CubitVector *eval_dv) 00059 { 00060 CubitVector normal; 00061 CubitStatus stat = CUBIT_SUCCESS; 00062 int tri_index; 00063 double A, B, C; 00064 map_to_tri_system( u, v, tri_index, A, B, C ); 00065 CubitVector ac(A,B,C); 00066 CubitFacet *tri_facet = get_tri_facet( tri_index ); 00067 CubitVector point; 00068 stat = tri_facet->evaluate( ac, &point, eval_normal ); 00069 if (!stat) 00070 return stat; 00071 if (eval_point != NULL) 00072 *eval_point = point; 00073 if (eval_du != NULL || eval_dv != NULL) 00074 { 00075 CubitVector du, dv; 00076 stat = eval_derivatives( u, v, point, du, dv ); 00077 normal = du * dv; 00078 normal.normalize(); 00079 if (eval_du != NULL) 00080 *eval_du = du; 00081 if (eval_dv != NULL) 00082 *eval_dv = dv; 00083 if (eval_normal != NULL) 00084 *eval_normal = normal; 00085 } 00086 return stat; 00087 } 00088 00089 //=========================================================================== 00090 // Function: eval_derivatives 00091 // Purpose: evaluate derivatives on quad with respect to the u,v system 00092 // on the quad 00093 // Date: 5/01 00094 // Author: sjowen 00095 //=========================================================================== 00096 CubitStatus CubitQuadFacet::eval_derivatives( double u, double v, 00097 CubitVector &point, 00098 CubitVector &du, 00099 CubitVector &dv ) 00100 { 00101 // do a forward, backward or central difference depending on where the 00102 // u, v is located on the quad 00103 00104 CubitStatus stat = CUBIT_SUCCESS; 00105 double incr = 0.001; 00106 double min = -1.0; 00107 double max = 1.0; 00108 double uf, vf, ub, vb; 00109 CubitVector pf, pb; 00110 if (u < min + incr) 00111 { 00112 uf = u + incr; 00113 stat = evaluate(uf, v, &pf); 00114 du = ( pf - point ) / incr; 00115 } 00116 else if (u > max - incr) 00117 { 00118 ub = u - incr; 00119 stat = evaluate( ub, v, &pb); 00120 du = ( point - pb ) / incr; 00121 } 00122 else 00123 { 00124 uf = u + incr; 00125 ub = u - incr; 00126 stat = evaluate( uf, v, &pf ); 00127 stat = evaluate( ub, v, &pb ); 00128 du = ( pf - pb ) / (2.0 * incr); 00129 } 00130 if (v < min + incr) 00131 { 00132 vf = v + incr; 00133 stat = evaluate(u, vf, &pf); 00134 dv = ( pf - point ) / incr; 00135 } 00136 else if (v > max - incr) 00137 { 00138 vb = v - incr; 00139 stat = evaluate( u, vb, &pb); 00140 dv = ( point - pb ) / incr; 00141 } 00142 else 00143 { 00144 vf = v + incr; 00145 vb = v - incr; 00146 stat = evaluate( u, vf, &pf ); 00147 stat = evaluate( u, vb, &pb ); 00148 dv = ( pf - pb ) / (2.0 * incr); 00149 } 00150 return stat; 00151 } 00152 00153 //=========================================================================== 00154 // Function: debug_draw 00155 // Purpose: draw the facets 00156 // Date: 4/11/01 00157 // Author: sjowen 00158 //=========================================================================== 00159 void CubitQuadFacet::debug_draw( int color, int flush_it, int draw_uv ) 00160 { 00161 CubitFacet *tri_facet = get_tri_facet( 0 ); 00162 tri_facet->debug_draw(color, flush_it, draw_uv); 00163 tri_facet = get_tri_facet( 1 ); 00164 tri_facet->debug_draw(color, flush_it, draw_uv); 00165 } 00166 00167 //=========================================================================== 00168 // Function: map_to_tri_system 00169 // Purpose: given a u,v coordinate, return the triangle and area coordinate 00170 // Date: 4/11/01 00171 // Author: sjowen 00172 //=========================================================================== 00173 void CubitQuadFacet::map_to_tri_system(double u, double v, 00174 int &tri_index, 00175 double &A, double &B, double &C) 00176 { 00177 double trivert[3][2]; 00178 double areacoords[2][3]; 00179 int ii, jj, j0, j1; 00180 double small_ac[2]; 00181 small_ac[0] = small_ac[1] = 1.0; 00182 00183 // loop through both tris 00184 00185 for (ii=0; ii<2; ii++) 00186 { 00187 00188 // set up the (u,v) vertex coordinates for the tri 00189 00190 for (jj=0; jj<3; jj++) 00191 { 00192 switch(tri_to_quad_index(ii,jj)) 00193 { 00194 case 0: 00195 trivert[jj][0] = -1.0; 00196 trivert[jj][1] = -1.0; 00197 break; 00198 case 1: 00199 trivert[jj][0] = 1.0; 00200 trivert[jj][1] = -1.0; 00201 break; 00202 case 2: 00203 trivert[jj][0] = 1.0; 00204 trivert[jj][1] = 1.0; 00205 break; 00206 case 3: 00207 trivert[jj][0] = -1.0; 00208 trivert[jj][1] = 1.0; 00209 break; 00210 } 00211 } 00212 00213 // compute the area coordinates 00214 00215 for (jj=0; jj<3; jj++) 00216 { 00217 j0 = (jj+1)%3; 00218 j1 = (jj+2)%3; 00219 areacoords[ii][jj] = DETERM( trivert[j0][0], trivert[j0][1], 00220 trivert[j1][0], trivert[j1][1], u, v ); 00221 if (small_ac[ii] > areacoords[ii][jj]) 00222 { 00223 small_ac[ii] = areacoords[ii][jj]; 00224 } 00225 } 00226 } 00227 tri_index = (small_ac[0] > small_ac[1]) ? 0 : 1; 00228 A = areacoords[tri_index][0]; 00229 B = areacoords[tri_index][1]; 00230 C = areacoords[tri_index][2]; 00231 double sum = A + B + C; 00232 A /= sum; 00233 B /= sum; 00234 C /= sum; 00235 } 00236 00237 //=========================================================================== 00238 // Function: get_control_points 00239 // Purpose: retreive the control points from the quad 00240 // Date: 4/11/01 00241 // Author: sjowen 00242 //=========================================================================== 00243 void CubitQuadFacet::get_control_points( double *ctrl_pts ) 00244 { 00245 // assumes 6 control points per triangle and 3 along the diagonal edge 00246 00247 int ii, jj; 00248 int ipt = 0; 00249 int index = 0; 00250 int numtri = 2; 00251 int num_ctrl_pts_per_tri = 6; 00252 for (ii=0; ii<numtri; ii++) 00253 { 00254 CubitFacet *tri_facet = get_tri_facet( ii ); 00255 CubitVector *tri_ctrl_pts = tri_facet->control_points(); 00256 assert(tri_ctrl_pts != NULL); 00257 for (jj=0; jj<num_ctrl_pts_per_tri; jj++) 00258 { 00259 index = ipt * 3; 00260 ctrl_pts[index] = tri_ctrl_pts[jj].x(); 00261 ctrl_pts[index+1] = tri_ctrl_pts[jj].y(); 00262 ctrl_pts[index+2] = tri_ctrl_pts[jj].z(); 00263 ipt++; 00264 } 00265 } 00266 00267 int num_ctrl_pts_per_edge = 3; 00268 CubitVector *edge_ctrl_pts = NULL; 00269 CubitFacetEdge *edge_ptr = this->point(0)->shared_edge( this->point(2) ); 00270 assert(edge_ptr != NULL); 00271 edge_ctrl_pts = edge_ptr->control_points(); 00272 for (ii=0; ii<num_ctrl_pts_per_edge; ii++) 00273 { 00274 index = ipt * 3; 00275 ctrl_pts[index] = edge_ctrl_pts[ii].x(); 00276 ctrl_pts[index+1] = edge_ctrl_pts[ii].y(); 00277 ctrl_pts[index+2] = edge_ctrl_pts[ii].z(); 00278 ipt++; 00279 } 00280 } 00281 00282 //=========================================================================== 00283 // Function: set_control_points 00284 // Purpose: set the control points into the quad 00285 // Date: 4/11/01 00286 // Author: sjowen 00287 //=========================================================================== 00288 void CubitQuadFacet::set_control_points( double *ctrl_pts ) 00289 { 00290 // assumes 6 control points per triangle and 3 along the diagonal edge 00291 00292 int ii; 00293 int index = 0; 00294 int numtri = 2; 00295 int num_ctrl_pts_per_tri = 6; 00296 for (ii=0; ii<numtri; ii++) 00297 { 00298 CubitFacet *tri_facet = get_tri_facet( ii ); 00299 index = 3 * ii * num_ctrl_pts_per_tri; 00300 tri_facet->set_control_points( &(ctrl_pts[index]) ); 00301 } 00302 00303 CubitFacetEdge *edge_ptr = this->point(0)->shared_edge( this->point(2) ); 00304 assert(edge_ptr != NULL); 00305 index = 3 * numtri * num_ctrl_pts_per_tri; 00306 edge_ptr->set_control_points( &(ctrl_pts[index]) ); 00307 } 00308 00309 //=========================================================================== 00310 // Function: points 00311 // Purpose: get the points on the quad. Virtual to FacetEntity 00312 // Date: 8/1/03 00313 // Author: sjowen 00314 //=========================================================================== 00315 void CubitQuadFacet::points(DLIList<CubitPoint*> &point_list ) 00316 { 00317 for ( int i = 0; i < 4; i++ ) 00318 point_list.append(this->point(i)); 00319 } 00320 00321 00322 //=========================================================================== 00323 // Function: facets 00324 // Purpose: append the two facets comprising this quad. Virtual to FacetEntity 00325 // Date: 8/1/03 00326 // Author: sjowen 00327 //=========================================================================== 00328 void CubitQuadFacet::facets(DLIList<CubitFacet*> &facet_list ) 00329 { 00330 facet_list.append( this->get_tri_facet(0) ); 00331 facet_list.append( this->get_tri_facet(1) ); 00332 } 00333 00334 00335 //=========================================================================== 00336 // Function: edges 00337 // Purpose: append the edges of this quad. Virtual to FacetEntity 00338 // Date: 8/1/03 00339 // Author: sjowen 00340 //=========================================================================== 00341 void CubitQuadFacet::edges(DLIList<CubitFacetEdge*> &edge_list ) 00342 { 00343 for ( int i = 0; i < 4; i++ ) 00344 edge_list.append(this->edge(i)); 00345 } 00346 00347 //=========================================================================== 00348 // Function: init_patch 00349 // Purpose: computes the interior control points for the quad facet and 00350 // stores them with the quad facet. Assumes edge control points 00351 // on the four boundary edges have already been computed 00352 // Date: 10/03 00353 // Author: sjowen 00354 //=========================================================================== 00355 CubitStatus CubitQuadFacet::init_patch( ) 00356 { 00357 // compute control point for the internal diagonal edge 00358 00359 CubitFacetEdge *edge_ptr = this->point(0)->shared_edge( this->point(2) ); 00360 assert(edge_ptr != NULL); 00361 CubitPoint *pt0 = edge_ptr->point(0); 00362 CubitPoint *pt1 = edge_ptr->point(1); 00363 CubitVector P0 = pt0->coordinates(); 00364 CubitVector P1 = pt1->coordinates(); 00365 CubitVector N0 = pt0->normal( edge_ptr ); 00366 CubitVector N1 = pt1->normal( edge_ptr ); 00367 CubitVector T0 = P1 - P0; 00368 T0.normalize(); 00369 CubitVector T1 = T0; 00370 CubitVector Pi[3]; 00371 CubitStatus stat = FacetEvalTool::init_edge_control_points( P0, P1, N0, N1, T0, T1, Pi); 00372 if (stat == CUBIT_FAILURE) 00373 return stat; 00374 edge_ptr->control_points( Pi, 4 ); 00375 00376 // compute control points on the triangles 00377 00378 stat = this->get_tri_facet(0)->init_patch(); 00379 if (stat != CUBIT_FAILURE) 00380 stat = this->get_tri_facet(1)->init_patch(); 00381 return stat; 00382 } 00383 00384 00385 00386 //EOF