cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : RefEdge.cpp 00003 // 00004 // Purpose : This file contains the implementation of the class 00005 // RefEdge. 00006 // 00007 // Special Notes : 00008 // 00009 // Creator : Xuechen Liu 00010 // 00011 // Creation Date : 07/11/96 00012 // 00013 // Owner : Malcolm J. Panthaki 00014 //------------------------------------------------------------------------- 00015 00016 // ********** BEGIN STANDARD INCLUDES ********** 00017 #include <assert.h> 00018 // ********** END STANDARD INCLUDES ********** 00019 00020 // ********** BEGIN CUBIT INCLUDES ********** 00021 #include "CubitDefines.h" 00022 00023 #include "RefVolume.hpp" 00024 #include "RefFace.hpp" 00025 #include "RefEdge.hpp" 00026 #include "RefVertex.hpp" 00027 #include "Chain.hpp" 00028 00029 #include "Curve.hpp" 00030 #include "CoEdge.hpp" 00031 #include "Loop.hpp" 00032 00033 #include "RefEntityFactory.hpp" 00034 #include "GeometryQueryTool.hpp" 00035 00036 #include "CastTo.hpp" 00037 #include "DLIList.hpp" 00038 00039 #include "CubitAttrib.hpp" 00040 #include "CubitUtil.hpp" 00041 #include "ModelQueryEngine.hpp" 00042 00043 #include "ToolData.hpp" 00044 #include "CpuTimer.hpp" 00045 00046 bool RefEdge::mSuppressEdgeLengthWarning = false; 00047 00048 //------------------------------------------------------------------------- 00049 // Purpose : Constructor with a pointer to a Curve 00050 // 00051 // Special Notes : 00052 // 00053 // Creator : Xuechen Liu 00054 // 00055 // Creation Date : 07/11/96 00056 //------------------------------------------------------------------------- 00057 RefEdge::RefEdge(Curve* curvePtr) 00058 { 00059 // Set the GeometryEntity pointer 00060 if (curvePtr != NULL) 00061 { 00062 set_geometry_entity_ptr(curvePtr) ; 00063 } 00064 else 00065 { 00066 PRINT_ERROR("In the RefEdge(Curve*) constructor\n"); 00067 PRINT_ERROR(" Input Curve pointer is NULL\n"); 00068 assert(CUBIT_FALSE); 00069 } 00070 00071 // Initialize the member data 00072 initialize(); 00073 } 00074 00075 //------------------------------------------------------------------------- 00076 // Purpose : The destructor. 00077 // 00078 // Special Notes : 00079 // 00080 // Creator : Raikanta Sahu 00081 // 00082 // Creation Date : 10/22/96 00083 //------------------------------------------------------------------------- 00084 RefEdge::~RefEdge() 00085 { 00086 } 00087 00088 //------------------------------------------------------------------------- 00089 // Purpose : Return a pointer to the curve associated with a edge. 00090 // 00091 // Special Notes : 00092 // 00093 // Creator : Xuechen Liu 00094 // 00095 // Creation Date : 08/02/96 00096 //------------------------------------------------------------------------- 00097 Curve* RefEdge::get_curve_ptr() 00098 { 00099 return STATIC_CAST_TO(get_geometry_entity_ptr(), Curve) ; 00100 } 00101 00102 const Curve* RefEdge::get_curve_ptr() const 00103 { 00104 return STATIC_CAST_TO(get_geometry_entity_ptr(), Curve) ; 00105 } 00106 00107 //------------------------------------------------------------------------- 00108 // Purpose : Get Chain associated with this RefEdge 00109 // 00110 // Special Notes : 00111 // 00112 // Creator : Jason Kraftcheck 00113 // 00114 // Creation Date : 07/22/03 00115 //------------------------------------------------------------------------- 00116 Chain* RefEdge::get_chain_ptr() 00117 { 00118 GroupingEntity* gpe_ptr = get_first_grouping_entity_ptr(); 00119 if ( !gpe_ptr || // no chain 00120 gpe_ptr->next() ) // multiple chains 00121 { 00122 return 0; 00123 } 00124 00125 return static_cast<Chain*>(gpe_ptr); 00126 } 00127 00128 CubitStatus RefEdge::get_point_direction( CubitVector& origin, CubitVector& direction ) 00129 { 00130 Curve* curve_ptr = get_curve_ptr(); 00131 00132 if( curve_ptr != NULL ) 00133 { 00134 00135 if( curve_ptr->geometry_type() != STRAIGHT_CURVE_TYPE ) 00136 return CUBIT_FAILURE; 00137 00138 if( curve_ptr->get_point_direction( origin, direction ) == CUBIT_FAILURE ) 00139 { 00140 origin = start_coordinates(); 00141 direction = end_coordinates() - origin; 00142 direction.normalize(); 00143 } 00144 } 00145 else 00146 { 00147 PRINT_WARNING("In RefEdge::get_point_direction\n" 00148 " %s (curve %d) is not associated with a valid\n" 00149 " underlying geometric Curve\n", 00150 entity_name().c_str(), id()) ; 00151 return CUBIT_FAILURE ; 00152 } 00153 00154 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 00155 direction = -direction; 00156 00157 return CUBIT_SUCCESS; 00158 00159 } 00160 00161 CubitStatus RefEdge::get_center_radius( CubitVector& center, double& radius ) 00162 { 00163 Curve* curve_ptr = get_curve_ptr(); 00164 00165 if( curve_ptr != NULL ) 00166 { 00167 00168 if( curve_ptr->geometry_type() != ARC_CURVE_TYPE && 00169 curve_ptr->geometry_type() != ELLIPSE_CURVE_TYPE ) 00170 return CUBIT_FAILURE; 00171 00172 if( curve_ptr->get_center_radius( center, radius ) == CUBIT_FAILURE ) 00173 return CUBIT_FAILURE; 00174 } 00175 else 00176 { 00177 PRINT_WARNING("In RefEdge::get_center_radius\n" 00178 " %s (curve %d) is not associated with a valid\n" 00179 " underlying geoemtric Curve\n", 00180 entity_name().c_str(), id()) ; 00181 return CUBIT_FAILURE ; 00182 } 00183 00184 return CUBIT_SUCCESS; 00185 } 00186 00187 //------------------------------------------------------------------------- 00188 // Purpose : Finds the closest point on the RefEdge to the input 00189 // point and modifies the coordinate values of the input 00190 // point to be those of the closest point. 00191 // 00192 // Special Notes : 00193 // 00194 // Creator : Malcolm J. Panthaki 00195 // 00196 // Creation Date : 2/25/97 00197 //------------------------------------------------------------------------- 00198 void RefEdge::move_to_curve( CubitVector& vector ) 00199 { 00200 // Get the Curve associated with this RefEdge 00201 Curve* curvePtr = this->get_curve_ptr(); 00202 00203 // Move the point to the Curve (the following call modifes the values 00204 // of the input "vector", if necessary) 00205 CubitVector closest_point; 00206 curvePtr->closest_point_trimmed(vector, closest_point); 00207 vector.set( closest_point.x(), 00208 closest_point.y(), 00209 closest_point.z() ); 00210 } 00211 00212 CubitStatus RefEdge::get_interior_extrema(DLIList<CubitVector*>& interior_points, 00213 CubitSense& return_sense) const 00214 { 00215 CubitStatus result; 00216 00217 // Cast away the constness of the Curve 00218 Curve* curve = const_cast<Curve*>(get_curve_ptr()); 00219 result = curve->get_interior_extrema(interior_points, return_sense); 00220 if (curve->bridge_sense() == CUBIT_REVERSED) 00221 return_sense = CubitUtil::opposite_sense(return_sense); 00222 return result; 00223 } 00224 00225 CubitStatus RefEdge::closest_point( CubitVector const& location, 00226 CubitVector& closest_location, 00227 CubitVector* tangent_ptr, 00228 CubitVector* curvature_ptr) 00229 { 00230 Curve *curve_ptr = get_curve_ptr(); 00231 CubitStatus result = curve_ptr->closest_point(location, closest_location, 00232 tangent_ptr, curvature_ptr); 00233 if (tangent_ptr && curve_ptr->bridge_sense() == CUBIT_REVERSED) 00234 *tangent_ptr = -(*tangent_ptr); 00235 00236 return result; 00237 } 00238 00239 CubitStatus RefEdge::closest_point_trimmed( CubitVector const& location, 00240 CubitVector& closest_location) 00241 { 00242 Curve *curve_ptr = get_curve_ptr(); 00243 return curve_ptr->closest_point_trimmed(location, closest_location); 00244 } 00245 00246 CubitPointContainment RefEdge::point_containment( const CubitVector &point ) 00247 { 00248 Curve *curve_ptr = get_curve_ptr(); 00249 return curve_ptr->point_containment(point); 00250 } 00251 00252 00253 //------------------------------------------------------------------------- 00254 // Purpose : These functions return the start and end global coordinate 00255 // locations of the RefEdge. 00256 // 00257 // Special Notes : 00258 // These coordinates remain consistent throughout the life of the 00259 // RefEdge, regardless of the fact that the actual start and 00260 // end RefVerex'es may change (e.g., after a merge operation). 00261 // 00262 // Creator : Malcolm J. Panthaki 00263 // 00264 // Creation Date : 07/03/97 00265 //------------------------------------------------------------------------- 00266 CubitVector RefEdge::start_coordinates() 00267 { 00268 return this->start_vertex()->coordinates(); 00269 } 00270 00271 CubitVector RefEdge::end_coordinates() 00272 { 00273 return this->end_vertex()->coordinates(); 00274 } 00275 00276 void RefEdge::tangent ( const CubitVector &point, CubitVector& tangent_vec ) 00277 { 00278 // Get the tangent at the point closest to "point" on the RefEdge. 00279 // The tangent is always pointing in the positive direction of the 00280 // RefEdge 00281 Curve* curve_ptr = this->get_curve_ptr(); 00282 CubitVector closest_point; 00283 curve_ptr->closest_point( point, closest_point, &tangent_vec ); 00284 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 00285 tangent_vec = -tangent_vec; 00286 } 00287 //------------------------------------------------------------------------- 00288 // Purpose : Get the correct tangent with respect to 00289 // the ref_face_ptr. 00290 // Special Note : This tangent function is not the safest method for getting 00291 // : the tangent on a surface. In face if there could be 00292 // another direction, this function could fail...(assert). 00293 // This function assumes that there is only 1 co-edge per 00294 // this ref_face for this REfEdge. 00295 // 00296 // Creator : David White 00297 // 00298 // Creation Date : 03/15/97 00299 //------------------------------------------------------------------------- 00300 CubitStatus RefEdge::tangent( const CubitVector &point, 00301 CubitVector& tangent_vec, 00302 RefFace *ref_face_ptr ) 00303 { 00304 //Get the tangent for this edge. 00305 tangent( point, tangent_vec ); 00306 00307 //Now allign the tangent with the face. 00308 //For this function we assume that there must only be one 00309 //co edge for this ref_edge. 00310 DLIList<CoEdge*> co_edge_list; 00311 get_co_edges( co_edge_list, ref_face_ptr ); 00312 00313 if( co_edge_list.size() != 1 ) 00314 { 00315 PRINT_ERROR( "Ambiguous case in tangent calculation.\n" ); 00316 return CUBIT_FAILURE; 00317 } 00318 // assert( co_edge_list.size() == 1 ); 00319 00320 if ( co_edge_list.get()->get_sense() == CUBIT_REVERSED ) 00321 tangent_vec = -tangent_vec; 00322 return CUBIT_SUCCESS; 00323 } 00324 00325 //------------------------------------------------------------------------- 00326 // Purpose : Get the correct tangent with respect to 00327 // the ref_face_ptr and the next_ref_edge 00328 // Special Note : For this function next_ref_edge must follow RefEdge. 00329 // : This tangent function is the safest method for getting 00330 // : the tangent on a surface. The others are less restrictive 00331 // : about the tangents direction... (forward, reverse) 00332 // 00333 // Creator : David White 00334 // 00335 // Creation Date : 03/15/97 00336 //------------------------------------------------------------------------- 00337 CubitStatus RefEdge::tangent( const CubitVector &point, 00338 CubitVector& tangent_vec, 00339 RefEdge *next_ref_edge, 00340 RefFace *ref_face_ptr ) 00341 { 00342 CoEdge *co_edge_this = NULL; 00343 CoEdge *co_edge_next = NULL; 00344 //First get the two coedges that corrispond to 00345 //this ref_edge an the next one, with reference to 00346 //the ref_face_ptr. 00347 CubitStatus status = get_two_co_edges( next_ref_edge, 00348 ref_face_ptr, 00349 co_edge_this, 00350 co_edge_next ); 00351 if (status == CUBIT_FAILURE ) 00352 return status; 00353 00354 assert(co_edge_this != NULL ); 00355 assert(co_edge_next != NULL ); 00356 00357 //Now get the tangent from this curve. 00358 tangent ( point, tangent_vec ); 00359 00360 //with the go_edge data we have, we can get the tangent 00361 //going in the right direction... 00362 if ( co_edge_this->get_sense() == CUBIT_REVERSED ) 00363 tangent_vec = -tangent_vec; 00364 return CUBIT_SUCCESS; 00365 } 00366 00367 double RefEdge::get_arc_length () 00368 { 00369 // Get the Curve associated with this RefEdge 00370 Curve* curve_ptr = get_curve_ptr(); 00371 00372 assert(curve_ptr != NULL); 00373 00374 // Get the length 00375 return curve_ptr->get_arc_length(); 00376 } 00377 00378 double RefEdge::get_arc_length ( const CubitVector &point1, 00379 const CubitVector &point2 ) 00380 { 00381 // Get the Curve associated with this RefEdge 00382 Curve* curve_ptr = get_curve_ptr(); 00383 00384 assert(curve_ptr != NULL); 00385 00386 // Get the length between the 2 points 00387 return curve_ptr->get_arc_length(point1, point2); 00388 } 00389 00390 double RefEdge::get_arc_length ( const CubitVector &point1, 00391 int which_end ) 00392 { 00393 Curve* curve_ptr = get_curve_ptr(); 00394 00395 assert (curve_ptr != NULL); 00396 00397 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 00398 which_end = 1 - which_end; 00399 00400 return curve_ptr->get_arc_length(point1, which_end); 00401 } 00402 00403 double RefEdge::get_chord_length() 00404 { 00405 CubitVector start_pos(start_vertex()->coordinates()); 00406 CubitVector end_pos(start_vertex()->coordinates()); 00407 double distance = (start_pos - end_pos).length(); 00408 return distance; 00409 } 00410 00411 00412 //------------------------------------------------------------------------- 00413 // Purpose : Return the "actual" center point (the midpoint along 00414 // the arc length) of the RefEdge. 00415 // 00416 // Special Notes : 00417 // 00418 // Creator : Malcolm Panthaki 00419 // 00420 // Creation Date : 2/27/97 00421 //------------------------------------------------------------------------- 00422 CubitVector RefEdge::center_point() 00423 { 00424 // Get the parameter range of the RefEdge 00425 Curve* curve_ptr = get_curve_ptr(); 00426 00427 assert (curve_ptr != NULL); 00428 00429 return curve_ptr->center_point(); 00430 } 00431 00432 CubitStatus RefEdge::mid_point ( const CubitVector &point1, 00433 const CubitVector &point2, 00434 CubitVector& mid_point ) 00435 { 00436 // Get the Curve associated with this RefEdge 00437 Curve* curve_ptr = get_curve_ptr(); 00438 00439 assert(curve_ptr != NULL); 00440 00441 // Get the global location of parameter3 00442 return curve_ptr->mid_point(point1, point2, mid_point); 00443 00444 } 00445 00446 CubitStatus RefEdge::mid_point ( CubitVector& mid_point ) 00447 { 00448 // Get the Curve associated with this RefEdge 00449 Curve* curve_ptr = get_curve_ptr(); 00450 00451 assert(curve_ptr != NULL); 00452 00453 // Get the global location of parameter3 00454 return curve_ptr->mid_point(mid_point); 00455 00456 } 00457 CubitStatus RefEdge::position_from_fraction( double fraction_along_curve, 00458 CubitVector& output_position ) 00459 { 00460 00461 //Get the Curve of this RefEdge. 00462 Curve* curve_ptr = this->get_curve_ptr(); 00463 00464 assert( fraction_along_curve < 1.0000001 && fraction_along_curve > -0.0000001 ); 00465 //Now get the postion from this fraction value. 00466 00467 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 00468 fraction_along_curve = 1.0 - fraction_along_curve; 00469 00470 CubitStatus result = curve_ptr->position_from_fraction( fraction_along_curve, 00471 output_position ); 00472 return result; 00473 } 00474 00475 //------------------------------------------------------------------------- 00476 // Purpose : Get the parameter value of the start of the RefEdge. 00477 // 00478 // Special Notes : 00479 // 00480 // Creator : Malcolm J. Panthaki 00481 // 00482 // Creation Date : 2/27/97 00483 //------------------------------------------------------------------------- 00484 double RefEdge::start_param() 00485 { 00486 // Get the Curve associated with this RefEdge 00487 Curve* curve_ptr = get_curve_ptr(); 00488 00489 assert(curve_ptr != NULL); 00490 00491 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 00492 return -(curve_ptr->end_param()); 00493 else 00494 return curve_ptr->start_param(); 00495 } 00496 00497 //------------------------------------------------------------------------- 00498 // Purpose : Get the parameter value of the end of the RefEdge. 00499 // 00500 // Special Notes : 00501 // 00502 // Creator : Malcolm J. Panthaki 00503 // 00504 // Creation Date : 2/27/97 00505 //------------------------------------------------------------------------- 00506 double RefEdge::end_param() 00507 { 00508 // Get the Curve associated with this RefEdge 00509 Curve* curve_ptr = get_curve_ptr(); 00510 00511 assert(curve_ptr != NULL); 00512 00513 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 00514 return -(curve_ptr->start_param()); 00515 else 00516 return curve_ptr->end_param(); 00517 } 00518 00519 CubitBoolean RefEdge::get_param_range( double& start_param, double& end_param ) 00520 { 00521 // Get the Curve of this RefEdge 00522 Curve* curvePtr = this->get_curve_ptr(); 00523 00524 // Now get the parameter values of the start and end locations 00525 // of this RefEdge 00526 CubitBoolean result = curvePtr->get_param_range( start_param, end_param ); 00527 00528 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00529 { 00530 double tmp_start_param = start_param; 00531 start_param = -end_param; 00532 end_param = -tmp_start_param; 00533 } 00534 00535 return result; 00536 } 00537 00538 double RefEdge::u_from_position (const CubitVector& input_position) 00539 { 00540 // Get the Curve of this RefEdge 00541 Curve* curvePtr = this->get_curve_ptr(); 00542 00543 // Now get the parameter values of the start and end locations 00544 // of this RefEdge 00545 double param = curvePtr->u_from_position(input_position); 00546 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00547 param = -param; 00548 00549 return param; 00550 } 00551 00552 CubitStatus RefEdge::position_from_u (double u_value, 00553 CubitVector& output_position) 00554 { 00555 // Get the Curve of this RefEdge 00556 Curve* curvePtr = this->get_curve_ptr(); 00557 00558 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00559 u_value = -u_value; 00560 00561 // Now get the parameter values of the start and end locations 00562 // of this RefEdge 00563 return curvePtr->position_from_u(u_value, output_position); 00564 } 00565 00566 double RefEdge::u_from_arc_length ( double root_param, double arc_length ) 00567 { 00568 // Get the Curve of this RefEdge 00569 Curve* curvePtr = this->get_curve_ptr(); 00570 00571 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00572 return -(curvePtr->u_from_arc_length(-root_param, -arc_length)); 00573 else 00574 return curvePtr->u_from_arc_length(root_param, arc_length); 00575 } 00576 00577 double RefEdge::fraction_from_arc_length(RefVertex *root_vertex, 00578 double length) 00579 { 00580 if (root_vertex != start_vertex() && root_vertex != end_vertex()) 00581 return -1.0; 00582 00583 if (geometry_type() == POINT_CURVE_TYPE || get_arc_length() < GEOMETRY_RESABS) 00584 return 0.0; 00585 00586 if (length >= get_arc_length()) 00587 return 1.0; 00588 00589 if (root_vertex == start_vertex()) 00590 return length/get_arc_length(); 00591 00592 else 00593 return 1-length/get_arc_length(); 00594 } 00595 00596 CubitStatus RefEdge::point_from_arc_length ( const CubitVector& root_point, 00597 double arc_length, 00598 CubitVector& new_point ) 00599 { 00600 // Get the Curve of this RefEdge 00601 Curve* curvePtr = this->get_curve_ptr(); 00602 00603 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00604 arc_length = -arc_length; 00605 00606 // Now get the parameter values of the start and end locations 00607 // of this RefEdge 00608 return curvePtr->point_from_arc_length (root_point, arc_length, 00609 new_point ); 00610 } 00611 00612 CubitStatus RefEdge::point_from_arc_length ( double root_param, 00613 double arc_length, 00614 CubitVector& new_point ) 00615 { 00616 // Get the Curve of this RefEdge 00617 Curve* curvePtr = this->get_curve_ptr(); 00618 00619 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00620 arc_length = -arc_length; 00621 00622 // Now get the parameter values of the start and end locations 00623 // of this RefEdge 00624 return curvePtr->point_from_arc_length (root_param, arc_length, 00625 new_point ); 00626 } 00627 00628 double RefEdge::length_from_u( double parameter1, 00629 double parameter2 ) 00630 { 00631 // Get the Curve of this RefEdge 00632 Curve* curvePtr = this->get_curve_ptr(); 00633 00634 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00635 return -(curvePtr->length_from_u(-parameter1, -parameter2)); 00636 else 00637 return curvePtr->length_from_u(parameter1, parameter2); 00638 } 00639 00640 CubitBoolean RefEdge::is_periodic( ) 00641 { 00642 double temp_val; 00643 return this->is_periodic(temp_val); 00644 } 00645 00646 CubitBoolean RefEdge::is_periodic( double& period) 00647 { 00648 // Get the Curve of this RefEdge 00649 Curve* curvePtr = this->get_curve_ptr(); 00650 00651 // Now get the parameter values of the start and end locations 00652 // of this RefEdge 00653 CubitBoolean periodic = curvePtr->is_periodic(period); 00654 00655 if (curvePtr->bridge_sense() == CUBIT_REVERSED) 00656 period = -period; 00657 00658 return periodic; 00659 } 00660 00661 //------------------------------------------------------------------------- 00662 // Purpose : Get parent CoEdges 00663 // 00664 // Special Notes : 00665 // 00666 // Creator : Jason Kraftcheck 00667 // 00668 // Creation Date : 07/29/03 00669 //------------------------------------------------------------------------- 00670 CubitStatus RefEdge::get_co_edges( DLIList<CoEdge*>& co_edges_found_list, 00671 RefFace *input_ref_face_ptr ) 00672 { 00673 for (SenseEntity* coedge_ptr = get_first_sense_entity_ptr(); 00674 coedge_ptr; 00675 coedge_ptr = coedge_ptr->next_on_bte()) 00676 { 00677 if (!input_ref_face_ptr || 00678 coedge_ptr->get_parent_basic_topology_entity_ptr() == input_ref_face_ptr) 00679 { 00680 co_edges_found_list.append (dynamic_cast<CoEdge*>(coedge_ptr)); 00681 } 00682 } 00683 00684 return CUBIT_SUCCESS; 00685 } 00686 00687 double RefEdge::angle_between( RefEdge *other_edge_ptr, 00688 RefFace *face_ptr ) 00689 { 00690 DLIList<DLIList<RefEdge*> > ref_edge_loop; 00691 CubitVector vertex_vector, normal_vector; 00692 CubitVector left_vector, right_vector; 00693 00694 // Loop through face's loops. 00695 face_ptr->ref_edge_loops( ref_edge_loop ); 00696 double return_val = CUBIT_DBL_MAX; 00697 00698 for( int i = 0; i<ref_edge_loop.size(); i++ ) 00699 { 00700 // Look for this edge in the list. 00701 DLIList<RefEdge*>& ref_edge_list = ref_edge_loop[i]; 00702 if( !ref_edge_list.move_to( this ) ) 00703 continue; 00704 // Look for other_edge in the list. 00705 if( !ref_edge_list.move_to( other_edge_ptr ) ) 00706 { 00707 PRINT_ERROR("Attempted to get angle between two " 00708 "RefEdges not on the same Loop.\n"); 00709 return 0.; 00710 } 00711 00712 // If other_edge is before this edge in the loop . . . 00713 if( ref_edge_list.next() == this ) 00714 { // (other = left, this = right) 00715 // Get the vector of the the common vertex. 00716 vertex_vector = 00717 other_edge_ptr->common_ref_vertex(this, face_ptr)->coordinates(); 00718 // Get the normal vector of the face. 00719 normal_vector = face_ptr->normal_at( vertex_vector ); 00720 // Get the vectors of both edges. 00721 other_edge_ptr->tangent( vertex_vector, left_vector, 00722 this, face_ptr ); 00723 this->tangent( vertex_vector, right_vector, 00724 ref_edge_list.next(2), face_ptr); 00725 } 00726 00727 // If this edge is before other_edge in the loop . . . 00728 else if( ref_edge_list.prev() == this ) 00729 { // (this = left, other = right) 00730 // Get the vector of the the common vertex. 00731 vertex_vector = 00732 common_ref_vertex(other_edge_ptr,face_ptr)->coordinates(); 00733 // Get the normal vector of the face. 00734 normal_vector = face_ptr->normal_at( vertex_vector ); 00735 // Get the vectors of both edges. 00736 this->tangent( vertex_vector, left_vector, 00737 other_edge_ptr, face_ptr); 00738 other_edge_ptr->tangent( vertex_vector, right_vector, 00739 ref_edge_list.next(), face_ptr ); 00740 } 00741 00742 // Otherwise, error. 00743 else 00744 { 00745 PRINT_ERROR("Attempted to get angle between two " 00746 "non-consecutive edges.\n"); 00747 return 0.; 00748 } 00749 00750 // Return the angle between the vectors. 00751 return_val = normal_vector.vector_angle( right_vector, -left_vector ); 00752 break; 00753 } 00754 // If this far, then error. 00755 if (CUBIT_DBL_MAX == return_val) { 00756 PRINT_ERROR("Attempted to get angle between two edges " 00757 "where one is not found on the given face.\n"); 00758 return_val = 0.0; 00759 } 00760 return return_val; 00761 } 00762 00763 int RefEdge::dimension() const 00764 { 00765 return 1; 00766 } 00767 00768 double RefEdge::measure() 00769 { 00770 return get_arc_length(); 00771 } 00772 00773 CubitString RefEdge::measure_label() 00774 { 00775 return "length"; 00776 } 00777 00778 int RefEdge::num_of_common_ref_face( RefEdge *other_edge ) 00779 { 00780 DLIList<RefFace*> ref_faces, ref_faces_for_other_edge; 00781 this->ref_faces(ref_faces); 00782 other_edge->ref_faces(ref_faces_for_other_edge); 00783 00784 int i, j; 00785 int num = 0; 00786 for (i = 0; i < ref_faces.size(); i++) 00787 { 00788 RefFace * ref_face = ref_faces.get_and_step(); 00789 for (j = 0; j < ref_faces_for_other_edge.size(); j++) 00790 if (ref_face == ref_faces_for_other_edge.get_and_step()) 00791 num++; 00792 } 00793 00794 return num; 00795 } 00796 00797 // Get one common RefFace between two edges. 00798 RefFace *RefEdge::common_ref_face( RefEdge *other_edge ) 00799 { 00800 DLIList<RefFace*> ref_faces, ref_faces_for_other_edge; 00801 this->ref_faces(ref_faces); 00802 other_edge->ref_faces(ref_faces_for_other_edge); 00803 00804 int i, j; 00805 for (i = 0; i < ref_faces.size(); i++) 00806 { 00807 RefFace * ref_face = ref_faces.get_and_step(); 00808 for (j = 0; j < ref_faces_for_other_edge.size(); j++) 00809 if (ref_face == ref_faces_for_other_edge.get_and_step()) 00810 return ref_face; 00811 } 00812 00813 return NULL; 00814 } 00815 00816 int RefEdge::common_ref_faces ( RefEdge* input_edge, DLIList<RefFace*> &common_face_list ) 00817 { 00818 int nedges = 0; 00819 DLIList<RefFace*> ref_faces, ref_faces_for_other_edge; 00820 this->ref_faces(ref_faces); 00821 input_edge->ref_faces(ref_faces_for_other_edge); 00822 00823 int i, j; 00824 for (i = 0; i < ref_faces.size(); i++) 00825 { 00826 RefFace * ref_face = ref_faces.get_and_step(); 00827 for (j = 0; j < ref_faces_for_other_edge.size(); j++) 00828 if (ref_face == ref_faces_for_other_edge.get_and_step()) 00829 { 00830 common_face_list.append(ref_face); 00831 nedges++; 00832 } 00833 } 00834 00835 return nedges; 00836 } 00837 00838 RefVertex *RefEdge::common_ref_vertex( RefEdge *other_edge ) 00839 { 00840 RefVertex *this_start = start_vertex(); 00841 RefVertex *this_end = end_vertex(); 00842 RefVertex *other_start = other_edge->start_vertex(); 00843 RefVertex *other_end = other_edge->end_vertex(); 00844 00845 if ( this_start == other_start || this_start == other_end ) 00846 { 00847 return this_start; 00848 } 00849 else if ( this_end == other_start || this_end == other_end ) 00850 { 00851 return this_end; 00852 } 00853 else 00854 { 00855 return NULL; 00856 } 00857 } 00858 CubitBoolean RefEdge::common_vertices( RefEdge *other_edge, 00859 DLIList<RefVertex*> &common_verts) 00860 { 00861 CubitBoolean result = CUBIT_FALSE; 00862 RefVertex *this_start = start_vertex(); 00863 RefVertex *this_end = end_vertex(); 00864 RefVertex *other_start = other_edge->start_vertex(); 00865 RefVertex *other_end = other_edge->end_vertex(); 00866 00867 if ( this_start == other_start || this_start == other_end ) 00868 { 00869 common_verts.append(this_start); 00870 result = CUBIT_TRUE; 00871 } 00872 if ( this_end == other_start || this_end == other_end ) 00873 { 00874 common_verts.append(this_end); 00875 result = CUBIT_TRUE; 00876 } 00877 00878 return result; 00879 } 00880 //------------------------------------------------------------------------- 00881 // Purpose : Return a pointer to the ref_vertex that is common 00882 // between the two ref edges and is in the correct order 00883 // going with respect to the face. 00884 // 00885 // Creator : David White 00886 // 00887 // Creation Date : 03/15/97 00888 //------------------------------------------------------------------------- 00889 00890 RefVertex *RefEdge::common_ref_vertex( RefEdge *next_ref_edge, 00891 RefFace *ref_face_ptr ) 00892 { 00893 CoEdge *co_edge_this = NULL; 00894 CoEdge *co_edge_next = NULL; 00895 00896 //First get the two coedges that corrispond to 00897 //this ref_edge an the next one, with reference to 00898 //the ref_face_ptr. 00899 CubitStatus status = get_two_co_edges( next_ref_edge, 00900 ref_face_ptr, 00901 co_edge_this, 00902 co_edge_next ); 00903 if (status == CUBIT_FAILURE ) 00904 return NULL; 00905 assert(co_edge_this != NULL ); 00906 assert(co_edge_next != NULL ); 00907 RefVertex *common_vertex; 00908 00909 //Now according to the sense get the vertex at the 00910 //end of this edge (start if reversed). 00911 if ( co_edge_this->get_sense() == CUBIT_FORWARD ) 00912 common_vertex = end_vertex(); 00913 else 00914 common_vertex = start_vertex(); 00915 00916 //Lets just do a sanitiy check... 00917 if (common_vertex == NULL || 00918 !next_ref_edge->is_directly_related( common_vertex )) { 00919 00920 // let's check for bad sense, then print warning and return 00921 // correct vertex 00922 common_vertex = other_vertex(common_vertex); 00923 if (common_vertex != NULL && 00924 next_ref_edge->is_directly_related( common_vertex )) { 00925 00926 PRINT_ERROR(" bad sense between curve %d and surface %d; please" 00927 " report this.\n", id(), ref_face_ptr->id()); 00928 } 00929 else { 00930 PRINT_ERROR("unable to find common vertex (curves %d, %d)", 00931 this->id(), next_ref_edge->id()); 00932 assert(CUBIT_TRUE); 00933 return (RefVertex*)NULL; 00934 } 00935 } 00936 //Hurray, Success... 00937 return common_vertex; 00938 } 00939 00940 RefEdge* RefEdge::get_other_curve(RefVertex* common_vertex, 00941 RefFace* ref_face_ptr) 00942 { 00943 DLIList<RefEdge*> curves; 00944 ref_face_ptr->ref_edges(curves); 00945 for(int ii = curves.size(); ii>0; ii--) 00946 { 00947 RefEdge* temp_edge = curves.get_and_step(); 00948 if((temp_edge->is_directly_related(common_vertex)) && 00949 (this != temp_edge)) 00950 return temp_edge; 00951 } 00952 return NULL; 00953 } 00954 00955 00956 //------------------------------------------------------------------------- 00957 // Purpose : Returns the co_edge that corresponds to 'this' ref_edge 00958 // and the one that corresponds to next_ref_edge, with 00959 // respect to the ref_face_ptr. 00960 // Special Notes : next_ref_edge must follow 'this' ref_edge in a Loop 00961 // on the ref_face_ptr, this is assumed so the function 00962 // will assert if this is not done... 00963 // 00964 // Creator : David White 00965 // 00966 // Creation Date : 03/15/97 00967 //------------------------------------------------------------------------- 00968 CubitStatus RefEdge::get_two_co_edges( RefEdge *next_ref_edge, 00969 RefFace *ref_face_ptr, 00970 CoEdge *&co_edge_this, 00971 CoEdge *&co_edge_next ) 00972 { 00973 DLIList<Loop*> loop_list; 00974 Loop *loop_ptr; 00975 CubitStatus status; 00976 DLIList<CoEdge*> co_edge_list; 00977 00978 //First get the loops for this ref_face; 00979 ref_face_ptr->loops( loop_list ); 00980 //Now we want to find the coedge list that 00981 //has 'this' refedge followed by the next one 00982 assert( loop_list.size() != 0 ); 00983 00984 for ( int i = loop_list.size(); i--; ) 00985 { 00986 // get the ordered co-edges of this loop 00987 loop_ptr = loop_list.get_and_step(); 00988 co_edge_list.clean_out(); 00989 status = loop_ptr->ordered_co_edges( co_edge_list ); 00990 00991 //Now find the coedges corresponding to this ref_edge 00992 // and the next ref_edge. 00993 if ( status == CUBIT_SUCCESS ) { 00994 for ( int j = co_edge_list.size(); j--; ) 00995 { 00996 // candidates 00997 co_edge_this = co_edge_list.get_and_step(); 00998 co_edge_next = co_edge_list.get(); 00999 01000 // really correspond to this and next edge? 01001 if ( co_edge_this->get_ref_edge_ptr() == this && 01002 co_edge_next->get_ref_edge_ptr() == next_ref_edge ) 01003 { 01004 return CUBIT_SUCCESS; 01005 } 01006 } 01007 } 01008 } 01009 co_edge_this = co_edge_next = NULL; 01010 PRINT_ERROR("in RefEdge::get_two_co_edges.\n" 01011 "Couldn't find CoEdgeList with this edge\n" 01012 "and the next edge passed in.\n"); 01013 return CUBIT_FAILURE; 01014 } 01015 01016 01017 RefVertex *RefEdge::other_vertex( RefVertex *vertex ) 01018 { 01019 if ( vertex == start_vertex() ) 01020 { 01021 return end_vertex(); 01022 } 01023 else if ( vertex == end_vertex() ) 01024 { 01025 return start_vertex(); 01026 } 01027 else 01028 { 01029 return NULL; 01030 } 01031 } 01032 01033 RefFace *RefEdge::other_face(RefFace *not_face, RefVolume *ref_volume) 01034 { 01035 //- return the (an) other face sharing this edge, which also borders 01036 //- ref_volume if non-NULL 01037 DLIList<RefFace*> temp_faces; 01038 ref_faces(temp_faces); 01039 int i; 01040 for (i = temp_faces.size(); i > 0; i--) { 01041 RefFace *other_face = temp_faces.get_and_step(); 01042 if (other_face != not_face && 01043 (!ref_volume || other_face->is_directly_related(ref_volume))) 01044 return other_face; 01045 } 01046 01047 return NULL; 01048 } 01049 01050 01051 CubitStatus RefEdge::relative_sense( RefEdge *ref_edge_ptr_2, 01052 double tolerance_factor, 01053 CubitSense *sense, 01054 CubitBoolean &spatially_equal, 01055 CubitBoolean force_merge) 01056 { 01057 // It is assumed that the endpoints have been determined to be 01058 // spatially equal before this function is called. 01059 01060 // Algorithm: Get a point from 'this' (the 1/3 point). See if it 01061 // lies on the second RefEdge also, within tolerance. If so, 01062 // spatially_equal is set to true. Next, compare the normal directions 01063 // at the common point. If they point the same direction (dot product 01064 // of tangents is > 0), sense is forward. Else, sense is reversed. If 01065 // the tangent dot product is between -.5 and .5, a warning is printed. 01066 01067 const double ONE_THIRD = 1.0/3.0; 01068 if (sense) 01069 *sense = CUBIT_FORWARD; 01070 CubitStatus result; 01071 01072 // Find the point 1/3 along *this* 01073 CubitVector test_point_1, test_point_2; 01074 result = this->position_from_fraction( ONE_THIRD, 01075 test_point_1); 01076 if ( result != CUBIT_SUCCESS ) 01077 { 01078 PRINT_ERROR("Error in RefEdge::compare(refedges).\n" 01079 "Can't find position 1/3 along curve.\n"); 01080 return CUBIT_FAILURE; 01081 } 01082 01083 // See if the 1/3 point on *this* lies on the other curve 01084 if ( ref_edge_ptr_2->closest_point_trimmed(test_point_1, test_point_2) 01085 != CUBIT_SUCCESS ) 01086 { 01087 return CUBIT_FAILURE; 01088 } 01089 if ( GeometryQueryTool::instance()-> 01090 about_spatially_equal(test_point_1, test_point_2,tolerance_factor )) 01091 { 01092 spatially_equal = CUBIT_TRUE; 01093 } 01094 else if ( !force_merge ) 01095 { 01096 return CUBIT_FAILURE; 01097 } 01098 01099 // Now find the sense 01100 if (sense) 01101 { 01102 CubitVector tangent_1, tangent_2; 01103 result = this->closest_point(test_point_2, 01104 test_point_1, 01105 &tangent_1); 01106 if (result == CUBIT_SUCCESS) 01107 result = ref_edge_ptr_2->closest_point(test_point_1, 01108 test_point_2, 01109 &tangent_2); 01110 if ( result != CUBIT_SUCCESS ) 01111 { 01112 PRINT_ERROR("Error in RefEdge::relative_sense(refedges).\n" 01113 "Can't find Curve tangents.\n"); 01114 return CUBIT_FAILURE; 01115 } 01116 01117 // Find the sense 01118 01119 //If one of the curves is zero-length, it will have a zero 01120 //tangent vector. 01121 double len_product = tangent_1.length() * tangent_2.length(); 01122 if( len_product > CUBIT_DBL_MIN ) 01123 { 01124 01125 double dot_product = (tangent_1 % tangent_2) / len_product; 01126 if (dot_product < 0) 01127 *sense = CUBIT_REVERSED; 01128 //if (dot_product > -.5 && dot_product < .5) 01129 // tangent_warning = CUBIT_TRUE; 01130 } 01131 else 01132 { 01133 //If one of the tangents is zero-length, one of the curves had 01134 //better be as well. 01135 assert( (measure() * ref_edge_ptr_2->measure()) < CUBIT_RESABS ); 01136 } 01137 } 01138 return CUBIT_SUCCESS; 01139 } 01140 01141 //------------------------------------------------------------------------- 01142 // Purpose : Spatially compare two RefEdges. Does not go down to EDGE 01143 // level. It does it at the ref_edge level so the parameter 01144 // values are consistant. 01145 // 01146 // Special Notes : 01147 // 01148 // Creator : David White 01149 // 01150 // Creation Date : 04/07/97 01151 //------------------------------------------------------------------------- 01152 CubitBoolean RefEdge::about_spatially_equal( 01153 RefEdge* ref_edge_ptr_2, 01154 double tol_factor, 01155 CubitSense* sensePtr, 01156 CubitBoolean notify_refEntity ) 01157 01158 { 01159 if( this == ref_edge_ptr_2) 01160 { 01161 if (sensePtr) 01162 *sensePtr = CUBIT_FORWARD; 01163 if (notify_refEntity) 01164 remove_compare_data(); 01165 return CUBIT_TRUE; 01166 } 01167 01168 CubitBoolean spatially_equal = CUBIT_FALSE; 01169 CubitSense rel_sense = CUBIT_FORWARD; 01170 CubitStatus stat = CUBIT_SUCCESS; 01171 stat = relative_sense( ref_edge_ptr_2, tol_factor, 01172 &rel_sense, spatially_equal); 01173 01174 if (stat != CUBIT_SUCCESS || !spatially_equal) 01175 { 01176 return CUBIT_FALSE; 01177 } 01178 01179 if (sensePtr) 01180 *sensePtr = rel_sense; 01181 01182 //compare the start and end vertices to be spatially equal. 01183 RefVertex* this_start = start_vertex(); 01184 RefVertex* this_end = end_vertex(); 01185 RefVertex* edge2_start = ref_edge_ptr_2->start_vertex(); 01186 RefVertex* edge2_end = ref_edge_ptr_2->end_vertex(); 01187 01188 // Swap vertices to simplify things later. 01189 if (rel_sense == CUBIT_REVERSED) 01190 std::swap(edge2_start, edge2_end); 01191 01192 //compare vertex locations unless force_merge is true. 01193 // closed curve case 01194 if (this_start == this_end || edge2_start == edge2_end) 01195 { 01196 if ((this_start != this_end) || 01197 (edge2_start != edge2_end) || 01198 !this_start->about_spatially_equal(edge2_start, tol_factor, CUBIT_FALSE)) 01199 return CUBIT_FALSE; 01200 } 01201 else 01202 { 01203 if ((this_start == edge2_end) || 01204 (this_end == edge2_start) || 01205 !this_start->about_spatially_equal(edge2_start, tol_factor, CUBIT_FALSE) || 01206 !this_end->about_spatially_equal(edge2_end, tol_factor, CUBIT_FALSE)) 01207 return CUBIT_FALSE; 01208 } 01209 01210 //Now if they match report it. 01211 //Do vertices explicitly here rather than in 01212 //RefVertex::about_spatially_equal(..) because we don't call 01213 //RefVertex::about_spatially_equal(..) if force_merge is true. 01214 if (notify_refEntity) 01215 { 01216 this->comparison_found(ref_edge_ptr_2); 01217 if (this_start != edge2_start) 01218 this_start->comparison_found(edge2_start); 01219 else 01220 this_start->remove_compare_data(); 01221 if (this_end != edge2_end) 01222 this_end->comparison_found(edge2_end); 01223 else 01224 this_end->remove_compare_data(); 01225 } 01226 01227 return CUBIT_TRUE; 01228 } 01229 01230 int RefEdge::validate() 01231 { 01232 //- This function determines whether the entity is valid. 01233 //- Several types of checks can be done, 01234 int error = 0; 01235 01236 // Perform general RefEntity checks (measure > 0) 01237 error += RefEntity::validate(); 01238 01239 // Pass through to curve and add in its validation 01240 Curve *curve = get_curve_ptr(); 01241 01242 // check curve ptr 01243 if (curve != NULL) { 01244 // Check underlying curve 01245 DLIList <TopologyEntity*> bad_entities; 01246 error += curve->validate(entity_name(),bad_entities); 01247 } else { 01248 PRINT_WARNING("\tWARNING: Null underlying curve for %s, (%s %d)\n", 01249 entity_name().c_str(), class_name(), id()); 01250 error++; 01251 } 01252 return error; 01253 } 01254 01255 // ********** END PUBLIC FUNCTIONS ********** 01256 01257 // ********** BEGIN PROTECTED FUNCTIONS ********** 01258 // ********** END PROTECTED FUNCTIONS ********** 01259 01260 // ********** BEGIN PRIVATE FUNCTIONS ********** 01261 01262 //------------------------------------------------------------------------- 01263 // Purpose : Initializes the member data of the RefEdge 01264 // 01265 // Special Notes : 01266 // 01267 // Creator : Malcolm J. Panthaki 01268 // 01269 // Creation Date : 10/07/96 01270 //------------------------------------------------------------------------- 01271 void RefEdge::initialize() 01272 { 01273 // Initialize some member data 01274 refEdgeClone = 0; 01275 markedFlag = CUBIT_FALSE; 01276 01277 // Make sure the arc length is not zero if there are start and end 01278 // RefVertex'es already assigned to this RefEdge 01279 if ( get_arc_length() < CUBIT_DBL_MIN ) 01280 { 01281 if ( start_vertex() && end_vertex() ) 01282 { 01283 CubitVector start_pt = start_vertex()->coordinates(); 01284 CubitVector end_pt = end_vertex()->coordinates(); 01285 PRINT_WARNING ( "(RefEdge::initialize): Edge has zero arclength.\n" 01286 " Start vertex location is (%9.2f, %9.2f, %9.2f ).\n" 01287 " End vertex location is (%9.2f, %9.2f, %9.2f ).\n", 01288 start_pt.x(), start_pt.y(), start_pt.z(), 01289 end_pt.x(), end_pt.y(), end_pt.z() ); 01290 } 01291 else if (!mSuppressEdgeLengthWarning) 01292 { 01293 PRINT_WARNING( "Edge found with zero arclength\n" 01294 " For cones, this may be normal.\n"); 01295 } 01296 01297 } 01298 01299 // Set the Entity ID for this new RefEdge 01300 GeometryEntity* geom_ptr = get_geometry_entity_ptr(); 01301 int saved_id = geom_ptr->get_saved_id(); 01302 if ( !saved_id || RefEntityFactory::instance()->get_ref_edge(saved_id) ) 01303 { 01304 saved_id = RefEntityFactory::instance()->next_ref_edge_id(); 01305 geom_ptr->set_saved_id(saved_id); 01306 } 01307 entityId = saved_id; 01308 01309 // read and initialize attributes 01310 auto_read_cubit_attrib(); 01311 auto_actuate_cubit_attrib(); 01312 01313 // Assign a default entity name 01314 assign_default_name(); 01315 } 01316 01317 //------------------------------------------------------------------------- 01318 // Purpose : Return a pointer to the start RefVertex of this RefEdge. 01319 // 01320 // Special Notes : The assumption is that there is only 1 Chain associated 01321 // with each RefEdge. Also, the RefVertex associated with 01322 // the first CoVertex in this Chain is the start RefVertex 01323 // of this RefEdge and the RefVertex associated with the 01324 // last CoVertex in this Chain is the end RefVertex of this 01325 // RefEdge. 01326 // 01327 // Creator : Malcolm J. Panthaki 01328 // 01329 // Creation Date : 10/21/96 01330 //------------------------------------------------------------------------- 01331 RefVertex* RefEdge::start_vertex() 01332 { 01333 // Get the first (and only) Chain associated with this RefEdge. 01334 Chain* chain_ptr = this->get_chain_ptr(); 01335 01336 // Ask the Chain for its first RefVertex 01337 if (chain_ptr == NULL) 01338 { 01339 return NULL; 01340 } 01341 01342 else 01343 { 01344 return chain_ptr->start_vertex(); 01345 } 01346 } 01347 01348 //------------------------------------------------------------------------- 01349 // Purpose : Return a pointer to the end RefVertex of this RefEdge. 01350 // 01351 // Special Notes : The assumption is that there is only 1 Chain associated 01352 // with each RefEdge. Also, the RefVertex associated with 01353 // the first CoVertex in this Chain is the start RefVertex 01354 // of this RefEdge and the RefVertex associated with the 01355 // last CoVertex in this Chain is the end RefVertex of this 01356 // RefEdge. 01357 // 01358 // Creator : Malcolm J. Panthaki 01359 // 01360 // Creation Date : 10/21/96 01361 //------------------------------------------------------------------------- 01362 RefVertex* RefEdge::end_vertex() 01363 { 01364 // Get the first (and only) Chain associated with this RefEdge. 01365 Chain* chain_ptr = get_chain_ptr(); 01366 01367 // Ask the Chain for its end (last) RefVertex 01368 if (chain_ptr == NULL) 01369 { 01370 return NULL; 01371 } 01372 01373 else 01374 { 01375 return chain_ptr->end_vertex(); 01376 } 01377 } 01378 01379 void RefEdge::reverse_topology() 01380 { 01381 Chain* chain_ptr = get_chain_ptr(); 01382 chain_ptr->reverse_direction(); 01383 01384 // switch co_edge senses 01385 DLIList<SenseEntity*> co_edge_list; 01386 get_sense_entity_list(co_edge_list); 01387 for ( int i = co_edge_list.size(); i--; ) 01388 co_edge_list.get_and_step()->reverse_sense(); 01389 } 01390 01391 CubitSense RefEdge::sense( RefFace *face ) 01392 { 01393 DLIList<CoEdge*> co_edge_list; 01394 get_co_edges(co_edge_list, face); 01395 CoEdge *coedge; 01396 CubitSense my_sense = CUBIT_UNKNOWN; 01397 for ( int i = co_edge_list.size(); i--; ) { 01398 coedge = co_edge_list.get_and_step(); 01399 if(coedge->get_sense() == CUBIT_FORWARD) 01400 { 01401 if (my_sense == CUBIT_REVERSED) 01402 return CUBIT_UNKNOWN; 01403 my_sense = CUBIT_FORWARD; 01404 } 01405 else 01406 { 01407 if (my_sense == CUBIT_FORWARD) 01408 return CUBIT_UNKNOWN; 01409 my_sense = CUBIT_REVERSED; 01410 } 01411 } 01412 return my_sense; 01413 } 01414 01415 CubitBoolean RefEdge::is_tolerant() 01416 { 01417 Curve* curve_ptr = get_curve_ptr(); 01418 if (curve_ptr == NULL) { 01419 PRINT_WARNING("\tWARNING: Null underlying curve for %s, (%s %d)\n", 01420 entity_name().c_str(), class_name(), id()); 01421 return CUBIT_FALSE; 01422 } 01423 01424 return curve_ptr->is_tolerant(); 01425 } 01426 01427 CubitVector RefEdge::curve_center() 01428 { 01429 CubitVector p1 = start_vertex()->coordinates(); 01430 CubitVector p2 = end_vertex()->coordinates(); 01431 if ( start_vertex() == end_vertex() ) 01432 { 01433 mid_point(p2); 01434 } 01435 p1 += p2; 01436 p1 /= 2.0; 01437 return p1; 01438 } 01439 01440 CubitStatus RefEdge::get_graphics( GMem& polyline, double angle_tolerance, 01441 double distance_tolerance, 01442 double max_edge_length ) 01443 { 01444 Curve* curve_ptr = get_curve_ptr(); 01445 if (!curve_ptr) 01446 { 01447 PRINT_ERROR("RefEdge %d is invalid -- no attached Curve.\n",id()); 01448 return CUBIT_FAILURE; 01449 } 01450 01451 return curve_ptr->get_geometry_query_engine()->get_graphics(curve_ptr, 01452 &polyline, angle_tolerance, distance_tolerance, max_edge_length ); 01453 } 01454 01455 //------------------------------------------------------------------------- 01456 // Purpose : Reverse RefEdge sense relative to Curve(s) 01457 // 01458 // Special Notes : 01459 // 01460 // Creator : Jason Kraftcheck 01461 // 01462 // Creation Date : 10/14/03 01463 //------------------------------------------------------------------------- 01464 void RefEdge::reverse_tangent() 01465 { 01466 bridge_manager()->reverse_bridge_senses(); 01467 reverse_topology(); 01468 } 01469 01470 void RefEdge::suppress_edge_length_warning(bool flag) 01471 { 01472 mSuppressEdgeLengthWarning = flag; 01473 } 01474 01475 CubitStatus RefEdge::evaluate_exterior_angle(double *exterior_angle) 01476 { 01477 //- Get the center point of this curve 01478 CubitVector center = this->center_point(); 01479 CubitVector surf_norm[2]; 01480 CubitVector tangent; 01481 RefFace* ref_face = NULL; 01482 RefEdge* next_curve = NULL; 01483 01484 int i, j, k; 01485 01486 //- Get surfaces on this curve 01487 DLIList<RefFace*> surf_list; 01488 this->ref_faces(surf_list); 01489 if(surf_list.size() == 2) 01490 { 01491 for( i = 0; i < surf_list.size(); i++) 01492 { 01493 RefFace* this_surf = surf_list.get_and_step(); 01494 surf_norm[i] = this_surf->normal_at(center); 01495 if( i == 1) 01496 { 01497 //- Get the referance surface and curve to get exterior angle 01498 ref_face = this_surf; 01499 DLIList<DLIList<RefEdge*> > loop_lists; 01500 ref_face->ref_edge_loops(loop_lists); 01501 for( j = 0; j < loop_lists.size(); j++ ) 01502 { 01503 DLIList<RefEdge*>& current_list = loop_lists[j]; 01504 for( k = 0; k < current_list.size(); k++ ) 01505 { 01506 RefEdge* current_curve = current_list.get_and_step(); 01507 if( current_curve == this ) 01508 { 01509 next_curve = current_list.get(); 01510 break; 01511 } 01512 } 01513 if(next_curve != NULL) 01514 break; 01515 } 01516 } 01517 } 01518 } 01519 else 01520 { 01521 *exterior_angle = 0.0; 01522 PRINT_ERROR("There aren't 2 surfaces on curve %d. Can't compute angle.\n", this->id()); 01523 return CUBIT_FAILURE; 01524 } 01525 01526 this->tangent(center, tangent, next_curve, ref_face); 01527 01528 //Find the angle from normal 1 to normal 0. 01529 double rad_angle = tangent.vector_angle_quick(surf_norm[1], surf_norm[0]); //angle in radians 01530 double angle = rad_angle * (180.0 / 3.14159); //angle in degrees 01531 01532 //Now convert to the exterior angle between the two surfaces. 01533 angle += 180.0; 01534 if( angle > 360.0 ) 01535 angle -= 360.0; 01536 01537 //- Return the exterior angle for this curve in degrees. 01538 *exterior_angle = angle; 01539 return CUBIT_SUCCESS; 01540 } 01541 01542 void RefEdge::get_parent_ref_entities(DLIList<RefEntity*>& entity_list) 01543 { 01544 01545 // First get the type of RefEntity that is a child of "this" one 01546 DagType parent_type = get_parent_ref_entity_type();; 01547 01548 DLIList<TopologyEntity*> tempList ; 01549 01550 CubitStatus result = ModelQueryEngine::instance()-> 01551 query_model( *this, parent_type, tempList ); 01552 if (result == CUBIT_FAILURE) 01553 { 01554 PRINT_ERROR("In RefEntity::get_parent_ref_entities\n"); 01555 PRINT_ERROR(" Query failed for unknown reason.\n"); 01556 return; 01557 } 01558 01559 entity_list.clean_out(); 01560 for(int i=0; i<tempList.size(); i++) 01561 { 01562 entity_list.append(static_cast<ParentType*>(tempList[i])); 01563 } 01564 }