cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : RefFace.cpp 00003 // 00004 // Purpose : This file contains the implementation of the class 00005 // RefFace. 00006 // 00007 // Special Notes : 00008 // 00009 // Creator : 00010 // 00011 // Creation Date : 00012 // 00013 // Owner : 00014 //------------------------------------------------------------------------- 00015 00016 #include <stdio.h> 00017 #include <math.h> 00018 #include "CubitDefines.h" 00019 #include "CubitVector.hpp" 00020 00021 #include "Body.hpp" 00022 #include "RefVolume.hpp" 00023 #include "RefFace.hpp" 00024 #include "RefEdge.hpp" 00025 #include "RefVertex.hpp" 00026 00027 #include "CubitObserver.hpp" 00028 #include "RefEntityFactory.hpp" 00029 #include "GeometryQueryTool.hpp" 00030 #include "GfxDebug.hpp" 00031 #include "GeometryDefines.h" 00032 #include "Loop.hpp" 00033 00034 #include "CoFace.hpp" 00035 #include "CoEdge.hpp" 00036 00037 #include "Surface.hpp" 00038 00039 // lists 00040 #include "DLIList.hpp" 00041 00042 #include "CastTo.hpp" 00043 #include "CubitString.hpp" 00044 #include "CubitUtil.hpp" 00045 //for measuring/cacheing the area of the surface. 00046 #include "GeomMeasureTool.hpp" 00047 00048 #include "GeometryUtil.hpp" 00049 #include "ModelQueryEngine.hpp" 00050 00051 //static RefEdge* find_edge_to_adjust(DLIList<RefEdge*>& ref_edge_list); 00052 00053 //------------------------------------------------------------------------- 00054 // Purpose : Constructor with a pointer to a Surface 00055 // 00056 // Special Notes : 00057 // 00058 // Creator : Xuechen Liu 00059 // 00060 // Creation Date : 07/11/96 00061 //------------------------------------------------------------------------- 00062 RefFace::RefFace(Surface* surfacePtr) 00063 { 00064 // Set the GeometryEntity pointer if (surfacePtr != NULL) 00065 if (surfacePtr != NULL) 00066 { 00067 set_geometry_entity_ptr(surfacePtr) ; 00068 } 00069 else 00070 { 00071 PRINT_ERROR("In the RefFace(Surface*) constructor\n" 00072 " Input Surface pointer is NULL\n"); 00073 assert(CUBIT_FALSE); 00074 } 00075 00076 // Initialize the member data 00077 initialize(); 00078 } 00079 00080 //------------------------------------------------------------------------- 00081 // Purpose : The destructor. 00082 // 00083 // Special Notes : Note that the GeometryEntity associated with this 00084 // RefEntity is deleted in the destructor of the 00085 // BasicTopologyEntity class. 00086 // 00087 // Creator : Malcolm J. Panthaki 00088 // 00089 // Creation Date : 10/22/96 00090 //------------------------------------------------------------------------- 00091 RefFace::~RefFace() 00092 { 00093 // Delete the hardpoints associated with this RefFace 00094 00095 00096 // // Delete the contents of the SurfVertexList 00097 // for ( i = surfVertexList.size(); i > 0; i --) 00098 // { 00099 // delete surfVertexList.get_and_step(); 00100 // } 00101 00102 // Delete the contents of the HardPointList (these are RefVertices). 00103 // Calling the remove() function ensures that the DAG cleaned out 00104 // appropriately. 00105 int i; 00106 for ( i = hardPointList.size(); i > 0; i --) 00107 { 00108 hardPointList.get_and_step()->remove_from_DAG(); 00109 } 00110 00111 remove_from_observers(); 00112 } 00113 00114 00115 static void dist_between(RefEdge* edge1, RefEdge* edge2, CubitVector& v1, CubitVector& v2, double& dist) 00116 { 00117 // check compatibility first 00118 DLIList<TopologyEntity*> entity_list(2); 00119 DLIList<TopologyBridge*> bridge_list(2); 00120 entity_list.append(edge1); 00121 entity_list.append(edge2); 00122 GeometryQueryEngine* gqe = GeometryQueryTool::instance()->common_query_engine( entity_list, bridge_list ); 00123 if(gqe) 00124 GeometryQueryTool::instance()->entity_entity_distance(edge1, edge2, v1, v2, dist); 00125 else 00126 { 00127 BasicTopologyEntity* bte1 = dynamic_cast<BasicTopologyEntity*>(edge1); 00128 BasicTopologyEntity* bte2 = dynamic_cast<BasicTopologyEntity*>(edge2); 00129 if(bte1 && bte2) 00130 { 00131 GeometryEntity *ge1 = dynamic_cast<GeometryEntity*>(bte1->bridge_manager()->topology_bridge()); 00132 GeometryEntity *ge2 = dynamic_cast<GeometryEntity*>(bte2->bridge_manager()->topology_bridge()); 00133 GeometryQueryTool::instance()->entity_entity_distance(ge1, ge2, v1, v2, dist); 00134 } 00135 } 00136 } 00137 00138 double RefFace::get_crack_length() 00139 { 00140 // find two loops to check the shortest distance between as that's where Cubit is most 00141 // likely to crack surfaces 00142 00143 DLIList<Loop*> crack_loops; 00144 00145 DLIList<Loop*> loops; 00146 this->loops(loops); 00147 00148 int i, j; 00149 for(i=0; i<loops.size(); i++) 00150 { 00151 Loop* l = loops.get_and_step(); 00152 LoopType loop_type = l->loop_type(); 00153 if(loop_type == LOOP_TYPE_U_PERIODIC || loop_type == LOOP_TYPE_V_PERIODIC) 00154 crack_loops.append(l); 00155 } 00156 00157 if(crack_loops.size() >= 2) 00158 { 00159 Loop* loop1 = crack_loops.get_and_step(); 00160 Loop* loop2 = crack_loops.get_and_step(); 00161 00162 DLIList<RefEdge*> loop1_edges; 00163 loop1->ref_edges(loop1_edges); 00164 DLIList<RefEdge*> loop2_edges; 00165 loop2->ref_edges(loop2_edges); 00166 00167 CubitVector p1, p2; 00168 double min_dist = -1.0; 00169 00170 for(i=0; i<loop1_edges.size(); i++) 00171 { 00172 RefEdge* edge1 = loop1_edges.get_and_step(); 00173 for(j=0; j<loop2_edges.size(); j++) 00174 { 00175 RefEdge* edge2 = loop2_edges.get_and_step(); 00176 if(edge2 != edge1) 00177 { 00178 CubitVector v1, v2; 00179 double dist = -1; 00180 dist_between(edge1, edge2, v1, v2, dist); 00181 if(min_dist < 0 || (dist < min_dist && dist > 0)) 00182 { 00183 min_dist = dist; 00184 p1 = v1; 00185 p2 = v2; 00186 } 00187 } 00188 } 00189 } 00190 00191 // estimate distance along the surface in case of curvature 00192 if(min_dist > 0) 00193 { 00194 double new_min_dist = 0; 00195 double start_uv[2]; 00196 double end_uv[2]; 00197 this->u_v_from_position(p1, start_uv[0], start_uv[1]); 00198 this->u_v_from_position(p2, end_uv[0], end_uv[1]); 00199 double delta_uv[2]; 00200 delta_uv[0] = (end_uv[0] - start_uv[0]) / 10.0; 00201 delta_uv[1] = (end_uv[1] - start_uv[1]) / 10.0; 00202 00203 CubitVector start = p1; 00204 CubitVector next; 00205 for(i=0; i<10; i++) 00206 { 00207 start_uv[0] += delta_uv[0]; 00208 start_uv[1] += delta_uv[1]; 00209 next = this->position_from_u_v( start_uv[0], start_uv[1] ); 00210 new_min_dist += start.distance_between(next); 00211 start = next; 00212 } 00213 min_dist = new_min_dist; 00214 } 00215 00216 if(min_dist < 0) 00217 { 00218 min_dist = 0; 00219 } 00220 00221 PRINT_DEBUG_99("Crack_length is %f\n", min_dist); 00222 return min_dist; 00223 } 00224 00225 PRINT_DEBUG_99("No valid crack length for surface %i\n", this->id()); 00226 return 0.0; 00227 } 00228 00229 CubitVector RefFace::normal_at ( const CubitVector& location, 00230 RefVolume* volume, 00231 double* u_guess, double* v_guess) 00232 { 00233 // The Surface::normal_at function not only returns the normal, but 00234 // also returns the point on the actual surface that is closest to 00235 // the input location. The normal is actually computed at *this* 00236 // (closest) point on the surface, not at the input location. 00237 CubitVector normal; 00238 CubitStatus result; 00239 Surface* surface_ptr = get_surface_ptr(); 00240 00241 if(!u_guess || !v_guess) // no guess was provided 00242 { 00243 if (u_guess || v_guess) 00244 { 00245 PRINT_ERROR("normal_at(): neither or both of u_guess and " 00246 "v_guess must be specified.\n"); 00247 assert(u_guess && v_guess); 00248 } 00249 result = surface_ptr->closest_point(location, NULL, &normal); 00250 } 00251 else 00252 { 00253 result = surface_ptr->closest_point_uv_guess(location, 00254 *u_guess, *v_guess, 00255 NULL, &normal ); 00256 } 00257 00258 if (result == CUBIT_FAILURE) 00259 { 00260 PRINT_ERROR("In RefFace::normal_at\n" 00261 " Could not compute the requested normal at " 00262 "location {%f %f %f} on %s (surface %d).\n", 00263 location.x(), location.y(), location.z(), 00264 this->entity_name().c_str(), 00265 this->id()); 00266 //assert ( result == CUBIT_SUCCESS ); 00267 return CubitVector(0.0, 0.0, 0.0); 00268 } 00269 00270 if (surface_ptr->bridge_sense() == CUBIT_REVERSED) 00271 normal = -normal; 00272 00273 if ( volume ) 00274 { 00275 CubitSense s = sense( volume ); 00276 if( s != CUBIT_FORWARD && s != CUBIT_REVERSED ) 00277 { 00278 if(!(volume->is_sheet())) 00279 { 00280 PRINT_ERROR("Surface %d has bad sense information with respect to volume %d\n" 00281 " Probably is a 2-sided surface embedded in volume %d\n" 00282 " Cannot handle this case.\n", id(), volume->id(), volume->id() ); 00283 return CubitVector(0.0, 0.0, 0.0); 00284 } 00285 } 00286 00287 if ( s == CUBIT_REVERSED ) 00288 normal = -normal; 00289 } 00290 00291 return normal; 00292 } 00293 00294 CubitStatus RefFace::uv_derivitives( double u_param, 00295 double v_param, 00296 CubitVector &du, 00297 CubitVector &dv ) 00298 { 00299 return get_surface_ptr()->uv_derivitives(u_param, v_param, du, dv); 00300 } 00301 00302 void RefFace::find_closest_point_trimmed(CubitVector from_point, 00303 CubitVector& point_on_surface) 00304 { 00305 get_surface_ptr()->closest_point_trimmed(from_point, point_on_surface); 00306 } 00307 00308 void RefFace::find_closest_points_trimmed(std::vector<CubitVector> &from_points, 00309 std::vector<CubitVector> &points_on_surface) 00310 { 00311 get_surface_ptr()->closest_points_trimmed(from_points, points_on_surface); 00312 } 00313 00314 CubitStatus RefFace::move_to_surface ( CubitVector& location, 00315 CubitVector& along_vec ) 00316 { 00317 CubitVector closest_location; 00318 CubitStatus status = get_surface_ptr()->closest_point_along_vector(location, along_vec, 00319 closest_location); 00320 00321 if( CUBIT_SUCCESS == status ) 00322 location.set ( closest_location.x(), 00323 closest_location.y(), 00324 closest_location.z() ); 00325 00326 return status; 00327 } 00328 00329 void RefFace::move_to_surface ( CubitVector& location, 00330 double* u_guess, double* v_guess ) 00331 { 00332 CubitVector closest_location; 00333 CubitStatus result; 00334 00335 if(!u_guess || !v_guess) // no guess was provided 00336 { 00337 if (u_guess || v_guess) 00338 { 00339 PRINT_ERROR("move_to_surface(): neither or both of u_guess and " 00340 "v_guess must be specified.\n"); 00341 assert(u_guess && v_guess); 00342 } 00343 result = get_surface_ptr()->closest_point(location, &closest_location); 00344 } 00345 else 00346 { 00347 result = get_surface_ptr()->closest_point_uv_guess(location, 00348 *u_guess, *v_guess, 00349 &closest_location); 00350 } 00351 00352 00353 if (result == CUBIT_FAILURE) 00354 { 00355 PRINT_ERROR("In RefFace::move_to_surface\n" 00356 " Could not compute the closest point to " 00357 "location {%f %f %f} on %s (surface %d).\n", 00358 location.x(), location.y(), location.z(), 00359 this->entity_name().c_str(), 00360 this->id()); 00361 assert ( result == CUBIT_SUCCESS ); 00362 return; 00363 } 00364 00365 location.set ( closest_location.x(), 00366 closest_location.y(), 00367 closest_location.z() ); 00368 } 00369 00370 CubitPointContainment RefFace::point_containment( const CubitVector &point ) 00371 { 00372 Surface *surf = get_surface_ptr(); 00373 return surf->point_containment(point); 00374 } 00375 00376 CubitPointContainment RefFace::point_containment( double u, double v ) 00377 { 00378 Surface *surf = get_surface_ptr(); 00379 return surf->point_containment(u, v); 00380 } 00381 /* 00382 CubitPointContainment RefFace::point_containment( CubitVector &point, 00383 double u, double v ) 00384 { 00385 Surface *surf = get_surface_ptr(); 00386 return surf->point_containment(point, u, v); 00387 } 00388 */ 00389 CubitStatus RefFace::get_principal_curvatures( const CubitVector& point, 00390 double& curvature1, 00391 double& curvature2, 00392 RefVolume* ref_volume_ptr ) 00393 { 00394 Surface* surface_ptr = get_surface_ptr(); 00395 00396 // Call the relevant function to compute the curvatures 00397 CubitStatus status = surface_ptr-> 00398 principal_curvatures( point, curvature1, curvature2 ); 00399 if ( status != CUBIT_SUCCESS ) 00400 return status; 00401 00402 if (surface_ptr->bridge_sense() == CUBIT_REVERSED) { 00403 curvature1 = -curvature1; 00404 curvature2 = -curvature2; 00405 } 00406 00407 if ( ref_volume_ptr ) { 00408 CubitSense s = sense( ref_volume_ptr ); 00409 if ( s == CUBIT_REVERSED ) { 00410 curvature1 = -curvature1; 00411 curvature2 = -curvature2; 00412 } 00413 } 00414 return CUBIT_SUCCESS; 00415 } 00416 00417 int RefFace::genus() 00418 { 00419 int nloops = num_loops(); 00420 if (nloops > 0) return (nloops - 1); 00421 else { 00422 // need to compute poles 00423 int num_poles = this->num_poles(); 00424 return -(num_poles+1); 00425 } 00426 } 00427 00428 int RefFace::num_poles() 00429 { 00430 int num_poles = 0; 00431 double u_low, u_high, v_low, v_high; 00432 get_param_range_U(u_low, u_high); 00433 get_param_range_V(v_low, v_high); 00434 if (is_singular_in_U(u_low)) num_poles++; 00435 if (is_singular_in_U(u_high)) num_poles++; 00436 if (is_singular_in_V(v_low)) num_poles++; 00437 if (is_singular_in_V(v_high)) num_poles++; 00438 return num_poles; 00439 } 00440 00441 CubitVector RefFace::center_point () 00442 { 00443 CubitVector center_pt = bounding_box().center(); 00444 move_to_surface(center_pt); 00445 return center_pt; 00446 } 00447 00448 int RefFace::number_of_Loops () 00449 { 00450 int number_of_loops = 0; 00451 00452 // Get the GroupingEntities (Loops) associated with this 00453 // BasicTopologyEntity (RefFace) 00454 DLIList<GroupingEntity*> loopList; 00455 if ( this->get_grouping_entity_list(loopList) == CUBIT_SUCCESS) 00456 { 00457 number_of_loops = loopList.size(); 00458 } 00459 00460 else 00461 { 00462 PRINT_ERROR("In RefFace::number_of_Loops\n" 00463 " Unknown problem retrieving Loops " 00464 "for %s (surface %d).\n", 00465 entity_name().c_str(), 00466 this->id()); 00467 number_of_loops = 0; 00468 } 00469 00470 return number_of_loops; 00471 } 00472 00473 CubitSense RefFace::sense(RefVolume* volume) 00474 { 00475 SenseEntity* co_face = find_sense_entity(volume); 00476 return co_face ? co_face->get_sense() : CUBIT_UNKNOWN; 00477 } 00478 00479 CubitSense RefFace::sense( RefFace* face_ptr ) 00480 { 00481 DLIList<RefEdge*> edge_list, other_edge_list; 00482 ref_edges( edge_list ); 00483 face_ptr->ref_edges( other_edge_list ); 00484 edge_list.intersect( other_edge_list ); 00485 00486 CubitSense result = CUBIT_UNKNOWN; 00487 if( edge_list.size() > 0 ) 00488 { 00489 RefEdge* edge = edge_list.get_and_step(); 00490 if( edge->sense(this) == edge->sense(face_ptr) ) 00491 result = CUBIT_REVERSED; 00492 else result = CUBIT_FORWARD; 00493 } 00494 for( int i = edge_list.size(); i > 1; i-- ) 00495 { 00496 RefEdge* edge = edge_list.get_and_step(); 00497 CubitSense temp = (edge->sense(this)==edge->sense(face_ptr)) 00498 ? CUBIT_FORWARD : CUBIT_REVERSED; 00499 if( temp != result ) 00500 { 00501 result = CUBIT_UNKNOWN; 00502 break; 00503 } 00504 } 00505 return result; 00506 } 00507 00508 00509 00510 //------------------------------------------------------------------------- 00511 // Purpose : Spatially compare two RefFaces. Compare bounding boxes 00512 // first, then compare each of the ref-edges. This function 00513 // works strictly off of the ref-entities. 00514 // 00515 // Special Notes : 00516 // 00517 // Creator : Malcolm J. Panthaki 00518 // 00519 // Creation Date : 04/07/97 00520 //------------------------------------------------------------------------- 00521 CubitBoolean RefFace::about_spatially_equal( 00522 RefFace* ref_face_ptr_2, 00523 double tolerance_factor, 00524 CubitBoolean notify_refEntity, 00525 CubitBoolean test_bbox, 00526 int test_internal ) 00527 { 00528 // Get rid of the trivial case... 00529 if( this == ref_face_ptr_2) 00530 { 00531 if (notify_refEntity) 00532 remove_compare_data(); 00533 return CUBIT_TRUE; 00534 } 00535 00536 const double tolerance = tolerance_factor * GEOMETRY_RESABS; 00537 CubitBox box_1 = this->bounding_box(); 00538 CubitBox box_2 = ref_face_ptr_2->bounding_box(); 00539 if (!box_1.overlap( tolerance, box_2) ) 00540 return CUBIT_FALSE; 00541 00542 00543 GeometryQueryTool* gqt = GeometryQueryTool::instance(); 00544 DLIList<RefEdge*> ref_edge_list_1, ref_edge_list_2; 00545 this->ref_edges( ref_edge_list_1 ); 00546 ref_face_ptr_2->ref_edges( ref_edge_list_2 ); 00547 00548 //compare the size of the two lists. 00549 if ( ref_edge_list_1.size() != ref_edge_list_2.size() ) 00550 return CUBIT_FALSE; 00551 00552 if (test_internal == 2) // Do internal test for splines only 00553 { 00554 const GeometryType this_type = this->geometry_type(); 00555 const GeometryType othr_type = ref_face_ptr_2->geometry_type(); 00556 if (this_type != SPLINE_SURFACE_TYPE && 00557 this_type != BEST_FIT_SURFACE_TYPE && 00558 this_type != UNDEFINED_SURFACE_TYPE && 00559 othr_type != SPLINE_SURFACE_TYPE && 00560 othr_type != BEST_FIT_SURFACE_TYPE && 00561 othr_type != UNDEFINED_SURFACE_TYPE ) 00562 test_internal = 0; 00563 else 00564 test_bbox = CUBIT_FALSE; 00565 } 00566 00567 00568 //This compare precedure does the following : 00569 // 1. Test the bounding boxes of the 2 faces for equality; 00570 // If they are "equal" (within "resabs*tolerance_factor"): 00571 // 2. Compare the ref-edges. 00572 // 3. Test a point on the two surfaces. 00573 // 4. When notify_refEntity is CUBIT_TRUE, whenever find an 00574 // two ReEntity's are spatially equal, notify the RefEntity. 00575 //**** Reorderd by J.Kraftcheck, Sept 22, 2003 **** 00576 // - Check mergable curves first. Then check boxes and finally 00577 // the internal position. 00578 00579 DLIList<Loop*> loop_list_1, loop_list_2; 00580 DLIList<CoEdge*> loop_1_coedges; 00581 this->loops( loop_list_1 ); 00582 ref_face_ptr_2->loops( loop_list_2 ); 00583 if( loop_list_1.size() != loop_list_2.size() ) 00584 return CUBIT_FALSE; 00585 00586 CubitSense relative_sense = compare_alignment( ref_face_ptr_2 ); 00587 00588 // match each loop in loop_list_1 with one in loop_list_2 00589 for( int i1 = loop_list_1.size(); i1 > 0; i1-- ) 00590 { 00591 Loop* loop_1 = loop_list_1.get_and_step(); 00592 loop_1_coedges.clean_out(); 00593 loop_1->ordered_co_edges( loop_1_coedges ); 00594 bool loop_match = false; 00595 00596 // check every loop in loop_list_2 to see if it matches 00597 // the current loop from loop_list_1 00598 for( int i2 = loop_list_2.size(); (i2 > 0) && !loop_match; i2-- ) 00599 { 00600 Loop* loop_2 = loop_list_2.step_and_get(); 00601 loop_match = loop_2->about_spatially_equal( loop_1_coedges, 00602 relative_sense, 00603 tolerance_factor, 00604 notify_refEntity ); 00605 } 00606 00607 // loop from loop_list_1 did not match any loop in loop_list_2 00608 if( ! loop_match ) 00609 return CUBIT_FALSE; 00610 00611 // found a match for the current one, so remove it 00612 loop_list_2.extract(); 00613 00614 } // for( loop_list_1 ) 00615 00616 00617 if ( test_bbox ) 00618 { 00619 // This test checks to see that the min and max vectors of the 00620 // bounding boxes are within 10% of the length of the bbox diagonal. 00621 // Note that this assumes the default values of resabs=1e-6 and 00622 // tolerance_factor=500 00623 00624 // It has already been determined that the RefEdges of the 00625 // surfaces are mergeable, so the bounding boxes of the 00626 // RefEdges should be equivalent. Consider the bounding box 00627 // of each RefFace to be the RefFace's box united with the 00628 // box of all the curves. This removes any potential issues 00629 // with non-tight bounding boxes for spline curves from 00630 // consideration, while still comparing any extend of the boxes 00631 // that is the result of some internal feature of the surfaces. 00632 if (ref_edge_list_1.size()) 00633 { 00634 int i; 00635 // Call 'unmerged_bounding_box' here so that we get the aggregate bounding box 00636 // of all of the Topology Bridges of curves that are already merged. If we don't 00637 // do this we may not expand the bounding boxes sufficiently to get correct results. 00638 CubitBox edge_box = ref_edge_list_1.step_and_get()->unmerged_bounding_box(); 00639 for (i = ref_edge_list_1.size(); i > 1; i--) 00640 edge_box |= ref_edge_list_1.step_and_get()->unmerged_bounding_box(); 00641 for (i = ref_edge_list_2.size(); i > 0; i--) 00642 edge_box |= ref_edge_list_2.step_and_get()->unmerged_bounding_box(); 00643 box_1 |= edge_box; 00644 box_2 |= edge_box; 00645 } 00646 00647 CubitVector tol_vect( 00648 CUBIT_MIN(box_1.x_range(), box_2.x_range()), 00649 CUBIT_MIN(box_1.y_range(), box_2.y_range()), 00650 CUBIT_MIN(box_1.z_range(), box_2.z_range()) ); 00651 tol_vect *= 200.0 * tolerance; 00652 00653 if( tol_vect.x() < tolerance ) tol_vect.x(tolerance); 00654 if( tol_vect.y() < tolerance ) tol_vect.y(tolerance); 00655 if( tol_vect.z() < tolerance ) tol_vect.z(tolerance); 00656 00657 if( (fabs(box_1.minimum().x() - box_2.minimum().x()) > tol_vect.x()) || 00658 (fabs(box_1.maximum().x() - box_2.maximum().x()) > tol_vect.x()) || 00659 (fabs(box_1.minimum().y() - box_2.minimum().y()) > tol_vect.y()) || 00660 (fabs(box_1.maximum().y() - box_2.maximum().y()) > tol_vect.y()) || 00661 (fabs(box_1.minimum().z() - box_2.minimum().z()) > tol_vect.z()) || 00662 (fabs(box_1.maximum().z() - box_2.maximum().z()) > tol_vect.z()) ) 00663 { 00664 return CUBIT_FALSE; 00665 } 00666 } 00667 00668 //if both lists of edges are zero, this is the concentric sphere or torus case. 00669 //must look for a point on the surface then. 00670 if ( (ref_edge_list_1.size() == 0 && ref_edge_list_2.size() == 0 ) || 00671 test_internal != 0 ) 00672 { 00673 //test a point in the middle. 00674 CubitVector center_1, center_2; 00675 CubitVector temp_1 = this->center_point(); 00676 this->find_closest_point_trimmed( temp_1, center_1); 00677 //Okay, now we have the point. See if this point is on the other 00678 //surface. 00679 ref_face_ptr_2->find_closest_point_trimmed( center_1, center_2 ); 00680 if ( !gqt->about_spatially_equal(center_1, center_2, tolerance_factor ) ) 00681 return CUBIT_FALSE; 00682 } 00683 00684 00685 // If we have come this far, we have found matches for 00686 // every edge of the FACEs. Now notify the associated RefEntities 00687 // that a match was found. 00688 if (notify_refEntity == CUBIT_TRUE ) 00689 { 00690 this->comparison_found(ref_face_ptr_2); 00691 } 00692 00693 return CUBIT_TRUE; 00694 00695 } 00696 00697 //-NOTE: For this function it is assumed that the second_ref_face 00698 //- is spacially equivalient to the first one. 00699 //- This function could explode if this is not followed. 00700 //- If you don't know about the closness of the two faces, check the 00701 //- previous compare function first. 00702 CubitSense RefFace::compare_alignment( RefFace* second_ref_face_ptr ) 00703 { 00704 //Get the sense by testing the two RefFace's at their common 00705 //center point. 00706 CubitVector center_point = this->center_point(); 00707 CubitVector normal_this, normal_second; 00708 normal_this = this->normal_at( center_point ); 00709 normal_second = second_ref_face_ptr->normal_at( center_point ); 00710 00711 double dot = normal_this % normal_second; 00712 00713 CubitSense sense = CUBIT_FORWARD; 00714 if ( dot < 0 ) 00715 { 00716 sense = CUBIT_REVERSED; 00717 } 00718 // Moved this warning into merge tool because this function can 00719 // be used by other code, for which this warning is misleading. 00720 // j.k. - 10/11/01 00721 // else 00722 // { 00723 // PRINT_WARNING("Merging %s (surface %d) and %s (surface %d) " 00724 // " which have the same sense.\n" 00725 // "This may indicate bad geometry.\n", 00726 // entity_name().c_str(), id(), 00727 // second_ref_face_ptr->entity_name().c_str(), 00728 // second_ref_face_ptr->id() ); 00729 // } 00730 return sense; 00731 } 00732 00733 class LoopAngles 00734 { 00735 public: 00736 Loop* loopPtr; 00737 double angleMetric; 00738 00739 LoopAngles(Loop *loop_ptr ) 00740 { loopPtr = loop_ptr; } 00741 00742 double angle_metric() 00743 { return angleMetric; } 00744 }; 00745 00746 00747 #include "SDLList.hpp" 00748 SDLListdeclare(SDLLoopAngles, LoopAngles*, angle_metric, double) 00749 00750 // KGM -- These changes break pave-ansys/anc101.jou 00751 // create a sorting function for DLIList 00752 //template <> struct DLIListSorter<LoopAngles*> 00753 //{ 00754 // bool operator()(LoopAngles* a, LoopAngles* b) { return a->angle_metric() < b->angle_metric(); } 00755 //}; 00756 00757 CubitStatus RefFace::ordered_loops( DLIList<Loop*> &loop_list ) 00758 { 00759 CubitStatus status; 00760 SDLLoopAngles loop_angle_list; 00761 // DLIList<LoopAngles*> loop_angle_list; 00762 DLIList<Loop*> temp_loop_list; 00763 //Get all of the loops for this RefFace. 00764 loops( temp_loop_list ); 00765 00766 if ( temp_loop_list.size() < 2 ) 00767 { 00768 loop_list += temp_loop_list; 00769 } 00770 else 00771 { 00772 // See if the underlying geometry engine can give us the ordered list 00773 // before trying to do it manually. 00774 GeometryQueryTool::instance()->get_ordered_loops(this, loop_list); 00775 if(loop_list.size() > 0 && loop_list.size() == temp_loop_list.size()) 00776 return CUBIT_SUCCESS; 00777 else 00778 loop_list.clean_out(); 00779 00780 // If we were not able to get the ordered list from the underlying 00781 // geometry engine we will do it manually. 00782 00783 // Order the list of loops from outside to inside. 00784 Loop *loop_ptr; 00785 LoopAngles *loop_angles; 00786 00787 for ( int ii = temp_loop_list.size(); ii > 0; ii-- ) 00788 { 00789 loop_ptr = temp_loop_list.get_and_step(); 00790 loop_angles = new LoopAngles( loop_ptr ); 00791 status = loop_ptr->get_angle_metric( loop_angles->angleMetric ); 00792 if ( status == CUBIT_FAILURE ) 00793 { 00794 PRINT_ERROR("In RefFace::ordered_loops\n" 00795 " Unknown problem computing the angle metric" 00796 " of the Loop.\n"); 00797 delete loop_angles; 00798 00799 while( loop_angle_list.size() != 0 ) 00800 delete loop_angle_list.remove(); 00801 00802 return CUBIT_FAILURE; 00803 } 00804 loop_angle_list.append( loop_angles ); 00805 } 00806 00807 loop_angle_list.sort(); 00808 // std::stable_sort(&loop_angle_list[0], &loop_angle_list[0]+loop_angle_list.size(), DLIListSorter<LoopAngles*>()); 00809 loop_angle_list.reset(); 00810 for ( int jj = 0; jj < loop_angle_list.size(); jj++ ) 00811 { 00812 Loop* loop = loop_angle_list.get_and_step()->loopPtr; 00813 loop_list.append( loop ); 00814 bool debug = false; 00815 if (debug) 00816 { 00817 DLIList<RefEdge*> edge_list; 00818 loop->ordered_ref_edges(edge_list); 00819 for (int kk = 0; kk < edge_list.size(); kk++) 00820 { 00821 RefEdge *e = edge_list[kk]; 00822 GfxDebug::highlight_ref_edge(e); 00823 GfxDebug::flush(); 00824 } 00825 GfxDebug::clear_highlight(); 00826 } 00827 } 00828 00829 //Delete loop_angles 00830 while( loop_angle_list.size() != 0 ) 00831 delete loop_angle_list.remove(); 00832 } 00833 00834 bool debug = false; 00835 if (debug) 00836 { 00837 PRINT_INFO("Debugging ordered_loops\n"); 00838 for (int i = 0; i < loop_list.size(); i++) 00839 { 00840 DLIList<RefEdge*> edge_list; 00841 Loop* loop = loop_list[i]; 00842 loop->ordered_ref_edges(edge_list); 00843 PRINT_INFO(" Edges: "); 00844 for (int j = 0; j < edge_list.size(); j++) 00845 { 00846 PRINT_INFO("%d ", edge_list[j]->id()); 00847 } 00848 PRINT_INFO("\n"); 00849 } 00850 } 00851 return CUBIT_SUCCESS; 00852 } 00853 00854 int RefFace::co_edge_loops ( DLIList<DLIList<CoEdge*> >& co_edge_loops ) 00855 { 00856 DLIList<DLIList<CoEdge*> > temp_loop_list; 00857 DLIList<Loop*> loop_list; 00858 CubitStatus status = CUBIT_FAILURE; 00859 Loop *loop_ptr; 00860 00861 //Get the ordered loops (outside to inside); 00862 status = ordered_loops( loop_list ); 00863 if ( status == CUBIT_FAILURE ) 00864 return status; 00865 00866 //Now get the co_edges associated with the loops. 00867 for ( int ii = loop_list.size(); ii > 0; ii-- ) 00868 { 00869 loop_ptr = loop_list.get_and_step(); 00870 00871 // Get the CoEdges on this Loop (the "24" is just a memory allocation 00872 // chunking value and doesn't imply that we have a list of size 24!!) 00873 DLIList<CoEdge*> co_edge_list; 00874 00875 //Get the ref_edges with respect to the loop. 00876 status = loop_ptr->ordered_co_edges( co_edge_list ); 00877 if ( status == CUBIT_FAILURE ) 00878 { 00879 return status; 00880 } 00881 temp_loop_list.append( co_edge_list ); 00882 } 00883 co_edge_loops += temp_loop_list; 00884 00885 return CUBIT_SUCCESS; 00886 } 00887 00888 int RefFace::ref_edge_loops ( DLIList<DLIList<RefEdge*> >& ref_edge_loops ) 00889 { 00890 // NOTE: all of the ref_edge_list's will need to be deleted by 00891 // the calling function... 00892 00893 DLIList<RefEdge*> ref_edge_list; 00894 DLIList<DLIList<RefEdge*> > temp_loop_list; 00895 DLIList<Loop*> loop_list; 00896 CubitStatus status = CUBIT_FAILURE; 00897 Loop *loop_ptr; 00898 00899 //Get the ordered loops (outside to inside); 00900 status = ordered_loops( loop_list ); 00901 if ( status == CUBIT_FAILURE ) 00902 return status; 00903 00904 //Now get the ref-edges associated with the loops. 00905 for ( int ii = loop_list.size(); ii > 0; ii-- ) 00906 { 00907 loop_ptr = loop_list.get_and_step(); 00908 00909 ref_edge_list.clean_out(); 00910 00911 //Get the ref_edges with respect to the loop. 00912 status = loop_ptr->ordered_ref_edges( ref_edge_list ); 00913 if ( status == CUBIT_FAILURE ) 00914 { 00915 return status; 00916 } 00917 temp_loop_list.append( ref_edge_list ); 00918 } 00919 ref_edge_loops += temp_loop_list; 00920 00921 return CUBIT_SUCCESS; 00922 } 00923 00924 00925 RefVolume* RefFace::ref_volume() 00926 { 00927 DLIList<RefEntity*> entity_list; 00928 DLIList<RefVolume*> vol_list; 00929 RefVolume *vol_ptr; 00930 00931 // Get the list of RefVolumes that own this RefFace. 00932 get_parent_ref_entities( entity_list ); 00933 CAST_LIST( entity_list, vol_list , RefVolume); 00934 00935 // Return the first valid RefVolume from the list. 00936 vol_list.reset(); 00937 for( int i = vol_list.size(); i>0; i-- ) 00938 { 00939 vol_ptr = vol_list.get_and_step(); 00940 if( vol_ptr ) 00941 return vol_ptr; 00942 } 00943 00944 // Print ERROR if no valid RefVolume was found. 00945 PRINT_ERROR("No RefVolume found for the RefEdge.\n"); 00946 return NULL; 00947 } 00948 00949 //NOTE: There could be more than one CoFace that is associated with this 00950 // volume and ref-faces, (hard-surfaces). 00951 CoFace* RefFace::get_matching_CoFace(RefVolume* ref_volume_ptr) 00952 { 00953 return dynamic_cast<CoFace*>(find_sense_entity(ref_volume_ptr)); 00954 } 00955 00956 00957 void RefFace::add_hard_point( RefVertex* ref_vertex_ptr) 00958 { 00959 hardPointList.append( ref_vertex_ptr ); 00960 } 00961 00962 void RefFace::hard_points( DLIList<RefVertex*>& new_hard_point_list ) 00963 { 00964 new_hard_point_list = hardPointList; 00965 } 00966 00967 CubitVector RefFace::position_from_u_v (double u, double v) 00968 { 00969 // Get the Surface this object points to 00970 Surface* surfacePtr = get_surface_ptr(); 00971 00972 // Make sure we get a valid Surface 00973 assert(surfacePtr != NULL) ; 00974 00975 // Ask the Surface to do the real work 00976 return surfacePtr->position_from_u_v(u, v) ; 00977 } 00978 00979 CubitStatus RefFace::u_v_from_position (CubitVector const& location, 00980 double& u, 00981 double& v, 00982 CubitVector* closest_location ) 00983 { 00984 //- This function returns the {u, v} coordinates of the point 00985 //- on the Surface closest to the input point (specified in global 00986 //- space). The closest_location is also returned. 00987 00988 // pass call directly to surface 00989 Surface *surface = get_surface_ptr(); 00990 00991 // check surface ptr 00992 assert(surface != NULL); 00993 00994 if(is_parametric() == CUBIT_TRUE) 00995 { 00996 return surface->u_v_from_position (location, u, v, 00997 closest_location); 00998 } 00999 else 01000 { 01001 return CUBIT_FAILURE; 01002 } 01003 } 01004 01005 01006 CubitBoolean RefFace::is_parametric() 01007 { 01008 //- This function determines whether the underlying geometry of the 01009 //- Surface is parametrically defined or not. Returns CUBIT_TRUE if 01010 //- it is and CUBIT_FALSE if it is not. 01011 01012 // pass call directly to surface 01013 Surface *surface = get_surface_ptr(); 01014 01015 // check surface ptr 01016 assert(surface != NULL); 01017 01018 return surface->is_parametric(); 01019 } 01020 01021 CubitBoolean RefFace::get_param_range_U( double& lower_bound, 01022 double& upper_bound ) 01023 { 01024 //- Returns the lower and upper parametric bounds of the 01025 //- surface in U, if it is parametric. Otherwise, it returns 01026 //- CUBIT_FALSE and zeroes for the upper and lower parametric 01027 //- bounds. 01028 01029 // pass call directly to surface 01030 Surface *surface = get_surface_ptr(); 01031 01032 // check surface ptr 01033 assert(surface != NULL); 01034 01035 return surface->get_param_range_U(lower_bound, upper_bound); 01036 } 01037 01038 01039 CubitBoolean RefFace::get_param_range_V( double& lower_bound, 01040 double& upper_bound ) 01041 { 01042 //- Returns the lower and upper parametric bounds of the 01043 //- surface in V, if it is parametric. Otherwise, it returns 01044 //- CUBIT_FALSE and zeroes for the upper and lower parametric 01045 //- bounds. 01046 01047 // pass call directly to surface 01048 Surface *surface = get_surface_ptr(); 01049 01050 // check surface ptr 01051 assert(surface != NULL); 01052 01053 return surface->get_param_range_V(lower_bound, upper_bound); 01054 } 01055 01056 CubitBoolean RefFace::is_periodic() 01057 { 01058 //- This function determines whether the underlying geometry of the 01059 //- Surface is periodic or not. Returns CUBIT_TRUE if it is and 01060 //- CUBIT_FALSE if it is not. 01061 01062 // pass call directly to surface 01063 Surface *surface = get_surface_ptr(); 01064 01065 // check surface ptr 01066 assert(surface != NULL); 01067 01068 return surface->is_periodic(); 01069 } 01070 01071 CubitBoolean RefFace::is_periodic_in_U( double& period ) 01072 { 01073 //- Determines whether the surface object is 01074 //- periodic in the U direction or not. If it is, it 01075 //- returns CUBIT_TRUE and the value of the period. Otherwise, 01076 //- it returns CUBIT_FALSE and a value of 0.0 or the period. 01077 01078 // pass call directly to surface 01079 Surface *surface = get_surface_ptr(); 01080 01081 // check surface ptr 01082 assert(surface != NULL); 01083 01084 return surface->is_periodic_in_U(period); 01085 } 01086 01087 CubitBoolean RefFace::is_periodic_in_V( double& period ) 01088 { 01089 //- Determines whether the surface object is 01090 //- periodic in the V direction or not. If it is, it 01091 //- returns CUBIT_TRUE and the value of the period. Otherwise, 01092 //- it returns CUBIT_FALSE and a value of 0.0 or the period. 01093 01094 // pass call directly to surface 01095 Surface *surface = get_surface_ptr(); 01096 01097 // check surface ptr 01098 assert(surface != NULL); 01099 01100 return surface->is_periodic_in_V(period); 01101 } 01102 CubitBoolean RefFace::is_singular_in_U( double u_param ) 01103 { 01104 //- Determines whether the surface object is 01105 //- singular in the U direction or not. 01106 // pass call directly to surface 01107 Surface *surface = get_surface_ptr(); 01108 01109 // check surface ptr 01110 assert(surface != NULL); 01111 01112 return surface->is_singular_in_U(u_param); 01113 } 01114 CubitBoolean RefFace::is_singular_in_V( double v_param ) 01115 { 01116 //- Determines whether the surface object is 01117 //- singular in the V direction or not. 01118 // pass call directly to surface 01119 Surface *surface = get_surface_ptr(); 01120 01121 // check surface ptr 01122 assert(surface != NULL); 01123 01124 return surface->is_singular_in_V(v_param); 01125 } 01126 01127 RefEdge* RefFace::common_ref_edge ( RefFace* input_face_ptr ) 01128 { 01129 DLIList<RefEdge*> this_edge_list; 01130 ref_edges ( this_edge_list ); 01131 01132 for ( int i = this_edge_list.size(); i > 0; i--) 01133 { 01134 RefEdge* edge = this_edge_list.get_and_step(); 01135 if (edge->find_sense_entity(input_face_ptr)) 01136 return edge; 01137 } 01138 01139 return NULL; 01140 } 01141 01142 int RefFace::common_ref_edges ( RefFace* input_face_ptr, DLIList<RefEdge*> &common_edge_list ) 01143 { 01144 DLIList<RefEdge*> this_edge_list; 01145 ref_edges ( this_edge_list ); 01146 int nedges = 0; 01147 01148 for ( int i = this_edge_list.size(); i > 0; i--) 01149 { 01150 RefEdge* edge = this_edge_list.get_and_step(); 01151 if (edge->find_sense_entity(input_face_ptr)) 01152 { 01153 common_edge_list.append(edge); 01154 nedges++; 01155 } 01156 } 01157 01158 return nedges; 01159 } 01160 01161 RefVolume* RefFace::common_ref_volume ( RefFace* input_face_ptr ) 01162 { 01163 DLIList<RefVolume*> this_volume_list; 01164 DLIList<RefVolume*> input_volume_list; 01165 01166 ref_volumes ( this_volume_list ); 01167 input_face_ptr->ref_volumes ( input_volume_list ); 01168 01169 for ( int i = this_volume_list.size(); i > 0; i--) 01170 { 01171 if (input_volume_list.move_to (this_volume_list.get())) 01172 { 01173 return this_volume_list.get(); 01174 } 01175 01176 this_volume_list.step(); 01177 } 01178 01179 return NULL; 01180 } 01181 01182 int RefFace::dimension() const 01183 { 01184 return 2; 01185 } 01186 double RefFace::area() 01187 { 01188 return GeomMeasureTool::measure_area(this); 01189 } 01190 01191 double RefFace::measure() 01192 { 01193 return this->area(); 01194 } 01195 01196 CubitString RefFace::measure_label() 01197 { 01198 return "area"; 01199 } 01200 01201 //------------------------------------------------------------------------- 01202 // Purpose : Return a pointer to the surface associated with a face. 01203 // 01204 // Special Notes : 01205 // 01206 // Creator : Xuechen Liu 01207 // 01208 // Creation Date : 08/02/96 01209 //------------------------------------------------------------------------- 01210 Surface* RefFace::get_surface_ptr() 01211 { 01212 // Just do one cast instead of two -- KGM 01213 TopologyBridge* bridge = bridge_manager()->topology_bridge(); 01214 return CAST_TO(bridge, Surface); 01215 //return CAST_TO(get_geometry_entity_ptr(), Surface); 01216 } 01217 01218 const Surface* RefFace::get_surface_ptr() const 01219 { 01220 return CAST_TO(get_geometry_entity_ptr(), Surface); 01221 } 01222 01223 01224 //------------------------------------------------------------------------- 01225 // Purpose : This function returns CUBIT_TRUE if the underlying 01226 // geometry of the face is planar. CUBIT_FALSE otherwise. 01227 // 01228 // Special Notes : 01229 // 01230 // Creator : Raikanta Sahu 01231 // 01232 // Creation Date : 12/17/96 01233 //------------------------------------------------------------------------- 01234 CubitBoolean RefFace::is_planar() 01235 { 01236 // Cast the generic GeometryEntity pointer to Surface pointer 01237 Surface* surfacePtr = this->get_surface_ptr() ; 01238 01239 // Check if we have a valid Surface. If so, return the result of 01240 // querying the Surface if it is planar. 01241 if ( surfacePtr != NULL ) 01242 { 01243 GeometryType geo_type; 01244 geo_type = surfacePtr->geometry_type(); 01245 return geo_type == PLANE_SURFACE_TYPE ? CUBIT_TRUE : CUBIT_FALSE; 01246 } 01247 else 01248 { 01249 PRINT_WARNING("In RefFace::is_planar\n" 01250 " %s (surface %d) is not associated with a valid\n" 01251 " underlying geoemtric Surface\n", 01252 entity_name().c_str(), id()) ; 01253 return CUBIT_FALSE ; 01254 } 01255 } 01256 01257 01258 //------------------------------------------------------------------------- 01259 // Purpose : This function returns CUBIT_TRUE if the underlying 01260 // geometry of the face is cylindrical. CUBIT_FALSE otherwise. 01261 // 01262 // Special Notes : 01263 // 01264 // Creator : KGM 01265 // 01266 // Creation Date : 03/22/07 01267 //------------------------------------------------------------------------- 01268 CubitBoolean RefFace::is_cylindrical() 01269 { 01270 // Cast the generic GeometryEntity pointer to Surface pointer 01271 Surface* surfacePtr = this->get_surface_ptr() ; 01272 01273 // Check if we have a valid Surface. If so, return the result of 01274 // querying the Surface if it is planar. 01275 if ( surfacePtr != NULL ) 01276 { 01277 GeometryType geo_type; 01278 geo_type = surfacePtr->is_cylindrical(); 01279 return geo_type == CYLINDER_SURFACE_TYPE ? CUBIT_TRUE : CUBIT_FALSE; 01280 } 01281 else 01282 { 01283 PRINT_WARNING("In RefFace::is_cylindrical\n" 01284 " %s (surface %d) is not associated with a valid\n" 01285 " underlying geoemtric Surface\n", 01286 entity_name().c_str(), id()) ; 01287 return CUBIT_FALSE ; 01288 } 01289 } 01290 01291 CubitStatus RefFace::get_point_normal( CubitVector& origin, CubitVector& normal ) 01292 { 01293 if( is_planar() == CUBIT_FALSE) 01294 return CUBIT_FAILURE; 01295 01296 Surface* surface_ptr = get_surface_ptr(); 01297 01298 if( surface_ptr != NULL ) 01299 { 01300 if( surface_ptr->get_point_normal( origin, normal ) == CUBIT_FAILURE ) 01301 return CUBIT_FAILURE; 01302 } 01303 else 01304 { 01305 PRINT_WARNING("In RefFace::get_point_normal\n" 01306 " %s (surface %d) is not associated with a valid\n" 01307 " underlying geoemtric Surface\n", 01308 entity_name().c_str(), id()) ; 01309 return CUBIT_FAILURE; 01310 } 01311 01312 if (surface_ptr->bridge_sense() == CUBIT_REVERSED) 01313 normal = -normal; 01314 01315 return CUBIT_SUCCESS; 01316 } 01317 01318 int RefFace::validate() 01319 { 01320 //- This function determines whether the entity is valid. 01321 //- Several types of checks can be done, 01322 int error = 0; 01323 01324 // Perform general RefEntity checks (measure > 0) 01325 error += RefEntity::validate(); 01326 01327 // Pass through to surface and add in its validation 01328 Surface *surface = get_surface_ptr(); 01329 01330 // check surface ptr 01331 if (surface != NULL) { 01332 // Check underlying surface 01333 DLIList <TopologyEntity*> bad_entities; 01334 error += surface->validate(entity_name(), bad_entities); 01335 } else { 01336 PRINT_WARNING("\tWARNING: Null underlying surface for %s, (%s %d)\n", 01337 entity_name().c_str(), class_name(), id()); 01338 error++; 01339 } 01340 return error; 01341 } 01342 01343 //------------------------------------------------------------------------- 01344 // Purpose : Initializes all member data 01345 // 01346 // Special Notes : 01347 // 01348 // Creator : Malcolm J. Panthaki 01349 // 01350 // Creation Date : 09/25/96 01351 //------------------------------------------------------------------------- 01352 void RefFace::initialize() 01353 { 01354 // Set the Entity ID for this new RefFace 01355 GeometryEntity* geom_ptr = get_geometry_entity_ptr(); 01356 int saved_id = geom_ptr->get_saved_id(); 01357 if ( !saved_id || RefEntityFactory::instance()->get_ref_face(saved_id) ) 01358 { 01359 saved_id = RefEntityFactory::instance()->next_ref_face_id(); 01360 geom_ptr->set_saved_id(saved_id); 01361 } 01362 entityId = saved_id; 01363 01364 // Default graphics attributes 01365 hardPointColor = 1; 01366 01367 // initialize meshing data 01368 01369 // initialize the bounding box 01370 CubitBox bound_box = bounding_box(); 01371 maxPositionDeviation = 01372 (bound_box.maximum() - bound_box.minimum()).length()/10.0; 01373 01374 // read and initialize attributes 01375 auto_read_cubit_attrib(); 01376 auto_actuate_cubit_attrib(); 01377 01378 #ifdef ALPHA_TREADSWEEP 01379 if(entityId != saved_id) 01380 geom_ptr->set_saved_id(entityId); 01381 #endif 01382 01383 // Assign a default entity name 01384 assign_default_name(); 01385 01386 } 01387 01388 void RefFace::reverse_topology() 01389 { 01390 01391 int i; 01392 01393 // switch sense going up in dimension 01394 DLIList<CoFace*> co_face_list; 01395 co_faces( co_face_list ); 01396 for ( i = co_face_list.size(); i--; ) { 01397 CoFace *co_face = co_face_list.get_and_step(); 01398 co_face->set_sense( CubitUtil::opposite_sense( co_face->get_sense() ) ); 01399 } 01400 01401 // switch sense going down in dimension 01402 DLIList<Loop*> loop_list; 01403 loops( loop_list ); 01404 for ( i = loop_list.size(); i--; ) 01405 loop_list.get_and_step()->reverse_direction(); 01406 } 01407 01408 void RefFace::reverse_normal() 01409 { 01410 bridge_manager()->reverse_bridge_senses(); 01411 reverse_topology(); 01412 } 01413 01414 CubitBoolean RefFace::set_outward_normal( RefVolume *volume ) 01415 { 01416 CubitSense vol_sense = sense( volume ); 01417 if ( vol_sense == CUBIT_UNKNOWN ) 01418 return CUBIT_FALSE; 01419 assert( vol_sense == CUBIT_FORWARD || vol_sense == CUBIT_REVERSED ); 01420 if ( vol_sense == CUBIT_REVERSED ) { 01421 reverse_normal(); 01422 return CUBIT_TRUE; 01423 } 01424 // else already right pointing right way. 01425 return CUBIT_FALSE; 01426 } 01427 01428 CubitStatus RefFace::get_graphics( GMem& facets, 01429 unsigned short normal_tolerance, 01430 double distance_tolerance, 01431 double longest_edge ) 01432 { 01433 Surface* surf_ptr = get_surface_ptr(); 01434 if (!surf_ptr) 01435 { 01436 PRINT_ERROR("RefFace %d is invalid -- no attached Surface.\n",id()); 01437 return CUBIT_FAILURE; 01438 } 01439 01440 return surf_ptr->get_geometry_query_engine()-> 01441 get_graphics(surf_ptr, &facets, 01442 normal_tolerance, distance_tolerance, longest_edge ); 01443 } 01444 01445 CubitBoolean RefFace::is_closed_in_U() 01446 { 01447 Surface* surface_ptr = get_surface_ptr(); 01448 return surface_ptr->is_closed_in_U(); 01449 } 01450 01451 CubitBoolean RefFace::is_closed_in_V() 01452 { 01453 Surface* surface_ptr = get_surface_ptr(); 01454 return surface_ptr->is_closed_in_V(); 01455 } 01456 01457 CubitStatus RefFace::evaluate( double u, double v, 01458 CubitVector *position, 01459 CubitVector *normal, 01460 CubitVector *curvature1, 01461 CubitVector *curvature2 ) 01462 { 01463 if( NULL == position && NULL == normal && 01464 NULL == curvature1 && NULL == curvature2 ) 01465 return CUBIT_FAILURE; 01466 01467 Surface* surf_ptr = get_surface_ptr(); 01468 if (!surf_ptr) 01469 { 01470 PRINT_ERROR("RefFace %d is invalid -- no attached Surface.\n",id()); 01471 return CUBIT_FAILURE; 01472 } 01473 01474 return surf_ptr->evaluate(u, v, position, normal, curvature1, curvature2 ); 01475 } 01476 01477 01478 CubitStatus RefFace::get_projected_distance_on_surface( CubitVector *pos1, 01479 CubitVector *pos2, 01480 double &distance ) 01481 { 01482 if( pos1 == pos2 ) 01483 return CUBIT_FAILURE; 01484 01485 if( NULL == pos1 || NULL == pos2 ) 01486 return CUBIT_FAILURE; 01487 01488 Surface* surf_ptr = get_surface_ptr(); 01489 if (!surf_ptr) 01490 { 01491 PRINT_ERROR("RefFace %d is invalid -- no attached Surface.\n",id()); 01492 return CUBIT_FAILURE; 01493 } 01494 01495 return surf_ptr->get_projected_distance_on_surface( pos1, pos2, distance ); 01496 } 01497 01498 void RefFace::get_parent_ref_entities(DLIList<RefEntity*>& entity_list) 01499 { 01500 01501 // First get the type of RefEntity that is a child of "this" one 01502 DagType parent_type = get_parent_ref_entity_type();; 01503 01504 DLIList<TopologyEntity*> tempList ; 01505 01506 CubitStatus result = ModelQueryEngine::instance()-> 01507 query_model( *this, parent_type, tempList ); 01508 if (result == CUBIT_FAILURE) 01509 { 01510 PRINT_ERROR("In RefEntity::get_parent_ref_entities\n"); 01511 PRINT_ERROR(" Query failed for unknown reason.\n"); 01512 return; 01513 } 01514 01515 entity_list.clean_out(); 01516 for(int i=0; i<tempList.size(); i++) 01517 { 01518 entity_list.append(static_cast<ParentType*>(tempList[i])); 01519 } 01520 }