cgma
CubitQuadFacet.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines