cgma
|
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