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