cgma
FacetParamTool.cpp
Go to the documentation of this file.
00001 //===================================================================================
00002 //
00003 // File: FacetParamTool.cpp
00004 //
00005 // Descripiton: interface for 3D-2D parameterization algorithms
00006 //
00007 //===================================================================================
00008 
00009 
00010 #include "FacetParamTool.hpp"
00011 #include "CastTo.hpp"
00012 #include "Surface.hpp"
00013 #include "FacetSurface.hpp"
00014 #include "FacetEvalTool.hpp"
00015 #include "FacetorTool.hpp"
00016 #include "CubitPoint.hpp"
00017 #include "CubitPointData.hpp"
00018 #include "CubitFacet.hpp"
00019 #include "CubitFacetData.hpp"
00020 #include "CubitBox.hpp"
00021 #include "TDFacetBoundaryPoint.hpp"
00022 
00023 #ifdef ROADKILL
00024 #include "ParamManager.hpp"
00025 #endif
00026 
00027 #define DETERM(p1,q1,p2,q2,p3,q3)\
00028      ((q3)*((p2)-(p1)) + (q2)*((p1)-(p3)) + (q1)*((p3)-(p2)))
00029 #define INSIDE_TOL 1.0e-6
00030 
00031 //===================================================================================
00032 // Function: FacetParamTool (Public)
00033 // Description: Constructor
00034 // Author: chynes
00035 // Date: 1/02
00036 //===================================================================================
00037 FacetParamTool::FacetParamTool(int numn, int nume, double* nodes, int* tri) 
00038 {}
00039 
00040 
00041 //-------------------------------------------------------------------------
00042 // Function:    FacetParamTool
00043 // Description: constructor
00044 // Author:      chynes
00045 // Date:        7/10/2002
00046 //-------------------------------------------------------------------------
00047 FacetParamTool::FacetParamTool(Surface *surf) 
00048 {
00049     refSurf = surf;
00050 }
00051 
00052 //===================================================================================
00053 // Function: ~FacetParamTool
00054 // Description: Deconstructor
00055 // Author: chynes
00056 // Date: 1/02
00057 //===================================================================================
00058 FacetParamTool::~FacetParamTool() {}
00059 
00060 //===================================================================================
00061 // Function: set_up_space (Public)
00062 // Description: sets up space of flattening, flattens, and then updates surface
00063 // Author: chynes
00064 // Date: 7/10/02
00065 //===================================================================================
00066 CubitStatus FacetParamTool::set_up_space() 
00067 { 
00068 #ifdef ROADKILL
00069     FacetEvalTool *fetool = CAST_TO(refSurf, FacetSurface)->get_eval_tool();
00070 
00071     if ((fetool->loops())->size() != 1)
00072     {
00073         PRINT_WARNING("Cannot parameterize surface.  Multiple loops detected\n");
00074         return CUBIT_FAILURE;
00075     }
00076 
00077     DLIList<CubitPoint *> my_point_list;
00078     fetool->get_points(my_point_list);
00079     DLIList<CubitFacet *> my_facet_list;
00080     fetool->get_facets(my_facet_list);
00081 
00082   // make arrays out of the points and facets
00083     double *points = new double [3 * my_point_list.size()];
00084     int *facets = new int [3 * my_facet_list.size()];
00085     if (!points || !facets)
00086     {
00087         PRINT_ERROR("Could not define parameterization for surface (out of memory)\n");
00088         return CUBIT_FAILURE;
00089     }
00090     int ii;
00091     CubitPoint *pt;
00092     my_point_list.reset();
00093     for (ii=0; ii<my_point_list.size(); ii++)
00094     {
00095         pt = my_point_list.get_and_step();
00096         points[ii*3] = pt->x();
00097         points[ii*3+1] = pt->y();
00098         points[ii*3+2] = pt->z();
00099         pt->marked(ii);
00100     }
00101     CubitFacet *facet;
00102     CubitPoint *pts[3];
00103     for (ii=0; ii<my_facet_list.size(); ii++)
00104     {
00105         facet = my_facet_list.get_and_step();    
00106         facet->points( pts[0], pts[1], pts[2] );
00107         facets[ii*3]   = pts[0]->marked();
00108         facets[ii*3+1] = pts[1]->marked();
00109         facets[ii*3+2] = pts[2]->marked();
00110     }
00111 
00112     //debug, export facets
00113 //  export_facets(my_point_list.size(), my_facet_list.size(), points, facets);
00114 //  PRINT_ERROR("Debugging Failure.  Please remove export_facets from FacetParamTool\n");
00115 //  return CUBIT_FAILURE;
00116 
00117     // do the parameterization
00118     ParamManager parammanager( my_point_list.size(), my_facet_list.size(),
00119                             points, facets );
00120     if(!parammanager.flatten())
00121     {
00122         PRINT_ERROR("Surface Parameterizer Failed\n");
00123         return CUBIT_FAILURE;
00124     }
00125     else
00126     {
00127         double ratio;
00128         double *sizes;
00129         parammanager.build_sizing();
00130         double *uv = parammanager.get_uvs_sizing( ratio, sizes ); 
00131         
00132         // update the points with uvs values
00133 
00134         TDFacetBoundaryPoint *td_fbp;
00135         CubitBoolean on_internal_boundary;
00136         my_point_list.reset();
00137         for (ii=0; ii<my_point_list.size(); ii++)
00138         {
00139             pt = my_point_list.get_and_step();
00140             DLIList <CubitFacet *> facet_list;
00141             pt->facets_on_surf( fetool->tool_id(), facet_list, on_internal_boundary );
00142             if (on_internal_boundary)
00143             {
00144                 td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt );
00145                 if (!td_fbp)
00146                 {
00147                     TDFacetBoundaryPoint::add_facet_boundary_point( pt );
00148                     td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt );
00149                     td_fbp->add_surf_facets( facet_list );
00150                     td_fbp->set_uvs( facet_list.get(), uv[ii*2], uv[ii*2+1], sizes[ii]);
00151                 }
00152                 else
00153                 {
00154                     if (td_fbp->set_uvs( facet_list.get(),
00155                         uv[ii*2], uv[ii*2+1], sizes[ii] ) != CUBIT_SUCCESS)
00156                     {
00157                         td_fbp->add_surf_facets( facet_list );
00158                         td_fbp->set_uvs( facet_list.get(), uv[ii*2], uv[ii*2+1], sizes[ii]);
00159                     }
00160                 }
00161             }
00162             else
00163             {
00164                 pt->set_uvs( uv[ii*2], uv[ii*2+1], sizes[ii]);
00165             }
00166         }
00167     
00168         PRINT_INFO("Surface Parameterization succeeded\n");
00169         delete [] sizes;
00170         delete [] uv;
00171     
00172     }
00173     
00174     // clean up
00175 
00176     delete [] points;
00177     delete [] facets;
00178     return CUBIT_SUCCESS;
00179 
00180 #else
00181     return CUBIT_FAILURE;
00182 #endif
00183 
00184 }
00185 
00186 //===================================================================================
00187 // Function: transform_to_uv (Public)
00188 // Description: same as title, set_up_space must have been already called
00189 // the local sizing will be returned in the z coord 
00190 // of the uv location vector
00191 // Author: chynes
00192 // Date: 7/10/02
00193 //===================================================================================
00194 CubitStatus FacetParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location) 
00195 {
00196     DLIList<CubitFacet *> facet_list; 
00197     FacetEvalTool *fetool;
00198     CubitFacet *tri_ptr;
00199     CubitBoolean outside = CUBIT_FALSE;
00200     CubitVector closest_point;
00201     CubitVector area_coord;
00202     double u, v, s;
00203     double compare_tol;
00204 
00205     // find best compare_tol
00206     fetool = CAST_TO(refSurf, FacetSurface)->get_eval_tool();
00207     compare_tol = 1e-3*(fetool->bounding_box().diagonal().length());
00208 
00209     // locate point
00210     CubitStatus rv = CUBIT_SUCCESS;
00211     fetool->get_facets(facet_list);
00212     rv = FacetEvalTool::project_to_facets(facet_list, 
00213                                           tri_ptr, 
00214                                           0, 
00215                                           compare_tol, 
00216                                           xyz_location, 
00217                                           CUBIT_FALSE, 
00218                                           &outside, 
00219                                           &closest_point, 
00220                                           NULL);
00221     // determine barycentric coordinates for in facet
00222     if(rv == CUBIT_SUCCESS) 
00223     {
00224         FacetEvalTool::facet_area_coordinate(tri_ptr, closest_point, area_coord);
00225 
00226         // extract data
00227         double u0, u1, u2, v0, v1, v2, s0, s1, s2;
00228         CubitPoint *p0, *p1, *p2;
00229         tri_ptr->points(p0, p1, p2);
00230         p0->get_uvs(tri_ptr, u0, v0, s0);
00231         p1->get_uvs(tri_ptr, u1, v1, s1);
00232         p2->get_uvs(tri_ptr, u2, v2, s2);
00233 
00234         // determine u coordinate
00235         u = (area_coord.x()*u0) + (area_coord.y()*u1) + (area_coord.z()*u2);
00236 
00237         // determine v coordinate
00238         v = (area_coord.x()*v0) + (area_coord.y()*v1) + (area_coord.z()*v2);
00239 
00240         // determine sizing
00241         s = (area_coord.x()*s0) + (area_coord.y()*s1) + (area_coord.z()*s2);
00242 
00243         uv_location.set(u,v,s);
00244     }
00245 
00246         return rv;  
00247 }
00248 
00249 //===================================================================================
00250 // Function: transform_to_xyz (Public)
00251 // Description: same as title
00252 // Author: chynes
00253 // Date: 7/10/02
00254 //===================================================================================
00255 CubitStatus FacetParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location) 
00256 {
00257     CubitStatus rv = CUBIT_SUCCESS;
00258     CubitFacet *tri_ptr;
00259     FacetSurface *facet_surf = CAST_TO(refSurf, FacetSurface);
00260     CubitVector area_coord;
00261     double x, y, z;
00262 
00263     //locate point
00264     rv = locate_point_in_uv(facet_surf, uv_location, tri_ptr);
00265 
00266     if(rv == CUBIT_SUCCESS)
00267     {
00268         // create uv facet
00269         CubitPoint* uvpoint_array[3];
00270         DLIList<CubitPoint *> point_list;
00271         CubitPoint *pt_ptr;
00272         double u,v;
00273         int ii;
00274         tri_ptr->points(point_list);
00275         for(ii = 0; ii<3; ii++)
00276         {
00277             pt_ptr = point_list.get_and_step();
00278             pt_ptr->get_uv(tri_ptr, u, v);
00279             uvpoint_array[ii] = (CubitPoint *) new CubitPointData(u, v, 0.0);
00280         }
00281         CubitFacet *uvfacet_ptr = (CubitFacet *) new CubitFacetData( uvpoint_array[0], 
00282                                                                      uvpoint_array[1], 
00283                                                                      uvpoint_array[2] );
00284 
00285         // determine barycentric coordinates of uv point in uv facet
00286         FacetEvalTool::facet_area_coordinate(uvfacet_ptr, uv_location, area_coord);
00287 
00288         //delete created objects
00289         delete uvfacet_ptr;
00290         for(ii = 0; ii<3; ii++)
00291         {
00292             pt_ptr = uvpoint_array[ii];
00293             delete pt_ptr;
00294         }
00295 
00296         CubitPoint *p0, *p1, *p2;
00297         CubitVector coord0, coord1, coord2;
00298         tri_ptr->points(p0,p1,p2);
00299         coord0 = p0->coordinates();
00300         coord1 = p1->coordinates();
00301         coord2 = p2->coordinates();
00302 
00303         //determine x coordinate
00304         x =   (area_coord.x()*coord0.x())
00305             + (area_coord.y()*coord1.x())
00306             + (area_coord.z()*coord2.x());
00307         //determine y coordinate
00308         y =   (area_coord.x()*coord0.y())
00309             + (area_coord.y()*coord1.y())
00310             + (area_coord.z()*coord2.y());
00311         //determine z coordinate
00312         z =   (area_coord.x()*coord0.z())
00313             + (area_coord.y()*coord1.z())
00314             + (area_coord.z()*coord2.z());
00315 
00316         xyz_location.set(x,y,z);
00317 
00318     }
00319 
00320     return rv;
00321 }
00322 
00323 
00324 //===================================================================================
00325 // Function: locate_point_in_uv (Public)
00326 // Description: same as title (the_point must have coords (u,v,0.0))
00327 // Author: chynes
00328 // Date: 7/10/02
00329 //===================================================================================
00330 CubitStatus FacetParamTool::
00331 locate_point_in_uv(FacetSurface *surf, const CubitVector &the_point, CubitFacet *&tri_ptr) 
00332 {
00333     CubitStatus rv = CUBIT_SUCCESS;
00334 
00335     DLIList<CubitFacet *> facet_list;
00336     int tool_id = surf->get_eval_tool()->tool_id();
00337     surf->get_eval_tool()->get_facets(facet_list);
00338     tri_ptr = facet_list.get();
00339 
00340     // loop until we find something
00341 
00342     CubitPoint *p0, *p1, *p2;
00343     double aa, bb, cc;
00344     double u0, u1, u2, v0, v1, v2;
00345     CubitBoolean found = CUBIT_FALSE;
00346     while(!found && rv == CUBIT_SUCCESS)
00347     {
00348         tri_ptr->points(p0, p1, p2);
00349         p0->get_uv(tri_ptr, u0, v0);
00350         p1->get_uv(tri_ptr, u1, v1);
00351         p2->get_uv(tri_ptr, u2, v2);
00352         aa = DETERM(the_point.x(), the_point.y(), u1, v1, u2, v2);
00353         bb = DETERM(u0, v0, the_point.x(), the_point.y(), u2, v2);
00354         cc = DETERM(u0, v0, u1, v1, the_point.x(), the_point.y());
00355         if (aa > -INSIDE_TOL &&
00356             bb > -INSIDE_TOL &&
00357             cc > -INSIDE_TOL)
00358         {
00359             found = CUBIT_TRUE;  // this is the one
00360         }
00361         else
00362         {
00363             // set up to check the next logical neighbor
00364             if (aa <= bb && aa <= cc) {
00365                 int edge_index = 1;
00366                 tri_ptr = tri_ptr->adjacent( edge_index, &tool_id );
00367             }
00368             else if (bb <= aa && bb <= cc) {
00369                 int edge_index = 2;
00370                 tri_ptr = tri_ptr->adjacent( edge_index, &tool_id );
00371             }
00372             else {
00373                 int edge_index = 0;
00374                 tri_ptr = tri_ptr->adjacent( edge_index, &tool_id);
00375             }
00376             // check to see if we've left the triangulation
00377       
00378             if (tri_ptr == NULL)
00379             {
00380                 rv = exhaustive_locate_point_in_uv(surf, the_point, tri_ptr );
00381                 found = CUBIT_TRUE;
00382             }
00383         }
00384     }
00385 
00386     return rv;
00387 }
00388 //===================================================================================
00389 // Function: exhaustive_locate_point_in_uv (Public)
00390 // Description: same as title
00391 // Author: chynes
00392 // Date: 7/10/02
00393 //===================================================================================
00394 CubitStatus FacetParamTool::
00395 exhaustive_locate_point_in_uv(FacetSurface *surf, const CubitVector &the_point, CubitFacet *&tri_ptr) 
00396 {
00397     CubitStatus rv = CUBIT_SUCCESS;
00398 
00399     DLIList<CubitFacet *> facet_list;
00400     surf->get_eval_tool()->get_facets(facet_list);
00401 
00402     // loop until we find something
00403 
00404     CubitPoint *p0, *p1, *p2;
00405     int ii;
00406     double aa, bb, cc;
00407     double u0, u1, u2, v0, v1, v2;
00408     CubitBoolean found = CUBIT_FALSE;
00409     for(ii = 0; ii < facet_list.size() && !found; ii++)
00410     {
00411         tri_ptr = facet_list.get_and_step();
00412         tri_ptr->points(p0, p1, p2);
00413         p0->get_uv(tri_ptr, u0, v0);
00414         p1->get_uv(tri_ptr, u1, v1);
00415         p2->get_uv(tri_ptr, u2, v2);
00416         aa = DETERM(the_point.x(), the_point.y(), u1, v1, u2, v2);
00417         bb = DETERM(u0, v0, the_point.x(), the_point.y(), u2, v2);
00418         cc = DETERM(u0, v0, u1, v1, the_point.x(), the_point.y());
00419         if (aa > -INSIDE_TOL &&
00420             bb > -INSIDE_TOL &&
00421             cc > -INSIDE_TOL)
00422         {
00423             found = CUBIT_TRUE;  // this is the one
00424         }
00425     }
00426     if (!found)
00427     {
00428         rv = CUBIT_FAILURE;
00429         tri_ptr = NULL;
00430     }
00431     return rv;
00432 }
00433 
00434 //===================================================================================
00435 // Function: flatten
00436 // Description: accessor function to the parameterization algorithms
00437 // Author: chynes
00438 // Date: 1/02
00439 //====================================================================================
00440 
00441 
00442 //EOF
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines