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