cgma
|
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