cgma
|
00001 //- Class: MergeTool 00002 //- Description: Location of all Merge and Unmerge functionality 00003 //- Owner: Steven Jankovich 00004 //- Created: 27 April 1998 00005 //- Checked By: 00006 //- Version: $Id: 00007 00008 #ifndef MERGETOOL_HPP 00009 #define MERGETOOL_HPP 00010 00011 #include "CubitDefines.h" 00012 #include "GeometryDefines.h" 00013 #include "CpuTimer.hpp" 00014 #include "DLIList.hpp" 00015 #include "CGMGeomConfigure.h" 00016 00017 #include <typeinfo> 00018 00019 class MergeToolAssistant; 00020 00021 class RefEntity; 00022 class TopologyEntity; 00023 class BasicTopologyEntity; 00024 class GroupingEntity; 00025 class SenseEntity; 00026 class TopologyBridge; 00027 class GeometryEntity; 00028 00029 class RefFace; 00030 class RefEdge; 00031 class RefVertex; 00032 class Loop; 00033 class CoEdge; 00034 00035 class BodySM; 00036 class Body; 00037 class RefEntity; 00038 class RefVolume; 00039 class RefFace; 00040 class RefEdge; 00041 class RefVertex; 00042 class RefGroup; 00043 //template <class X> class DLIList; 00044 class GeometryEntity; 00045 class CAMergePartner; 00046 class UnMergeEvent; 00047 00048 class Surface; 00049 class Curve; 00050 class TBPoint; 00051 class LoopSM; 00052 class CoEdgeSM; 00053 00054 00055 00056 class CUBIT_GEOM_EXPORT MergeTool 00057 { 00058 friend class CAMergePartner; 00059 friend class OldUnmergeCode; 00060 public : 00061 00062 bool displayProgress; 00063 // Show progress meter when merging 00064 00065 static MergeTool* instance(); 00066 // Returns a static pointer to unique instance of this class. 00067 00068 ~MergeTool(); 00069 //- Destructor. 00070 00071 static void delete_instance() 00072 { 00073 if(instance_) 00074 delete instance_; 00075 instance_ = NULL; 00076 } 00077 00078 void imprint_merge_solutions_for_overlapping_surfaces( 00079 RefFace *face1, 00080 RefFace *face2, 00081 bool execute, 00082 DLIList<CubitString> &display_strings, 00083 DLIList<CubitString> &command_strings, 00084 DLIList<CubitString> &preview_strings ); 00085 00086 void merge_with_auto_imprint(RefFace *surf1, RefFace *surf2); 00087 00092 CubitBoolean contains_merged_entities( DLIList<Body*> &bodies ); 00093 00095 CubitBoolean contains_merged_children( Body *body, 00096 DLIList<RefEntity*> &merged_children ); 00097 00101 CubitBoolean contains_merged_entities( DLIList<RefEntity*> &ref_entities, 00102 DLIList<RefEntity*> *merged_ref_ents = NULL ); 00103 00106 CubitBoolean parents_contain_merged_entities( DLIList<RefEntity*> &ref_entities); 00107 00110 CubitBoolean entity_merged( TopologyEntity *entity ); 00111 00114 CubitStatus merge_all_bodies(); 00115 00118 CubitStatus merge_bodies( DLIList<Body*>& refbody_list ); 00119 00122 CubitStatus merge_volumes( DLIList<RefVolume*>& vol_list, 00123 CubitBoolean print_info = CUBIT_TRUE ); 00124 00126 CubitStatus merge_all_reffaces(); 00127 00129 CubitStatus merge_reffaces_old( DLIList<RefFace*>& refface_list, 00130 CubitBoolean print_info = CUBIT_TRUE); 00131 00134 CubitStatus merge_reffaces( DLIList<RefFace*>& refface_list, 00135 CubitBoolean print_info = CUBIT_TRUE); 00136 00138 CubitStatus merge_all_refedges(); 00139 00141 CubitStatus old_merge_refedges( DLIList<RefEdge*>& refedge_list, 00142 CubitBoolean should_clean_out = CUBIT_TRUE, 00143 CubitBoolean print_info = CUBIT_TRUE); 00144 00150 CubitStatus merge_refedges( DLIList<RefEdge*>& refedge_list, 00151 CubitBoolean should_clean_out = CUBIT_TRUE, 00152 CubitBoolean print_info = CUBIT_TRUE); 00153 00155 CubitStatus merge_all_refvertices(); 00156 00158 CubitStatus old_merge_refvertices( DLIList<RefVertex*>& refvertex_list, 00159 CubitBoolean print_info = CUBIT_TRUE ); 00160 00162 CubitStatus merge_refvertices( DLIList<RefVertex*>& refvertex_list, 00163 CubitBoolean print_info = CUBIT_TRUE ); 00164 00166 CubitStatus merge_entities( DLIList<RefEntity*>& entity_list, 00167 CubitBoolean should_clean_out = CUBIT_TRUE, 00168 CubitBoolean print_info = CUBIT_TRUE); 00169 00171 CubitStatus unmerge_all(); 00172 00179 CubitStatus unmerge( DLIList<RefEntity*>& entity_list, CubitBoolean descend = CUBIT_TRUE ); 00180 00182 00183 00184 00185 00186 00187 00188 00189 CubitStatus unmerge( RefEntity* entity_ptr, CubitBoolean descend = CUBIT_TRUE ); 00190 CubitStatus unmerge( RefFace* face_ptr, CubitBoolean descend = CUBIT_TRUE, DLIList<RefFace*> *new_faces = NULL ); 00191 CubitStatus unmerge( RefEdge* edge_ptr, CubitBoolean descend = CUBIT_TRUE, DLIList<RefEdge*> *new_curves = NULL ); 00192 CubitStatus unmerge( Body* body_ptr ); 00193 CubitStatus unmerge( RefVolume* vol_ptr ); 00194 CubitStatus unmerge( RefVertex* vertex_ptr, DLIList<RefVertex*> *new_verts = NULL ); 00196 00200 int unmerged_entities( DLIList<RefEntity*>* entities = NULL ) const; 00201 00206 CubitStatus separate_bodies( DLIList<Body*>& separate_list, 00207 DLIList<Body*>* from_list = NULL ); 00208 00210 00211 00212 00213 00214 CubitStatus separate_volumes( DLIList<RefVolume*>& separate_list, 00215 DLIList<RefVolume*>* from_list = NULL ); 00217 00219 00220 00221 00222 00223 CubitStatus separate_faces( DLIList<RefFace*>& separate_list, 00224 DLIList<RefFace*>* from_list = NULL ); 00226 00228 00229 00230 00231 00232 CubitStatus separate_edges( DLIList<RefEdge*>& separate_list, 00233 DLIList<RefEdge*>* from_list = NULL ); 00235 00237 00238 00239 00240 RefFace* force_merge( RefFace* face1, RefFace* face2 ); 00241 RefEdge* force_merge( RefEdge* edge1, RefEdge* edge2 ); 00242 RefVertex* force_merge( RefVertex* vtx1, RefVertex* vtx2 ); 00243 RefEntity* force_merge( RefEntity* ent1, RefEntity* ent2 ); 00244 RefEntity* force_merge( const DLIList<RefEntity*>& list ); 00245 00247 static void group_results( CubitBoolean t_or_f ); 00248 00250 00251 static void set_new_ids_on_unmerge( CubitBoolean value ); 00252 static CubitBoolean get_new_ids_on_unmerge(); 00254 00256 static void initialize_settings(); 00257 00259 void compare_notify(RefEntity *entity); 00260 00262 void remove_compare_data(); 00263 00264 void add_merge_tool_assistant( MergeToolAssistant* mta_ptr ); 00265 void remove_merge_tool_assistant( MergeToolAssistant* mta_ptr ); 00266 MergeToolAssistant* find_merge_tool_assistant( const std::type_info& type ); 00267 00268 static void destroy_dead_geometry( CubitBoolean yes_no ) 00269 { destroyDeadGeometry = yes_no; } 00270 00277 RefGroup* get_group_last_merged_surfs() 00278 { 00279 //clear this out once this function has been called. 00280 RefGroup *temp = lastSurfsMerged; 00281 lastSurfsMerged = NULL; 00282 return temp; 00283 } 00284 00285 00292 RefGroup* get_group_last_merged_curvs() 00293 { 00294 //clear this out once this function has been called. 00295 RefGroup *temp = lastCurvsMerged; 00296 lastCurvsMerged = NULL; 00297 return temp; 00298 } 00299 00306 RefGroup* get_group_last_merged_verts() 00307 { 00308 //clear this out once this function has been called. 00309 RefGroup *temp = lastVertsMerged; 00310 lastVertsMerged = NULL; 00311 return temp; 00312 } 00313 00314 00320 CubitStatus find_mergeable_refentities( DLIList<RefEntity*> &entities, 00321 DLIList< DLIList<RefFace*>*> &lists_of_mergeable_ref_faces, 00322 DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges, 00323 DLIList< DLIList<RefVertex*>*> &lists_of_mergeable_ref_vertices); 00324 00328 CubitStatus find_mergeable_reffaces( DLIList<RefEntity*> &entities, 00329 DLIList< DLIList<RefFace*>*> &lists_of_mergeable_ref_faces, 00330 bool clean_up_compare_data = true ); 00331 00335 CubitStatus find_mergeable_refedges( DLIList<RefEntity*> &entities, 00336 DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges, 00337 bool clean_up_compare_data = true ); 00338 00342 CubitStatus find_mergeable_refvertices( DLIList<RefEntity*> &entities, 00343 DLIList< DLIList<RefVertex*>*> &lists_of_mergeable_ref_vertices, 00344 bool clean_up_compare_data = true ); 00345 00346 00348 00349 00350 00351 CubitStatus find_only_mergeable_curves( DLIList<Surface*> &surf_list, 00352 DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves, double input_tol = -1.0 ); 00353 CubitStatus find_only_mergeable_curves( DLIList<Curve*> &all_curves, 00354 DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves, double input_tol = -1.0 ); 00355 CubitStatus find_only_mergeable_curves( DLIList<BodySM*> &body_list, 00356 DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves, double input_tol = -1.0 ); 00357 CubitStatus find_only_mergeable_refedges( DLIList<Body*> &body_list, 00358 DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges ); 00360 00362 CubitStatus find_only_mergeable_surfaces( DLIList<BodySM*> &body_list, 00363 DLIList< DLIList<Surface*>*> &lists_of_mergeable_surfaces); 00364 00366 CubitStatus find_only_mergeable_surfaces( DLIList<BodySM*> &body_list, 00367 DLIList< DLIList<Surface*>*> &lists_of_mergeable_surfaces, const double tol ); 00368 00369 00371 CubitBoolean about_spatially_equal( Surface *surf_1, Surface *surf_2, 00372 double tolerance_factor ); 00373 00375 CubitBoolean about_spatially_equal( LoopSM *loop_1, LoopSM *loop_2, 00376 CubitSense relative_sense, double tolerance_factor ); 00377 00379 CubitBoolean about_spatially_equal( CoEdgeSM *coedge_1, CoEdgeSM *coedge_2, 00380 CubitSense relative_sense, double tolerance_factor ); 00381 00383 CubitBoolean about_spatially_equal( Curve *curve_1, Curve *curve_2, 00384 CubitSense &relative_sense, double tolerance_factor ); 00385 00387 CubitBoolean about_spatially_equal( TBPoint *point_1, TBPoint *point_2, 00388 double tolerance_factor ); 00389 00390 protected : 00391 00398 CubitStatus separate_entities( DLIList<TopologyEntity*>& separate_list, 00399 DLIList<TopologyEntity*>* from_list = NULL ); 00400 00404 BasicTopologyEntity* can_separate( DLIList<TopologyBridge*>& bridge_list, 00405 bool check_parents ); 00406 00410 RefFace* separate_face( DLIList<Surface*>& bridges, bool descend ); 00411 00415 RefEdge* separate_edge( DLIList<Curve*>& bridges, bool descend ); 00416 00417 RefVertex* separate_vertex( DLIList<TBPoint*>& bridges ); 00418 //- Split a merged entity into two such that the returned, new 00419 //- entity contains the passed list of bridges. 00420 00421 void cleanup_unmerge(); 00422 //- Does post-processing for unmerge (sending events and such.) 00423 00424 CubitStatus check_saved_id( BasicTopologyEntity* bte ); 00425 //- Used as part of unmerging. If the original geometry 00426 //- entity corresponding to the ID of the passed BTE has 00427 //- been removed/unmerged from the BTE, assign the BTE a 00428 //- new ID from it's current entities so that the new, 00429 //- unmerged entity can be assigned the current ID. 00430 00431 00432 private : 00433 00434 static void warn_about_refface_sense( RefFace* face_ptr_1, 00435 RefFace* face_ptr_2, 00436 bool faces_reversed ); 00437 00438 static CubitBoolean destroyDeadGeometry; 00439 00440 static MergeTool* instance_; 00441 // Static pointer to unique instance of this class 00442 00443 00444 RefGroup *lastSurfsMerged; 00445 RefGroup *lastCurvsMerged; 00446 RefGroup *lastVertsMerged; 00451 00452 DLIList<MergeToolAssistant*> assistant_list_; 00453 //- List of helper objects to handle updates outside the realm 00454 //- of CGM, like updating mesh. 00455 00456 static CubitBoolean groupResults; 00457 //- Tells the tool to group the merging results. 00458 00459 DLIList<RefEntity*> compareEntityList; 00460 //- A list containing entities that have found partners with 00461 //- whom they compare. 00462 00463 DLIList<RefEntity*> mergeSurvivorEntityList; 00464 //- A list containing entities that were involved in a merge 00465 //- operation and survived. 00466 00467 DLIList<RefEntity*> new_unmerged; 00468 DLIList<RefEntity*> old_unmerged; 00469 CubitBoolean unmerged_list_in_use; 00470 //- A list new entities created by unmerging, and a list of 00471 //- existing entities that were unmerged, and a flag set by the highest 00472 //- level method called to begin an unmerge. The flag signifies 00473 //- that lower-level methods should not clear the list when 00474 //- starting/finishing, and should not try to update the graphics. 00475 //- 00476 //- Any method that sets unmerged_list_in_use to true MUST 00477 //- set it to false before returning. 00478 00479 CubitBoolean start_unmerge(); 00480 void end_unmerge( CubitBoolean top ); 00481 //- Handle setting unmerged_list_in_use, clearing lists, 00482 //- and calling cleanup_unmerge(). 00483 00484 MergeTool(); 00485 //- Constructor for the MergeTool object 00486 00487 CubitStatus merge_BTE( BasicTopologyEntity* keeper_entity, 00488 BasicTopologyEntity* dead_entity ); 00489 //R CubitStatus 00490 //R- CUBIT_SUCCESS/FAILURE 00491 //I keeper_entity, dead_entity 00492 //I- The BasicTopologyEntities that are to be merged. 00493 //- This function merges the two BasicTopologyEntities 00494 00495 CubitBoolean compare_BTE( BasicTopologyEntity * keeper_entity, 00496 BasicTopologyEntity * dead_entity ) const; 00497 //R CubitBoolean 00498 //R- CUBIT_TRUE/CUBIT_FALSE 00499 //I basicTopoEntityPtr 00500 //I- The BTE that "this" BTE must be "compared" to. 00501 //- This function compares "this" BasicTopologyEntity with 00502 //- the input BasicTopologyEntity. This is a spatial comparison. 00503 //- IMPORTANT NOTE: 00504 //- The actual spatial comparison of the underlying GeometricEntities 00505 //- is NOT done in this routine. Before this routine is called, 00506 //- the SolidModelingEngine compare routines would have to be called. 00507 //- If matches are found there, the matching pairs of BTE's are tagged 00508 //- with TDCompare objects (containing doubly-linked pointers). This 00509 //- function merely checks to see if these TD objects exist on the 00510 //- "this" and basicTopoEntityPtr objects. If they do, the function 00511 //- checks their pointers to make sure they point to each other. 00512 //- Returns CUBIT_SUCCESS if the comparison was successful. 00513 00514 CubitStatus merge_GE( GroupingEntity* keeper_entity, 00515 GroupingEntity* dead_entity ); 00516 //R CubitStatus 00517 //R- CUBIT_SUCCESS/CUBIT_FAILURE 00518 //I keeper_entity, dead_entity 00519 //I- The GroupingEntities that are to be merged. 00520 //- This function merges the two GroupingEntities 00521 00522 CubitBoolean compare_GE( GroupingEntity* keeper_entity, 00523 GroupingEntity* dead_entity ); 00524 //R CubitBoolean 00525 //R- CUBIT_TRUE/CUBIT_FALSE 00526 //I dead_GroupingEntityPtr 00527 //I- This GroupingEntity with which comparision is to be done. 00528 //- This function patially compares this GroupingEntity to the input 00529 //- GroupingEntity. The function returns CUBIT_TRUE if the two 00530 //- objects are spatially equal, CUBIT_FALSE otherwise. 00531 //- MJP NOTE: 00532 //- The first trial check that is done is to make sure that the 00533 //- GroupingEntities have the same number of SenseEntities. 00534 //- If they do not, then we ASSUME that the GroupingEntities 00535 //- are not spatially equal. This is not strictly a good 00536 //- assumption, but we don't have a more exact algorithm 00537 //- that takes care of the case where, for example, the number 00538 //- of RefEdges associated with two Loops are different, but 00539 //- the Loops themselves are spatialy equal. Consider the case 00540 //- of 2 Loops representing the exact same square -- one can 00541 //- have 4 RefEdges and the other could have 5 (just bisect one 00542 //- of the previous ones...) 00543 00544 CubitStatus compare_and_merge( CubitBoolean merge_flag, 00545 GroupingEntity* keeper_entity, 00546 GroupingEntity* dead_entity ); 00547 //R CubitStatus 00548 //R- the result of spatial comparison if if_merge is CUBIT_FALSE, 00549 //R- or the result of merge if if_merge is CUBIT_TRUE 00550 //I if_merge 00551 //I- If this flag is CUBIT_TRUE, whenever find the matching SenseEntities, 00552 //I do the merge. otherwise, skip the merge block. 00553 //- This private function always do the spatially comparison of "this" 00554 //- GroupingEntity with the input GroupingEntity, by comparing the 00555 //- associated SenseEntities of "this" and input GroupingEntity. If all 00556 //- the SenseEntites associated with "this" GroupingEntity have matching 00557 //- SenseEntity associated with the input GroupingEntity, then "this" and 00558 //- the input GroupingEntity are spatially equal. 00559 //- SPECIAL NOTES : 00560 // Merging the OSME's and merging links are done in merge() 00561 // function. In this function, ONLY the matching SenseEntities 00562 // can be merged when asked to merge them ( i.e., if_merge 00563 // flag is set to CUBIT_TRUE ). 00564 00565 CubitStatus merge_SE( SenseEntity* keeper_entity, 00566 SenseEntity* dead_entity ); 00567 //R CubitStatus 00568 //R- CUBIT_SUCCESS/CUBIT_FAILURE 00569 //I dead_SenseEntityPtr 00570 //I- A pointer to a SenseEntity which is about to be merged 00571 //I- with "this". 00572 //- This function merges the input dead_SenseEntityPtr with this 00573 //- SenseEntity. If the operation can fail if the two entitys are 00574 //- of different types (derived types.) At the end of a successful 00575 //- operation, the dead_SenseEntityPtr is an entity that is 00576 //- dangling in space with no connection to any other entity. The 00577 //- return value is CUBIT_SUCCESS when a successful merge occurs, 00578 //- CUBIT_FAILURE otherwise. 00579 00580 CubitBoolean compare_SE( SenseEntity* keeper_entity, 00581 SenseEntity* dead_entity ); 00582 //R CubitBoolean 00583 //R- CUBIT_TRUE/CUBIT_FALSE 00584 //I dead_SenseEntityPtr 00585 //I- This SenseEntity with which comparision is to be done. 00586 //- This function patially compares this SenseEntity to the input 00587 //- SenseEntity. The function returns CUBIT_TRUE if the two 00588 //- objects are spatially equal, CUBIT_FALSE otherwise. 00589 00590 void complete_merge(); 00591 //- completed or abort a merge; clean up TDs and lists 00592 00593 void test_r_tree(DLIList<RefFace*> &refface_list); 00594 void test_r_star_tree(DLIList<RefFace*> &refface_list); 00595 void test_no_tree(DLIList<RefFace*> &refface_list); 00596 //- temp timing functions for testing with and without and r-tree. 00597 00598 }; 00599 inline void MergeTool::group_results(CubitBoolean t_or_f) 00600 {groupResults = t_or_f;} 00601 00602 00603 //------------------------------------------------------------------------- 00604 // Purpose : Start/stop unmerge 00605 // 00606 // Special Notes : 00607 // 00608 // Creator : Jason Kraftcheck 00609 // 00610 // Creation Date : 01/18/01 00611 //------------------------------------------------------------------------- 00612 inline CubitBoolean MergeTool::start_unmerge() 00613 { 00614 if( unmerged_list_in_use ) return CUBIT_FALSE; 00615 new_unmerged.clean_out(); 00616 old_unmerged.clean_out(); 00617 unmerged_list_in_use = CUBIT_TRUE; 00618 return CUBIT_TRUE; 00619 } 00620 inline void MergeTool::end_unmerge( CubitBoolean top ) 00621 { 00622 if( top ) 00623 { 00624 unmerged_list_in_use = CUBIT_FALSE; 00625 cleanup_unmerge(); 00626 } 00627 } 00628 00629 #endif 00630