cgma
OldUnmergeCode.cpp
Go to the documentation of this file.
00001 #include "OldUnmergeCode.hpp"
00002 
00003 #include "Body.hpp"
00004 #include "CoVolume.hpp"
00005 #include "RefVolume.hpp"
00006 #include "Shell.hpp"
00007 #include "CoFace.hpp"
00008 #include "RefFace.hpp"
00009 #include "Loop.hpp"
00010 #include "CoEdge.hpp"
00011 #include "RefEdge.hpp"
00012 #include "Chain.hpp"
00013 #include "CoVertex.hpp"
00014 #include "RefVertex.hpp"
00015 
00016 #include "BodySM.hpp"
00017 #include "Lump.hpp"
00018 #include "ShellSM.hpp"
00019 #include "Surface.hpp"
00020 #include "LoopSM.hpp"
00021 #include "CoEdgeSM.hpp"
00022 #include "Curve.hpp"
00023 #include "Point.hpp"
00024 
00025 #include "GeometryQueryTool.hpp"
00026 #include "RefEntityFactory.hpp"
00027 #include "CpuTimer.hpp"
00028 #include "ProgressTool.hpp"
00029 #include "AppUtil.hpp"
00030 
00031 #include "MergeTool.hpp"
00032 #include "MergeToolAssistant.hpp"
00033 #include "SettingHandler.hpp"
00034 
00035 
00036 void OldUnmergeCode::initialize_settings()
00037 {
00038   SettingHandler::instance()->add_setting("unmerge new ids",
00039                                           OldUnmergeCode::set_use_old_unmerge_code,
00040                                           OldUnmergeCode::get_use_old_unmerge_code);
00041 }
00042 
00043 bool OldUnmergeCode::useOldUnmergeCode = false;
00044 
00045    
00046 bool OldUnmergeCode::get_use_old_unmerge_code()
00047     { return useOldUnmergeCode; }
00048     
00049 void OldUnmergeCode::set_use_old_unmerge_code( bool value )
00050     { useOldUnmergeCode = value; }
00051 
00052 
00053 
00054 
00055 OldUnmergeCode& OldUnmergeCode::instance()
00056 {
00057   static OldUnmergeCode instance_;
00058   return instance_;
00059 }
00060 
00061 //-------------------------------------------------------------------------
00062 // Purpose       : Unmerge everything
00063 //
00064 // Special Notes : 
00065 //
00066 // Creator       : Jason Kraftcheck
00067 //
00068 // Creation Date : 03/27/01
00069 //-------------------------------------------------------------------------
00070 CubitStatus OldUnmergeCode::unmerge_all()
00071 {
00072   if (!get_use_old_unmerge_code())
00073     return MergeTool::instance()->unmerge_all();
00074   
00075   int i;
00076   CubitStatus result = CUBIT_SUCCESS;
00077   CubitBoolean top = start_unmerge();
00078   
00079   
00080   DLIList<RefFace*>  face_list;
00081   DLIList<RefEdge*>  edge_list;
00082   DLIList<RefVertex*> vtx_list;
00083   
00084   GeometryQueryTool::instance()->ref_faces( face_list );
00085   GeometryQueryTool::instance()->ref_edges( edge_list );
00086   GeometryQueryTool::instance()->ref_vertices( vtx_list );
00087   
00088   for( i = face_list.size(); (i > 0) && !AppUtil::instance()->interrupt(); i-- )
00089     if( ! unmerge(face_list.get_and_step(),CUBIT_FALSE) )
00090       result = CUBIT_FAILURE;
00091  
00092   for( i = edge_list.size(); (i > 0) && !AppUtil::instance()->interrupt(); i-- )
00093     if( ! unmerge(edge_list.get_and_step(),CUBIT_FALSE) ) 
00094       result = CUBIT_FAILURE;
00095   
00096   for( i = vtx_list.size(); (i > 0) && !AppUtil::instance()->interrupt(); i-- )
00097     if( ! unmerge(vtx_list.get_and_step()) )
00098       result = CUBIT_FAILURE;
00099   
00100   end_unmerge(top);
00101   return result;
00102 }
00103 
00104 
00105 //-------------------------------------------------------------------------
00106 // Purpose       : Unmerge RefEntities
00107 //
00108 // Special Notes : 
00109 //
00110 // Creator       : Jason Kraftcheck
00111 //
00112 // Creation Date : 01/18/01
00113 //-------------------------------------------------------------------------
00114 CubitStatus OldUnmergeCode::unmerge( DLIList<RefEntity*> &entity_list,
00115                                 CubitBoolean descend )
00116 {
00117   if (!get_use_old_unmerge_code())
00118     return MergeTool::instance()->unmerge(entity_list, descend);
00119   
00120   CubitBoolean top = start_unmerge();
00121   
00122   for( int i = entity_list.size(); (i > 0) && !AppUtil::instance()->interrupt(); i-- )
00123     unmerge( entity_list.get_and_step(), descend );
00124   
00125   end_unmerge(top);
00126   return CUBIT_SUCCESS;
00127 }
00128 
00129 //-------------------------------------------------------------------------
00130 // Purpose       : Unmerge a RefEntity
00131 //
00132 // Special Notes : All parents must be unmerged.
00133 //
00134 // Creator       : Jason Kraftcheck
00135 //
00136 // Creation Date : 01/18/01
00137 //-------------------------------------------------------------------------
00138 CubitStatus OldUnmergeCode::unmerge( RefEntity* entity_ptr, CubitBoolean descend )
00139 {
00140   if (!get_use_old_unmerge_code())
00141     return MergeTool::instance()->unmerge(entity_ptr, descend);
00142   
00143   if( CAST_TO( entity_ptr, Body ) )
00144      return descend ? unmerge(CAST_TO(entity_ptr,Body)) : CUBIT_FAILURE;
00145   else if( CAST_TO( entity_ptr, RefVolume ) )
00146      return descend ? unmerge(CAST_TO(entity_ptr,RefVolume)) : CUBIT_FAILURE;
00147   else if( CAST_TO( entity_ptr, RefFace ) )
00148      return unmerge( CAST_TO(entity_ptr,RefFace), descend );
00149   else if( CAST_TO( entity_ptr, RefEdge ) )
00150      return unmerge( CAST_TO(entity_ptr,RefEdge), descend );
00151   else if( CAST_TO( entity_ptr, RefVertex ) )
00152      return unmerge( CAST_TO(entity_ptr,RefVertex) );
00153   else
00154   {
00155     PRINT_ERROR("Bad Entity \"%s\" in "
00156                 "OldUnmergeCode::unmerge(RefEntity*,CubitBoolean)\n",
00157                 entity_ptr->class_name());
00158       return CUBIT_FAILURE;
00159   }
00160 }
00161 
00162 CubitStatus OldUnmergeCode::unmerge( Body* body_ptr )
00163 {
00164   if (!get_use_old_unmerge_code())
00165     return MergeTool::instance()->unmerge(body_ptr);
00166   
00167   CubitBoolean top = start_unmerge();
00168   CubitStatus result = CUBIT_SUCCESS;
00169   DLIList<RefVolume*> vol_list;
00170   body_ptr->ref_volumes(vol_list);
00171   for( int i = vol_list.size(); (i > 0) && !AppUtil::instance()->interrupt(); i-- )
00172     if( !unmerge(vol_list.get_and_step()) )
00173       result = CUBIT_FAILURE;
00174   end_unmerge(top);
00175   return result;
00176 }
00177 
00178 CubitStatus OldUnmergeCode::unmerge( RefVolume* vol_ptr )
00179 {
00180   if (!get_use_old_unmerge_code())
00181     return MergeTool::instance()->unmerge(vol_ptr);
00182   
00183   CubitBoolean top = start_unmerge();
00184   CubitStatus result = CUBIT_SUCCESS;
00185   DLIList<RefFace*> face_list, new_faces;
00186   DLIList<RefEdge*> edge_list, new_edges;
00187   DLIList<RefVertex*> vtx_list;
00188   vol_ptr->ref_faces(face_list);
00189   vol_ptr->ref_edges(edge_list);
00190   vol_ptr->ref_vertices(vtx_list);
00191   face_list.reset();
00192   while( face_list.size() && !AppUtil::instance()->interrupt() )
00193   {
00194     RefFace* old_face = face_list.extract();
00195     RefFace* new_face = unmerge(old_face,vol_ptr);
00196     if( new_face ) 
00197       new_faces.append(new_face);
00198     else
00199       result = CUBIT_FAILURE;
00200   }
00201   
00202   while( edge_list.size() && !AppUtil::instance()->interrupt() )
00203   {
00204     RefEdge* old_edge = edge_list.extract();
00205     face_list.clean_out();
00206     old_edge->ref_faces(face_list);
00207     while( face_list.size() )
00208     {
00209       RefFace* face_ptr = face_list.extract();
00210       if( new_faces.is_in_list(face_ptr) )
00211       {
00212         RefEdge* new_edge = unmerge(old_edge,face_ptr);
00213         if( new_edge )
00214           new_edges.append(new_edge);
00215         else
00216           result = CUBIT_FAILURE;
00217         break;
00218       }
00219     }
00220   }
00221   
00222   
00223   while( vtx_list.size() && !AppUtil::instance()->interrupt() )
00224   {
00225     RefVertex* old_vtx = vtx_list.extract();
00226     edge_list.clean_out();
00227     old_vtx->ref_edges(edge_list);
00228     while( edge_list.size() )
00229     {
00230       RefEdge* edge_ptr = edge_list.extract();
00231       if( new_edges.is_in_list(edge_ptr) )
00232       {
00233         RefVertex* new_vtx = unmerge(old_vtx,edge_ptr);
00234         if( !new_vtx )
00235           result = CUBIT_FAILURE;
00236         break;
00237       }
00238     }
00239   }
00240   
00241   end_unmerge(top);
00242   return result;
00243 }
00244 
00245 CubitStatus OldUnmergeCode::unmerge( RefFace* face_ptr, CubitBoolean descend )
00246 {
00247   if (!get_use_old_unmerge_code())
00248     return MergeTool::instance()->unmerge(face_ptr, descend);
00249   
00250   CubitBoolean top = start_unmerge();
00251   CubitStatus result = CUBIT_SUCCESS;
00252   CubitBoolean reversed;
00253   int i;
00254   
00255 //  if( !face_ptr->can_modify() )
00256 //    return CUBIT_FAILURE;
00257   
00258   DLIList<RefFace*> unmerged_faces;
00259   DLIList<RefVolume*> vol_list;
00260   face_ptr->ref_volumes(vol_list);
00261   if( vol_list.size() )
00262   {
00263     for( i = vol_list.size(); i > 0; i-- )
00264     {
00265       RefFace* new_face = unmerge(face_ptr,vol_list.get_and_step());
00266       if( new_face )
00267         unmerged_faces.append_unique(new_face);
00268       else
00269         result = CUBIT_FAILURE;
00270     }
00271   }
00272   else
00273   {
00274     DLIList<TopologyBridge*> bridge_list;
00275     face_ptr->bridge_manager()->get_bridge_list( bridge_list );
00276     
00277     //Try top remove each bridge
00278     for( i = bridge_list.size(); i > 0; i-- )
00279     {
00280       //but stop if there is only one left
00281       if( face_ptr->bridge_manager()->number_of_bridges() == 1 )
00282       {
00283         unmerged_faces.append(face_ptr);
00284         break;
00285       }
00286       
00287       TopologyBridge* bridge_ptr = bridge_list.get_and_step();
00288       Surface* surf_ptr = CAST_TO(bridge_ptr,Surface);
00289       assert(surf_ptr != 0);
00290       RefFace* new_face = split_out_Surface(surf_ptr, reversed);
00291       if( new_face )
00292       {
00293         unmerged_faces.append(new_face);
00294   
00295           //Notify merge assistants of unmerge
00296         DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
00297         for( int a = assistant_list_.size(); a > 0; a-- )
00298           assistant_list_.get_and_step()->
00299             unmerged( face_ptr, new_face, reversed );
00300       }
00301       else
00302         result = CUBIT_FAILURE;
00303     }
00304     if( !unmerged_faces.is_in_list(face_ptr) )
00305       result = CUBIT_FAILURE;
00306   }
00307   
00308   if( !descend ) 
00309   {
00310     end_unmerge(top);
00311     return result;
00312   }
00313   
00314   DLIList<RefEdge*> edge_list, unmerged_edges;
00315   for( i = unmerged_faces.size(); i > 0; i-- )
00316   {
00317     face_ptr = unmerged_faces.get_and_step();
00318     edge_list.clean_out();
00319     face_ptr->ref_edges(edge_list);
00320     for( int j = edge_list.size(); j > 0; j-- )
00321     {
00322       RefEdge* new_edge = unmerge(edge_list.get_and_step(),face_ptr);
00323       if( new_edge )
00324         unmerged_edges.append_unique(new_edge);
00325       else
00326         result = CUBIT_FAILURE;
00327     }
00328   }
00329   
00330   DLIList<RefVertex*> vtx_list;
00331   for( i = unmerged_edges.size(); i > 0; i-- )
00332   {
00333     RefEdge* edge_ptr = unmerged_edges.get_and_step();
00334     vtx_list.clean_out();
00335     edge_ptr->ref_vertices(vtx_list);
00336     for( int j = vtx_list.size(); j > 0; j-- )
00337     {
00338       RefVertex* new_vtx = unmerge(vtx_list.get_and_step(),edge_ptr);
00339       if( !new_vtx ) result = CUBIT_FAILURE;
00340     }
00341   }
00342        
00343   end_unmerge(top);
00344   return result;
00345 }
00346 
00347 
00348 CubitStatus OldUnmergeCode::unmerge( RefEdge* edge_ptr, CubitBoolean descend )
00349 {
00350   if (!get_use_old_unmerge_code())
00351     return MergeTool::instance()->unmerge(edge_ptr, descend);
00352   
00353   CubitBoolean top = start_unmerge();
00354   CubitStatus result = CUBIT_SUCCESS;
00355   CubitBoolean reversed;
00356   int i;
00357   
00358 //  if( !edge_ptr->can_modify() )
00359 //    return CUBIT_FAILURE;
00360   
00361   DLIList<RefEdge*> unmerged_edges;
00362   DLIList<RefFace*> face_list;
00363   edge_ptr->ref_faces(face_list);
00364   if( face_list.size() )
00365   {
00366     for( i = face_list.size(); i > 0; i-- )
00367     {
00368       RefEdge* new_edge = unmerge(edge_ptr,face_list.get_and_step());
00369       if( new_edge )
00370         unmerged_edges.append_unique(new_edge);
00371       else
00372         result = CUBIT_FAILURE;
00373     }
00374   }
00375   else
00376   {
00377     DLIList<TopologyBridge*> bridge_list;
00378     DLIList<Curve*> curve_list;
00379     edge_ptr->bridge_manager()->get_bridge_list( bridge_list );
00380     
00381     //Try top remove each bridge
00382     for( i = bridge_list.size(); i > 0; i-- )
00383     {
00384       //but stop if there is only one left
00385       if( edge_ptr->bridge_manager()->number_of_bridges() == 1 )
00386       {
00387         unmerged_edges.append(edge_ptr);
00388         break;
00389       }
00390       
00391       TopologyBridge* bridge_ptr = bridge_list.get_and_step();
00392       curve_list.clean_out();
00393       curve_list.append( CAST_TO(bridge_ptr,Curve) );
00394       RefEdge* new_edge = split_out_Curves(curve_list, reversed);
00395       if( new_edge )
00396       {
00397         unmerged_edges.append(new_edge);
00398   
00399           //Notify merge assistants of unmerge
00400         DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
00401         for( int a = assistant_list_.size(); a > 0; a-- )
00402           assistant_list_.get_and_step()->
00403             unmerged( edge_ptr, new_edge, reversed );
00404       }
00405       else
00406         result = CUBIT_FAILURE;
00407     }
00408     if( !unmerged_edges.is_in_list(edge_ptr) )
00409       result = CUBIT_FAILURE;
00410   }
00411   
00412   if( !descend ) 
00413   {
00414     end_unmerge(top);
00415     return result;
00416   }
00417   
00418   DLIList<RefVertex*> vtx_list;
00419   for( i = unmerged_edges.size(); i > 0; i-- )
00420   {
00421     edge_ptr = unmerged_edges.get_and_step();
00422     vtx_list.clean_out();
00423     edge_ptr->ref_vertices(vtx_list);
00424     for( int j = vtx_list.size(); j > 0; j-- )
00425     {
00426       RefVertex* new_vtx = unmerge(vtx_list.get_and_step(),edge_ptr);
00427       if( !new_vtx )
00428         result = CUBIT_FAILURE;
00429     }
00430   }
00431   
00432   end_unmerge(top);
00433   return result;
00434 }
00435 
00436 
00437 CubitStatus OldUnmergeCode::unmerge( RefVertex* vtx_ptr )
00438 {
00439   if (!get_use_old_unmerge_code())
00440     return MergeTool::instance()->unmerge(vtx_ptr);
00441   
00442   CubitBoolean top = start_unmerge();
00443   CubitStatus result = CUBIT_SUCCESS;
00444   int i;
00445   
00446 //  if( !vtx_ptr->can_modify() )
00447 //    return CUBIT_FAILURE;
00448   
00449   DLIList<RefVertex*> unmerged_vtxs;
00450   DLIList<RefEdge*> edge_list;
00451   vtx_ptr->ref_edges(edge_list);
00452   if( edge_list.size() )
00453   {
00454     for( i = edge_list.size(); i > 0; i-- )
00455     {
00456       RefVertex* new_vtx = unmerge(vtx_ptr,edge_list.get_and_step());
00457       if( new_vtx )
00458         unmerged_vtxs.append_unique(new_vtx);
00459       else
00460         result = CUBIT_FAILURE;
00461     }
00462   }
00463   else
00464   {
00465     DLIList<TopologyBridge*> bridge_list;
00466     DLIList<TBPoint*> point_list;
00467     vtx_ptr->bridge_manager()->get_bridge_list( bridge_list );
00468     
00469     //Try top remove each bridge
00470     for( i = bridge_list.size(); i > 0; i-- )
00471     {
00472       //but stop if there is only one left
00473       if( vtx_ptr->bridge_manager()->number_of_bridges() == 1 )
00474       {
00475         unmerged_vtxs.append(vtx_ptr);
00476         break;
00477       }
00478       
00479       TopologyBridge* bridge_ptr = bridge_list.get_and_step();
00480       point_list.clean_out();
00481       point_list.append( CAST_TO(bridge_ptr,TBPoint) );
00482       RefVertex* new_vtx = split_out_Points(point_list);
00483       if( new_vtx )
00484       {
00485         unmerged_vtxs.append(new_vtx);
00486   
00487           //Notify merge assistants of unmerge
00488         DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
00489         for( int a = assistant_list_.size(); a > 0; a-- )
00490           assistant_list_.get_and_step()->
00491             unmerged( vtx_ptr, new_vtx, CUBIT_FALSE );
00492       }
00493       else
00494         result = CUBIT_FAILURE;
00495     }
00496     if( !unmerged_vtxs.is_in_list(vtx_ptr) )
00497       result = CUBIT_FAILURE;
00498   }
00499   
00500   end_unmerge(top);
00501   return result;
00502 }
00503 
00504 
00505 //-------------------------------------------------------------------------
00506 // Purpose       : Given an unmerged parent, and a merged child, 
00507 //                 unmerge the topology bridge of the child that 
00508 //                 corresponds to the passed parent.
00509 //
00510 // Special Notes : 
00511 //
00512 // Creator       : Jason Kraftcheck
00513 //
00514 // Creation Date : 01/18/01
00515 //-------------------------------------------------------------------------
00516 RefFace* OldUnmergeCode::unmerge( RefFace* face_ptr, RefVolume* vol_ptr )
00517 {  
00518   assert( face_ptr && vol_ptr );
00519   CubitBoolean top = start_unmerge();
00520   CubitBoolean reversed;
00521   int i;
00522   
00523 //  if( !face_ptr->can_modify() )
00524 //  {
00525 //    end_unmerge(top);
00526 //    return 0;
00527 //  }
00528   
00529   //If passed entity is not merged, just return it.
00530   if( face_ptr->bridge_manager()->number_of_bridges() < 2 )
00531   {
00532     end_unmerge(top);
00533     return face_ptr;
00534   }
00535   
00536   //Find the Surfaces of face_ptr that go with vol_ptr
00537   DLIList<Lump*> surf_lumps;
00538   DLIList<Surface*> surface_list;
00539   DLIList<TopologyBridge*> bridge_list;
00540   face_ptr->bridge_manager()->get_bridge_list(bridge_list);
00541   for( i = bridge_list.size(); i > 0; i-- )
00542   {
00543     TopologyBridge* bridge_ptr = bridge_list.get_and_step();
00544     surf_lumps.clean_out();
00545     bridge_ptr->lumps(surf_lumps);
00546     for( int j = surf_lumps.size(); j> 0; j-- )
00547     {
00548       if( surf_lumps.get_and_step()->topology_entity() == vol_ptr )
00549       {
00550         surface_list.append(CAST_TO(bridge_ptr,Surface));
00551         break;
00552       }
00553     }
00554   }
00555   //face_ptr and vol_ptr have no association in SM topology!!
00556   if( ! surface_list.size() )
00557   {
00558     end_unmerge(top);
00559     return 0;
00560   }
00561   
00562   //Assuming this is true, until this assert fails
00563   assert(surface_list.size() == 1);
00564   Surface* surface_ptr = surface_list.get();
00565 
00566   // Unmerge any child GroupingEntities and SenseEntities,
00567   // and reconstruct a new owner.
00568   RefFace* new_entity 
00569     = split_out_Surface( surface_ptr, reversed );
00570   if( !new_entity )
00571   {
00572     end_unmerge(top);
00573     return 0;
00574   }
00575 
00576   // Find any links from parent to old entity, and move them
00577   // to the new, unmerged entity.
00578   DLIList<CoFace*> coface_list;
00579   DLIList<ShellSM*> shellsm_list;
00580   surface_ptr->shellsms( shellsm_list );
00581   for( i = shellsm_list.size(); i > 0; i-- )
00582   {
00583     ShellSM* shellsm = shellsm_list.get_and_step();
00584     Shell* shell_ptr = CAST_TO(shellsm->topology_entity(),Shell);
00585     if( !shell_ptr ) continue;
00586     
00587     coface_list.clean_out();
00588     shell_ptr->co_faces(coface_list);
00589     for( int j = coface_list.size(); j > 0; j-- )
00590     {
00591       CoFace* cof_ptr = coface_list.get_and_step();
00592       if( cof_ptr->get_ref_face_ptr() == face_ptr )
00593       {
00594         cof_ptr->switch_basic_topology_entity(new_entity);
00595         if( reversed ) cof_ptr->reverse_sense();
00596       }
00597     }
00598   }
00599   
00600   //We have changed the topology of the passed RefVolume.
00601   //Note this for later.
00602   unmerge_modified.append( face_ptr );
00603   
00604   //Notify merge assistants of unmerge
00605   DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
00606   for( int a = assistant_list_.size(); a > 0; a-- )
00607     assistant_list_.get_and_step()->
00608       unmerged( face_ptr, new_entity, reversed );
00609   
00610   end_unmerge(top);  
00611   return new_entity;
00612 }
00613 
00614 
00615 RefEdge* OldUnmergeCode::unmerge( RefEdge* edge_ptr, RefFace* face_ptr )
00616 {  
00617   assert( face_ptr && edge_ptr );
00618   CubitBoolean top = start_unmerge();
00619   CubitBoolean reversed;
00620   int i;
00621   
00622 //  if( !edge_ptr->can_modify() )
00623 //  {
00624 //    end_unmerge(top);
00625 //    return 0;
00626 //  }
00627   
00628   //If passed entity is not merged, just return it.
00629   if( edge_ptr->bridge_manager()->number_of_bridges() < 2 )
00630   {
00631     end_unmerge(top);
00632     return edge_ptr;
00633   }
00634   
00635   //If parent is merged, cannot proceed.
00636   if( face_ptr->bridge_manager()->number_of_bridges() != 1 )
00637   {
00638     end_unmerge(top);
00639     return 0;
00640   }
00641   
00642   //Parent is not merged.  This is the only Surface
00643   Surface* surf_ptr = CAST_TO( face_ptr->get_geometry_entity_ptr(), Surface );
00644   assert(surf_ptr != 0);
00645   
00646   //Find curves in edge_ptr associated with surf_ptr.
00647   //We need to check links in both directions becuase with virtual
00648   //geometry, links may only exist in one direction.
00649   //
00650   //Check downward links.
00651   DLIList<Curve*> curve_list, surf_curves;
00652   surf_ptr->curves(surf_curves);
00653   for( i = surf_curves.size(); i > 0; i-- )
00654   {
00655     Curve* curve_ptr = surf_curves.get_and_step();
00656     if( curve_ptr->topology_entity() == edge_ptr )
00657       curve_list.append(curve_ptr);
00658 //    else if( curve_ptr->topology_entity()->is_parasite(edge_ptr) )
00659 //      curve_list.append(curve_ptr);
00660   }
00661   //Check upward links.
00662   DLIList<TopologyBridge*> bridge_list;
00663   DLIList<Surface*> curve_surfs;
00664   edge_ptr->bridge_manager()->get_bridge_list(bridge_list);
00665   for( i = bridge_list.size(); i > 0; i-- )
00666   {
00667     TopologyBridge* bridge_ptr = bridge_list.get_and_step();
00668     curve_surfs.clean_out();
00669     bridge_ptr->surfaces(curve_surfs);
00670     for( int j = curve_surfs.size(); j > 0; j-- )
00671     {
00672       TopologyEntity* te_ptr = curve_surfs.get_and_step()->topology_entity();
00673       //if( te_ptr == face_ptr )
00674       if (te_ptr == face_ptr) /*|| face_ptr->is_host(te_ptr)*/
00675       {
00676         curve_list.append_unique(CAST_TO(bridge_ptr,Curve));
00677         break;
00678       }
00679     }
00680   }
00681   
00682   //If there is no association between the passed edge_ptr and
00683   //face_ptr in the SM topology
00684   if( ! curve_list.size() )
00685   {
00686     end_unmerge(top);
00687     return 0;
00688   }
00689   
00690   // Unmerge any child GroupingEntities and SenseEntities,
00691   // and reconstruct a new owner.
00692   RefEdge* new_entity 
00693     = split_out_Curves( curve_list, reversed );
00694   if( !new_entity )
00695   {
00696     end_unmerge(top);
00697     return 0;
00698   }
00699   
00700   //We have changed the topology of the passed RefFace.
00701   //Note this for later.
00702   unmerge_modified.append( edge_ptr );
00703 
00704   // Find any links from parent to old entity, and move them
00705   // to the new, unmerged entity.
00706   DLIList<CoEdge*> coedge_list;
00707   DLIList<Curve*> coe_curves, tmp_list;
00708   DLIList<TopologyBridge*> tb_list;
00709   edge_ptr->get_co_edges (coedge_list);
00710   for( i = coedge_list.size(); i > 0; i-- )
00711   {
00712     tb_list.clean_out();
00713     coe_curves.clean_out();
00714     CoEdge* coe_ptr = coedge_list.get_and_step();
00715     coe_ptr->bridge_manager()->get_bridge_list(tb_list);
00716     for( int j = tb_list.size(); j> 0; j-- )
00717     {
00718       tmp_list.clean_out();
00719       tb_list.get_and_step()->curves(tmp_list);
00720       coe_curves.merge_unique(tmp_list);
00721     }
00722     coe_curves.intersect(curve_list);
00723     
00724     if( coe_curves.size() )
00725     {
00726       coe_ptr->switch_basic_topology_entity(new_entity);
00727       if( reversed ) 
00728         coe_ptr->reverse_sense();
00729     }
00730   }
00731   
00732   //Notify merge assistants of unmerge
00733   DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
00734   for( int a = assistant_list_.size(); a > 0; a-- )
00735     assistant_list_.get_and_step()->
00736       unmerged( edge_ptr, new_entity, reversed );
00737   
00738   
00739   end_unmerge(top);  
00740   return new_entity;
00741 }
00742 
00743 RefVertex* OldUnmergeCode::unmerge( RefVertex* vtx_ptr, RefEdge* edge_ptr )
00744 {  
00745   assert( vtx_ptr && edge_ptr );
00746   CubitBoolean top = start_unmerge();
00747   int i;
00748   
00749 //  if( !vtx_ptr->can_modify() )
00750 //  {
00751 //    end_unmerge(top);
00752 //    return 0;
00753 //  }
00754   
00755   //If passed entity is not merged, just return it.
00756   if( vtx_ptr->bridge_manager()->number_of_bridges() < 2 )
00757   {
00758     end_unmerge(top);
00759     return vtx_ptr;
00760   }
00761   
00762   //If parent is merged, cannot proceed.
00763   if( edge_ptr->bridge_manager()->number_of_bridges() != 1 )
00764   {
00765     end_unmerge(top);
00766     return 0;
00767   }
00768   
00769   //Parent is not merged,  This is the only Curve.
00770   Curve* curve_ptr = CAST_TO( edge_ptr->get_geometry_entity_ptr(), Curve );
00771   assert(curve_ptr != 0);
00772 
00773   //Find points in vtx_ptr associated with curve_ptr.
00774   DLIList<TBPoint*> curve_points, point_list;
00775   curve_ptr->points(curve_points);
00776   for( i = curve_points.size(); i > 0; i-- )
00777   {
00778     TBPoint* point_ptr = curve_points.get_and_step();
00779     if( point_ptr->topology_entity() == vtx_ptr )
00780       point_list.append(point_ptr);
00781   }
00782 
00783   //If parent and child are not related in the SolidModelingEngine,
00784   //return failure.
00785   if( ! point_list.size() )
00786   {
00787     end_unmerge(top);
00788     return 0;
00789   }
00790 
00791   // Find any links from parent to old entity, and move them
00792   // to the new, unmerged entity.
00793   DLIList<RefEdge*> edge_list; 
00794   DLIList<TBPoint*> curve_pts;
00795   DLIList<CoVertex*> cvtx_to_change;
00796   
00797   vtx_ptr->ref_edges( edge_list );
00798   for( i = edge_list.size(); i > 0; i-- )
00799   {
00800     edge_ptr = edge_list.get_and_step();
00801     if( edge_ptr->bridge_manager()->number_of_bridges() > 1 )
00802       continue;
00803     
00804     curve_ptr = edge_ptr->get_curve_ptr();
00805     assert( curve_ptr != 0 );
00806     curve_pts.clean_out();
00807     curve_ptr->points(curve_pts);
00808     curve_pts.intersect(point_list);
00809     if( ! curve_pts.size() )
00810       continue;
00811       
00812     CoVertex* start_cvtx = edge_ptr->get_chain_ptr()->start_co_vertex();
00813     CoVertex*   end_cvtx = edge_ptr->get_chain_ptr()->  end_co_vertex();
00814     if (start_cvtx && start_cvtx->get_ref_vertex_ptr() == vtx_ptr)
00815       cvtx_to_change.append( start_cvtx );
00816     if (end_cvtx && end_cvtx->get_ref_vertex_ptr() == vtx_ptr)
00817       cvtx_to_change.append( end_cvtx );
00818       
00819   }
00820 
00821   // Make new RefVertex with points.
00822   RefVertex* new_entity = split_out_Points( point_list );
00823   if( !new_entity )
00824   {
00825     end_unmerge(top);
00826     return 0;
00827   }
00828 
00829   for( i = cvtx_to_change.size(); i--; )
00830   {
00831     cvtx_to_change.get_and_step()->switch_basic_topology_entity(new_entity);
00832   }
00833   
00834   //We have changed the topology of the passed RefEdge.
00835   //Note this for later.
00836   unmerge_modified.append( vtx_ptr );
00837   
00838   //Notify merge assistants of unmerge
00839   DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
00840   for( int a = assistant_list_.size(); a > 0; a-- )
00841     assistant_list_.get_and_step()->
00842       unmerged( vtx_ptr, new_entity, CUBIT_FALSE );
00843   
00844   
00845   end_unmerge(top);  
00846   return new_entity;
00847 }
00848 
00849 
00850 void OldUnmergeCode::remove_CAEntityId_attrib( TopologyBridge* tb_ptr )
00851 {
00852   DLIList<CubitSimpleAttrib> attrib_list;
00853   tb_ptr->get_simple_attribute( attrib_list );
00854   for( int i = attrib_list.size(); i > 0; i-- )
00855   {
00856     const CubitSimpleAttrib& attrib = attrib_list.get_and_step();
00857     if( attrib.character_type() == "ENTITY_ID" )
00858     {
00859       tb_ptr->remove_simple_attribute_virt( attrib );
00860     }
00861   }
00862 }  
00863 
00864 
00865 //-------------------------------------------------------------------------
00866 // Purpose       : Remove a surface from its owning RefFace, and make a new
00867 //                 RefFace with the Surface.
00868 //
00869 // Special Notes : 
00870 //
00871 // Creator       : Jason Kraftcheck
00872 //
00873 // Creation Date : 01/18/01
00874 //-------------------------------------------------------------------------
00875 RefFace* OldUnmergeCode::split_out_Surface( Surface* surface, CubitBoolean& reversed )
00876 {
00877   // Remove the child from the old owner.
00878   reversed = false;
00879   TopologyEntity* te_ptr = surface->topology_entity();
00880   RefFace* old_entity = CAST_TO( te_ptr, RefFace );
00881   if( te_ptr )
00882   {
00883     assert( old_entity != 0 );
00884     
00885     te_ptr->bridge_manager()->remove_bridge( surface );
00886     remove_CAEntityId_attrib( surface );
00887     old_unmerged.append( old_entity );
00888     
00889     if (te_ptr->bridge_manager()->topology_bridge()->bridge_sense() == CUBIT_REVERSED)
00890     { 
00891       te_ptr->reverse_topology();
00892       te_ptr->bridge_manager()->reverse_bridge_senses();
00893       reversed = !reversed;
00894     }
00895     if (surface->bridge_sense() == CUBIT_REVERSED)
00896     {
00897       surface->reverse_bridge_sense();
00898       reversed = !reversed;
00899     }
00900   }
00901   
00902   surface->set_saved_id(0);
00903   
00904   // make new refface
00905   RefFace* new_entity = RefEntityFactory::instance()->construct_RefFace( surface );
00906 
00907   // Unmerge Loops
00908   DLIList<LoopSM*> loopsms;
00909   surface->loopsms( loopsms );
00910   for( int i = loopsms.size(); i > 0; i-- )
00911   {
00912     Loop* new_loop = split_out_Loop(loopsms.get_and_step(), new_entity, reversed);
00913     new_entity->add_grouping_entity( new_loop );
00914   }
00915   
00916   new_unmerged.append(new_entity);
00917   event_list.append( new UnMergeEvent( old_entity, new_entity ) );
00918   
00919   return new_entity;
00920 }
00921 
00922 //-------------------------------------------------------------------------
00923 // Purpose       : Unmerge Loop and CoEdges
00924 //
00925 // Special Notes : 
00926 //
00927 // Creator       : Jason Kraftcheck
00928 //
00929 // Creation Date : 01/23/01
00930 //-------------------------------------------------------------------------
00931 Loop* OldUnmergeCode::split_out_Loop( LoopSM* loopsm, RefFace* /*new_entity*/, CubitBoolean reverse )
00932 {
00933   // Remove from existing TopologyEntity
00934   TopologyEntity* topo = loopsm->topology_entity();
00935   loopsm->bridge_manager()->remove_bridge( loopsm );
00936 
00937   int i;
00938   Loop* old_loop = CAST_TO( topo, Loop );  
00939   assert( old_loop != 0 );
00940   //RefFace* old_face = old_loop->get_ref_face_ptr();
00941   Loop* new_loop = new Loop( loopsm );
00942   DLIList<TopologyBridge*> tb_list;
00943   DLIList<CoEdge*> coedges;
00944   old_loop->ordered_co_edges( coedges );
00945   if( !reverse ) coedges.reverse();
00946   
00947   CoEdge* prev = 0;
00948   while( coedges.size() > 0 )
00949   {
00950     coedges.last();
00951     CoEdge* coedge_ptr = coedges.remove();
00952     
00953     // Find the corresponding CoEdgeSM to unmerge.
00954     tb_list.clean_out();
00955     coedge_ptr->bridge_manager()->get_bridge_list(tb_list);
00956     CoEdgeSM* coedgesm = NULL;  //Match to LoopSM
00957     for( i = tb_list.size(); i > 0; i-- )
00958     {
00959       TopologyBridge* tb_ptr = tb_list.get_and_step();
00960       if( tb_ptr->loopsm() == loopsm )
00961       {
00962         coedgesm = CAST_TO(tb_ptr,CoEdgeSM);
00963         break;
00964       }
00965     }
00966     
00967     assert(coedgesm != 0);
00968     
00969     // Unmerge CoEdge
00970     coedge_ptr->bridge_manager()->remove_bridge( coedgesm );
00971     RefEdge* edge_ptr = coedge_ptr->get_ref_edge_ptr();
00972     CubitSense sense = coedge_ptr->get_sense();
00973     if( reverse ) 
00974       sense = CubitUtil::opposite_sense( sense );
00975     CoEdge* new_coedge = new CoEdge( edge_ptr, sense );
00976     new_coedge->set_co_edge_sm_ptr( coedgesm );
00977     new_loop->add_sense_entity( new_coedge, prev );
00978     prev = new_coedge;
00979   }
00980   
00981   return new_loop;
00982 }
00983 
00984 
00985     
00986 //-------------------------------------------------------------------------
00987 // Purpose       : VG provides downward query of TopologyBridges, but
00988 //                 not always upward queries.  So to do upward queries,
00989 //                 do downward queries and search for source object.
00990 //
00991 // Special Notes : 
00992 //
00993 // Creator       : Jason Kraftcheck
00994 //
00995 // Creation Date : 03/26/01
00996 //-------------------------------------------------------------------------
00997 void OldUnmergeCode::find_curves( TBPoint* point_ptr, DLIList<Curve*>& result_set )
00998 {
00999   //Do normal TB query for real geometry
01000   point_ptr->curves(result_set);
01001   
01002   //Now account for missing TB links due to virtual geometry
01003   RefVertex* vtx_ptr = CAST_TO(point_ptr->topology_entity(),RefVertex);
01004   if( vtx_ptr )
01005   {
01006     DLIList<RefEdge*> vtx_edges;
01007     DLIList<TBPoint*> curve_pts;
01008     DLIList<TopologyBridge*> edge_bridges;
01009     vtx_ptr->ref_edges(vtx_edges);
01010     for( int i = vtx_edges.size(); i > 0; i-- )
01011     {
01012       RefEdge* edge_ptr = vtx_edges.get_and_step();
01013       edge_bridges.clean_out();
01014       edge_ptr->bridge_manager()->get_bridge_list( edge_bridges );
01015       for( int j = edge_bridges.size(); j > 0; j-- )
01016       {
01017         TopologyBridge* bridge_ptr = edge_bridges.get_and_step();
01018         curve_pts.clean_out();
01019         bridge_ptr->points(curve_pts);
01020         if( curve_pts.is_in_list( point_ptr ) )
01021         {
01022           Curve* curve_ptr = CAST_TO(bridge_ptr,Curve);
01023           assert(curve_ptr != 0);
01024           result_set.append_unique(curve_ptr);
01025         }
01026       }
01027     }
01028   }
01029 }
01030     
01031 //-------------------------------------------------------------------------
01032 // Purpose       : VG provides downward query of TopologyBridges, but
01033 //                 not always upward queries.  So to do upward queries,
01034 //                 do downward queries and search for source object.
01035 //
01036 // Special Notes : 
01037 //
01038 // Creator       : Jason Kraftcheck
01039 //
01040 // Creation Date : 03/26/01
01041 //-------------------------------------------------------------------------
01042 void OldUnmergeCode::find_surfaces( Curve* curve_ptr, DLIList<Surface*>& result_set )
01043 {
01044   //Do normal TB query for real geometry
01045   curve_ptr->surfaces(result_set);
01046 }
01047 
01048 
01049 //-------------------------------------------------------------------------
01050 // Purpose       : Unmerge a Curve from its owning RefEdge, and make a new
01051 //                 RefEdge
01052 //
01053 // Special Notes : 
01054 //
01055 // Creator       : Jason Kraftcheck
01056 //
01057 // Creation Date : 01/18/01
01058 //-------------------------------------------------------------------------
01059 RefEdge* OldUnmergeCode::split_out_Curves( DLIList<Curve*>& curve_list, CubitBoolean& reversed )
01060 {
01061   int i;
01062   
01063   // If any parent Surfaces are still merged, we
01064   // cannot continue.
01065   DLIList<Surface*> surface_list;
01066   for( i = curve_list.size(); i > 0; i-- )
01067   {
01068     surface_list.clean_out();
01069     find_surfaces( curve_list.get_and_step(), surface_list );
01070     for( int j = surface_list.size(); j > 0; j-- )
01071       if( surface_list.get_and_step()->bridge_manager()
01072         ->number_of_bridges() != curve_list.size() )
01073         return NULL;
01074   }
01075   
01076   // Remove the curves from the old owner.
01077   curve_list.reset();
01078   Curve* curve = curve_list.get();
01079   TopologyEntity* te_ptr = curve->topology_entity();
01080   for( i = curve_list.size(); i > 0; i-- )
01081     if( curve_list.get_and_step()->topology_entity() != te_ptr )
01082       return 0;
01083       
01084   assert( te_ptr->bridge_manager()->number_of_bridges() > curve_list.size() );
01085   
01086   reversed = false;
01087   RefEdge* old_entity = CAST_TO( te_ptr, RefEdge );
01088   if( te_ptr )
01089   {
01090     assert( old_entity != 0 );
01091     
01092     curve_list.reset();
01093     for( i = curve_list.size(); i > 0; i-- )
01094     {
01095       Curve* ptr = curve_list.get_and_step();
01096       te_ptr->bridge_manager()->remove_bridge( ptr );
01097       remove_CAEntityId_attrib( ptr );
01098     }
01099     old_unmerged.append( old_entity );
01100 
01101     curve_list.reset();
01102     if (te_ptr->bridge_manager()->topology_bridge()->bridge_sense() == CUBIT_REVERSED)
01103     {
01104       te_ptr->reverse_topology();
01105       te_ptr->bridge_manager()->reverse_bridge_senses();
01106       reversed = !reversed;
01107     }
01108     
01109     if (curve->bridge_sense() == CUBIT_REVERSED)
01110     {
01111       for (i = curve_list.size(); i--; )
01112         curve_list.get_and_step()->reverse_bridge_sense();
01113       reversed = !reversed;
01114     }
01115   }
01116   
01117   curve_list.reset();
01118   for ( i = curve_list.size(); i--; )
01119     curve_list.get_and_step()->set_saved_id(0);
01120   
01121   RefEdge* new_entity = RefEntityFactory::instance()->construct_RefEdge( curve );
01122   Chain* chain = new Chain;
01123   new_entity->add_grouping_entity(chain);
01124 
01125   DLIList<TopologyBridge*> points(2);
01126   curve->get_children(points);
01127   points.reset();
01128   for (i = 0; i < 2; i++)
01129   {
01130     CoVertex* cvtx = new CoVertex;
01131     TopologyEntity* owner = points.get_and_step()->topology_entity();
01132     cvtx->attach_basic_topology_entity( dynamic_cast<RefVertex*>(owner) );
01133     chain->add_sense_entity(cvtx);
01134   }
01135   
01136   for( i = curve_list.size(); i > 0; i-- )
01137   {
01138     Curve* a_curve = curve_list.get_and_step();
01139     if( curve != a_curve )
01140       new_entity->bridge_manager()->add_bridge(a_curve);
01141   }  
01142 
01143   PRINT_DEBUG_19("  Unmerged %s from %s.\n", 
01144              new_entity->entity_name().c_str(), 
01145              old_entity->entity_name().c_str() );
01146   
01147   
01148   
01149   new_unmerged.append( new_entity );
01150   event_list.append( new UnMergeEvent( old_entity, new_entity ) );
01151 
01152   return new_entity;
01153 }
01154 
01155 //-------------------------------------------------------------------------
01156 // Purpose       : Unmerge a TBPoint from its Vertex and make new Vertex
01157 //
01158 // Special Notes : 
01159 //
01160 // Creator       : Jason Kraftcheck
01161 //
01162 // Creation Date : 01/18/01
01163 //-------------------------------------------------------------------------
01164 RefVertex* OldUnmergeCode::split_out_Points( DLIList<TBPoint*>& point_list )
01165 {
01166   int i;
01167   
01168   // If any parent Curves are still merged, we 
01169   // cannot continue.
01170   DLIList<Curve*> curve_list;
01171   for( i = point_list.size(); i > 0; i-- )
01172   {
01173     curve_list.clean_out();
01174     find_curves(point_list.get_and_step(),curve_list);
01175     for( int j = curve_list.size(); j > 0; j-- )
01176       if( curve_list.get_and_step()->bridge_manager()
01177         ->number_of_bridges() != point_list.size() )
01178         return NULL;
01179   }
01180   
01181   // Remove the child from the old owner.
01182   TopologyEntity* te_ptr = point_list.get()->topology_entity();
01183   
01184   // All points must have same bridge manager.
01185   for( i = point_list.size(); i > 0; i-- )
01186     if( point_list.get_and_step()->topology_entity() != te_ptr )
01187       return NULL;
01188   
01189   RefVertex* old_entity = CAST_TO( te_ptr, RefVertex );
01190   if( te_ptr )
01191   {
01192     assert(old_entity != 0);
01193     for( i = point_list.size(); i > 0; i-- )
01194     {
01195       TBPoint* ptr = point_list.get_and_step();
01196       te_ptr->bridge_manager()->remove_bridge( ptr );
01197       remove_CAEntityId_attrib( ptr );
01198     }
01199     old_unmerged.append( old_entity );
01200   }
01201 
01202   point_list.reset();
01203   for (i = point_list.size(); i--; )
01204     point_list.get_and_step()->set_saved_id(0);
01205 
01206   RefVertex* new_entity = RefEntityFactory::instance()
01207     ->construct_RefVertex(point_list.get_and_step());
01208   for( i = point_list.size(); i > 1; i-- )
01209     new_entity->bridge_manager()->add_bridge(point_list.get_and_step());
01210     
01211   PRINT_DEBUG_19("    Unmerged %s from %s.\n", 
01212              new_entity->entity_name().c_str(), 
01213              old_entity->entity_name().c_str() );
01214   
01215   new_unmerged.append( new_entity );
01216   event_list.append( new UnMergeEvent( old_entity, new_entity ) );
01217 
01218   return new_entity;
01219 }
01220 
01221 //-------------------------------------------------------------------------
01222 // Purpose       : Handle sending various events as a result of unmerging.
01223 //
01224 // Special Notes : 
01225 //
01226 // Creator       : Jason Kraftcheck
01227 //
01228 // Creation Date : 01/18/01
01229 //-------------------------------------------------------------------------
01230 void OldUnmergeCode::cleanup_unmerge()
01231 {
01232   DLIList<RefEntity*> temp_list, marked_list;
01233   int i, j;
01234   CpuTimer timer;
01235   
01236   //Remove entities from unmerge_modified that
01237   // a) are duplicate entries in the list
01238   // b) also exist in new_unmerged
01239   // c) have parent entities already in unmerge_modified.
01240   
01241   //Change unmerge_modified to be a list of the immediate
01242   //parents of the entities currently in the list
01243   marked_list = unmerge_modified;
01244   unmerge_modified.clean_out();
01245   for( i = marked_list.size(); i--; )
01246   {
01247     temp_list.clean_out();
01248     marked_list.get_and_step()->get_parent_ref_entities( temp_list );
01249     unmerge_modified += temp_list;
01250   }
01251   for( i = new_unmerged.size(); i > 0; i-- )
01252   {
01253     temp_list.clean_out();
01254     new_unmerged.get_and_step()->get_parent_ref_entities( temp_list );
01255     unmerge_modified += temp_list;
01256   }
01257   
01258   //Reset marks on all entities in list
01259   for( i = unmerge_modified.size(); i > 0; i-- )
01260     unmerge_modified.get_and_step()->marked(0);
01261 
01262   //Set instance count (mark) to one for all in new_unmerged
01263   for( i = new_unmerged.size(); i > 0; i-- )
01264     new_unmerged.get_and_step()->marked(1);
01265     
01266   
01267     
01268   //Increment instance count (mark) for each occurance
01269   //in unmerge_modified.
01270   for( i = unmerge_modified.size(); i > 0; i-- )
01271   {
01272     unmerge_modified.get()->marked( unmerge_modified.get()->marked()+1 );
01273     temp_list.clean_out();
01274     unmerge_modified.get()->get_all_child_ref_entities(temp_list);
01275     marked_list += temp_list; 
01276     unmerge_modified.step();
01277   }
01278   
01279   for( i = marked_list.size(); i > 0; i-- )
01280   {
01281     marked_list.get()->marked( marked_list.get()->marked() + 1 );
01282     marked_list.step();
01283   }
01284   
01285   //If the entity's mark is non-zero after decrementing
01286   //the mark, remove it because it occurs again later in
01287   //the list.
01288   unmerge_modified.reset();
01289   for( i = unmerge_modified.size(); i > 0; i-- )
01290   {
01291     unmerge_modified.get()->marked( unmerge_modified.get()->marked() - 1 );
01292     if( unmerge_modified.get()->marked() )
01293       unmerge_modified.extract();
01294     else
01295       unmerge_modified.step();
01296   }
01297 
01298   //Clear out other marks we set.
01299   for( i = new_unmerged.size(); i > 0; i-- )
01300     new_unmerged.get_and_step()->marked(0);
01301   for( i = marked_list.size(); i > 0; i-- )
01302     marked_list.get_and_step()->marked(0);
01303   
01304   
01305   //Now remove duplicates from old_unmerged. 
01306   for( i = old_unmerged.size(); i > 0; i-- )
01307     old_unmerged.get_and_step()->marked(1);
01308   old_unmerged.reset();
01309   for( i = old_unmerged.size(); i > 0; i-- )
01310   {
01311     if( old_unmerged.get()->marked() )
01312       old_unmerged.get_and_step()->marked(0);
01313     else
01314       old_unmerged.extract();
01315   }
01316   
01317   
01318   // Finally, done rearranging lists.  Now actually do
01319   // the important stuff.
01320   
01321   // Count occurances of each type of entity, and 
01322   // output counts.
01323   int face_count = 0, edge_count = 0, vtx_count = 0;
01324   new_unmerged.reset();
01325   for( i = new_unmerged.size(); i > 0; i-- )
01326   {
01327     if( CAST_TO( new_unmerged.get(), RefFace ) )
01328        face_count++;
01329     else if( CAST_TO( new_unmerged.get(), RefEdge ) )
01330        edge_count++;
01331     else if( CAST_TO( new_unmerged.get(), RefVertex ) )
01332        vtx_count++;
01333     else
01334       assert( 0 /*Bad EntityType*/ );
01335 
01336     new_unmerged.step();
01337   }
01338   
01339   if( AppUtil::instance()->interrupt() ) PRINT_WARNING("Unmerge aborted.\n");
01340   if( face_count ) PRINT_INFO("%4d surfaces unmerged.\n",face_count);
01341   if( edge_count ) PRINT_INFO("%4d  curves  unmerged.\n",edge_count);
01342   if( vtx_count )  PRINT_INFO("%4d vertices unmerged.\n",vtx_count);
01343   PRINT_DEBUG_19("Unmerge completed in %0.2f seconds.\n",
01344                                          timer.cpu_secs() );
01345   
01346   //Let the user know if we actually unmerged anything.
01347   if( !new_unmerged.size() )
01348     PRINT_INFO("No entities unmerged.\n");
01349  
01350   int event_count = new_unmerged.size() + event_list.size() + unmerge_modified.size();
01351   ProgressTool* progress = 0;
01352   if (event_count > 20)
01353     progress = AppUtil::instance()->progress_tool();
01354   if (progress)
01355     progress->start( 0, event_count, "Updating Graphics" );
01356  
01357   //Info for DEBUG output
01358   const char* entity_names[] = { "Vertices", "Curves", "Surfaces" };
01359   timer.cpu_secs();
01360   
01361   //Add all new entities to the graphics.  Do lowest-dimension
01362   //entities first, so that they exist in the graphics when the
01363   //higher-dimension entities owning them are added.
01364   for( j = 0; j < 3; j++ )
01365   {
01366     int count = 0; //for PRINT_DEBUG statement below.
01367       
01368     for( i = new_unmerged.size(); i > 0; i-- )
01369     {
01370       RefEntity* entity = new_unmerged.get_and_step();
01371       if( entity->dimension() != j ) 
01372         continue;
01373       
01374       count++;
01375       
01376       //Is this a free RefEntity?
01377       temp_list.clean_out();
01378       entity->get_parent_ref_entities( temp_list );
01379       
01380       if( temp_list.size() == 0 )
01381         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, entity));
01382 
01383       if (progress)
01384         progress->step();
01385       PRINT_DEBUG_19("\t\tAdded %s to graphics\n", entity->entity_name().c_str() );
01386 
01387       //entity->notify_all_observers( NEW_ENTITY_UNMERGED );
01388     }
01389     PRINT_DEBUG_19("\tAdded %d new %s to graphics in %0.2f seconds.\n",
01390       count, entity_names[j], timer.cpu_secs() );
01391   }
01392   
01393   while( event_list.size() )
01394   {
01395     UnMergeEvent* event = event_list.pop();
01396     //event->new_entity->notify_observers(event)
01397     AppUtil::instance()->send_event( *event );
01398     delete event;
01399     if (progress)
01400       progress->step();
01401   }
01402   
01403   //Update for other non-new entities that got modified
01404   //as a part of unmerging.
01405   for( i = unmerge_modified.size(); i > 0; i-- )
01406   {
01407     PRINT_DEBUG_19("\t\tUpdated graphics for %s.\n", unmerge_modified.get()->entity_name().c_str() );
01408     AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, unmerge_modified.get_and_step()));
01409     if (progress)
01410       progress->step();  
01411   }
01412   if (progress)
01413     progress->end();
01414   
01415   PRINT_DEBUG_19("Sent TOPOLOGY_MODIFIED event for %d entities in %0.2f "
01416                  "seconds\n",unmerge_modified.size(), timer.cpu_secs());
01417   PRINT_DEBUG_19("Total time to update after unmerge: %0.2f seconds.\n",
01418     timer.elapsed() );
01419 
01420   DLIList<MergeToolAssistant*>& assistant_list_ = MergeTool::instance()->assistant_list_;
01421   for( int a = assistant_list_.size(); a--; )
01422     assistant_list_.get_and_step()->finish_unmerge();
01423 }
01424 
01425     
01426 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines