cgma
|
00001 //- Class: CurveFacetEvalTool 00002 //- Description: The CurveFacetEvalTool is a tool to perform generic geometric 00003 //- operations on a set of facets. 00004 //- Assumptions: All of the facets are connected topologically correct. 00005 //- 00006 //- Owner: Steve J. Owen 00007 //- Checked by: 00008 00009 #include "CubitVector.hpp" 00010 #include "CubitPoint.hpp" 00011 #include "CubitFacet.hpp" 00012 #include "CubitFacetEdge.hpp" 00013 #include "CubitFacetEdgeData.hpp" 00014 #include "CubitBox.hpp" 00015 #include "DLIList.hpp" 00016 #include "CurveFacetEvalTool.hpp" 00017 #include "FacetEvalTool.hpp" 00018 #include "GeometryDefines.h" 00019 #include "CastTo.hpp" 00020 #include "GfxDebug.hpp" 00021 #include "CubitFileIOWrapper.hpp" 00022 #include "Cholla.h" 00023 #include "FacetDataUtil.hpp" 00024 00025 //=========================================================================== 00026 //Function Name: initialize 00027 // 00028 //Member Type: PUBLIC 00029 //Description: initialize a CurveFacetEvalTool - uses end locations of the curve 00030 // (does geometric comparisons to match facet points) 00031 //=========================================================================== 00032 CubitStatus CurveFacetEvalTool::initialize( 00033 FacetEvalTool *surf_eval_tool, // the adjacent surface facet eval tool 00034 CubitVector &start, CubitVector &end, // begin and end vertex 00035 CubitSense orientation_wrt_surface ) // direction wrt the surface 00036 { 00037 // static int counter = 0; 00038 output_id = -1; 00039 myBBox = NULL; 00040 00041 surfFacetEvalTool = surf_eval_tool; 00042 00043 CubitStatus stat = get_segments_from_loops( surfFacetEvalTool->loops(), start, end, 00044 myEdgeList, myPointList, orientation_wrt_surface ); 00045 goodCurveData = (stat == CUBIT_SUCCESS) ? CUBIT_TRUE : CUBIT_FALSE; 00046 if( !goodCurveData ) 00047 { 00048 PRINT_ERROR( "Unable to initialize Curve Evaluation Tool for Faceted Geometry.\n" ); 00049 return CUBIT_FAILURE; 00050 } 00051 00052 interpOrder = surfFacetEvalTool->interp_order(); 00053 curvSense = find_curv_sense( start ); 00054 bounding_box(); 00055 return CUBIT_SUCCESS; 00056 } 00057 00058 CubitStatus CurveFacetEvalTool::initialize( 00059 FacetEvalTool *surf_eval_tool, // the adjacent surface facet eval tool 00060 CubitVector &start, // begin vertex 00061 std::vector<CubitVector> &positions ) 00062 { 00063 // static int counter = 0; 00064 output_id = -1; 00065 myBBox = NULL; 00066 00067 surfFacetEvalTool = surf_eval_tool; 00068 00069 CubitStatus stat = get_segments_from_positions( positions, start, 00070 myEdgeList, myPointList ); 00071 00072 goodCurveData = (stat == CUBIT_SUCCESS) ? CUBIT_TRUE : CUBIT_FALSE; 00073 if( !goodCurveData ) 00074 { 00075 PRINT_ERROR( "Unable to initialize Curve Evaluation Tool for Faceted Geometry.\n" ); 00076 return CUBIT_FAILURE; 00077 } 00078 00079 interpOrder = surfFacetEvalTool->interp_order(); 00080 curvSense = find_curv_sense( start ); 00081 bounding_box(); 00082 return CUBIT_SUCCESS; 00083 } 00084 00085 //=========================================================================== 00086 //Function Name: initialize 00087 // 00088 //Member Type: PUBLIC 00089 //Description: initialize a CurveFacetEvalTool - uses end point pointers of the curve 00090 //=========================================================================== 00091 CubitStatus CurveFacetEvalTool::initialize( 00092 FacetEvalTool *surf_eval_tool, // the adjacent surface facet eval tool 00093 CubitPoint *start_pt, CubitPoint *end_pt, // begin and end points 00094 CubitSense orientation_wrt_surf ) // direction wrt the surface 00095 { 00096 // static int counter = 0; 00097 output_id = -1; 00098 00099 myBBox = NULL; 00100 surfFacetEvalTool = surf_eval_tool; 00101 CubitStatus stat = get_segments_from_loops( surfFacetEvalTool->loops(), 00102 start_pt, end_pt, 00103 myEdgeList, myPointList, 00104 orientation_wrt_surf ); 00105 goodCurveData = (stat == CUBIT_SUCCESS) ? CUBIT_TRUE : CUBIT_FALSE; 00106 if( !goodCurveData ) 00107 { 00108 PRINT_ERROR( "Unable to initialize Curve Evaluation Tool for Faceted Geometry.\n" ); 00109 return CUBIT_FAILURE; 00110 } 00111 interpOrder = surfFacetEvalTool->interp_order(); 00112 curvSense = find_curv_sense( start_pt ); 00113 bounding_box(); 00114 return CUBIT_SUCCESS; 00115 } 00116 00117 //=========================================================================== 00118 //Function Name: CurveFacetEvalTool 00119 // 00120 //Member Type: PUBLIC 00121 //Description: initialize a CurveFacetEvalTool - uses an existing set of 00122 // ordered facet edges to define curve 00123 //=========================================================================== 00124 CubitStatus CurveFacetEvalTool::initialize( 00125 DLIList<CubitFacetEdge*> &edge_list, // the ordered facet edges on this curve 00126 DLIList<CubitPoint*> &point_list, FacetEvalTool* surf_eval) // the ordered points on this curve 00127 { 00128 // static int counter = 0; 00129 output_id = -1; 00130 myBBox = NULL; 00131 curvSense = CUBIT_FORWARD; 00132 surfFacetEvalTool = surf_eval; 00133 myEdgeList = edge_list; 00134 myPointList = point_list; 00135 set_length(); 00136 00137 CubitStatus status = fix_point_edge_order(); 00138 00139 if( CUBIT_SUCCESS != status ) 00140 return status; 00141 00142 interpOrder = 0; 00143 if(surf_eval) 00144 interpOrder = surf_eval->interp_order(); 00145 bounding_box(); 00146 goodCurveData = CUBIT_TRUE; 00147 return CUBIT_SUCCESS; 00148 } 00149 00150 CurveFacetEvalTool::CurveFacetEvalTool() 00151 { 00152 static int counter = 0; 00153 toolID = counter++; 00154 myBBox = NULL; 00155 goodCurveData = CUBIT_TRUE; 00156 00157 } 00158 //=========================================================================== 00159 //Function Name: ~CurveFacetEvalTool 00160 // 00161 //Member Type: PUBLIC 00162 //Description: destructor 00163 //=========================================================================== 00164 CurveFacetEvalTool::~CurveFacetEvalTool() 00165 { 00166 if ( myBBox ) delete myBBox; 00167 destroy_facets(); 00168 } 00169 00170 //=========================================================================== 00171 //Function Name: get_segments_from_loops 00172 // 00173 //Member Type: PRIVATE 00174 //Description: extract the facet edges from the loops list that are 00175 // used for the current curve. Uses CubitVectors at curve 00176 // ends to determine curve -- has to do geometric comaprisons 00177 // so it may be less reliable than the overloaded function 00178 // assumption: the sense (orientation) of the RefFace is the same as that of 00179 // the facets and the facetedge loop list 00180 //=========================================================================== 00181 CubitStatus CurveFacetEvalTool::get_segments_from_loops( 00182 DLIList<DLIList<CubitFacetEdge*>*> *facet_loop_list, // lists of boundary edges 00183 CubitVector &start, CubitVector &end, // begin and end vertex 00184 DLIList<CubitFacetEdge*> &edge_list, // return the edges used for this curve 00185 DLIList<CubitPoint*> &point_list, // return the points used for this curve 00186 CubitSense orientation_wrt_surf ) 00187 { 00188 CubitStatus stat = CUBIT_SUCCESS; 00189 int ii, jj; 00190 int mydebug = 0; 00191 00192 CubitBoolean done = CUBIT_FALSE; 00193 DLIList<CubitFacetEdge*> *facet_loop; 00194 CubitFacetEdge *edge, *startedge = NULL; 00195 CubitPoint *pt0, *pt1; 00196 CubitVector loc_pt0, loc_pt1; 00197 double edge_length; 00198 00199 facetLength = 0.0e0; 00200 00201 int tool_id = surfFacetEvalTool->tool_id(); 00202 //loop over the "loops" 00203 for (ii=0; ii<facet_loop_list->size() && !done && stat == CUBIT_SUCCESS; ii++) { 00204 //get the next facet loop 00205 facet_loop = facet_loop_list->get_and_step(); 00206 00207 // now loop over the edges in that loop 00208 for (jj=0; jj<facet_loop->size() && !done; jj++) { 00209 //get the start edge... we will 00210 //traverse the list forwards, if the surface is oriented forward 00211 //otherwise, traverse it backwards 00212 startedge = 00213 (orientation_wrt_surf == CUBIT_FORWARD) ? facet_loop->get_and_step() : 00214 facet_loop->get_and_back(); 00215 00216 if (startedge->get_flag() == 0) { 00217 if (orientation_wrt_surf == CUBIT_FORWARD) { 00218 startedge->boundary_edge_points( pt0, pt1, tool_id ); 00219 } 00220 else { 00221 startedge->boundary_edge_points( pt1, pt0, tool_id ); 00222 } 00223 loc_pt0 = pt0->coordinates(); 00224 loc_pt1 = pt1->coordinates(); 00225 if (loc_pt0.within_tolerance( start, GEOMETRY_RESABS )) { 00226 startedge->set_flag( 1 ); 00227 edge = startedge; 00228 if (mydebug) draw_edge( edge, CUBIT_GREEN_INDEX ); 00229 while (!done) { 00230 edge_list.append( edge ); 00231 point_list.append( pt0 ); 00232 edge_length = loc_pt0.distance_between( loc_pt1 ); 00233 facetLength += edge_length; 00234 //if the other end of the edge is at the begginning of the 00235 //loop, then we're done. 00236 if (loc_pt1.within_tolerance( end, GEOMETRY_RESABS )) { 00237 done = CUBIT_TRUE; 00238 point_list.append( pt1 ); 00239 } 00240 else {//otherwise... 00241 if (orientation_wrt_surf == CUBIT_FORWARD) { 00242 edge = facet_loop->get_and_step(); 00243 edge->boundary_edge_points( pt0, pt1, tool_id ); 00244 } 00245 else { 00246 edge = facet_loop->get_and_back(); 00247 edge->boundary_edge_points( pt1, pt0, tool_id ); 00248 } 00249 loc_pt0 = pt0->coordinates(); 00250 loc_pt1 = pt1->coordinates(); 00251 if (mydebug) draw_edge( edge, CUBIT_BLUE_INDEX ); 00252 //if we got back to the startedge without the 00253 // other end of an edge getting to the start vertex, 00254 // we have a problem.... 00255 if (edge == startedge) 00256 { 00257 stat = CUBIT_FAILURE; // this shouldn't happen 00258 done = CUBIT_TRUE; 00259 }//end edge == startedge 00260 }//end else not within tolerance 00261 }//end while not done 00262 }//end if within tolerance 00263 }//end if not marked 00264 }//end loop over edges in facet loop 00265 }//end loop over facet loops 00266 if(done!=CUBIT_TRUE) 00267 { 00268 PRINT_ERROR("Can't define curve representation in mesh-based geometry\n"); 00269 stat = CUBIT_FAILURE; 00270 } 00271 return stat; 00272 00273 } 00274 00275 //=========================================================================== 00276 //Function Name: get_segments_from_loops 00277 // 00278 //Member Type: PRIVATE 00279 //Description: extract the facet edges from the loops list that are 00280 // used for the current curve. Uses the CubitPoints at 00281 // the ends of the curve to determine curve 00282 // assumption: the sense (orientation) of the RefFace is the same as that of 00283 // the facets and the facetedge loop list 00284 //=========================================================================== 00285 CubitStatus CurveFacetEvalTool::get_segments_from_loops( 00286 DLIList<DLIList<CubitFacetEdge*>*> *facet_loop_list, // lists of boundary edges 00287 CubitPoint *start_pt, CubitPoint *end_pt, // begin and end point 00288 DLIList<CubitFacetEdge*> &edge_list, // return the edges used for this curve 00289 DLIList<CubitPoint*> &point_list, // return the points used for this curve 00290 CubitSense orientation_wrt_surf ) 00291 { 00292 CubitStatus stat = CUBIT_SUCCESS; 00293 int ii, jj; 00294 int mydebug = DEBUG_FLAG(181); 00295 CubitBoolean done = CUBIT_FALSE; 00296 DLIList<CubitFacetEdge*> *facet_loop; 00297 CubitFacetEdge *edge, *startedge = NULL; 00298 CubitPoint *pt0, *pt1; 00299 CubitVector loc_pt0, loc_pt1; 00300 double edge_length; 00301 DLIList<CubitFacetEdge*> temp_edge_list; 00302 DLIList<CubitPoint*> temp_point_list; 00303 00304 if (mydebug) 00305 { 00306 GfxDebug::draw_point( start_pt->x(), 00307 start_pt->y(), 00308 start_pt->z(), 00309 CUBIT_RED_INDEX ); 00310 GfxDebug::draw_point( end_pt->x(), 00311 end_pt->y(), 00312 end_pt->z(), 00313 CUBIT_GREEN_INDEX ); 00314 GfxDebug::flush(); 00315 } 00316 00317 int tool_id = surfFacetEvalTool->tool_id(); 00318 //loop over the list of facet loops 00319 for (ii=0; ii<facet_loop_list->size() && !done && stat == CUBIT_SUCCESS; ii++) { 00320 //get the next facet loop 00321 facet_loop = facet_loop_list->get_and_step(); 00322 //now loop over the edges in that facet loop 00323 for (jj=0; jj<facet_loop->size() && !done; jj++) { 00324 //get the start edge... we will 00325 //traverse the list forwards, if the surface is oriented forward 00326 //otherwise, traverse it backwards 00327 startedge = 00328 (orientation_wrt_surf == CUBIT_FORWARD) ? facet_loop->get_and_step() : 00329 facet_loop->get_and_back(); 00330 //if startedge isn't marked 00331 if (startedge->get_flag() == 0) { 00332 //get the points from the start edge in the appropriate order 00333 if (orientation_wrt_surf == CUBIT_FORWARD) { 00334 startedge->boundary_edge_points( pt0, pt1, tool_id ); 00335 } 00336 else { 00337 startedge->boundary_edge_points( pt1, pt0, tool_id ); 00338 } 00339 //convert to CubitVector 00340 loc_pt0 = pt0->coordinates(); 00341 loc_pt1 = pt1->coordinates(); 00342 //if the first point on the edge is the start_pt... otherwise step 00343 if (pt0 == start_pt) { 00344 //mark the startedge 00345 CubitFacetEdge* marked_edge = NULL; 00346 edge = startedge; 00347 if (mydebug) draw_edge( edge, CUBIT_GREEN_INDEX );//draw the start edge 00348 //loop until we have reached an end or no more choices 00349 while (!done) { 00350 //if the first point is at the start, we are either 00351 // just starting, or we have looped back onto the 00352 // start point. The latter _may_ be ok. In case 00353 // the latter is the case, clean out the temporary 00354 // lists and (re)initialize the length. Also, unmark 00355 // the edge that we marked the last time we started, 00356 // if we previously marked an edge. 00357 if (pt0 == start_pt){ 00358 temp_point_list.clean_out(); 00359 temp_edge_list.clean_out(); 00360 facetLength = 0.0; 00361 if(marked_edge) 00362 marked_edge->set_flag(0); 00363 marked_edge=edge; 00364 edge->set_flag(1); 00365 } 00366 //add the current edge to the edge list 00367 temp_edge_list.append( edge ); 00368 //add the current start point to the point list 00369 temp_point_list.append( pt0 ); 00370 //measure the edge... essentially 00371 edge_length = loc_pt0.distance_between( loc_pt1 ); 00372 //keep a running tally of the curve length 00373 facetLength += edge_length; 00374 00375 //if the second point is at the end, we're done 00376 if (pt1 == end_pt ) { 00377 done = CUBIT_TRUE; 00378 temp_point_list.append( pt1 ); 00379 } 00380 //otherwise, we need to step forward 00381 else { 00382 if (orientation_wrt_surf == CUBIT_FORWARD) { 00383 edge = facet_loop->get_and_step(); 00384 edge->boundary_edge_points( pt0, pt1, tool_id ); 00385 } 00386 else { 00387 edge = facet_loop->get_and_back(); 00388 edge->boundary_edge_points( pt1, pt0, tool_id ); 00389 } 00390 //convert point to CubitVector, as above 00391 loc_pt0 = pt0->coordinates(); 00392 loc_pt1 = pt1->coordinates(); 00393 if (mydebug) draw_edge( edge, CUBIT_BLUE_INDEX ); 00394 if (edge == startedge) 00395 { 00396 stat = CUBIT_FAILURE; // this shouldn't happen 00397 done = CUBIT_TRUE; 00398 } 00399 }//end else (ie, if not pt1==end_pt) 00400 }//end while !done 00401 }//end if pt0 == start_pt 00402 }//end if start edge isn't marked 00403 }//end loop over edges in the loop 00404 }//end loop over facet loops 00405 00406 //now put the temporary list entries onto the end of the list we return. 00407 point_list += temp_point_list; 00408 edge_list += temp_edge_list; 00409 00410 if(done!=CUBIT_TRUE || stat == CUBIT_FAILURE) 00411 { 00412 stat = CUBIT_FAILURE; 00413 PRINT_WARNING("Can't define curve representation in mesh-based geometry\n"); 00414 PRINT_INFO(" Hint: Try importing as a free mesh and examining nodes and attached\n"); 00415 PRINT_INFO(" elements near the following locations:\n"); 00416 PRINT_INFO(" Start curve = %f %f %f\n", start_pt->x(), start_pt->y(), start_pt->z()); 00417 PRINT_INFO(" End curve = %f %f %f\n", end_pt->x(), end_pt->y(), end_pt->z()); 00418 if (mydebug) 00419 { 00420 surfFacetEvalTool->debug_draw_facets( CUBIT_YELLOW_INDEX ); 00421 int i, j; 00422 for (i=0; i<facet_loop_list->size(); i++) 00423 { 00424 DLIList<CubitFacetEdge*> *my_facet_loop = facet_loop_list->get_and_step(); 00425 for (j=0; j<my_facet_loop->size(); j++) 00426 { 00427 draw_edge( my_facet_loop->get_and_step(), CUBIT_RED_INDEX ); 00428 } 00429 } 00430 GfxDebug::mouse_xforms(); 00431 } 00432 } 00433 return stat; 00434 } 00435 00436 //=========================================================================== 00437 //Function Name: get_segments_from_positions 00438 // 00439 //Member Type: PRIVATE 00440 //Description: extract the facet edges from the facets of the parent surface. 00441 // This function is used exclusively for hardlines. 00442 //=========================================================================== 00443 CubitStatus CurveFacetEvalTool::get_segments_from_positions( 00444 std::vector<CubitVector> &positions, // postions of points on curve 00445 CubitVector &start, // begin point 00446 DLIList<CubitFacetEdge*> &edge_list, // return the edges used for this curve 00447 DLIList<CubitPoint*> &point_list ) // return the points used for this curve 00448 { 00449 DLIList<CubitPoint*> surface_pts; 00450 surfFacetEvalTool->get_points( surface_pts ); 00451 00452 facetLength = 0; 00453 00454 double smallest_dist = CUBIT_DBL_MAX; 00455 CubitPoint *start_pt = NULL; 00456 //find the closest point to 'start' 00457 for( int k=surface_pts.size(); k--; ) 00458 { 00459 double tmp_dist = surface_pts.get()->coordinates().distance_between_squared( start ); 00460 00461 if( tmp_dist < smallest_dist ) 00462 { 00463 smallest_dist = tmp_dist; 00464 start_pt = surface_pts.get(); 00465 } 00466 surface_pts.get_and_step(); 00467 } 00468 00469 myPointList.append( start_pt ); 00470 00471 CubitPoint *current_pt = start_pt; 00472 CubitPoint *next_pt = NULL; 00473 for (size_t k = 1; k < positions.size(); k++ ) 00474 { 00475 CubitVector current_pos = positions[k]; 00476 00477 //find the CubitPoint attached to this point via an edge 00478 double smallest_dist = CUBIT_DBL_MAX; 00479 CubitFacetEdge *next_edge; 00480 00481 DLIList<CubitFacetEdge*> adj_edges; 00482 current_pt->edges( adj_edges ); 00483 00484 for( int m=adj_edges.size(); m--; ) 00485 { 00486 CubitFacetEdge *tmp_edge = adj_edges.get_and_step(); 00487 CubitPoint *other_pt = tmp_edge->other_point( current_pt ); 00488 00489 double tmp_dist = current_pos.distance_between_squared( other_pt->coordinates() ); 00490 if( tmp_dist < smallest_dist ) 00491 { 00492 smallest_dist = tmp_dist; 00493 next_pt = other_pt; 00494 next_edge = tmp_edge; 00495 } 00496 } 00497 00498 current_pt = next_pt; 00499 00500 facetLength += next_edge->length(); 00501 00502 myEdgeList.append( next_edge ); 00503 myPointList.append( current_pt ); 00504 } 00505 00506 if ((size_t)myPointList.size() != positions.size() || 00507 (size_t)myEdgeList.size() != positions.size() - 1 ) 00508 return CUBIT_FAILURE; 00509 00510 return CUBIT_SUCCESS; 00511 } 00512 00513 //=========================================================================== 00514 //Function Name: find_curv_sense 00515 // 00516 //Member Type: PRIVATE 00517 //Description: Determines 'curvSense' depending on the CubitFacetEdges 00518 // in 'myEdgeList' Assumption is that all edges 00519 // are oriented the same in the curve 00520 //=========================================================================== 00521 CubitSense CurveFacetEvalTool::find_curv_sense( CubitPoint *start_pt ) 00522 { 00523 myEdgeList.reset(); 00524 CubitFacetEdge *edge_ptr = myEdgeList.get(); 00525 CubitPoint *pt0 = edge_ptr->point(0); 00526 CubitPoint *pt1 = edge_ptr->point(1); 00527 CubitSense sense; 00528 00529 if (start_pt == pt0) 00530 { 00531 sense = CUBIT_FORWARD; 00532 } 00533 else if (start_pt == pt1) 00534 { 00535 sense = CUBIT_REVERSED; 00536 } 00537 else 00538 { 00539 sense = CUBIT_UNKNOWN; 00540 } 00541 return sense; 00542 } 00543 00544 //=========================================================================== 00545 //Function Name: find_curv_sense 00546 // 00547 //Member Type: PRIVATE 00548 //Description: Determines 'curvSense' depending on the CubitFacetEdges 00549 // in 'myEdgeList' Assumption is that all edges 00550 // are oriented the same in the curve 00551 //=========================================================================== 00552 00553 CubitSense CurveFacetEvalTool::find_curv_sense( CubitVector &start ) 00554 { 00555 myEdgeList.reset(); 00556 CubitFacetEdge* temp_edge = myEdgeList.get(); 00557 00558 CubitVector temp_vector = temp_edge->point(1)->coordinates() - 00559 temp_edge->point(0)->coordinates(); 00560 00561 double tol = temp_vector.length() / 100.0; 00562 //if point(0) of first edge in list == start, it is CUBIT_FORWARD 00563 if(start.within_tolerance(temp_edge->point(0)->coordinates(), tol ) ) 00564 return CUBIT_FORWARD; 00565 //if point(1) of first edge in list == start, it is CUBIT_REVERSED 00566 else if(start.within_tolerance(temp_edge->point(1)->coordinates(), tol ) ) 00567 return CUBIT_REVERSED; 00568 else 00569 return CUBIT_UNKNOWN; 00570 } 00571 00572 //=========================================================================== 00573 //Function Name: bounding_box 00574 // 00575 //Member Type: PUBLIC 00576 //Description: Calculates the bounding box of the curve. 00577 //=========================================================================== 00578 CubitBox CurveFacetEvalTool::bounding_box() 00579 { 00580 if ( !myBBox ) 00581 { 00582 int ii; 00583 CubitPoint *point_ptr; 00584 double x, y, z; 00585 double x_min = CUBIT_DBL_MAX, x_max = -CUBIT_DBL_MAX; 00586 double y_min = CUBIT_DBL_MAX, y_max = -CUBIT_DBL_MAX; 00587 double z_min = CUBIT_DBL_MAX, z_max = -CUBIT_DBL_MAX; 00588 for ( ii = myPointList.size(); ii > 0; ii-- ) 00589 { 00590 point_ptr = myPointList.get_and_step(); 00591 x = point_ptr->x(); 00592 y = point_ptr->y(); 00593 z = point_ptr->z(); 00594 if ( x < x_min ) 00595 x_min = x; 00596 if ( y < y_min ) 00597 y_min = y; 00598 if ( z < z_min ) 00599 z_min = z; 00600 if ( x > x_max ) 00601 x_max = x; 00602 if ( y > y_max ) 00603 y_max = y; 00604 if ( z > z_max ) 00605 z_max = z; 00606 } 00607 CubitVector min_v(x_min, y_min, z_min ); 00608 CubitVector max_v(x_max, y_max, z_max ); 00609 myBBox = new CubitBox( min_v, max_v ); 00610 } 00611 return *(myBBox); 00612 } 00613 00614 //=========================================================================== 00615 //Function Name: position_from_fraction 00616 // 00617 //Member Type: PUBLIC 00618 //Description: evaluates the location a fraction of the way along the curve 00619 // based on the sum of the lengths of the facet edges on this curve 00620 //=========================================================================== 00621 CubitStatus CurveFacetEvalTool::position_from_fraction( 00622 double fraction, // between 0 and 1 00623 CubitVector &location_on_curve ) 00624 { 00625 CubitStatus status = CUBIT_SUCCESS; 00626 CubitBoolean done = CUBIT_FALSE; 00627 double length, curlength, targetlength, lastlength; 00628 CubitFacetEdge *edge = NULL; 00629 CubitPoint *pt0=NULL, *pt1=NULL; 00630 CubitVector loc_pt0, loc_pt1; 00631 CubitVector eval_location; 00632 myEdgeList.reset(); 00633 00634 myPointList.reset(); 00635 pt0 = myPointList.get(); 00636 if (fraction <= 0.0) { 00637 edge = myEdgeList.get_and_step(); 00638 location_on_curve = pt0->coordinates(); 00639 return status; 00640 } 00641 curlength = lastlength = 0.0e0; 00642 targetlength = fraction * facetLength; 00643 assert(myEdgeList.size() > 0); 00644 int ii = 0; 00645 for ( ; ii<myEdgeList.size() && !done; ii++) { 00646 edge = myEdgeList.get_and_step(); 00647 loc_pt0 = edge->point( 0 )->coordinates(); 00648 loc_pt1 = edge->point( 1 )->coordinates(); 00649 length = loc_pt0.distance_between( loc_pt1 ); 00650 curlength += length; 00651 if ( edge->point(0) == pt0 ){ 00652 pt1 = edge->point(1); 00653 } 00654 else{ 00655 pt1 = edge->point(0); 00656 } 00657 if (targetlength <= curlength) { 00658 done = CUBIT_TRUE; 00659 00660 loc_pt0 = pt0->coordinates(); 00661 loc_pt1 = pt1->coordinates(); 00662 double local_fraction = (targetlength - lastlength) / length; 00663 eval_location = loc_pt0 + local_fraction * (loc_pt1 - loc_pt0); 00664 if (interpOrder == 0 || !surfFacetEvalTool) { 00665 location_on_curve = eval_location; 00666 } 00667 else { 00668 // evaluate Bezier edge 00669 int index0 = 0; 00670 int index1 = 1; 00671 if ( pt1 == edge->point(0) ) { 00672 //switching the indices causes evaluate_bezier_edge to compute the 00673 //wrong location, so I'm removing the switch (mbrewer) 00674 //index0 = 1; 00675 //index1 = 0; 00676 local_fraction = 1. - local_fraction; 00677 } 00678 status = evaluate_bezier_edge(edge,index0,index1,local_fraction, 00679 location_on_curve,0); 00680 } 00681 } 00682 else { 00683 lastlength = curlength; 00684 } 00685 if ( edge->point(0) == pt0 ) 00686 pt0 = edge->point(1); 00687 else 00688 pt0 = edge->point(0); 00689 } 00690 00691 if (!done) { 00692 if(pt1 == NULL){ 00693 PRINT_ERROR("Opposite point not found while evaluating a curve.\n"); 00694 location_on_curve.set(0.0,0.0,0.0); 00695 return CUBIT_FAILURE; 00696 } 00697 location_on_curve = pt1->coordinates(); 00698 } 00699 return status; 00700 } 00701 00702 //=========================================================================== 00703 //Function Name: evaluate_bezier_edge 00704 // 00705 //Member Type: PRIVATE 00706 //Description: evaluates a fractional length onto a Bezier edge 00707 //=========================================================================== 00708 CubitStatus CurveFacetEvalTool::evaluate_bezier_edge(CubitFacetEdge *edge, 00709 int index0, 00710 int index1, 00711 double fraction, 00712 CubitVector &location_on_curve, 00713 double* tangent) 00714 { 00715 CubitStatus status; 00716 int numEdge, numVert, numLocs; 00717 int edgeVert[2]; 00718 //int order; 00719 double vert[6], edgeCtrlPts[9], location[3]; 00720 CubitVector *edge_ctrl_pts; 00721 double scaled_parameter; 00722 00723 numEdge = 1; 00724 numVert = 2; 00725 numLocs = 1; 00726 edgeVert[0] = 0; edgeVert[1] = 1; 00727 vert[0] = edge->point(index0)->x(); 00728 vert[1] = edge->point(index0)->y(); 00729 vert[2] = edge->point(index0)->z(); 00730 vert[3] = edge->point(index1)->x(); 00731 vert[4] = edge->point(index1)->y(); 00732 vert[5] = edge->point(index1)->z(); 00733 00734 edge_ctrl_pts = edge->control_points(); 00735 edgeCtrlPts[0] = edge_ctrl_pts[0].x(); 00736 edgeCtrlPts[1] = edge_ctrl_pts[0].y(); 00737 edgeCtrlPts[2] = edge_ctrl_pts[0].z(); 00738 edgeCtrlPts[3] = edge_ctrl_pts[1].x(); 00739 edgeCtrlPts[4] = edge_ctrl_pts[1].y(); 00740 edgeCtrlPts[5] = edge_ctrl_pts[1].z(); 00741 edgeCtrlPts[6] = edge_ctrl_pts[2].x(); 00742 edgeCtrlPts[7] = edge_ctrl_pts[2].y(); 00743 edgeCtrlPts[8] = edge_ctrl_pts[2].z(); 00744 00745 //evalBezierEdge takes a parameter in the range of -1 to 1. 00746 // evalBezierEdge calls functions which convert back to 00747 // a range of 0 to 1, 00748 // but we must convert to -1 to 1, before sending it. 00749 scaled_parameter = (2.0 * fraction) - 1.0; 00750 00751 // static function in Cholla.cpp 00752 evalBezierEdge(numEdge,numVert,edgeVert,vert,edgeCtrlPts,numLocs, 00753 &scaled_parameter, location,tangent); 00754 00755 location_on_curve.x(location[0]); 00756 location_on_curve.y(location[1]); 00757 location_on_curve.z(location[2]); 00758 00759 status = CUBIT_SUCCESS; 00760 00761 return status; 00762 } 00763 00764 //=========================================================================== 00765 //Function Name: u_from_arc_length 00766 // 00767 //Member Type: PUBLIC 00768 //Description: see notes in FacetCurve::u_from_arc_length 00769 //=========================================================================== 00770 double CurveFacetEvalTool::u_from_arc_length ( double root_param, 00771 double arc_length ) 00772 { 00773 if( facetLength == 0 ) 00774 return 0; 00775 00776 double u = root_param + arc_length / facetLength; 00777 00778 return u; 00779 00780 } 00781 00782 //=========================================================================== 00783 //Function Name: length_from_u 00784 // 00785 //Member Type: PUBLIC 00786 //Description: return length along curve from u parameter 00787 //=========================================================================== 00788 double CurveFacetEvalTool::length_from_u ( double root_param, 00789 double end_param ) 00790 { 00791 double length = (end_param - root_param) * facetLength; 00792 00793 return length; 00794 } 00795 00796 //=========================================================================== 00797 //Function Name: closest_point 00798 // 00799 //Member Type: PUBLIC 00800 //Description: Finds the closest point from the vector (this_point) to the 00801 // set of facets that lies on the set of facets. If the point 00802 // lies outside this set, the closest point will be on the plane 00803 // of the closest facet. The closest_point is set to be that point. 00804 //=========================================================================== 00805 CubitStatus CurveFacetEvalTool::closest_point(CubitVector &this_point, 00806 CubitVector &closest_point, 00807 CubitVector *tangent_ptr, 00808 CubitVector *curvature_ptr, 00809 double *param ) 00810 { 00811 CubitStatus stat = CUBIT_SUCCESS; 00812 // int outside; 00813 int mydebug = 0; 00814 if (mydebug) 00815 { 00816 draw_location(this_point, CUBIT_RED_INDEX); 00817 } 00818 /* 00819 if (surfFacetEvalTool == NULL) 00820 { 00821 stat = project_to_linear_facet_edge( this_point, closest_point, 00822 tangent_ptr, curvature_ptr, 00823 param, &outside ); 00824 } 00825 else 00826 { 00827 stat = project_to_facet_edge( this_point, closest_point, 00828 tangent_ptr, curvature_ptr, param, &outside ); 00829 } 00830 */ 00831 int i; 00832 CubitVector test_pt_v, closest_pt_v, pt0_v, pt1_v; 00833 double distance2, closest_distance2; // distance squared 00834 CubitFacetEdge *edge, *best_edge = NULL; 00835 00836 myEdgeList.reset(); 00837 closest_distance2 = CUBIT_DBL_MAX; 00838 for ( i = myEdgeList.size(); i > 0; i-- ) { 00839 edge = myEdgeList.get_and_step(); 00840 pt0_v = edge->point(0)->coordinates(); 00841 pt1_v = edge->point(1)->coordinates(); 00842 test_pt_v = FacetDataUtil::squared_distance_to_segment(this_point, 00843 pt0_v,pt1_v,distance2); 00844 if ( distance2 < closest_distance2 ) { 00845 closest_distance2 = distance2; 00846 closest_pt_v = test_pt_v; 00847 best_edge = edge; 00848 if ( distance2 < GEOMETRY_RESABS*GEOMETRY_RESABS ) break; 00849 } 00850 } 00851 00852 00853 if (mydebug) 00854 { 00855 myEdgeList.reset(); 00856 for ( i = myEdgeList.size(); i > 0; i-- ) { 00857 edge = myEdgeList.get_and_step(); 00858 pt0_v = edge->point(0)->coordinates(); 00859 pt1_v = edge->point(1)->coordinates(); 00860 GfxDebug::draw_point(pt0_v, CUBIT_GREEN_INDEX ); 00861 GfxDebug::draw_point(pt1_v, CUBIT_RED_INDEX ); 00862 GfxDebug::flush(); 00863 } 00864 } 00865 00866 if ( interpOrder == 0 ) { 00867 closest_point = closest_pt_v; 00868 if (tangent_ptr) { 00869 CubitVector tangent; 00870 if (best_edge->edge_tangent( closest_point, tangent ) != CUBIT_SUCCESS) { 00871 return CUBIT_FAILURE; 00872 } 00873 if (curvSense == CUBIT_REVERSED) 00874 tangent = -tangent; 00875 *tangent_ptr = tangent; 00876 } 00877 // evaluate the curvature if required 00878 if (curvature_ptr) 00879 { 00880 if( myEdgeList.size() == 1 ) 00881 (*curvature_ptr).set( 0, 0, 0); 00882 else 00883 { 00884 CubitVector curvature; 00885 myEdgeList.move_to( best_edge ); 00886 int index = myEdgeList.get_index(); 00887 00888 //"best_edge" could be last or first on curve 00889 CubitFacetEdge* prev_edge = NULL; 00890 myEdgeList.back(); 00891 if( (index - 1) == myEdgeList.get_index() ) 00892 prev_edge = myEdgeList.get(); 00893 00894 CubitFacetEdge* next_edge = NULL; 00895 myEdgeList.step(2); 00896 if( (index + 1) == myEdgeList.get_index() ) 00897 next_edge = myEdgeList.get(); 00898 00899 00900 CubitFacetEdge *closest_edge; 00901 //determine which adjacent edge is closest to "best_point" 00902 if( prev_edge && next_edge ) 00903 { 00904 CubitVector tmp_vec; 00905 double prev_dist, next_dist; 00906 tmp_vec = (prev_edge->point(0)->coordinates() + 00907 prev_edge->point(1)->coordinates() ) / 2; 00908 prev_dist = closest_point.distance_between( tmp_vec ); 00909 00910 tmp_vec = (next_edge->point(0)->coordinates() + 00911 next_edge->point(1)->coordinates() ) / 2; 00912 next_dist = closest_point.distance_between( tmp_vec ); 00913 00914 if( prev_dist < next_dist ) 00915 closest_edge = prev_edge; 00916 else 00917 closest_edge = next_edge; 00918 } 00919 else if( prev_edge ) 00920 closest_edge = prev_edge; 00921 else 00922 closest_edge = next_edge; 00923 00924 if (best_edge->edge_curvature( closest_point, curvature, closest_edge ) != CUBIT_SUCCESS) { 00925 return CUBIT_FAILURE; 00926 } 00927 if (curvSense == CUBIT_REVERSED) 00928 curvature = -curvature; 00929 *curvature_ptr = curvature; 00930 } 00931 } 00932 } else if ( interpOrder == 4 ) { 00933 double t_value; 00934 double tangent[3]; 00935 stat = project_to_bezier_edge(best_edge,this_point, 00936 closest_point,tangent,&t_value); 00937 if(curvSense == CUBIT_REVERSED){ 00938 tangent[0]= -tangent[0]; 00939 tangent[1]= -tangent[1]; 00940 tangent[2]= -tangent[2]; 00941 } 00942 00943 if ( tangent_ptr ) { 00944 tangent_ptr->x(tangent[0]); 00945 tangent_ptr->y(tangent[1]); 00946 tangent_ptr->z(tangent[2]); 00947 } 00948 00949 if ( curvature_ptr ) { 00950 // The idea here is to get the planes normal to two points on the curve 00951 // on either side of the closest_point, and also to get the plane through 00952 // these three points. The point of intersection of these three planes 00953 // should be a good approximation of the center of curvature, from which 00954 // the curvature vector is readily found. 00955 // tan1 and tan2 are the normals to the two planes for the endpoints; 00956 // norm3 is the normal for the plane through the three points. 00957 CubitVector tan1, tan2, point_1, point_2; 00958 CubitVector *tan1_ptr = &tan1; 00959 CubitVector *tan2_ptr = &tan2; 00960 // CubitVector *point_1_ptr = &point_1; 00961 CubitVector *point_2_ptr = &point_2; 00962 t_value -= 0.01; 00963 best_edge->evaluate_single_tangent(t_value,tan1_ptr); 00964 t_value += 0.02; 00965 best_edge->evaluate_single(t_value,tan2_ptr); 00966 best_edge->evaluate_single_tangent(t_value,point_2_ptr); 00967 tan1.normalize(); 00968 tan2.normalize(); 00969 // Get the plane through the point and normal to the tangent for the two 00970 // points at the end. 00971 // Get the plane for the three points. 00972 CubitVector arm1 = point_1 - closest_point; 00973 CubitVector arm2 = point_2 - closest_point; 00974 CubitVector norm3 = arm1*arm2; 00975 norm3.normalize(); 00976 double denominator; 00977 00978 denominator = tan1 % ( tan2 * norm3 ); 00979 00980 if ( fabs(denominator) < GEOMETRY_RESABS ) { // planes are parallel; 00981 // curvature is infinite 00982 curvature_ptr->x(CUBIT_DBL_MAX); 00983 curvature_ptr->y(CUBIT_DBL_MAX); 00984 curvature_ptr->z(CUBIT_DBL_MAX); 00985 00986 } else { 00987 CubitVector IntersectionPoint; 00988 IntersectionPoint = ( (point_1%tan1)*(norm3*tan2) + 00989 (closest_point%norm3)*(tan2*tan1) + 00990 (point_2%tan2)*(tan1*norm3) )/denominator; 00991 00992 curvature_ptr->x(closest_point.x() - IntersectionPoint.x()); 00993 curvature_ptr->y(closest_point.y() - IntersectionPoint.y()); 00994 curvature_ptr->z(closest_point.z() - IntersectionPoint.z()); 00995 00996 } 00997 00998 } 00999 } else { 01000 PRINT_ERROR("Error: Only curves or order 0 or 4 are supported.\n"); 01001 return CUBIT_FAILURE; 01002 } 01003 01004 01005 01006 if (param) 01007 { 01008 *param = u_on_facet_edge( best_edge, closest_point ); 01009 } 01010 01011 if (mydebug) 01012 { 01013 draw_location(closest_point, CUBIT_GREEN_INDEX); 01014 } 01015 return stat; 01016 01017 } 01018 01019 //=========================================================================== 01020 //Function Name: project_to_bezier_edge 01021 // 01022 //Member Type: PRIVATE 01023 //Description: projects a point onto a Bezier edge 01024 //=========================================================================== 01025 CubitStatus CurveFacetEvalTool::project_to_bezier_edge(CubitFacetEdge *edge, 01026 CubitVector &point, CubitVector &projected_point, 01027 double *tangent, double *tval) 01028 { 01029 CubitStatus stat; 01030 int numEdge, numVert, edgeVert[2], numLocs; 01031 double vert[6], edgeCtrlPts[9], xyz[3], xyzOnEdge[3]; 01032 CubitVector *edge_ctrl_pts; 01033 01034 stat = CUBIT_SUCCESS; 01035 01036 numEdge = 1; 01037 numVert = 2; 01038 numLocs = 1; 01039 edgeVert[0] = 0; edgeVert[1] = 1; 01040 vert[0] = edge->point(0)->x(); 01041 vert[1] = edge->point(0)->y(); 01042 vert[2] = edge->point(0)->z(); 01043 vert[3] = edge->point(1)->x(); 01044 vert[4] = edge->point(1)->y(); 01045 vert[5] = edge->point(1)->z(); 01046 01047 edge_ctrl_pts = edge->control_points(); 01048 edgeCtrlPts[0] = edge_ctrl_pts[0].x(); 01049 edgeCtrlPts[1] = edge_ctrl_pts[0].y(); 01050 edgeCtrlPts[2] = edge_ctrl_pts[0].z(); 01051 edgeCtrlPts[3] = edge_ctrl_pts[1].x(); 01052 edgeCtrlPts[4] = edge_ctrl_pts[1].y(); 01053 edgeCtrlPts[5] = edge_ctrl_pts[1].z(); 01054 edgeCtrlPts[6] = edge_ctrl_pts[2].x(); 01055 edgeCtrlPts[7] = edge_ctrl_pts[2].y(); 01056 edgeCtrlPts[8] = edge_ctrl_pts[2].z(); 01057 xyz[0] = point.x(); 01058 xyz[1] = point.y(); 01059 xyz[2] = point.z(); 01060 projToBezierEdge( numEdge,numVert,edgeVert,vert,edgeCtrlPts, 01061 numLocs,xyz,xyzOnEdge,tangent,tval ); 01062 01063 projected_point.x(xyzOnEdge[0]); 01064 projected_point.y(xyzOnEdge[1]); 01065 projected_point.z(xyzOnEdge[2]); 01066 01067 return stat; 01068 } 01069 /* 01070 //=========================================================================== 01071 //Function Name: project_to_facet_edge 01072 // 01073 //Member Type: PRIVATE 01074 //Description: project the point to the facets defining this curve 01075 //=========================================================================== 01076 CubitStatus CurveFacetEvalTool::project_to_facet_edge(CubitVector &this_point, 01077 CubitVector &closest_point, 01078 CubitVector *tangent_ptr, 01079 CubitVector *curvature_ptr, 01080 double *param, 01081 int *outside ) 01082 { 01083 int trim = 0; 01084 int ncheck, ii, nincr=0; 01085 static int calls=0; 01086 static int nncheck=0; 01087 static int ntol=0; 01088 static int mydebug=0; 01089 CubitBoolean outside_facet, best_outside_facet; 01090 CubitVector boxmin, boxmax, p0, p1; 01091 CubitVector close_point, best_point, best_areacoord; 01092 CubitFacetEdge *best_edge, *edge; 01093 CubitFacet *best_facet, *facet; 01094 01095 double tol = surfFacetEvalTool->compare_tol(); 01096 double facet_tol = 1.0e-3 * surfFacetEvalTool->compare_tol(); 01097 double mindist = 0.0e0; 01098 CubitVector pt_on_edge; 01099 CubitBoolean done = CUBIT_FALSE; 01100 while(!done) { 01101 01102 // define a bounding box around the point 01103 01104 CubitVector ptmin( this_point.x() - tol, 01105 this_point.y() - tol, 01106 this_point.z() - tol ); 01107 01108 CubitVector ptmax( this_point.x() + tol, 01109 this_point.y() + tol, 01110 this_point.z() + tol ); 01111 01112 mindist = CUBIT_DBL_MAX; 01113 ncheck = 0; 01114 best_outside_facet = CUBIT_TRUE; 01115 myEdgeList.reset(); 01116 for ( ii = myEdgeList.size(); ii > 0 && !done; ii-- ) { 01117 edge = myEdgeList.get_and_step(); 01118 p0 = edge->point( 0 )->coordinates(); 01119 p1 = edge->point( 1 )->coordinates(); 01120 01121 // Try to trivially reject this facet with a bounding box test 01122 01123 boxmin.x( CUBIT_MIN( p0.x(), p1.x() ) ); 01124 boxmax.x( CUBIT_MAX( p0.x(), p1.x() ) ); 01125 if (ptmax.x() < boxmin.x() || 01126 ptmin.x() > boxmax.x()) { 01127 continue; 01128 } 01129 boxmin.y( CUBIT_MIN( p0.y(), p1.y() ) ); 01130 boxmax.y( CUBIT_MAX( p0.y(), p1.y() ) ); 01131 if (ptmax.y() < boxmin.y() || 01132 ptmin.y() > boxmax.y()) { 01133 continue; 01134 } 01135 boxmin.z( CUBIT_MIN( p0.z(), p1.z() ) ); 01136 boxmax.z( CUBIT_MAX( p0.z(), p1.z() ) ); 01137 if (ptmax.z() < boxmin.z() || 01138 ptmin.z() > boxmax.z()) { 01139 continue; 01140 } 01141 01142 // Only facets that pass the bounding box test will get past here! 01143 01144 // Project point to plane of the facet and determine its area coordinates 01145 01146 ncheck++; 01147 CubitVector pt_on_plane; 01148 double dist_to_plane; 01149 facet = edge->adj_facet( 0 ); 01150 if (!facet) { 01151 facet = edge->adj_facet( 1 ); 01152 } 01153 project_to_edge_line( edge, this_point, pt_on_plane, dist_to_plane ); 01154 CubitVector areacoord; 01155 pt_on_edge = pt_on_plane; 01156 surfFacetEvalTool->facet_area_coordinate( facet, pt_on_plane, areacoord ); 01157 01158 // If sign of areacoords are all positive then its inside the triangle 01159 // and we are done - go interpolate the point. (use an absolute 01160 // tolerance since the coordinates arenormalized) 01161 01162 if (areacoord.x() > -GEOMETRY_RESABS && 01163 areacoord.y() > -GEOMETRY_RESABS && 01164 areacoord.z() > -GEOMETRY_RESABS) { 01165 if (interpOrder == 0 && dist_to_plane < facet_tol) { 01166 outside_facet = CUBIT_FALSE; 01167 close_point = this_point; 01168 } 01169 else { 01170 if (surfFacetEvalTool->eval_facet( facet, this_point, areacoord, 01171 close_point, outside_facet ) 01172 != CUBIT_SUCCESS) { 01173 return CUBIT_FAILURE; 01174 } 01175 } 01176 } 01177 01178 // otherwise find the closest vertex or edge to the projected point 01179 01180 else if (areacoord.x() < GEOMETRY_RESABS) 01181 { 01182 outside_facet = CUBIT_TRUE; 01183 if (areacoord.y() < GEOMETRY_RESABS) 01184 { 01185 if (surfFacetEvalTool->eval_point( facet, 2, close_point ) 01186 != CUBIT_SUCCESS) { 01187 return CUBIT_FAILURE; 01188 } 01189 } 01190 else if(areacoord.z() < GEOMETRY_RESABS) 01191 { 01192 if (surfFacetEvalTool->eval_point( facet, 1, close_point ) 01193 != CUBIT_SUCCESS) { 01194 return CUBIT_FAILURE; 01195 } 01196 } 01197 else 01198 { 01199 if (surfFacetEvalTool->project_to_facetedge( facet, 1, 2, this_point, pt_on_plane, 01200 close_point, outside_facet ) !=CUBIT_SUCCESS) { 01201 return CUBIT_FAILURE; 01202 } 01203 } 01204 } 01205 else if (areacoord.y() < GEOMETRY_RESABS) 01206 { 01207 outside_facet = CUBIT_TRUE; 01208 if (areacoord.z() < GEOMETRY_RESABS) 01209 { 01210 if (surfFacetEvalTool->eval_point( facet, 0, close_point ) 01211 != CUBIT_SUCCESS) { 01212 return CUBIT_FAILURE; 01213 } 01214 } 01215 else 01216 { 01217 if (surfFacetEvalTool->project_to_facetedge( facet, 2, 0, this_point, pt_on_plane, 01218 close_point, outside_facet ) !=CUBIT_SUCCESS) { 01219 return CUBIT_FAILURE; 01220 } 01221 } 01222 } 01223 else 01224 { 01225 outside_facet = CUBIT_TRUE; 01226 if (surfFacetEvalTool->project_to_facetedge( facet, 0, 1, this_point, pt_on_plane, 01227 close_point, outside_facet ) !=CUBIT_SUCCESS) { 01228 return CUBIT_FAILURE; 01229 } 01230 } 01231 01232 // keep track of the minimum distance 01233 01234 double dist = sqrt(sqr(close_point.x() - this_point.x()) + 01235 sqr(close_point.y() - this_point.y()) + 01236 sqr(close_point.z() - this_point.z())); 01237 if (dist < mindist) { 01238 if ((best_outside_facet == CUBIT_FALSE && outside_facet == CUBIT_TRUE)) { 01239 //int x=1; 01240 } 01241 else { 01242 mindist = dist; 01243 best_point = close_point; 01244 best_edge = edge; 01245 best_facet = facet; 01246 best_areacoord = areacoord; 01247 best_outside_facet = outside_facet; 01248 01249 if (dist < facet_tol) { 01250 done = CUBIT_TRUE; 01251 } 01252 } 01253 } 01254 } 01255 01256 // We are done if we found at least one triangle. Otherwise 01257 // increase the tolerance and try again 01258 01259 nincr++; 01260 if (ncheck > 0) { 01261 if (best_outside_facet && nincr < 10) { 01262 tol *= 2.0; 01263 ntol++; 01264 } 01265 else { 01266 done = CUBIT_TRUE; 01267 } 01268 } 01269 else { 01270 tol *= 2.0e0; 01271 ntol++; 01272 } 01273 } 01274 01275 01276 //If area coords are still negative...we are still not on a "best_facet" 01277 //Find closest point to "best_edge" and use this point for area coordinates 01278 if (best_areacoord.x() <= -GEOMETRY_RESABS || 01279 best_areacoord.y() <= -GEOMETRY_RESABS || 01280 best_areacoord.z() <= -GEOMETRY_RESABS) 01281 { 01282 surfFacetEvalTool->facet_area_coordinate( best_facet, best_point, best_areacoord ); 01283 } 01284 01285 01286 // if the closest point is outside of a facet, then evaluate the point 01287 // on the facet using its area coordinates (otherwise it would be 01288 // trimmed to an edge or point) 01289 if ( !trim && best_outside_facet && interpOrder != 4) { 01290 if (surfFacetEvalTool->eval_facet( best_facet, this_point, best_areacoord, 01291 best_point, best_outside_facet ) 01292 != CUBIT_SUCCESS) { 01293 return CUBIT_FAILURE; 01294 } 01295 01296 // see if its really outside (it could just be on an edge where the 01297 // curvature is convex) 01298 01299 best_outside_facet = surfFacetEvalTool->is_outside( best_facet, best_areacoord ); 01300 } 01301 01302 // evaluate the tangent if required 01303 01304 CubitVector tangent_vec; 01305 if (tangent_ptr || curvature_ptr) { 01306 CubitVector facet_tangent = best_edge->point(1)->coordinates() - 01307 best_edge->point(0)->coordinates(); 01308 if (curvSense == CUBIT_REVERSED) 01309 facet_tangent = -facet_tangent; 01310 facet_tangent.normalize(); 01311 if (surfFacetEvalTool->interp_order() == 0) 01312 { 01313 tangent_vec = facet_tangent; 01314 } 01315 else 01316 { 01317 CubitVector normal; 01318 if (surfFacetEvalTool->eval_facet_normal( best_facet, best_areacoord, normal ) 01319 != CUBIT_SUCCESS) { 01320 return CUBIT_FAILURE; 01321 } 01322 tangent_vec = normal * (facet_tangent * normal); 01323 } 01324 } 01325 01326 if( tangent_ptr ) 01327 *tangent_ptr = tangent_vec; 01328 01329 if (curvature_ptr) { 01330 //get adjacent facet edges to "best_edge" 01331 myEdgeList.move_to( best_edge ); 01332 int index = myEdgeList.get_index(); 01333 01334 //"best_edge" could be last or first on curve 01335 CubitFacetEdge* prev_edge = NULL; 01336 myEdgeList.back(); 01337 if( (index - 1) == myEdgeList.get_index() ) 01338 prev_edge = myEdgeList.get(); 01339 01340 CubitFacetEdge* next_edge = NULL; 01341 myEdgeList.step(2); 01342 if( (index + 1) == myEdgeList.get_index() ) 01343 next_edge = myEdgeList.get(); 01344 01345 //now get 1 facet on each adj. edge 01346 CubitFacet *prev_facet = NULL; 01347 if( prev_edge ) 01348 { 01349 prev_facet = prev_edge->adj_facet( 0 ); 01350 if (!prev_facet) 01351 prev_facet = prev_edge->adj_facet( 1 ); 01352 } 01353 01354 CubitFacet *next_facet = NULL; 01355 if( next_edge ) 01356 { 01357 next_facet = next_edge->adj_facet( 0 ); 01358 if (!next_facet) 01359 next_facet = next_edge->adj_facet( 1 ); 01360 } 01361 01362 //get tangent at midpoint of prev_edge 01363 CubitVector prev_tangent_vec; 01364 if( prev_edge ) 01365 { 01366 CubitVector facet_tangent = prev_edge->point(1)->coordinates() - 01367 prev_edge->point(0)->coordinates(); 01368 if (curvSense == CUBIT_REVERSED) 01369 facet_tangent = -facet_tangent; 01370 facet_tangent.normalize(); 01371 01372 if (surfFacetEvalTool->interp_order() == 0) 01373 prev_tangent_vec = facet_tangent; 01374 else 01375 { 01376 CubitVector prev_mid_point; 01377 prev_mid_point = (prev_edge->point(0)->coordinates() + 01378 prev_edge->point(1)->coordinates() ) / 2; 01379 01380 CubitVector areacoord; 01381 surfFacetEvalTool->facet_area_coordinate( prev_facet, prev_mid_point, areacoord ); 01382 CubitVector normal; 01383 if (surfFacetEvalTool->eval_facet_normal( prev_facet, areacoord, normal ) 01384 != CUBIT_SUCCESS) 01385 { 01386 return CUBIT_FAILURE; 01387 } 01388 prev_tangent_vec = normal * (facet_tangent * normal); 01389 } 01390 } 01391 01392 //get tangent at midpoint of next_edge 01393 CubitVector next_tangent_vec; 01394 if( next_edge ) 01395 { 01396 CubitVector facet_tangent = next_edge->point(1)->coordinates() - 01397 next_edge->point(0)->coordinates(); 01398 if (curvSense == CUBIT_REVERSED) 01399 facet_tangent = -facet_tangent; 01400 facet_tangent.normalize(); 01401 01402 if (surfFacetEvalTool->interp_order() == 0) 01403 next_tangent_vec = facet_tangent; 01404 else 01405 { 01406 CubitVector next_mid_point; 01407 next_mid_point = (next_edge->point(0)->coordinates() + 01408 next_edge->point(1)->coordinates() ) / 2; 01409 01410 CubitVector areacoord; 01411 surfFacetEvalTool->facet_area_coordinate( next_facet, next_mid_point, areacoord ); 01412 CubitVector normal; 01413 if (surfFacetEvalTool->eval_facet_normal( next_facet, areacoord, normal ) 01414 != CUBIT_SUCCESS) 01415 { 01416 return CUBIT_FAILURE; 01417 } 01418 next_tangent_vec = normal * (facet_tangent * normal); 01419 } 01420 } 01421 01422 //decide how to weight the tangents 01423 double prev_weight, next_weight; 01424 if( !prev_edge ) 01425 { 01426 prev_weight = 0; 01427 next_weight = 2; 01428 } 01429 else if( !next_edge ) 01430 { 01431 prev_weight = 2; 01432 next_weight = 0; 01433 } 01434 else 01435 { 01436 double dist1 = best_edge->point(0)->coordinates().distance_between( 01437 best_edge->point(1)->coordinates() ); 01438 double dist2 = best_edge->point(0)->coordinates().distance_between( 01439 best_point); 01440 next_weight = dist2/dist1; 01441 next_weight *= 2; 01442 prev_weight = 2-next_weight; 01443 } 01444 01445 *curvature_ptr = (prev_weight*( tangent_vec - prev_tangent_vec ) + 01446 next_weight*( next_tangent_vec - tangent_vec ) ); 01447 } 01448 01449 closest_point = best_point; 01450 01451 *outside = best_outside_facet; 01452 01453 if (mydebug) { 01454 nncheck+= ncheck; 01455 calls++; 01456 if (calls%100==0){ 01457 char message[100]; 01458 sprintf(message,"calls = %d, ckecks = %d, ntol = %d\n",calls,nncheck,ntol); 01459 PRINT_INFO(message); 01460 } 01461 } 01462 01463 // determine the parameter on the curve 01464 01465 if (param) 01466 { 01467 *param = u_on_facet_edge( best_edge, closest_point ); 01468 } 01469 01470 return CUBIT_SUCCESS; 01471 } 01472 01473 //=========================================================================== 01474 //Function Name: project_to_edge_line 01475 // 01476 //Member Type: PRIVATE 01477 //Description: compute the area coordinate on the linear facet edge 01478 //=========================================================================== 01479 CubitStatus CurveFacetEvalTool::project_to_edge_line( CubitFacetEdge *edge, 01480 CubitVector &this_point, 01481 CubitVector &pt_on_edge, 01482 double &dist_to_edge ) 01483 { 01484 CubitVector p0 = edge->point(0)->coordinates(); 01485 CubitVector p1 = edge->point(1)->coordinates(); 01486 CubitVector v0 = p1 - p0; 01487 CubitVector v1 = this_point - p0; 01488 double h = v1.normalize(); 01489 v0.normalize(); 01490 double costheta = v0 % v1; 01491 double l = h * costheta; 01492 dist_to_edge = sqrt( fabs((h*h) - (l*l)) ); 01493 pt_on_edge = p0 + l*v0; 01494 01495 return CUBIT_SUCCESS; 01496 } 01497 01498 //=========================================================================== 01499 //Function Name: project_to_linear_facet_edge 01500 // 01501 //Member Type: PRIVATE 01502 //Description: project the point to the facets defining this curve. 01503 // Note: this function assumes a piecewise linear representation 01504 // of the curve. Does not rely on an adjacent surface 01505 // eval tool to project the point 01506 //=========================================================================== 01507 CubitStatus CurveFacetEvalTool::project_to_linear_facet_edge(CubitVector &this_point, 01508 CubitVector &closest_point, 01509 CubitVector *tangent_ptr, 01510 CubitVector *curvature_ptr, 01511 double *param, 01512 int *outside ) 01513 { 01514 int trim = 0; 01515 int ncheck, ii, nincr=0; 01516 static int ntol=0; 01517 CubitBoolean outside_facet, best_outside_facet; 01518 CubitVector boxmin, boxmax, p0, p1; 01519 CubitVector close_point, best_point; 01520 CubitFacetEdge *best_edge, *edge; 01521 01522 // so we don't evaluate an edge more than once - mark the edges 01523 // as we evaluate them. Put the evaluated edges on a used_edge_list 01524 // so we clear the marks off when we are done. Note: this assumes 01525 // theat marks are initially cleared. 01526 01527 DLIList<CubitFacetEdge *>used_edge_list; 01528 for(ii=0; ii<myEdgeList.size(); ii++) 01529 myEdgeList.get_and_step()->set_flag(0); 01530 CubitBoolean eval_all = CUBIT_FALSE; 01531 01532 double tol = facetLength * 1.0e-3; 01533 double facet_tol = facetLength * GEOMETRY_RESABS; 01534 double mindist = CUBIT_DBL_MAX; 01535 double dist = 0.0e0; 01536 CubitBoolean done = CUBIT_FALSE; 01537 while(!done) { 01538 01539 // define a bounding box around the point 01540 01541 CubitVector ptmin( this_point.x() - tol, 01542 this_point.y() - tol, 01543 this_point.z() - tol ); 01544 01545 CubitVector ptmax( this_point.x() + tol, 01546 this_point.y() + tol, 01547 this_point.z() + tol ); 01548 01549 ncheck = 0; 01550 best_outside_facet = CUBIT_TRUE; 01551 myEdgeList.reset(); 01552 for ( ii = myEdgeList.size(); ii > 0 && !done; ii-- ) 01553 { 01554 edge = myEdgeList.get_and_step(); 01555 01556 // if( (edge->get_flag() == 1) ) 01557 // continue; 01558 01559 p0 = edge->point( 0 )->coordinates(); 01560 p1 = edge->point( 1 )->coordinates(); 01561 01562 // Try to trivially reject this facet with a bounding box test 01563 01564 if (!eval_all) 01565 { 01566 boxmin.x( CUBIT_MIN( p0.x(), p1.x() ) ); 01567 boxmax.x( CUBIT_MAX( p0.x(), p1.x() ) ); 01568 if (ptmax.x() < boxmin.x() || 01569 ptmin.x() > boxmax.x()) { 01570 continue; 01571 } 01572 boxmin.y( CUBIT_MIN( p0.y(), p1.y() ) ); 01573 boxmax.y( CUBIT_MAX( p0.y(), p1.y() ) ); 01574 if (ptmax.y() < boxmin.y() || 01575 ptmin.y() > boxmax.y()) { 01576 continue; 01577 } 01578 boxmax.z( CUBIT_MAX( p0.z(), p1.z() ) ); 01579 if (ptmax.z() < boxmin.z() || 01580 ptmin.z() > boxmax.z()) { 01581 continue; 01582 } 01583 } 01584 01585 // Only edges that pass the bounding box test will get past here! 01586 01587 // find distance to this edge 01588 dist = edge->dist_to_edge( this_point, close_point, outside_facet ); 01589 01590 if (dist <= mindist) { 01591 if ((best_outside_facet == CUBIT_FALSE && outside_facet == CUBIT_TRUE)) { 01592 //int x=1; 01593 } 01594 else { 01595 mindist = dist; 01596 best_point = close_point; 01597 best_edge = edge; 01598 best_outside_facet = outside_facet; 01599 01600 if (dist < facet_tol) { 01601 done = CUBIT_TRUE; 01602 } 01603 } 01604 } 01605 ncheck++; 01606 // edge->set_flag(1); 01607 // used_edge_list.append(edge); 01608 } 01609 01610 // We are done if we found at least one edge. Otherwise 01611 // increase the tolerance and try again 01612 01613 nincr++; 01614 if (ncheck > 0) { 01615 done = CUBIT_TRUE; 01616 if (best_outside_facet && nincr < 10) { 01617 done = CUBIT_FALSE; 01618 } 01619 } 01620 01621 if (!done) 01622 { 01623 if (nincr < 10) 01624 { 01625 tol *= 2.0e0; 01626 ntol++; 01627 } 01628 else { 01629 eval_all = CUBIT_TRUE; 01630 } 01631 } 01632 } 01633 01634 assert(best_edge != NULL); 01635 01636 // if the closest point is outside of a facet, then evaluate the point 01637 // on the facet using its area coordinates (otherwise it would be 01638 // trimmed to an edge or point) 01639 01640 01641 if ( !trim && best_outside_facet) { 01642 // if (best_edge->proj_to_line( this_point, best_point )!= CUBIT_SUCCESS) { 01643 if (best_edge->closest_point( this_point, best_point )!= CUBIT_SUCCESS) { 01644 return CUBIT_FAILURE; 01645 } 01646 } 01647 01648 01649 // evaluate the tangent if required 01650 01651 if (tangent_ptr) { 01652 //get 2 adjacent edges 01653 CubitVector tangent; 01654 if (best_edge->edge_tangent( best_point, tangent ) 01655 != CUBIT_SUCCESS) { 01656 return CUBIT_FAILURE; 01657 } 01658 if (curvSense == CUBIT_REVERSED) 01659 tangent = -tangent; 01660 *tangent_ptr = tangent; 01661 } 01662 01663 // evaluate the curvature if required 01664 if (curvature_ptr) { 01665 CubitVector curvature; 01666 myEdgeList.move_to( best_edge ); 01667 int index = myEdgeList.get_index(); 01668 01669 //"best_edge" could be last or first on curve 01670 CubitFacetEdge* prev_edge = NULL; 01671 myEdgeList.back(); 01672 if( (index - 1) == myEdgeList.get_index() ) 01673 prev_edge = myEdgeList.get(); 01674 01675 CubitFacetEdge* next_edge = NULL; 01676 myEdgeList.step(2); 01677 if( (index + 1) == myEdgeList.get_index() ) 01678 next_edge = myEdgeList.get(); 01679 01680 01681 CubitFacetEdge *closest_edge; 01682 //determine which adjacent edge is closest to "best_point" 01683 if( prev_edge && next_edge ) 01684 { 01685 CubitVector tmp_vec; 01686 double prev_dist, next_dist; 01687 tmp_vec = (prev_edge->point(0)->coordinates() + 01688 prev_edge->point(1)->coordinates() ) / 2; 01689 prev_dist = best_point.distance_between( tmp_vec ); 01690 01691 tmp_vec = (next_edge->point(0)->coordinates() + 01692 next_edge->point(1)->coordinates() ) / 2; 01693 next_dist = best_point.distance_between( tmp_vec ); 01694 01695 if( prev_dist < next_dist ) 01696 closest_edge = prev_edge; 01697 else 01698 closest_edge = next_edge; 01699 } 01700 else if( prev_edge ) 01701 closest_edge = prev_edge; 01702 else 01703 closest_edge = next_edge; 01704 01705 if (best_edge->edge_curvature( best_point, curvature, closest_edge ) != CUBIT_SUCCESS) { 01706 return CUBIT_FAILURE; 01707 } 01708 if (curvSense == CUBIT_REVERSED) 01709 curvature = -curvature; 01710 *curvature_ptr = curvature; 01711 } 01712 01713 closest_point = best_point; 01714 *outside = best_outside_facet; 01715 01716 if (param) 01717 { 01718 *param = u_on_facet_edge( best_edge, closest_point ); 01719 } 01720 01721 // clear the marks from the used edges 01722 01723 for (ii=0; ii<used_edge_list.size(); ii++) 01724 { 01725 edge = used_edge_list.get_and_step(); 01726 edge->set_flag( 0 ); 01727 } 01728 01729 01730 return CUBIT_SUCCESS; 01731 } 01732 01733 */ 01734 //=========================================================================== 01735 //Function Name: u_on_facet_edge 01736 // 01737 //Member Type: PRIVATE 01738 //Description: return the u param on the facet curve given a point on the 01739 // curve and the facet edge it is on 01740 //=========================================================================== 01741 double CurveFacetEvalTool::u_on_facet_edge( CubitFacetEdge *edge_at_pt, 01742 CubitVector pt ) 01743 { 01744 int ii; 01745 double cum_len = 0.0; 01746 CubitBoolean done = CUBIT_FALSE; 01747 myEdgeList.reset(); 01748 for (ii=0; ii<myEdgeList.size() && !done; ii++) { 01749 CubitFacetEdge *edge = myEdgeList.get_and_step(); 01750 if (edge != edge_at_pt) 01751 { 01752 cum_len += edge->length(); 01753 } 01754 else 01755 { 01756 CubitVector pt0; 01757 if (curvSense == CUBIT_REVERSED) 01758 { 01759 pt0 = edge->point( 1 )->coordinates(); 01760 } 01761 else 01762 { 01763 pt0 = edge->point( 0 )->coordinates(); 01764 } 01765 cum_len += pt.distance_between( pt0 ); 01766 done = CUBIT_TRUE; 01767 } 01768 } 01769 if (!done) 01770 { 01771 PRINT_DEBUG_122( "Error in CurveFacetEvalTool::u_on_facet_edge" ); 01772 } 01773 double u = cum_len / facetLength; 01774 return u; 01775 } 01776 01777 //=========================================================================== 01778 //Function Name: destroy_facets 01779 // 01780 //Member Type: PRIVATE 01781 //Description: Deletes the points and facets. 01782 //=========================================================================== 01783 void CurveFacetEvalTool::destroy_facets() 01784 { 01785 01786 } 01787 01788 01789 //=========================================================================== 01790 //Function Name: draw_edges 01791 // 01792 //Member Type: PRIVATE 01793 //Description: draw the facet edges 01794 //=========================================================================== 01795 void CurveFacetEvalTool::draw_edges(int color) 01796 { 01797 int ii; 01798 if ( color == -1 ) 01799 color = CUBIT_BLUE_INDEX; 01800 for ( ii = myEdgeList.size(); ii > 0; ii-- ) 01801 { 01802 CubitFacetEdge *edge = myEdgeList.get_and_step(); 01803 CubitPoint *begin_point = edge->point(0); 01804 CubitPoint *end_point = edge->point(1); 01805 GfxDebug::draw_line(begin_point->x(), 01806 begin_point->y(), 01807 begin_point->z(), 01808 end_point->x(), 01809 end_point->y(), 01810 end_point->z(), 01811 color); 01812 } 01813 GfxDebug::flush(); 01814 } 01815 01816 //=========================================================================== 01817 //Function Name: draw_edge 01818 // 01819 //Member Type: PRIVATE 01820 //Description: draw the facet edge 01821 //=========================================================================== 01822 void CurveFacetEvalTool::draw_edge(CubitFacetEdge *edge, int color) 01823 { 01824 01825 CubitPoint *begin_point = edge->point(0); 01826 CubitPoint *end_point = edge->point(1); 01827 GfxDebug::draw_line(begin_point->x(), 01828 begin_point->y(), 01829 begin_point->z(), 01830 end_point->x(), 01831 end_point->y(), 01832 end_point->z(), 01833 color); 01834 01835 GfxDebug::flush(); 01836 } 01837 01838 //=========================================================================== 01839 //Function Name: draw_line 01840 // 01841 //Member Type: PRIVATE 01842 //=========================================================================== 01843 void CurveFacetEvalTool::draw_line(CubitVector &begin, CubitVector &end, int color) 01844 { 01845 GfxDebug::draw_line(begin.x(), begin.y(), begin.z(), 01846 end.x(), end.y(), end.z(), color); 01847 GfxDebug::flush(); 01848 } 01849 01850 //=========================================================================== 01851 //Function Name: draw_location 01852 // 01853 //Member Type: PRIVATE 01854 //=========================================================================== 01855 void CurveFacetEvalTool::draw_location(CubitVector &loc, int color ) 01856 { 01857 if ( color == -1 ) 01858 color = CUBIT_YELLOW_INDEX; 01859 GfxDebug::draw_point(loc, color); 01860 GfxDebug::flush(); 01861 } 01862 01863 //=========================================================================== 01864 //Function Name: set_length 01865 // 01866 //Member Type: PRIVATE 01867 //Description: compute the length of the facets in this curve 01868 // assumption: facet edges have been set up 01869 //=========================================================================== 01870 void CurveFacetEvalTool::set_length() 01871 { 01872 int ii; 01873 CubitFacetEdge *cf_edge; 01874 01875 facetLength = 0.0e0; 01876 01877 for (ii=0; ii<myEdgeList.size(); ii++) 01878 { 01879 cf_edge = myEdgeList.get_and_step(); 01880 facetLength += cf_edge->length(); 01881 } 01882 01883 } 01884 01885 //=========================================================================== 01886 //Function Name: save 01887 // 01888 //Member Type: PUBLIC 01889 //Description: save the curve facet eval tool to a cubit file 01890 // Assumption: contained edge facets have been previuosly saved. This function 01891 // saves only the edge facet ids. 01892 //=========================================================================== 01893 CubitStatus CurveFacetEvalTool::save( 01894 FILE *fp ) 01895 { 01896 NCubitFile::CIOWrapper cio(fp); 01897 typedef NCubitFile::UnsignedInt32 int32; 01898 01899 // write out "interpOrder" 01900 cio.Write(reinterpret_cast<int32*>(&interpOrder), 1); 01901 01902 // write the associated facet eval tool id. If there is none then write -1 01903 int surf_tool_id = -1; 01904 if (surfFacetEvalTool != NULL) 01905 surf_tool_id = surfFacetEvalTool->get_output_id(); 01906 cio.Write(reinterpret_cast<int32*>(&surf_tool_id), 1); 01907 01908 // convert "curvSense" in an int 01909 int sense; 01910 if( curvSense == CUBIT_UNKNOWN ) 01911 sense = -1; 01912 else 01913 sense = (curvSense == CUBIT_REVERSED) ? 1 : 0; 01914 01915 // write "curveSense" and "goodCurveData" 01916 cio.Write(reinterpret_cast<int32*>(&sense), 1); 01917 int32 is_good = goodCurveData ? 1 : 0; 01918 cio.Write(&is_good, 1); 01919 01920 // write "facetLength" 01921 cio.Write( &facetLength, 1 ); 01922 01923 // write ids of facet edges in "myEdgeList" 01924 int ii; 01925 CubitFacetEdge *edge_ptr; 01926 int nedges = myEdgeList.size(); 01927 int32* edge_id = new int32 [nedges]; 01928 myEdgeList.reset(); 01929 for (ii=0; ii<nedges; ii++) 01930 { 01931 edge_ptr = myEdgeList.get_and_step(); 01932 edge_id[ii] = edge_ptr->id(); 01933 } 01934 cio.Write(reinterpret_cast<int32*>(&nedges), 1); 01935 if (nedges > 0) 01936 { 01937 cio.Write(edge_id, nedges); 01938 } 01939 delete [] edge_id; 01940 01941 // write ids of points in "myPointList" 01942 CubitPoint *point_ptr; 01943 int npoints = myPointList.size(); 01944 int32* point_id = new int32 [npoints]; 01945 myPointList.reset(); 01946 for (ii=0; ii<npoints; ii++) 01947 { 01948 point_ptr = myPointList.get_and_step(); 01949 point_id[ii] = point_ptr->id(); 01950 } 01951 cio.Write(reinterpret_cast<int32*>(&npoints), 1); 01952 if (npoints > 0) 01953 { 01954 cio.Write(point_id, npoints); 01955 } 01956 delete [] point_id; 01957 01958 return CUBIT_SUCCESS; 01959 } 01960 01961 //=========================================================================== 01962 //Function Name: restore 01963 //Member Type: PUBLIC 01964 //Description: restore curve eval tool from a CUB file 01965 //author: sjowen 01966 //Date:1/28/2003 01967 //=========================================================================== 01968 CubitStatus CurveFacetEvalTool::restore(FILE *fp, 01969 unsigned int endian, 01970 int num_edges, 01971 int num_points, 01972 CubitFacetEdge **edges, 01973 CubitPoint **points, 01974 int num_fets, 01975 FacetEvalTool **fet_array) 01976 { 01977 NCubitFile::CIOWrapper cio(endian, fp); 01978 typedef NCubitFile::UnsignedInt32 int32; 01979 01980 // read stuff about this eval tool 01981 01982 int ii; 01983 int int_data[4]; 01984 cio.Read(reinterpret_cast<int32*>(int_data), 4); 01985 interpOrder = int_data[0]; 01986 int surf_tool_id = int_data[1]; 01987 01988 if (int_data[2] == -1 ) 01989 curvSense = CUBIT_UNKNOWN; 01990 else 01991 curvSense= int_data[2] ? CUBIT_REVERSED : CUBIT_FORWARD; 01992 01993 goodCurveData = (int_data[3]==0) ? CUBIT_FALSE : CUBIT_TRUE; 01994 01995 if( surf_tool_id != -1 ) 01996 surfFacetEvalTool = fet_array[ surf_tool_id ]; 01997 else 01998 surfFacetEvalTool = NULL; 01999 02000 cio.Read(&facetLength, 1); 02001 02002 // read the edges 02003 02004 int nedges; 02005 cio.Read(reinterpret_cast<int32*>(&nedges), 1); 02006 if (nedges > 0) 02007 { 02008 int32* edge_id = new int32 [nedges]; 02009 cio.Read(edge_id, nedges); 02010 int id; 02011 for (ii=0; ii<nedges; ii++) 02012 { 02013 id = edge_id[ii]; 02014 if (id <0 || id >= num_edges) 02015 { 02016 delete [] edge_id; 02017 return CUBIT_FAILURE; 02018 } 02019 myEdgeList.append(edges[id]); 02020 } 02021 delete [] edge_id; 02022 } 02023 02024 // read the points 02025 02026 int npoints; 02027 cio.Read(reinterpret_cast<int32*>(&npoints), 1); 02028 int id; 02029 if (npoints > 0) 02030 { 02031 int32* point_id = new int32 [npoints]; 02032 cio.Read(point_id, npoints); 02033 for (ii=0; ii<npoints; ii++) 02034 { 02035 id = point_id[ii]; 02036 if (id <0 || id >= num_points) 02037 { 02038 delete [] point_id; 02039 return CUBIT_FAILURE; 02040 } 02041 myPointList.append(points[id]); 02042 } 02043 delete [] point_id; 02044 } 02045 02046 bounding_box(); 02047 02048 return CUBIT_SUCCESS; 02049 } 02050 02051 CubitStatus CurveFacetEvalTool::fix_point_edge_order() 02052 { 02053 CubitFacetEdge* this_edge; 02054 CubitFacetEdge* next_edge; 02055 CubitPoint *this_pt1; 02056 CubitPoint *next_pt0, *next_pt1; 02057 02058 if( myEdgeList.size() == 0 ) 02059 return CUBIT_FAILURE; 02060 02061 this_edge = myEdgeList.get_and_step(); 02062 int ii; 02063 for( ii = myEdgeList.size() - 1; ii > 0; ii-- ) 02064 { 02065 if( 0 != this_edge->num_adj_facets() ) 02066 continue; 02067 02068 next_edge = myEdgeList.get_and_step(); 02069 02070 this_pt1 = this_edge->point( 1 ); 02071 next_pt0 = next_edge->point( 0 ); 02072 next_pt1 = next_edge->point( 1 ); 02073 02074 if( this_pt1 != next_pt0 && 02075 this_pt1 != next_pt1 ) 02076 { 02077 //Swap direction of edge. (mod. 3-7-06) Now calling flip instead 02078 // of doing the flip manually. The flip function also tracks 02079 // the orientation so that we can remember the original orientation 02080 // of the edge. 02081 this_edge->flip(); 02082 02083 } 02084 02085 this_edge = next_edge; 02086 } 02087 //Handle last edge 02088 next_edge = myEdgeList.prev(2); 02089 if( 0 == this_edge->num_adj_facets() ) 02090 { 02091 CubitPoint* this_pt0 = this_edge->point( 0 ); 02092 next_pt0 = next_edge->point( 0 ); 02093 next_pt1 = next_edge->point( 1 ); 02094 02095 if( this_pt0 != next_pt0 && 02096 this_pt0 != next_pt1 ) 02097 { 02098 //Swap direction of edge.(mod. 3-7-06) Now calling flip instead 02099 // of doing the flip manually. The flip function also tracks 02100 // the orientation so that we can remember the original orientation 02101 // of the edge. 02102 this_edge->flip(); 02103 02104 } 02105 } 02106 02107 return CUBIT_SUCCESS; 02108 } 02109 //=========================================================================== 02110 //Function Name: debug_draw_facet_edges 02111 // 02112 //Member Type: PUBLIC 02113 //Descriptoin: draw the facet edges for debug 02114 //=========================================================================== 02115 void CurveFacetEvalTool::debug_draw_facet_edges( int color ) 02116 { 02117 draw_edges(color); 02118 } 02119 02120 CubitBoolean CurveFacetEvalTool::replace_point( CubitPoint *del_pnt, CubitPoint *keep_pnt ) 02121 { 02122 CubitPoint *point_ptr; 02123 int npoints = myPointList.size(); 02124 myPointList.reset(); 02125 CubitBoolean istat = CUBIT_FALSE; 02126 int i; 02127 for ( i = 0; i < npoints; i++ ) 02128 { 02129 point_ptr = myPointList.get(); 02130 02131 if( point_ptr == del_pnt ) 02132 { 02133 myPointList.remove(); 02134 myPointList.insert( keep_pnt ); 02135 istat = CUBIT_TRUE; 02136 } 02137 myPointList.step(); 02138 } 02139 02140 return istat; 02141 } 02142 02143 02144 CubitBoolean CurveFacetEvalTool::replace_facets( DLIList< CubitFacetEdge *> &curv_edges ) 02145 { 02146 02147 // replace edges 02148 this->myEdgeList = curv_edges; 02149 02150 // replace points 02151 DLIList<CubitPoint *> point_list; 02152 int i; 02153 // insert start point of every facet_edge 02154 curv_edges.reset(); 02155 for( i = 0; i < curv_edges.size(); i++ ) 02156 { 02157 point_list.append( CAST_TO( curv_edges.get_and_step(), CubitFacetEdge )->point(0) ); 02158 } 02159 // insert end point of last facet_edge 02160 curv_edges.step( curv_edges.size() - 1 ); 02161 point_list.append( CAST_TO( curv_edges.get(), CubitFacetEdge )->point(1) ); 02162 this->myPointList = point_list; 02163 02164 return CUBIT_TRUE; 02165 } 02166 02167 02168 void CurveFacetEvalTool::remove_facets( DLIList<CubitFacetEdge*> &facet_edges) 02169 { 02170 facet_edges = myEdgeList; 02171 myEdgeList.clean_out(); 02172 myPointList.clean_out(); 02173 }