cgma
GeometryUtil.hpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : GeometryUtil.hpp
00003 //
00004 // Purpose       : This class groups simple geometric utility functions.
00005 //
00006 // Special Notes : 
00007 //
00008 // Creator       : Jason Kraftcheck
00009 //
00010 // Creation Date : 07/31/98
00011 //-------------------------------------------------------------------------
00012 
00013 #ifndef GEOMETRY_UTILITY_HPP
00014 #define GEOMETRY_UTILITY_HPP
00015 
00016 #include "CubitDefines.h"
00017 #include "CGMGeomConfigure.h"
00018 
00019 
00020 class Surface;
00021 class Curve;
00022 class TBPoint;
00023 class Loop;
00024 class CubitVector;
00025 class CoEdge;
00026 class RefEdge;
00027 class RefFace;
00028 class RefVolume;
00029 class RefVertex;
00030 class Shell;
00031 class Body;
00032 template <class X> class DLIList;
00033 class CoFace;
00034 class RefEdge;
00035 class TopologyEntity;
00036 class TopologyEntity;
00037 class RefEntity;
00038 class TopologyBridge;
00039 
00040 class CUBIT_GEOM_EXPORT GeometryUtil
00041 {
00042 public:
00043   
00044   double default_angle_tol;     //CUBIT_PI      == NONE
00045   double default_midpoint_tol;  //CUBIT_DBL_MAX == NONE
00046   
00047   static GeometryUtil* instance()
00048     {
00049       if( instance_ == NULL ) instance_ = new GeometryUtil;
00050       return instance_;
00051     }
00052   static void delete_instance()
00053   { 
00054     if(instance_)
00055       delete instance_;
00056     instance_ = NULL;
00057   } 
00058   
00059   CubitBoolean is_position_within_loop( const CubitVector& position,
00060                                         Loop* loop_ptr,
00061                                         CubitVector* closest_on_loop = NULL,
00062                                         CubitVector* normal = NULL );
00063     //R CubitBoolean    
00064     //R- CUBIT_TRUE/CUBIT_FALSE
00065     //I position
00066     //I- The position to test.  This position will be moved to the
00067     //I- surface if it does not lie on the surface.
00068     //I loop_ptr
00069     //I- A pointer to the loop to test.
00070     //O closest_on_loop
00071     //O- The closest point on the loop.
00072     //I normal
00073     //I- A pointer to a vector containing the normal on the surface at
00074     //I- the passed position.  If a normal is passed, the function assumes
00075     //I- that the point is on the surface.  
00076     //I- If no normal is specified, the function will query the loop_ptr 
00077     //I- for its parent face, moved the passed position to that face, and
00078     //I- evaluate the normal at that position.
00079     //- This method tests if a point lies within a loop.
00080     //-
00081     //- NOTE: This method will return the expected value only when
00082     //-       the loop is an outside loop!  If the loop represents
00083     //-       a hole, CUBIT_TRUE will be returned when the point
00084     //-       is OUTSIDE the loop. (or on the bounded RefFace)
00085   
00086   
00087   CubitStatus closest_point_trimmed( RefFace* face_ptr, 
00088                                      const CubitVector& from_pt,
00089                                      CubitVector& result_pt,
00090                                      CubitPointContainment* cont = 0 );
00091     //R CubitStatus
00092     //R- CUBIT_SUCCESS/CUBIT_FAILURE
00093     //I face_ptr
00094     //I- The surface to evaluate on.
00095     //I from_pt
00096     //I- The position to evaluate from.
00097     //O result_pt
00098     //O- The closest position on the surface.
00099     //- This is an implementation of closest_point_timmed which uses
00100     //- the modeling engine's closest_point method, but uses
00101     //- loop angle metric to determine if a point lies in a loop.
00102 
00103     double surface_cpu_time;
00104     double other_cpu_time;
00105     //Stats kept by closest_point_trimmed.
00106   
00107   CubitBoolean is_point_on_face( RefFace* ref_face_ptr,
00108                                  const CubitVector& point,
00109                                  CubitBoolean check_on_surface = CUBIT_TRUE );
00110     //R CubitBoolean
00111     //R- CUBIT_TRUE/CUBIT_FALSE
00112     //I ref_face_ptr
00113     //I- A pointer to the RefFace to test the point on
00114     //I point
00115     //I- The point to test
00116     //I check_on_surface
00117     //I- Check if the point is within CUBIT_RESABS of the surface.
00118     //- Test if the closest point on the passed RefFace to the passed
00119     //- point is within the boundary of the RefFace, and if 
00120     //- check_on_surface is true, check that the passed point is within
00121     //- CUBIT_RESABS of the surface.
00122 
00123   CubitStatus make_linearized_curve( Surface* surface_ptr,
00124                                      const CubitVector& start_pt,
00125                                      const CubitVector& end_pt,
00126                                      DLIList<CubitVector*>& segment_points,
00127                                      double arc_angle_tol = CUBIT_DBL_MAX,
00128                                      double midpoint_dist_tol = CUBIT_DBL_MAX,
00129                                      const CubitVector* mid_point = NULL );
00130     //R CubitStatus
00131     //R- CUBIT_SUCCESS/CUBIT_FAILURE
00132     //I surface_ptr
00133     //I- A surface the curve is to lie on.
00134     //I start_pt
00135     //I- The start point of the curve.
00136     //I end_pt
00137     //I- The end point of the curve.
00138     //O segment_points
00139     //O- The curve segments.
00140     //I arc_angle_tol
00141     //I- The maximum angle between surface normal vectors at the start and
00142     //I- end of a segment in a plane tangent to the segment.
00143     //I midpoint_dist_tol
00144     //I- The maximum distance bewteen the midpoint of a segment
00145     //I- and the surface.  
00146     //- This method creates a linear segment
00147     //- beween the start and end points, and then moves that line
00148     //- onto the surface by splitting it, and moveing the split 
00149     //- points onto the surface.  Each segment is bisected and the split
00150     //- point is moved to the surface, until the tolerances are met.
00151   
00152   double loop_area( Loop* loop_ptr );
00153     //R double
00154     //R- A (very) rough approximation of the area of a loop.
00155     //- Do a very rough approximation of the area of a loop.
00156 
00157   CoEdge* closest_loop_coedge( Loop* loop_ptr, 
00158                                const CubitVector& from_pt,
00159                                CoEdge*& other_coedge,
00160                                CubitVector* closest_pt = NULL );
00161   CoEdge* closest_face_coedge( RefFace* face_ptr, 
00162                                const CubitVector& from_pt,
00163                                CoEdge*& other_coedge,
00164                                CubitVector* closest_pt = NULL );
00165     //R CoEdge*
00166     //R- The closest coedge
00167     //I loop_ptr
00168     //I- The loop to check the coedges of.
00169     //I from_pt
00170     //I- The position to check from
00171     //O other_coedge
00172     //O- If the closest point was at a vertex, the other coedge
00173     //O- at that vertex.  This coedge follows the returned coedge
00174     //O- in the loop.
00175     //O closest_pt
00176     //O- The closest point on the loop.
00177     //- This method finds the closest point on a loop, and returnes the
00178     //- coedge it occured on, and optionally the position on that coedge.
00179     
00180   CubitStatus closest_shell_coface( Shell* shell_ptr,
00181                                     const CubitVector& from_pt,
00182                                     DLIList<CoFace*>& result_set,
00183                                     CubitVector* closest_pt = NULL );
00184     //R CubitStatus
00185     //I shell_ptr
00186     //I- A pointer to the shell to evaluate.
00187     //I from_pt
00188     //I- The position to evaluate.
00189     //O result_set
00190     //O- The closest coface to the passed position, or several CoFaces
00191     //O- if they are equidistant from the position.
00192     //O closest_pt
00193     //O- The closest point on the returned coface.
00194     //- This method finds the closest point on a shell, and returnes the
00195     //- coface it occured on, and optionally the position on that coface.
00196     
00197   CubitBoolean is_position_within_shell( const CubitVector& position,
00198                                          Shell* shell_ptr,
00199                                          CubitVector* closest_on_shell = NULL );
00200     //R CubitBoolean    
00201     //R- CUBIT_TRUE/CUBIT_FALSE
00202     //I position
00203     //I- The position to test.  
00204     //I shell_ptr
00205     //I- A pointer to the shell to test.
00206     //O closest_on_shell
00207     //O- The closest point on the shell.
00208     //- This method tests if a point lies within a shell.
00209     //-
00210     //- NOTE: This method will return the expected value only when
00211     //-       the shell is an outside loop!  If the shell represents
00212     //-       a void, CUBIT_TRUE will be returned when the point
00213     //-       is OUTSIDE the shell. (or within the bounded RefVolume)
00214   
00215   CubitBoolean is_position_in_volume( const CubitVector& position,
00216                                       RefVolume* ref_volume_ptr,
00217                                       CubitVector* closest_on_bounary = NULL );
00218     //R CubitBoolean
00219     //R- CUBIT_TRUE/CUBIT_FALSE
00220     //I ref_volume_ptr
00221     //I- A pointer to the RefVolume to test the point on
00222     //I position
00223     //I- The point to test
00224     //- Test if the passed position is within the bounded RefVolume.
00225     
00226   CubitBoolean is_shell_a_void( Shell* shell_ptr );
00227     //R CubitBoolean
00228     //R- CUBIT_TRUE  if the passed shell is a void, or
00229     //R- CUBIT_FALSE if the passed shell is a bounded region.
00230     //I shell_ptr
00231     //I- A pointer to the Shell to test
00232     //- Test if a Shell is a void or an enclosed region.
00233 
00234   RefEdge* find_connected_ref_edge_by_coord( CubitVector& coords, 
00235                                              DLIList<RefEdge*>& ref_edge_list,
00236                                              int& start_flg );
00237     // R RefEdge - pointer to refedge containing coords as start or end location
00238     // R- NULL if no refedge found
00239     // I coords 
00240     // I- xyz position to search for
00241     // I ref_edge_list
00242     // I- list of refedges to search through
00243     // O start_flg
00244     // O- A flag indicating whether coords was on start or end of refedge
00245     // O-  1 = on start
00246     // O-  0 = on end
00247 
00248   void find_connected_ref_edges_by_coord( CubitVector& coords, 
00249                                           DLIList<RefEdge*>& ref_edge_list,
00250                                           DLIList<RefEdge*>& connected_edges_list );
00251     //- From a list of ref_edges, find all that connect by coordinate.
00252 
00253   CubitStatus form_ref_edge_loop_by_coord( DLIList<RefEdge*>& ref_edge_list );
00254     //- Sorts a list of RefEdges such that they form a loop.  The RefEdges
00255     //- need not be connected by vertices - the function uses coordinates
00256     //- to find connected edges.  The order is preserved if they already form 
00257     //- a loop.  Otherwise, the order is determined from the first->second 
00258     //- ref_edge, or if these are not connected, from the start->end of first 
00259     //- ref_edge.  Function returns CUBIT_FAILURE if no loop can be found.
00260 
00261   CubitStatus form_ref_edge_chain_by_coord( DLIList<RefEdge*>& ref_edge_list );
00262     //- Sorts a list of RefEdges such that they form a chain.  The order is
00263     //- preserved if they already form a chain.  Otherwise, the order is
00264     //- determined from the first->second ref_edge, or if these are not
00265     //- connected, from the end of the first ref_edge whose coordinates are
00266     //- not shared by other ref_edges in the list.
00267     //- Function returns CUBIT_FAILURE if no single chain can be found.
00268 
00269   CubitStatus check_valid_chain_by_coord( DLIList<RefEdge*>& ref_edge_list, 
00270                                           DLIList<RefVertex*>& problem_vertices );
00271   CubitStatus check_valid_loop_by_coord( DLIList<RefEdge*>& ref_edge_list,
00272                                          DLIList<RefVertex*>& problem_vertices );
00273     //- Functions to ensure that a valid chain or loop was found.  Checks
00274     //- number of connected edges to each vertex
00275 
00276   // - Same functions as above, but connections by vertex rather than coord
00277   RefEdge* find_connected_ref_edge( RefVertex* ref_vertex_ptr, 
00278                                     DLIList<RefEdge*>& ref_edge_list,
00279                                     int& start_flg );
00280   //- From a list of ref_edges, finds one that connects by vertex.
00281   //- List is searched sequentially.  Also returns whether the
00282   //- start or end of the found curve matches the coordinates.
00283   //- Returns NULL if no matching RefEdge found.
00284 
00285   void find_connected_ref_edges( RefVertex* ref_vertex_ptr, 
00286                                  DLIList<RefEdge*>& ref_edge_list,
00287                                  DLIList<RefEdge*>& connected_edges_list );
00288   //- From a list of ref_edges, find all that connect by vertex.
00289   
00290   CubitStatus form_ref_edge_chain( DLIList<RefEdge*>& ref_edge_list );
00291   //- Sorts a list of RefEdges such that they form a chain.  The order is
00292   //- preserved if they already form a chain.  Otherwise, the order is
00293   //- determined from the first->second ref_edge, or if these are not
00294   //- connected, from the end of the first ref_edge whose coordinates are
00295   //- not shared by other ref_edges in the list.
00296   //- Function returns CUBIT_FAILURE if no single chain can be found.
00297 
00298   CubitStatus form_ref_edge_loop( DLIList<RefEdge*>& ref_edge_list );
00299   //- Sorts a list of RefEdges such that they form a loop.  The RefEdges
00300   //- need not be connected by vertices - the function uses coordinates
00301   //- to find connected edges.  The order is preserved if they already form 
00302   //- a loop.  Otherwise, the order is determined from the first->second 
00303   //- ref_edge, or if these are not connected, from the start->end of first 
00304   //- ref_edge.  Function returns CUBIT_FAILURE if no loop can be found.
00305 
00306   CubitStatus check_valid_chain( DLIList<RefEdge*>& ref_edge_list, 
00307                                  DLIList<RefVertex*>& problem_vertices );
00308   CubitStatus check_valid_loop( DLIList<RefEdge*>& ref_edge_list,
00309                                 DLIList<RefVertex*>& problem_vertices );
00310   //- Functions to ensure that a valid chain or loop was found.  Checks
00311   //- number of connected edges to each vertex
00312     
00313   CubitBoolean valid_edge( RefEdge* edge_ptr, 
00314                            CubitBoolean print_error = CUBIT_TRUE );
00315     //- Check if the vertices are in the correct order on the edge wrt
00316     //- to the specified start and end parameters of the edge.
00317     //- Check if the tangent vectors at the end vertices are in the
00318     //- correct direction.
00319   CubitBoolean valid_loop_coedges( Loop* loop_ptr,
00320                                    CubitBoolean print_error = CUBIT_TRUE );
00321     //- Check that the loop is closed and that the sense of each coedge
00322     //- is logical wrt the next coedge.
00323   CubitBoolean valid_shell_cofaces( Shell* shell_ptr,
00324                                     CubitBoolean print_error = CUBIT_TRUE );
00325     //- Check the relative sense of each coface wrt to its ajacent cofaces.
00326   CubitBoolean valid_topology( TopologyEntity* topo_ptr,
00327                                CubitBoolean print_error = CUBIT_TRUE,
00328                                DLIList<TopologyEntity*>* invalid_list = NULL );
00329     //- Call the above validation methods for the passed TopologyEntity 
00330     //- and all of its children.       
00331     
00332   CubitBoolean valid_sm_topology( DLIList<RefEntity*>& entity_list,
00333                                   CubitBoolean print_error = CUBIT_TRUE );
00334     //- Verify that the VGI DAG matches the solid modeler's topology
00335     //- graph.  Added for verifying correct unmerge.     
00336   CubitBoolean valid_sm_topology( Body*     body_ptr, CubitBoolean print );
00337     //- called by valid_sm_topology(DLIList<RefEntity*>&)
00338   CubitBoolean valid_sm_topology( RefVolume* vol_ptr, CubitBoolean print );
00339     //- called by valid_sm_topology(DLIList<RefEntity*>&)
00340   CubitBoolean valid_sm_topology( Shell*   shell_ptr, CubitBoolean print );
00341     //- called by valid_sm_topology(RefVolume*)
00342   CubitBoolean valid_sm_topology( RefFace*  face_ptr, CubitBoolean print );
00343     //- called by valid_sm_topology(DLIList<RefEntity*>&)
00344   CubitBoolean valid_sm_topology( Loop*     loop_ptr, CubitBoolean print );
00345     //- called by valid_sm_topology(RefFace*)
00346   CubitBoolean valid_sm_topology( CoEdge* coedge_ptr, CubitBoolean print );
00347     //- called by valid_sm_topology(Loop*)
00348   CubitBoolean valid_sm_topology( RefEdge*  edge_ptr, CubitBoolean print );
00349     //- called by valid_sm_topology(DLIList<RefEntity*>&)
00350   CubitBoolean valid_sm_topology( RefVertex* vtx_ptr, CubitBoolean print );
00351     //- called by valid_sm_topology(DLIList<RefEntity*>&)
00352                           
00353   static void list_SM_topology( TopologyBridge* bridge, int depth );
00354   
00355     
00356 protected:
00357 
00358   static void list_SM_topology( TopologyBridge* bridge, int depth, 
00359                                 int indent, int counts[8] );
00360   static int print_topo_bridge( TopologyBridge* bridge, int indent );
00361 
00362   CubitBoolean inside_of_curve( const CubitVector& curve_tangent,
00363                                 const CubitVector& curve_position,
00364                                 const CubitVector& surf_position,
00365                                 const CubitVector& surf_normal );
00366   
00367   CubitStatus recursive_make_curve( Surface* surface_ptr,
00368                                     const CubitVector& start_pt,
00369                                     const CubitVector& end_pt,
00370                                     DLIList<CubitVector*>& segment_points,
00371                                     double arc_angle_tol,
00372                                     double midpoint_dist_tol );
00373     //R CubitStatus
00374     //I surface_ptr
00375     //I- The surface the curve should lie on.
00376     //I start_pt, end_pt
00377     //I- The end points of the curve.
00378     //O segment_points
00379     //O- The list of positions defining the linear polyline result.
00380     //I cos_arc_angle_tol
00381     //I- The arc angle tolerance.
00382     //I midpoint_dist_tol_sqr
00383     //I- The midpoint distance tolerance.
00384     //- This is the recursive method used by 
00385     //- GeometryUtil::make_linearized_curve() to create
00386     //- a segmented curve on a surface.
00387     //-
00388     //- This method creates a line between the start and end points,
00389     //- and moves that line onto the surface by recursively bisecting 
00390     //- the line and moving the midpoint to the surface. 
00391   
00392   GeometryUtil();
00393     //- constructor
00394 
00395 private:
00396   
00397   static GeometryUtil* instance_;
00398   
00399   int linearized_curve_debug_count_;
00400   
00401 };
00402 
00403 #endif
00404 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines