cgma
RefEdge.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines