LCOV - code coverage report
Current view: top level - geom/virtual - PartitionEngine.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 182 3111 5.9 %
Date: 2020-06-30 00:58:45 Functions: 13 94 13.8 %
Branches: 370 8619 4.3 %

           Branch data     Line data    Source code
       1                 :            : //-------------------------------------------------------------------------
       2                 :            : // Filename      : PartitionEngine.cpp
       3                 :            : //
       4                 :            : // Purpose       : 
       5                 :            : //
       6                 :            : // Special Notes : 
       7                 :            : //
       8                 :            : // Creator       : Jason Kraftcheck
       9                 :            : //
      10                 :            : // Creation Date : 04/23/02
      11                 :            : //-------------------------------------------------------------------------
      12                 :            : 
      13                 :            : #include "PartitionEngine.hpp"
      14                 :            : #include "CompositeEngine.hpp"
      15                 :            : 
      16                 :            : #include "SubCurve.hpp"
      17                 :            : #include "SubSurface.hpp"
      18                 :            : #include "SegmentedCurve.hpp"
      19                 :            : #include "PartitionPoint.hpp"
      20                 :            : #include "PartitionCoEdge.hpp"
      21                 :            : #include "PartitionLoop.hpp"
      22                 :            : #include "PartitionSurface.hpp"
      23                 :            : #include "PartitionLump.hpp"
      24                 :            : #include "PartitionBody.hpp"
      25                 :            : #include "PartPTCurve.hpp"
      26                 :            : #include "PartitionShell.hpp"
      27                 :            : #include "BodySM.hpp"
      28                 :            : 
      29                 :            : 
      30                 :            : #include "GMem.hpp"
      31                 :            : #include "GeometryQueryEngine.hpp"
      32                 :            : #include "GeometryModifyEngine.hpp"
      33                 :            : #include "GeometryModifyTool.hpp"
      34                 :            : 
      35                 :            : #include "VGLoopTool.hpp"
      36                 :            : 
      37                 :            : #include "FacetProjectTool.hpp"
      38                 :            : #include "CubitFacetData.hpp"
      39                 :            : #include "CubitFacetEdgeData.hpp"
      40                 :            : #include "CubitPointData.hpp"
      41                 :            : #include "TDVGFacetOwner.hpp"
      42                 :            : #include "TDVGFacetSplit.hpp"
      43                 :            : #include "FacetEvalTool.hpp"
      44                 :            : #include "FacetDataUtil.hpp"
      45                 :            : #include "PartSurfFacetTool.hpp"
      46                 :            : #include "PartitionTool.hpp"
      47                 :            : 
      48                 :            : #include "CompositeSurface.hpp"
      49                 :            : #include "CompositePoint.hpp"
      50                 :            : #include "CompositeCurve.hpp"
      51                 :            : #include "PartitionLumpImprint.hpp"
      52                 :            : #include "GfxDebug.hpp"
      53                 :            : #include "BridgeManager.hpp"
      54                 :            : 
      55                 :            : #include "CADefines.hpp"
      56                 :            : 
      57                 :            : #include <set>
      58                 :            : #include "GeometryQueryTool.hpp"
      59                 :            : 
      60                 :            : #include "CubitTransformMatrix.hpp"
      61                 :            : #include "CubitObservable.hpp"
      62                 :            : #include "AppUtil.hpp"
      63                 :            : #include "GeometryEvent.hpp"
      64                 :            : 
      65                 :            : const char* const PARTITION_GEOM_ATTRIB_NAME = "PARTITION_GEOM";
      66                 :            : 
      67                 :            : static CubitStatus get_edge_replacements(
      68                 :            :                          std::vector<CubitFacetData*> &facet_list,
      69                 :            :                          std::vector<CubitFacetEdgeData*> replacement_edges[3]);
      70                 :            : 
      71                 :            : 
      72                 :            : PartitionEngine* PartitionEngine::instance_ = NULL; 
      73                 :            : 
      74                 :            : 
      75         [ #  # ]:          0 : PartitionEngine::~PartitionEngine()
      76                 :            : {
      77 [ #  # ][ #  # ]:          0 :   GeometryQueryTool::instance()->unregister_intermediate_engine(this);
      78         [ #  # ]:          0 : }
      79                 :            : 
      80                 :          0 : void PartitionEngine::delete_instance()
      81                 :            : {
      82         [ #  # ]:          0 :   if( NULL != instance_ )
      83                 :            :   {
      84         [ #  # ]:          0 :     delete instance_;
      85                 :          0 :     instance_ = NULL;
      86                 :            :   }
      87                 :          0 : }    
      88                 :            : 
      89                 :            : 
      90                 :            : //-------------------------------------------------------------------------
      91                 :            : // Purpose       : Constructor
      92                 :            : //
      93                 :            : // Special Notes : 
      94                 :            : //
      95                 :            : // Creator       : Jason Kraftcheck
      96                 :            : //
      97                 :            : // Creation Date : 08/25/03
      98                 :            : //-------------------------------------------------------------------------
      99         [ +  - ]:       1682 : PartitionEngine::PartitionEngine()
     100                 :            : {
     101 [ +  - ][ +  - ]:        841 :   CubitStatus r = GeometryQueryTool::instance()->register_intermediate_engine(this);
     102         [ -  + ]:        841 :   assert(r == CUBIT_SUCCESS);
     103         [ -  + ]:        841 :   if (CUBIT_SUCCESS != r) {
     104 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Failed to register intermediate engine.\n");
         [ #  # ][ #  # ]
     105                 :            :   }
     106                 :        841 : }
     107                 :            : 
     108                 :            : //-------------------------------------------------------------------------
     109                 :            : // Purpose       : Get instance
     110                 :            : //
     111                 :            : // Special Notes : 
     112                 :            : //
     113                 :            : // Creator       : Jason Kraftcheck
     114                 :            : //
     115                 :            : // Creation Date : 02/23/03
     116                 :            : //-------------------------------------------------------------------------
     117                 :        841 : PartitionEngine& PartitionEngine::instance()
     118                 :            : {
     119         [ +  - ]:        841 :   if( instance_ == NULL )
     120                 :            :   {
     121         [ +  - ]:        841 :     instance_ = new PartitionEngine();
     122         [ -  + ]:        841 :     assert( instance_ != NULL );
     123                 :            :   }
     124                 :            :   
     125                 :        841 :   return *instance_;
     126                 :            : }
     127                 :            : 
     128                 :            : //-------------------------------------------------------------------------
     129                 :            : // Purpose       : Used by SubEntitySet to update ID map.
     130                 :            : //
     131                 :            : // Special Notes : 
     132                 :            : //
     133                 :            : // Creator       : Jason Kraftcheck
     134                 :            : //
     135                 :            : // Creation Date : 02/23/03
     136                 :            : //-------------------------------------------------------------------------
     137                 :          0 : CubitStatus PartitionEngine::add_to_id_map( SubEntitySet* set, int unique_id )
     138                 :            : {
     139 [ #  # ][ #  # ]:          0 :   if( uniqueIdMap.find(unique_id) != uniqueIdMap.end() )
                 [ #  # ]
     140                 :          0 :     { assert(0); return CUBIT_FAILURE; }
     141                 :          0 :   uniqueIdMap[unique_id] = set;
     142                 :          0 :   return CUBIT_SUCCESS;
     143                 :            : }
     144                 :            : 
     145                 :            : //-------------------------------------------------------------------------
     146                 :            : // Purpose       : Used by SubEntitySet to update ID map.
     147                 :            : //
     148                 :            : // Special Notes : 
     149                 :            : //
     150                 :            : // Creator       : Jason Kraftcheck
     151                 :            : //
     152                 :            : // Creation Date : 02/23/03
     153                 :            : //-------------------------------------------------------------------------
     154                 :          0 : CubitStatus PartitionEngine::remove_from_id_map( SubEntitySet* set, int id )
     155                 :            : {
     156         [ #  # ]:          0 :   std::map<int,SubEntitySet*>::iterator itor = uniqueIdMap.find(id);
     157 [ #  # ][ #  # ]:          0 :   if( itor == uniqueIdMap.end() || itor->second != set )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     158                 :          0 :     { assert(0); return CUBIT_FAILURE; }
     159         [ #  # ]:          0 :   uniqueIdMap.erase(itor);
     160                 :          0 :   return CUBIT_SUCCESS;
     161                 :            : }
     162                 :            : 
     163                 :            : //-------------------------------------------------------------------------
     164                 :            : // Purpose       : Retreive an entity from the ID map
     165                 :            : //
     166                 :            : // Special Notes : 
     167                 :            : //
     168                 :            : // Creator       : Jason Kraftcheck
     169                 :            : //
     170                 :            : // Creation Date : 02/23/03
     171                 :            : //-------------------------------------------------------------------------
     172                 :          0 : SubEntitySet* PartitionEngine::get_from_id_map( int id )
     173                 :            : {
     174         [ #  # ]:          0 :   std::map<int,SubEntitySet*>::iterator itor = uniqueIdMap.find(id);
     175 [ #  # ][ #  # ]:          0 :   return itor == uniqueIdMap.end() ? 0 : itor->second;
         [ #  # ][ #  # ]
     176                 :            : }
     177                 :            : 
     178                 :            : //-------------------------------------------------------------------------
     179                 :            : // Purpose       : Replicate solid model topology in partition layer
     180                 :            : //
     181                 :            : // Special Notes : 
     182                 :            : //
     183                 :            : // Creator       : Jason Kraftcheck
     184                 :            : //
     185                 :            : // Creation Date : 02/23/03
     186                 :            : //-------------------------------------------------------------------------
     187                 :          0 : SubCurve* PartitionEngine::replace_curve( Curve* curve )
     188                 :            : {
     189         [ #  # ]:          0 :   SubCurve* result = dynamic_cast<SubCurve*>(curve);
     190         [ #  # ]:          0 :   if( result )
     191                 :          0 :     return result;
     192                 :            :  
     193 [ #  # ][ #  # ]:          0 :   if( dynamic_cast<SegmentedCurve*>(curve) )
                 [ #  # ]
     194                 :          0 :     return 0;
     195                 :            :   
     196         [ #  # ]:          0 :   DLIList<TopologyBridge*> list;
     197                 :            :   //curve->get_children_virt( list );
     198                 :            :   //fix_up_query_results( list );
     199 [ #  # ][ #  # ]:          0 :   curve->get_children(list, false, layer());
     200                 :          0 :   PartitionPoint *start_pt = 0, *end_pt = 0;
     201                 :          0 :   bool new_start = false, new_end = false;
     202         [ #  # ]:          0 :   list.reset();
     203         [ #  # ]:          0 :   TopologyBridge* bridge = list.get_and_step();
     204         [ #  # ]:          0 :   start_pt = dynamic_cast<PartitionPoint*>(bridge);
     205         [ #  # ]:          0 :   if( ! start_pt ) 
     206                 :            :   {
     207 [ #  # ][ #  # ]:          0 :     start_pt = replace_point( dynamic_cast<TBPoint*>(bridge) );
     208         [ #  # ]:          0 :     if( ! start_pt )
     209                 :          0 :       return 0;
     210                 :          0 :     new_start = true;
     211                 :            :   }
     212 [ #  # ][ #  # ]:          0 :   if( list.size() == 1 )
     213                 :            :   {
     214                 :          0 :     end_pt = start_pt;
     215                 :            :   }
     216 [ #  # ][ #  # ]:          0 :   else if( list.size() == 2 )
     217                 :            :   {
     218         [ #  # ]:          0 :     bridge = list.get();
     219         [ #  # ]:          0 :     end_pt = dynamic_cast<PartitionPoint*>(bridge);
     220         [ #  # ]:          0 :     if( !end_pt )
     221                 :            :     {
     222 [ #  # ][ #  # ]:          0 :       end_pt = replace_point( dynamic_cast<TBPoint*>(bridge) );
     223                 :          0 :       new_end = true;
     224         [ #  # ]:          0 :       if( !end_pt )
     225                 :            :       {
     226         [ #  # ]:          0 :         if( new_start )
     227         [ #  # ]:          0 :           restore_point( start_pt );
     228                 :          0 :         return 0;
     229                 :            :       }
     230                 :            :     }
     231                 :            :   }
     232                 :            :   
     233 [ #  # ][ #  # ]:          0 :   assert( start_pt && end_pt );
     234                 :            :   
     235 [ #  # ][ #  # ]:          0 :   result = new SubCurve( curve );
     236 [ #  # ][ #  # ]:          0 :   if( ! result->start_point( start_pt ) ||
         [ #  # ][ #  # ]
     237         [ #  # ]:          0 :       ! result->end_point( end_pt ) )
     238                 :            :   {
     239         [ #  # ]:          0 :     result->start_point(0);
     240         [ #  # ]:          0 :     result->end_point(0);
     241 [ #  # ][ #  # ]:          0 :     delete result;
     242         [ #  # ]:          0 :     if( new_start )
     243         [ #  # ]:          0 :       restore_point( start_pt );
     244         [ #  # ]:          0 :     if( new_end )
     245         [ #  # ]:          0 :       restore_point( end_pt );
     246                 :          0 :     return 0;
     247                 :            :   }
     248 [ #  # ][ #  # ]:          0 :   if( curve->owner() )
     249                 :            :   {
     250 [ #  # ][ #  # ]:          0 :     curve->owner()->swap_bridge(curve, result, false);
     251                 :            :   }
     252 [ #  # ][ #  # ]:          0 :   curve->owner(&(result->sub_entity_set()));
     253                 :            :   
     254         [ #  # ]:          0 :   list.clean_out();
     255         [ #  # ]:          0 :   curve->get_parents_virt( list );
     256                 :            :   //fix_up_query_results( list );
     257                 :            :   
     258 [ #  # ][ #  # ]:          0 :   for( int i = list.size(); i--; )
     259                 :            :   {
     260         [ #  # ]:          0 :     bridge = list.get_and_step();
     261         [ #  # ]:          0 :     CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(bridge);
     262         [ #  # ]:          0 :     assert( coedge != NULL );
     263 [ #  # ][ #  # ]:          0 :     PartitionCoEdge* pcoedge = new PartitionCoEdge( coedge );
     264         [ #  # ]:          0 :     CubitStatus s = result->add( pcoedge );
     265         [ #  # ]:          0 :     assert( s );
     266         [ #  # ]:          0 :     if (CUBIT_SUCCESS != s) {
     267 [ #  # ][ #  # ]:          0 :       PRINT_ERROR("Failed to add coedge to SubCurve.\n");
         [ #  # ][ #  # ]
     268                 :          0 :       return NULL;
     269                 :            :     }
     270 [ #  # ][ #  # ]:          0 :     if( coedge->owner() )
     271 [ #  # ][ #  # ]:          0 :       coedge->owner()->swap_bridge(coedge, pcoedge, false);
     272 [ #  # ][ #  # ]:          0 :     coedge->owner(&(pcoedge->sub_entity_set()));
     273                 :            :   }
     274                 :            :   
     275                 :            :   
     276                 :          0 :   PartitionBody* body = 0;
     277 [ #  # ][ #  # ]:          0 :   if( result->start_point()->sub_entity_set().body() )
         [ #  # ][ #  # ]
     278 [ #  # ][ #  # ]:          0 :     body = result->start_point()->sub_entity_set().body();
                 [ #  # ]
     279 [ #  # ][ #  # ]:          0 :   else if( result->end_point()->sub_entity_set().body() )
         [ #  # ][ #  # ]
     280 [ #  # ][ #  # ]:          0 :     body = result->end_point()->sub_entity_set().body();
                 [ #  # ]
     281                 :            :   else
     282         [ #  # ]:          0 :     body = make_body(result);
     283                 :            :     
     284         [ #  # ]:          0 :   if( body )
     285                 :            :   {
     286 [ #  # ][ #  # ]:          0 :     if( !result->start_point()->sub_entity_set().body() )
         [ #  # ][ #  # ]
     287 [ #  # ][ #  # ]:          0 :       body->add(result->start_point()->sub_entity_set());
                 [ #  # ]
     288 [ #  # ][ #  # ]:          0 :     if( !result->end_point()->sub_entity_set().body() )
         [ #  # ][ #  # ]
     289 [ #  # ][ #  # ]:          0 :       body->add(result->end_point()->sub_entity_set());
                 [ #  # ]
     290 [ #  # ][ #  # ]:          0 :     body->add(result->sub_entity_set());
     291                 :          0 :     PartitionCoEdge* coedge = 0;
     292 [ #  # ][ #  # ]:          0 :     while ( (coedge = result->next_coedge(coedge)) )
     293 [ #  # ][ #  # ]:          0 :       if ( !coedge->sub_entity_set().body() )
                 [ #  # ]
     294 [ #  # ][ #  # ]:          0 :         body->add(coedge->sub_entity_set());
     295                 :            :   }
     296                 :            : 
     297                 :            :   // we must notify the graphics of the modify from "real" to virtual -- KGM
     298                 :            :   // I realize that this is not where the other notifies are completed but there
     299                 :            :   // is no knowledge of the change later on. 
     300 [ #  # ][ #  # ]:          0 :   CubitObservable* observable = dynamic_cast<CubitObservable*>(result->topology_entity());
     301         [ #  # ]:          0 :   if (observable)
     302                 :            :   {
     303 [ #  # ][ #  # ]:          0 :      AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, dynamic_cast<RefEntity*>(result->topology_entity())));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     304                 :            :   }
     305                 :            : 
     306         [ #  # ]:          0 :   return result;
     307                 :            : }
     308                 :            : 
     309                 :            : //-------------------------------------------------------------------------
     310                 :            : // Purpose       : Replicate solid model topology in partition layer
     311                 :            : //
     312                 :            : // Special Notes : 
     313                 :            : //
     314                 :            : // Creator       : Jason Kraftcheck
     315                 :            : //
     316                 :            : // Creation Date : 02/23/03
     317                 :            : //-------------------------------------------------------------------------
     318                 :          0 : SubSurface* PartitionEngine::replace_surface( Surface* surface )
     319                 :            : {
     320                 :            :   int i, j;
     321                 :            : 
     322                 :            :   // check if the input surface is already a SubSurface
     323         [ #  # ]:          0 :   SubSurface* result = dynamic_cast<SubSurface*>(surface);
     324         [ #  # ]:          0 :   if( result )
     325                 :          0 :     return result;
     326                 :            :  
     327                 :            :   // check if the input surface is already a PartitionSurface
     328 [ #  # ][ #  # ]:          0 :   if( dynamic_cast<PartitionSurface*>(surface) )
                 [ #  # ]
     329                 :          0 :     return 0;
     330                 :            :   
     331                 :            :   // create a new SubSurface, swap out the TBOwner if it
     332                 :            :   // exists and reset the input surface TBOwner.
     333 [ #  # ][ #  # ]:          0 :   DLIList<TopologyBridge*> loop_list, coe_list, curve_list;
         [ #  # ][ #  # ]
                 [ #  # ]
     334 [ #  # ][ #  # ]:          0 :   surface->get_children( loop_list, false, layer() );
     335 [ #  # ][ #  # ]:          0 :   result = new SubSurface( surface );
     336 [ #  # ][ #  # ]:          0 :   if( surface->owner() )
     337 [ #  # ][ #  # ]:          0 :     surface->owner()->swap_bridge(surface, result, false);
     338 [ #  # ][ #  # ]:          0 :   surface->owner(&(result->sub_entity_set()));
     339                 :            :   
     340                 :            :   // Add the loop onto the new surface
     341         [ #  # ]:          0 :   loop_list.reset();
     342 [ #  # ][ #  # ]:          0 :   for( i = loop_list.size(); i--; )
     343                 :            :   {
     344 [ #  # ][ #  # ]:          0 :     LoopSM* loop = dynamic_cast<LoopSM*>(loop_list.get_and_step());
     345 [ #  # ][ #  # ]:          0 :     PartitionLoop* partloop = new PartitionLoop();
     346         [ #  # ]:          0 :     result->add( partloop );
     347 [ #  # ][ #  # ]:          0 :     if( loop->owner() )
     348 [ #  # ][ #  # ]:          0 :       loop->owner()->swap_bridge( loop, partloop, false );
     349         [ #  # ]:          0 :     loop->owner(0);
     350                 :            :     
     351                 :            :     // Take care of the curves in the loop
     352         [ #  # ]:          0 :     coe_list.clean_out();
     353 [ #  # ][ #  # ]:          0 :     loop->get_children( coe_list, false, layer() );
     354                 :            :     
     355         [ #  # ]:          0 :     coe_list.reset();
     356 [ #  # ][ #  # ]:          0 :     for( j = coe_list.size(); j--; )
     357                 :            :     {
     358 [ #  # ][ #  # ]:          0 :       CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(coe_list.get_and_step());
     359 [ #  # ][ #  # ]:          0 :       if(!dynamic_cast<PartitionCoEdge*>(coedge) &&
         [ #  # ][ #  # ]
     360 [ #  # ][ #  # ]:          0 :          !dynamic_cast<SubEntitySet*>(coedge->owner()) )
     361                 :            :       {
     362         [ #  # ]:          0 :         curve_list.clean_out();
     363         [ #  # ]:          0 :         coedge->get_children_virt( curve_list );
     364 [ #  # ][ #  # ]:          0 :         assert( curve_list.size() == 1 );
     365                 :            :       
     366 [ #  # ][ #  # ]:          0 :         Curve* curve = dynamic_cast<Curve*>(curve_list.get());
     367 [ #  # ][ #  # ]:          0 :         assert(! dynamic_cast<PartitionCurve*>(curve) );
     368         [ #  # ]:          0 :         SubCurve* pcurve = replace_curve( curve );
     369         [ #  # ]:          0 :         assert(pcurve != NULL);
     370         [ #  # ]:          0 :         if (NULL == pcurve) {
     371 [ #  # ][ #  # ]:          0 :           PRINT_ERROR("Failed to replace curve.\n");
         [ #  # ][ #  # ]
     372                 :          0 :           return NULL;
     373                 :            :         }
     374                 :            :       }
     375                 :            :     }
     376                 :            :     
     377         [ #  # ]:          0 :     coe_list.clean_out();
     378 [ #  # ][ #  # ]:          0 :     loop->get_children( coe_list, false, layer() );
     379                 :            :     
     380         [ #  # ]:          0 :     coe_list.reset();
     381                 :          0 :     PartitionCoEdge *curr, *prev = 0;
     382         [ #  # ]:          0 :     coe_list.reset();
     383 [ #  # ][ #  # ]:          0 :     for( j = coe_list.size(); j--; )
     384                 :            :     {
     385 [ #  # ][ #  # ]:          0 :       curr = dynamic_cast<PartitionCoEdge*>(coe_list.get_and_step());
     386         [ #  # ]:          0 :       assert( curr != NULL );
     387         [ #  # ]:          0 :       partloop->insert_after( curr, prev );
     388                 :          0 :       prev = curr;
     389                 :            :     }
     390                 :            :     
     391                 :            :   }
     392                 :            :   
     393                 :            :   // If the facet data is incorrect put everything back
     394 [ #  # ][ #  # ]:          0 :   if (!result->init_facet_data()) {
     395         [ #  # ]:          0 :     restore_surface( result );
     396                 :          0 :     return 0;
     397                 :            :   }
     398                 :            :   
     399                 :            :   // finalize by making the body
     400         [ #  # ]:          0 :   PartitionBody* body = make_body(result);
     401         [ #  # ]:          0 :   if( body )
     402 [ #  # ][ #  # ]:          0 :     body->add(result->sub_entity_set());
     403                 :            :   
     404         [ #  # ]:          0 :   return result;
     405                 :            : }
     406                 :            : 
     407                 :            : //-------------------------------------------------------------------------
     408                 :            : // Purpose       : Replicate solid model topology in partition layer
     409                 :            : //
     410                 :            : // Special Notes : 
     411                 :            : //
     412                 :            : // Creator       : Jason Kraftcheck
     413                 :            : //
     414                 :            : // Creation Date : 02/23/03
     415                 :            : //-------------------------------------------------------------------------
     416                 :          0 : PartitionLump* PartitionEngine::replace_lump( Lump* lump )
     417                 :            : {
     418                 :            :   int i, j;
     419         [ #  # ]:          0 :   PartitionLump* result = dynamic_cast<PartitionLump*>(lump);
     420         [ #  # ]:          0 :   if( result )
     421                 :          0 :     return result;
     422                 :            :  
     423 [ #  # ][ #  # ]:          0 :   DLIList<TopologyBridge*> shell_list, surface_list;
                 [ #  # ]
     424 [ #  # ][ #  # ]:          0 :   lump->get_children( shell_list, false, layer() );
     425                 :            :   
     426 [ #  # ][ #  # ]:          0 :   DLIList<PartitionShell*> new_shells;
     427         [ #  # ]:          0 :   shell_list.reset();
     428 [ #  # ][ #  # ]:          0 :   for( i = shell_list.size(); i--; )
     429                 :            :   {
     430 [ #  # ][ #  # ]:          0 :     ShellSM* shell = dynamic_cast<ShellSM*>(shell_list.get_and_step());
     431 [ #  # ][ #  # ]:          0 :     PartitionShell* pshell = new PartitionShell();
     432         [ #  # ]:          0 :     new_shells.append(pshell);
     433 [ #  # ][ #  # ]:          0 :     if( shell->owner() )
     434 [ #  # ][ #  # ]:          0 :       shell->owner()->swap_bridge( shell, pshell, false );
     435         [ #  # ]:          0 :     shell->owner(0);
     436                 :            :     
     437         [ #  # ]:          0 :     surface_list.clean_out();
     438 [ #  # ][ #  # ]:          0 :     shell->get_children( surface_list, false, layer() );
     439                 :            :     
     440         [ #  # ]:          0 :     surface_list.reset();
     441 [ #  # ][ #  # ]:          0 :     for( j = surface_list.size(); j--; )
     442                 :            :     {
     443 [ #  # ][ #  # ]:          0 :       Surface* surface = dynamic_cast<Surface*>(surface_list.get_and_step());
     444         [ #  # ]:          0 :       PartitionSurface* psurf = dynamic_cast<PartitionSurface*>(surface);
     445         [ #  # ]:          0 :       if( !psurf )
     446                 :            :       {
     447         [ #  # ]:          0 :         psurf = replace_surface( surface );
     448         [ #  # ]:          0 :         if (!psurf) 
     449                 :            :         {
     450 [ #  # ][ #  # ]:          0 :           while (new_shells.size())
     451 [ #  # ][ #  # ]:          0 :             destroy_shell(new_shells.pop());
     452                 :          0 :           return 0;
     453                 :            :         }
     454                 :            :       }
     455                 :            :       
     456 [ #  # ][ #  # ]:          0 :       Surface* real_surf = dynamic_cast<Surface*>(psurf->partitioned_entity());
     457         [ #  # ]:          0 :       assert(!!real_surf);
     458         [ #  # ]:          0 :       CubitSense sense = real_surf->get_shell_sense(shell);
     459 [ #  # ][ #  # ]:          0 :       assert(sense == CUBIT_FORWARD || sense == CUBIT_REVERSED);
     460         [ #  # ]:          0 :       pshell->add( psurf, sense );
     461                 :            :     }
     462                 :            :   }
     463                 :            : 
     464 [ #  # ][ #  # ]:          0 :   result = new PartitionLump( lump );
     465 [ #  # ][ #  # ]:          0 :   if( lump->owner() )
     466 [ #  # ][ #  # ]:          0 :     lump->owner()->swap_bridge(lump, result, false);
     467 [ #  # ][ #  # ]:          0 :   lump->owner(&(result->sub_entity_set()));
     468         [ #  # ]:          0 :   new_shells.reverse();
     469 [ #  # ][ #  # ]:          0 :   while( new_shells.size() )
     470 [ #  # ][ #  # ]:          0 :     result->add(new_shells.pop());
     471                 :            :   
     472         [ #  # ]:          0 :   PartitionBody* body = make_body(result);
     473         [ #  # ]:          0 :   if( body )
     474 [ #  # ][ #  # ]:          0 :     body->add( result->sub_entity_set() );
     475                 :            :   
     476         [ #  # ]:          0 :   return result;
     477                 :            : }
     478                 :            : 
     479                 :            : //-------------------------------------------------------------------------
     480                 :            : // Purpose       : Replicate solid model topology in partition layer
     481                 :            : //
     482                 :            : // Special Notes : 
     483                 :            : //
     484                 :            : // Creator       : Jason Kraftcheck
     485                 :            : //
     486                 :            : // Creation Date : 02/23/03
     487                 :            : //-------------------------------------------------------------------------
     488                 :          0 : PartitionPoint* PartitionEngine::replace_point( TBPoint* point )
     489                 :            : {
     490         [ #  # ]:          0 :   PartitionPoint* result = dynamic_cast<PartitionPoint*>(point);
     491         [ #  # ]:          0 :   if( !result )
     492                 :            :   {
     493         [ #  # ]:          0 :     result = new PartitionPoint( point );
     494                 :            :   }  
     495                 :            :   
     496         [ #  # ]:          0 :   if( result )
     497                 :            :   {
     498         [ #  # ]:          0 :     if( point->owner() )
     499                 :          0 :       point->owner()->swap_bridge( point, result, false );
     500                 :          0 :     point->owner( &(result->sub_entity_set()) );
     501                 :            :   }
     502                 :            :   
     503                 :          0 :   return result;
     504                 :            : }
     505                 :            : 
     506                 :            : //-------------------------------------------------------------------------
     507                 :            : // Purpose       : Restore original solid model topology.  (Inverse of
     508                 :            : //                 replace_point.)
     509                 :            : //
     510                 :            : // Special Notes : 
     511                 :            : //
     512                 :            : // Creator       : Jason Kraftcheck
     513                 :            : //
     514                 :            : // Creation Date : 02/23/03
     515                 :            : //-------------------------------------------------------------------------
     516                 :          0 : TBPoint* PartitionEngine::restore_point( PartitionPoint* point )
     517                 :            : {
     518         [ #  # ]:          0 :   if( point->num_curves() )
     519                 :          0 :     return 0;
     520                 :            :   
     521                 :          0 :   TBPoint* result = point->real_point();
     522         [ #  # ]:          0 :   if( result )
     523                 :            :   {
     524                 :          0 :     point->sub_entity_set().unwrap_attributes();
     525                 :          0 :     point->sub_entity_set().remove_bridge(result);
     526         [ #  # ]:          0 :     if( point->owner() )
     527                 :          0 :       point->owner()->swap_bridge( point, result, false );
     528         [ #  # ]:          0 :     delete point;
     529                 :            :   }
     530                 :            :   
     531                 :          0 :   return result;
     532                 :            : }
     533                 :            : 
     534                 :            : //-------------------------------------------------------------------------
     535                 :            : // Purpose       : Restore original solid model topology.  (Inverse of
     536                 :            : //                 replace_curve.)
     537                 :            : //
     538                 :            : // Special Notes : 
     539                 :            : //
     540                 :            : // Creator       : Jason Kraftcheck
     541                 :            : //
     542                 :            : // Creation Date : 02/23/03
     543                 :            : //-------------------------------------------------------------------------
     544                 :          0 : Curve* PartitionEngine::restore_curve( SubCurve* curve )
     545                 :            : {
     546         [ #  # ]:          0 :   if( curve->num_partitions() > 1 )
     547                 :          0 :     return 0;
     548                 :            :   
     549                 :          0 :   PartitionCoEdge* coedge = 0;
     550         [ #  # ]:          0 :   while( (coedge = curve->next_coedge( coedge )) )
     551         [ #  # ]:          0 :     if( coedge->get_loop() )
     552                 :          0 :       return 0;
     553                 :            :   
     554         [ #  # ]:          0 :   while( (coedge = curve->next_coedge(0)) )
     555                 :            :   {
     556                 :          0 :     curve->remove( coedge );
     557                 :          0 :     CoEdgeSM* real_coedge = coedge->real_coedge();
     558         [ #  # ]:          0 :     if( real_coedge )
     559                 :            :     {
     560                 :          0 :       coedge->sub_entity_set().remove_bridge( real_coedge );
     561         [ #  # ]:          0 :       if( coedge->owner() )
     562                 :          0 :         coedge->owner()->swap_bridge( coedge, real_coedge, false );
     563                 :            :     }
     564         [ #  # ]:          0 :     delete coedge;
     565                 :            :   }
     566                 :            :   
     567                 :          0 :   PartitionPoint* start = curve->start_point();
     568                 :          0 :   curve->start_point( 0 );
     569         [ #  # ]:          0 :   if( start->num_curves() == 0 )
     570                 :            :   {
     571         [ #  # ]:          0 :     if( start->real_point() )
     572                 :          0 :       restore_point( start );
     573                 :            :     else
     574         [ #  # ]:          0 :       delete start;
     575                 :            :   }
     576                 :            :   
     577                 :          0 :   PartitionPoint* end = curve->end_point();
     578                 :          0 :   curve->end_point(0);
     579         [ #  # ]:          0 :   if( end->num_curves() == 0 )
     580                 :            :   {
     581         [ #  # ]:          0 :     if( end->real_point() )
     582                 :          0 :       restore_point( end );
     583                 :            :     else
     584         [ #  # ]:          0 :       delete end;
     585                 :            :   }
     586                 :            :   
     587                 :          0 :   Curve* result = curve->real_curve();
     588                 :          0 :   curve->sub_entity_set().unwrap_attributes();
     589                 :          0 :   curve->sub_entity_set().remove_bridge( result );
     590         [ #  # ]:          0 :   if( curve->owner() )
     591                 :          0 :     curve->owner()->swap_bridge( curve, result, false );
     592         [ #  # ]:          0 :   delete curve;
     593                 :            : 
     594                 :            :   // we must notify the graphics of the modify from "real" to virtual -- KGM
     595                 :            :   // I realize that this is not where the other notifies are completed but there
     596                 :            :   // is no knowledge of the change later on. 
     597         [ #  # ]:          0 :   CubitObservable* observable = dynamic_cast<CubitObservable*>(result->topology_entity());
     598         [ #  # ]:          0 :   if (observable)
     599                 :            :   {
     600 [ #  # ][ #  # ]:          0 :     AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, dynamic_cast<RefEntity*>(result->topology_entity())));
                 [ #  # ]
     601                 :            :   }
     602                 :            : 
     603                 :          0 :   return result;
     604                 :            : }
     605                 :            : 
     606                 :            : 
     607                 :            : //-------------------------------------------------------------------------
     608                 :            : // Purpose       : Restore original solid model topology.  (Inverse of
     609                 :            : //                 replace_surface.)
     610                 :            : //
     611                 :            : // Special Notes : 
     612                 :            : //
     613                 :            : // Creator       : Jason Kraftcheck
     614                 :            : //
     615                 :            : // Creation Date : 02/23/03
     616                 :            : //-------------------------------------------------------------------------
     617                 :          0 : Surface* PartitionEngine::restore_surface( SubSurface* surface )
     618                 :            : {
     619 [ #  # ][ #  # ]:          0 :   if( surface->sub_entity_set().has_lower_order() || surface->next_co_surface() )
                 [ #  # ]
     620                 :          0 :     return 0;
     621                 :            :   
     622         [ #  # ]:          0 :   while( PartitionLoop* loop = surface->next_loop() )
     623                 :            :     // while surface has loops...
     624                 :            :   {
     625                 :          0 :     surface->remove( loop );
     626                 :            :     
     627         [ #  # ]:          0 :     while( loop->first_coedge() )
     628                 :            :     {
     629                 :          0 :       PartitionCoEdge* coedge = loop->first_coedge();
     630                 :          0 :       loop->remove( coedge );
     631                 :            :       
     632         [ #  # ]:          0 :       SubCurve* curve = dynamic_cast<SubCurve*>(coedge->get_curve());
     633 [ #  # ][ #  # ]:          0 :       if( !curve || curve->sub_entity_set().has_lower_order() )
                 [ #  # ]
     634                 :          0 :         continue;
     635                 :            :       
     636                 :          0 :       bool remove = true;
     637                 :          0 :       coedge = 0;
     638         [ #  # ]:          0 :       while( (coedge = curve->next_coedge( coedge )) )
     639                 :            :       {
     640         [ #  # ]:          0 :         if( coedge->get_loop() )
     641                 :            :         {
     642                 :          0 :           remove = false;
     643                 :          0 :           break;
     644                 :            :         }
     645                 :            :       }
     646                 :            :       
     647         [ #  # ]:          0 :       if( remove )
     648                 :            :       {
     649                 :          0 :         restore_curve( curve );
     650                 :            :       }
     651                 :            :       
     652                 :            :     }
     653                 :            :     
     654         [ #  # ]:          0 :     delete loop;
     655                 :            :   }
     656                 :            :   
     657                 :            :   
     658                 :          0 :   Surface* result = surface->partitioned_surface();
     659                 :          0 :   surface->sub_entity_set().unwrap_attributes();
     660                 :          0 :   surface->sub_entity_set().remove_bridge( result );
     661         [ #  # ]:          0 :   if( surface->owner() )
     662                 :          0 :     surface->owner()->swap_bridge( surface, result, false );
     663         [ #  # ]:          0 :   delete surface;
     664                 :          0 :   return result;
     665                 :            : }
     666                 :            : 
     667                 :            : //-------------------------------------------------------------------------
     668                 :            : // Purpose       : Destroy a single partition of a volume.
     669                 :            : //
     670                 :            : // Special Notes : Will restore original volume if this is the last/only
     671                 :            : //                  partition.
     672                 :            : //
     673                 :            : // Creator       : Jason Kraftcheck
     674                 :            : //
     675                 :            : // Creation Date : 02/11/03
     676                 :            : //-------------------------------------------------------------------------
     677                 :          0 : CubitStatus PartitionEngine::destroy_lump( PartitionLump* lump )
     678                 :            : {
     679                 :            :     /* only partition lump? */
     680         [ #  # ]:          0 :   if ( ! lump->sub_entity_set().has_multiple_sub_entities() )
     681                 :            :   {
     682         [ #  # ]:          0 :     DLIList<PartitionEntity*> child_entities;
     683 [ #  # ][ #  # ]:          0 :     lump->sub_entity_set().get_lower_order( child_entities );
     684 [ #  # ][ #  # ]:          0 :     DLIList<PartitionSurface*> surf_list;
     685 [ #  # ][ #  # ]:          0 :     CAST_LIST( child_entities, surf_list, PartitionSurface );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     686                 :            :     
     687 [ #  # ][ #  # ]:          0 :     while( surf_list.size() )
     688 [ #  # ][ #  # ]:          0 :       if( ! remove_surface( surf_list.pop() ) )
                 [ #  # ]
     689                 :          0 :         return CUBIT_FAILURE;
     690                 :            :     
     691 [ #  # ][ #  # ]:          0 :     return restore_lump(lump) ? CUBIT_SUCCESS : CUBIT_FAILURE;
                 [ #  # ]
     692                 :            :   }
     693                 :            :   
     694                 :            :   PartitionShell* shell;
     695         [ #  # ]:          0 :   while ( (shell = lump->next_shell(0)) )
     696                 :            :   {
     697                 :          0 :     lump->remove(shell);
     698                 :          0 :     destroy_shell(shell);
     699                 :            :   }
     700         [ #  # ]:          0 :   delete lump;
     701                 :            :   
     702                 :          0 :   return CUBIT_SUCCESS;
     703                 :            : }
     704                 :            :       
     705                 :            :     
     706                 :            : 
     707                 :            : //-------------------------------------------------------------------------
     708                 :            : // Purpose       : Restore original solid model topology.  (Inverse of
     709                 :            : //                 replace_lump.)
     710                 :            : //
     711                 :            : // Special Notes : 
     712                 :            : //
     713                 :            : // Creator       : Jason Kraftcheck
     714                 :            : //
     715                 :            : // Creation Date : 02/23/03
     716                 :            : //-------------------------------------------------------------------------
     717                 :          0 : Lump* PartitionEngine::restore_lump( PartitionLump* lump )
     718                 :            : {
     719         [ #  # ]:          0 :   if( lump->sub_entity_set().has_lower_order() )
     720                 :          0 :     return 0;
     721                 :            :   
     722         [ #  # ]:          0 :   while( PartitionShell* shell = lump->next_shell() )
     723                 :            :     // while surface has loops...
     724                 :            :   {
     725                 :          0 :     lump->remove( shell );
     726                 :          0 :     destroy_shell( shell );
     727                 :            :   }
     728                 :            :   
     729                 :            :   
     730                 :          0 :   Lump* result = lump->real_lump();
     731                 :          0 :   lump->sub_entity_set().unwrap_attributes();
     732                 :          0 :   lump->sub_entity_set().remove_bridge( result );
     733         [ #  # ]:          0 :   if( lump->owner() )
     734                 :          0 :     lump->owner()->swap_bridge( lump, result, false );
     735         [ #  # ]:          0 :   delete lump;
     736                 :          0 :   return result;
     737                 :            : }
     738                 :            : 
     739                 :          0 : bool PartitionEngine::is_partition(TBOwner *bridge_owner)
     740                 :            : {
     741                 :          0 :   bool ret = false;
     742         [ #  # ]:          0 :   if(bridge_owner)
     743                 :            :   {
     744 [ #  # ][ #  # ]:          0 :     if(dynamic_cast<SubEntitySet*>(bridge_owner))
                 [ #  # ]
     745                 :            :     {
     746                 :          0 :       ret = true;
     747                 :            :     }
     748                 :            :   }
     749                 :          0 :   return ret;
     750                 :            : }
     751                 :            : 
     752                 :          0 : bool PartitionEngine::is_composite(TBOwner *bridge_owner)
     753                 :            : {
     754                 :          0 :   return false;
     755                 :            : }
     756                 :            : 
     757                 :          0 : bool PartitionEngine::is_composite(TopologyBridge *bridge)
     758                 :            : {
     759                 :          0 :   return false;
     760                 :            : }
     761                 :            : 
     762                 :            : //-------------------------------------------------------------------------
     763                 :            : // Purpose       : Destroy a shell
     764                 :            : //
     765                 :            : // Special Notes : 
     766                 :            : //
     767                 :            : // Creator       : Jason Kraftcheck
     768                 :            : //
     769                 :            : // Creation Date : 03/11/04
     770                 :            : //-------------------------------------------------------------------------
     771                 :          0 : CubitStatus PartitionEngine::destroy_shell( PartitionShell* shell )
     772                 :            : {
     773         [ #  # ]:          0 :   if (shell->get_lump())
     774                 :            :   {
     775                 :          0 :     assert(0);
     776                 :            :     return CUBIT_FAILURE;
     777                 :            :   }
     778                 :            :   
     779         [ #  # ]:          0 :   while( PartitionCoSurf* cosurf = shell->next_co_surface() )
     780                 :            :   {
     781                 :          0 :     shell->remove( cosurf );
     782                 :            : 
     783         [ #  # ]:          0 :     SubSurface* psurf = dynamic_cast<SubSurface*>(cosurf->get_surface());
     784         [ #  # ]:          0 :     if (psurf)
     785                 :            :     {
     786                 :          0 :       psurf->remove(cosurf);
     787                 :            : 
     788                 :            :         // If PartitionSurface is the same as the underlying surface
     789                 :            :         // and is not part of any other PartitionLumps, remove it.
     790   [ #  #  #  # ]:          0 :       if( !psurf->sub_entity_set().has_lower_order() &&
                 [ #  # ]
     791                 :          0 :            psurf->next_co_surface() == 0 )
     792                 :          0 :         restore_surface( psurf );
     793                 :            :     }
     794                 :            :     
     795         [ #  # ]:          0 :     delete cosurf;
     796                 :            :   }
     797                 :            :     
     798         [ #  # ]:          0 :   delete shell;
     799                 :          0 :   return CUBIT_SUCCESS;
     800                 :            : }
     801                 :            : 
     802                 :            : 
     803                 :            : 
     804                 :            : //-------------------------------------------------------------------------
     805                 :            : // Purpose       : Partition a curve
     806                 :            : //
     807                 :            : // Special Notes : public interface to curve partitioning
     808                 :            : //
     809                 :            : // Creator       : Jason Kraftcheck
     810                 :            : //
     811                 :            : // Creation Date : 02/23/03
     812                 :            : //-------------------------------------------------------------------------
     813                 :          0 : TBPoint* PartitionEngine::insert_point( Curve* curve, double u )
     814                 :            : {
     815         [ #  # ]:          0 :   PartitionCurve* pcurve = dynamic_cast<PartitionCurve*>(curve);
     816                 :          0 :   bool replaced_curve = false;
     817                 :            :   
     818         [ #  # ]:          0 :   if( !pcurve )
     819                 :            :   {
     820 [ #  # ][ #  # ]:          0 :     if( CompositeCurve* comp = dynamic_cast<CompositeCurve*>(curve) )
     821                 :            :     {
     822 [ #  # ][ #  # ]:          0 :       return CompositeEngine::instance().insert_point( comp, u );
     823                 :            :     }
     824                 :            :   
     825         [ #  # ]:          0 :     pcurve = replace_curve( curve );
     826         [ #  # ]:          0 :     if( !pcurve )
     827                 :          0 :       return 0;
     828                 :          0 :     replaced_curve = true;
     829                 :            :   }
     830                 :            :   
     831         [ #  # ]:          0 :   CubitVector coords;
     832 [ #  # ][ #  # ]:          0 :   if( ! pcurve->position_from_u( u, coords ) )
     833                 :            :   {
     834         [ #  # ]:          0 :     if( replaced_curve )
     835 [ #  # ][ #  # ]:          0 :       restore_curve( dynamic_cast<SubCurve*>(pcurve) );
     836                 :          0 :     return 0;
     837                 :            :   }
     838                 :            :   
     839 [ #  # ][ #  # ]:          0 :   PartitionPoint* npoint = new PartitionPoint( coords, pcurve );
                 [ #  # ]
     840         [ #  # ]:          0 :   PartitionCurve* ncurve = insert_point(pcurve, npoint);
     841                 :            :   
     842         [ #  # ]:          0 :   if( !ncurve )
     843                 :            :   {
     844         [ #  # ]:          0 :     if( replaced_curve )
     845 [ #  # ][ #  # ]:          0 :       restore_curve( dynamic_cast<SubCurve*>(pcurve) );
     846 [ #  # ][ #  # ]:          0 :     delete npoint;
     847                 :          0 :     return 0;
     848                 :            :   }
     849                 :            :   
     850                 :          0 :   return npoint;
     851                 :            : }
     852                 :            : 
     853                 :            : 
     854                 :            : //-------------------------------------------------------------------------
     855                 :            : // Purpose       : Partition a curve
     856                 :            : //
     857                 :            : // Special Notes : not public
     858                 :            : //
     859                 :            : // Creator       : Jason Kraftcheck
     860                 :            : //
     861                 :            : // Creation Date : 02/23/03
     862                 :            : //-------------------------------------------------------------------------
     863                 :          0 : PartitionCurve* PartitionEngine::insert_point( PartitionCurve* pcurve, 
     864                 :            :                                                PartitionPoint* npoint )
     865                 :            : {
     866                 :          0 :   const double TOLSQR = GEOMETRY_RESABS * GEOMETRY_RESABS;
     867         [ #  # ]:          0 :   CubitVector coords = npoint->coordinates();
     868         [ #  # ]:          0 :   double u = pcurve->u_from_position(coords);
     869                 :            :   double u_min, u_max;
     870         [ #  # ]:          0 :   pcurve->get_param_range( u_min, u_max );
     871                 :            : 
     872         [ #  # ]:          0 :   if(u_min > u_max)
     873                 :            :   {
     874                 :          0 :     double dtemp = u_min;
     875                 :          0 :     u_min = u_max;
     876                 :          0 :     u_max = dtemp;
     877                 :            :   }
     878                 :            : 
     879 [ #  # ][ #  # ]:          0 :   if( u - u_min < CUBIT_RESABS || u_max - u < CUBIT_RESABS )
     880                 :          0 :     return 0;
     881                 :            :   
     882 [ #  # ][ #  # ]:          0 :   if( (pcurve->start_point()->coordinates() - coords).length_squared() < TOLSQR 
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
     883 [ #  # ][ #  # ]:          0 :    || (pcurve->end_point()->coordinates() - coords).length_squared() < TOLSQR )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     884                 :          0 :     return 0;
     885                 :            :   
     886         [ #  # ]:          0 :   PartitionCurve* ncurve = pcurve->split( u );
     887         [ #  # ]:          0 :   if( !ncurve ) 
     888                 :          0 :     return 0;
     889                 :            :   
     890 [ #  # ][ #  # ]:          0 :   ncurve->end_point( pcurve->end_point() );
     891         [ #  # ]:          0 :   pcurve->end_point( npoint );
     892         [ #  # ]:          0 :   ncurve->start_point( npoint );
     893         [ #  # ]:          0 :   pcurve->fix_facet_data( ncurve );
     894                 :            :   
     895                 :          0 :   PartitionCoEdge *pcoedge = 0, *ncoedge = 0;
     896 [ #  # ][ #  # ]:          0 :   while( (pcoedge = pcurve->next_coedge( pcoedge )) )
     897                 :            :   {
     898 [ #  # ][ #  # ]:          0 :     ncoedge = new PartitionCoEdge( pcoedge );
     899         [ #  # ]:          0 :     ncurve->add( ncoedge );
     900 [ #  # ][ #  # ]:          0 :     if( pcoedge->get_loop() )
     901                 :            :     {
     902 [ #  # ][ #  # ]:          0 :       if( pcoedge->sense() == CUBIT_FORWARD )
     903 [ #  # ][ #  # ]:          0 :         pcoedge->get_loop()->insert_after( ncoedge, pcoedge );
     904                 :            :       else
     905 [ #  # ][ #  # ]:          0 :         pcoedge->get_loop()->insert_before( ncoedge, pcoedge );
     906                 :            :     }
     907                 :            :   }
     908                 :            :   
     909 [ #  # ][ #  # ]:          0 :   if( pcurve->owner() )
     910 [ #  # ][ #  # ]:          0 :     pcurve->owner()->notify_split( ncurve, pcurve );
     911                 :            :   
     912                 :          0 :   return ncurve;
     913                 :            : }
     914                 :            : 
     915                 :            : //-------------------------------------------------------------------------
     916                 :            : // Purpose       : un-partition a curve
     917                 :            : //
     918                 :            : // Special Notes : 
     919                 :            : //
     920                 :            : // Creator       : Jason Kraftcheck
     921                 :            : //
     922                 :            : // Creation Date : 02/23/03
     923                 :            : //-------------------------------------------------------------------------
     924                 :          0 : Curve* PartitionEngine::remove_point( PartitionPoint* point, 
     925                 :            :                                       PartitionCurve* dead_curves[2] )
     926                 :            : {
     927         [ #  # ]:          0 :   if( dead_curves )
     928                 :          0 :     dead_curves[0] = dead_curves[1] = 0;
     929                 :            :   
     930 [ #  # ][ #  # ]:          0 :   if( point->num_curves() > 2 )
     931                 :          0 :     return 0;
     932                 :            :       
     933         [ #  # ]:          0 :   DLIList<TopologyBridge*> curve_bridges;
     934         [ #  # ]:          0 :   point->get_parents_virt( curve_bridges );
     935 [ #  # ][ #  # ]:          0 :   if( curve_bridges.size() > 2 )
     936                 :          0 :     return 0;
     937                 :            :   
     938 [ #  # ][ #  # ]:          0 :   if( curve_bridges.size() == 1 )
     939                 :            :   {
     940 [ #  # ][ #  # ]:          0 :     PartPTCurve* point_curve = dynamic_cast<PartPTCurve*>(curve_bridges.get());
     941         [ #  # ]:          0 :     if( ! point_curve )
     942                 :          0 :       return 0;
     943                 :            :     
     944         [ #  # ]:          0 :     if( dead_curves )
     945                 :          0 :       dead_curves[0] = point_curve;
     946         [ #  # ]:          0 :     remove_point_curve( point );
     947                 :          0 :     return 0;
     948                 :            :   }
     949                 :            : 
     950                 :            : /*  
     951                 :            :   TopologyBridge* real = point->partitioned_entity();
     952                 :            :   if( dynamic_cast<TBPoint*>(real) )
     953                 :            :   {
     954                 :            :     Curve* curve1 = dynamic_cast<Curve*>(curve_bridges.get());
     955                 :            :     Curve* curve2 = dynamic_cast<Curve*>(curve_bridges.next());
     956                 :            :     PartitionCurve* pc1 = dynamic_cast<PartitionCurve*>(curve1);
     957                 :            :     PartitionCurve* pc2 = dynamic_cast<PartitionCurve*>(curve2);
     958                 :            :     assert( pc1 || pc2 );
     959                 :            :     if( !pc1 )
     960                 :            :       pc1 = replace_curve( curve1 );
     961                 :            :     if( !pc2 )
     962                 :            :       pc2 = replace_curve( curve2 );
     963                 :            :     
     964                 :            :     CompositeEngine::instance()->remove_point( dynamic_cast<TBPoint*>(real) );
     965                 :            :     bool reverse = ( pc1->start_point() == pc2->start_point() ||
     966                 :            :                      pc2->end_point() == pc2->end_point() );
     967                 :            :     if( pc1->partitioned_entity() == 0 )
     968                 :            :     {
     969                 :            :       bool prepend = false;
     970                 :            :       if( pc1->other_point( pc2->start_point() ) )
     971                 :            :         prepend = true;
     972                 :            :       pc2->sub_entity_set().merge( pc1->sub_entity_set(), reverse, prepend );
     973                 :            :     }
     974                 :            :     else if( pc2->partitioned_entity() == 0 )
     975                 :            :     {
     976                 :            :       bool prepend = false;
     977                 :            :       if( pc2->other_point( pc1->start_point() ) )
     978                 :            :         prepend = true;
     979                 :            :       pc1->sub_entity_set().merge( pc2->sub_entity_set(), reverse, prepend );
     980                 :            :     }
     981                 :            :     else
     982                 :            :       return 0;
     983                 :            :   }
     984                 :            : */  
     985 [ #  # ][ #  # ]:          0 :   if( point->num_curves() != 2 )
     986                 :          0 :     return 0;
     987                 :            :   
     988         [ #  # ]:          0 :   PartitionCurve* survivor = point->next_curve(0);
     989         [ #  # ]:          0 :   PartitionCurve* casualty = point->next_curve(survivor);
     990 [ #  # ][ #  # ]:          0 :   if( survivor->start_point() == point &&
         [ #  # ][ #  # ]
     991         [ #  # ]:          0 :       casualty->end_point() == point )
     992                 :            :   {
     993                 :            :       // swap
     994                 :          0 :     survivor = casualty;
     995         [ #  # ]:          0 :     casualty = point->next_curve(0);
     996                 :            :   }
     997                 :            :   
     998 [ #  # ][ #  # ]:          0 :   if( ! survivor->combine( casualty ) )
     999                 :          0 :     return 0;
    1000                 :            :     
    1001                 :            :   PartitionPoint* other_pt = 
    1002         [ #  # ]:          0 :     casualty->start_point() == point ? 
    1003 [ #  # ][ #  # ]:          0 :     casualty->end_point() : casualty->start_point();
                 [ #  # ]
    1004         [ #  # ]:          0 :   casualty->start_point(0);
    1005         [ #  # ]:          0 :   casualty->end_point(0);
    1006                 :            :   
    1007 [ #  # ][ #  # ]:          0 :   if( survivor->start_point() == point )
    1008         [ #  # ]:          0 :     survivor->start_point( other_pt );
    1009                 :            :   else
    1010         [ #  # ]:          0 :     survivor->end_point( other_pt );
    1011                 :            :   
    1012 [ #  # ][ #  # ]:          0 :   delete point;
    1013                 :            :   
    1014 [ #  # ][ #  # ]:          0 :   while( PartitionCoEdge* coedge = casualty->next_coedge(0) )
    1015                 :            :   {
    1016 [ #  # ][ #  # ]:          0 :     if( coedge->get_loop() )
    1017 [ #  # ][ #  # ]:          0 :       coedge->get_loop()->remove( coedge );
    1018         [ #  # ]:          0 :     casualty->remove( coedge );
    1019 [ #  # ][ #  # ]:          0 :     delete coedge;
    1020                 :            :   }
    1021 [ #  # ][ #  # ]:          0 :   delete casualty;
    1022         [ #  # ]:          0 :   if( dead_curves )
    1023                 :          0 :     dead_curves[0] = casualty;
    1024                 :            :   
    1025                 :          0 :   Curve* result = survivor;
    1026         [ #  # ]:          0 :   SubCurve* subcurve = dynamic_cast<SubCurve*>(survivor);
    1027 [ #  # ][ #  # ]:          0 :   if( subcurve && !survivor->sub_entity_set().has_multiple_sub_entities() )
         [ #  # ][ #  # ]
                 [ #  # ]
    1028                 :            :   {
    1029         [ #  # ]:          0 :     Curve* real_curve = restore_curve( subcurve );
    1030         [ #  # ]:          0 :     if (real_curve)
    1031                 :            :     { 
    1032                 :          0 :       result = real_curve;
    1033         [ #  # ]:          0 :       if (dead_curves)
    1034                 :          0 :         dead_curves[1] = survivor;
    1035                 :            :     } 
    1036                 :            :   }
    1037                 :            : 
    1038         [ #  # ]:          0 :   return result;
    1039                 :            : }
    1040                 :            : 
    1041                 :            : //-------------------------------------------------------------------------
    1042                 :            : // Purpose       : Remove a point-curve (point imprinted on a surface)
    1043                 :            : //
    1044                 :            : // Special Notes : 
    1045                 :            : //
    1046                 :            : // Creator       : Jason Kraftcheck
    1047                 :            : //
    1048                 :            : // Creation Date : 02/23/03
    1049                 :            : //-------------------------------------------------------------------------
    1050                 :          0 : CubitStatus PartitionEngine::remove_point_curve( PartitionPoint* point )
    1051                 :            : {
    1052         [ #  # ]:          0 :   if( point->num_curves() != 1 )
    1053                 :          0 :     return CUBIT_FAILURE;
    1054                 :            :   
    1055         [ #  # ]:          0 :   PartPTCurve* curve = dynamic_cast<PartPTCurve*>(point->next_curve(0));
    1056         [ #  # ]:          0 :   if( !curve )
    1057                 :          0 :     return CUBIT_FAILURE;
    1058                 :            :   
    1059                 :          0 :   PartitionSurface* surf = 0;  
    1060         [ #  # ]:          0 :   if( curve->num_coedges() )
    1061                 :            :   {
    1062         [ #  # ]:          0 :     assert( curve->num_coedges() == 1 );
    1063                 :          0 :     PartitionCoEdge* coedge = curve->next_coedge(0);
    1064                 :          0 :     PartitionLoop* loop = coedge->get_loop();
    1065         [ #  # ]:          0 :     if( loop )
    1066                 :            :     {
    1067                 :          0 :       surf = loop->get_surface();
    1068                 :          0 :       surf->remove( loop );
    1069                 :          0 :       loop->remove( coedge );
    1070         [ #  # ]:          0 :       assert( loop->num_coedges() == 0 );
    1071         [ #  # ]:          0 :       delete loop;
    1072                 :            :     }
    1073                 :          0 :     curve->remove( coedge );
    1074         [ #  # ]:          0 :     delete coedge;
    1075                 :            :   }
    1076                 :            :   
    1077                 :          0 :   curve->start_point(0);
    1078                 :          0 :   curve->end_point(0);
    1079         [ #  # ]:          0 :   delete curve;
    1080         [ #  # ]:          0 :   delete point;
    1081                 :            :   
    1082 [ #  # ][ #  # ]:          0 :   if( surf && surf->owner() )
                 [ #  # ]
    1083                 :          0 :     surf->owner()->notify_topology_modified( surf );
    1084                 :            :   
    1085                 :          0 :   return CUBIT_SUCCESS;
    1086                 :            : }
    1087                 :            : 
    1088                 :            : //-------------------------------------------------------------------------
    1089                 :            : // Purpose       : Topological modifications for surface partitioning
    1090                 :            : //
    1091                 :            : // Special Notes : non-public, assumes surface facets have already been
    1092                 :            : //                 imprinted and the polyline of the imprint is already
    1093                 :            : //                 associated with the passed curve.
    1094                 :            : //
    1095                 :            : // Creator       : Jason Kraftcheck
    1096                 :            : //
    1097                 :            : // Creation Date : 02/23/03
    1098                 :            : //-------------------------------------------------------------------------
    1099                 :          0 : PartitionSurface* PartitionEngine::insert_curve( PartitionSurface* surface, 
    1100                 :            :                                                  SegmentedCurve* curve )
    1101                 :            : {
    1102                 :          0 :   PartitionSurface* new_surface = 0;
    1103 [ #  # ][ #  # ]:          0 :   assert( &(curve->sub_entity_set()) == &(surface->sub_entity_set()) );
                 [ #  # ]
    1104                 :            :   
    1105         [ #  # ]:          0 :   PartitionPoint *start_point = curve->start_point();
    1106         [ #  # ]:          0 :   PartitionPoint *end_point   = curve->end_point();
    1107                 :          0 :   PartitionLoop  *start_loop = 0, *end_loop = 0;
    1108                 :          0 :   PartitionCoEdge *start_prev_coedge = 0, *start_next_coedge = 0;
    1109                 :          0 :   PartitionCoEdge *end_prev_coedge = 0, *end_next_coedge = 0;
    1110                 :            :   
    1111                 :            :     // find where to insert new curve in loop
    1112 [ #  # ][ #  # ]:          0 :   if ( !find_coedges( surface, curve, start_point, start_prev_coedge, start_next_coedge ) )
    1113                 :          0 :     return 0;
    1114 [ #  # ][ #  # ]:          0 :   if ( !find_coedges( surface, curve, end_point, end_prev_coedge, end_next_coedge )) 
    1115                 :          0 :     return 0;
    1116                 :            :     
    1117 [ #  # ][ #  # ]:          0 :   assert((!start_prev_coedge && !start_next_coedge) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1118                 :            :          (start_prev_coedge && start_next_coedge && 
    1119         [ #  # ]:          0 :           start_prev_coedge->get_loop() == start_next_coedge->get_loop()));
    1120 [ #  # ][ #  # ]:          0 :   assert((!end_prev_coedge && !end_next_coedge) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1121                 :            :          (end_prev_coedge && end_next_coedge && 
    1122         [ #  # ]:          0 :           end_prev_coedge->get_loop() == end_next_coedge->get_loop()));
    1123         [ #  # ]:          0 :   if ( start_prev_coedge )
    1124         [ #  # ]:          0 :     start_loop = start_prev_coedge->get_loop();
    1125         [ #  # ]:          0 :   if ( end_prev_coedge )
    1126         [ #  # ]:          0 :     end_loop = end_prev_coedge->get_loop();
    1127                 :            :   
    1128                 :            :   
    1129                 :            :     // remove any point-curves
    1130                 :            :   PartitionCurve* pt_curve;
    1131                 :            :   PartPTCurve* point_curve;
    1132         [ #  # ]:          0 :   for ( int i = 0; i < 2; i++ ) // do once for each end point
    1133                 :            :   {
    1134         [ #  # ]:          0 :     PartitionPoint* pt = i ? end_point : start_point;
    1135         [ #  # ]:          0 :     pt_curve = pt->next_curve(0);
    1136         [ #  # ]:          0 :     while ( pt_curve  )
    1137                 :            :     {
    1138         [ #  # ]:          0 :       point_curve = dynamic_cast<PartPTCurve*>(pt_curve);
    1139         [ #  # ]:          0 :       pt_curve = pt->next_curve(pt_curve);
    1140 [ #  # ][ #  # ]:          0 :       if (point_curve && point_curve->next_coedge(0)->get_loop()->get_surface() == surface)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1141                 :            :       {
    1142         [ #  # ]:          0 :         point_curve->start_point(0);
    1143         [ #  # ]:          0 :         point_curve->end_point(0);
    1144                 :            : 
    1145         [ #  # ]:          0 :         PartitionCoEdge* coedge = point_curve->next_coedge(0);
    1146         [ #  # ]:          0 :         point_curve->remove(coedge);
    1147 [ #  # ][ #  # ]:          0 :         assert( !point_curve->next_coedge(0) );
    1148         [ #  # ]:          0 :         PartitionLoop* loop = coedge->get_loop();
    1149         [ #  # ]:          0 :         loop->remove(coedge);
    1150 [ #  # ][ #  # ]:          0 :         assert( !loop->first_coedge() );
    1151         [ #  # ]:          0 :         surface->remove(loop);
    1152 [ #  # ][ #  # ]:          0 :         delete loop;
    1153 [ #  # ][ #  # ]:          0 :         delete coedge;
    1154 [ #  # ][ #  # ]:          0 :         delete point_curve;
    1155                 :            :       }
    1156                 :            :     }
    1157                 :            :   }
    1158                 :            :   
    1159                 :            :   
    1160 [ #  # ][ #  # ]:          0 :   PartitionCoEdge* forward = new PartitionCoEdge( surface, CUBIT_FORWARD );
    1161 [ #  # ][ #  # ]:          0 :   PartitionCoEdge* reverse = new PartitionCoEdge( surface, CUBIT_REVERSED );
    1162         [ #  # ]:          0 :   curve->add(forward);
    1163         [ #  # ]:          0 :   curve->add(reverse);
    1164                 :            : 
    1165                 :            :     // new one-curve loop?
    1166 [ #  # ][ #  # ]:          0 :   if( !start_loop && !end_loop )
    1167                 :            :   {
    1168 [ #  # ][ #  # ]:          0 :     PartitionLoop* new_loop = new PartitionLoop();
    1169         [ #  # ]:          0 :     surface->add( new_loop );
    1170         [ #  # ]:          0 :     new_loop->insert_after( forward, 0 );
    1171                 :            :     
    1172 [ #  # ][ #  # ]:          0 :     if( curve->start_point() == curve->end_point() )
                 [ #  # ]
    1173                 :            :     {
    1174 [ #  # ][ #  # ]:          0 :       PartitionLoop* loop2 = new PartitionLoop();
    1175         [ #  # ]:          0 :       loop2->insert_after( reverse, 0 );
    1176                 :            :       
    1177         [ #  # ]:          0 :       if( VGLoopTool
    1178                 :            :           <PartitionSurface,PartitionLoop,PartitionCoEdge,PartitionCurve,PartitionPoint>
    1179         [ #  # ]:          0 :           ::loop_angle_metric( forward ) > 0 )
    1180                 :            :       {
    1181                 :          0 :         new_loop = loop2;
    1182                 :            :       }
    1183                 :            :       else
    1184                 :            :       {
    1185         [ #  # ]:          0 :         surface->remove(new_loop);
    1186         [ #  # ]:          0 :         surface->add( loop2 );
    1187                 :            :       }
    1188                 :            :       
    1189 [ #  # ][ #  # ]:          0 :       new_surface = split_surface( surface, new_loop->first_coedge() );
    1190         [ #  # ]:          0 :       new_surface->add( new_loop );
    1191                 :            :     }
    1192                 :            :     else
    1193                 :            :     {
    1194         [ #  # ]:          0 :       new_loop->insert_after( reverse, forward );
    1195                 :          0 :     }
    1196                 :            :   }
    1197                 :            :       
    1198                 :            :     // sipe
    1199 [ #  # ][ #  # ]:          0 :   else if( !start_loop || !end_loop )
    1200                 :            :   {
    1201                 :            :     PartitionCoEdge* prev;
    1202                 :            :     PartitionLoop* loop;
    1203         [ #  # ]:          0 :     if( start_loop )
    1204                 :            :     {
    1205                 :          0 :       loop = start_loop;
    1206                 :          0 :       prev = start_prev_coedge;
    1207                 :            :     }
    1208                 :            :     else
    1209                 :            :     {
    1210                 :          0 :       loop = end_loop;
    1211                 :          0 :       prev = end_prev_coedge;
    1212                 :            :     }
    1213                 :            :     
    1214 [ #  # ][ #  # ]:          0 :     if( forward->start_point() == prev->end_point() )
                 [ #  # ]
    1215                 :            :     {
    1216         [ #  # ]:          0 :       loop->insert_after( forward, prev );
    1217         [ #  # ]:          0 :       loop->insert_after( reverse, forward );
    1218                 :            :     }
    1219                 :            :     else
    1220                 :            :     {
    1221 [ #  # ][ #  # ]:          0 :       assert( reverse->start_point() == prev->end_point() );
                 [ #  # ]
    1222         [ #  # ]:          0 :       loop->insert_after( reverse, prev );
    1223         [ #  # ]:          0 :       loop->insert_after( forward, reverse );
    1224                 :          0 :     }
    1225                 :            :   }
    1226                 :            :   
    1227                 :            :     // join loops
    1228         [ #  # ]:          0 :   else if( start_loop != end_loop )
    1229                 :            :   {
    1230                 :          0 :     PartitionCoEdge* prev = start_prev_coedge;
    1231                 :          0 :     PartitionCoEdge* coedge = end_next_coedge;
    1232                 :          0 :     PartitionCoEdge* next = 0, *other_coedge;
    1233                 :            :     
    1234 [ #  # ][ #  # ]:          0 :     if( forward->start_point() == prev->end_point() )
                 [ #  # ]
    1235                 :            :     {
    1236         [ #  # ]:          0 :       start_loop->insert_after( forward, prev );
    1237                 :          0 :       prev = forward;
    1238                 :          0 :       other_coedge = reverse;
    1239                 :            :     }
    1240                 :            :     else 
    1241                 :            :     {
    1242 [ #  # ][ #  # ]:          0 :       assert( reverse->start_point() == prev->end_point() );
                 [ #  # ]
    1243         [ #  # ]:          0 :       start_loop->insert_after( reverse, prev );
    1244                 :          0 :       prev = reverse;
    1245                 :          0 :       other_coedge = forward;
    1246                 :            :     }
    1247                 :            :     
    1248 [ #  # ][ #  # ]:          0 :     while ( end_loop->first_coedge() )
    1249                 :            :     {
    1250         [ #  # ]:          0 :       next = end_loop->next_coedge( coedge );
    1251         [ #  # ]:          0 :       end_loop->remove( coedge );
    1252         [ #  # ]:          0 :       start_loop->insert_after( coedge, prev );
    1253                 :          0 :       prev = coedge;
    1254                 :          0 :       coedge = next;
    1255                 :            :     }
    1256                 :            :     
    1257                 :            :       // The other coedge for the curve we are restoring...
    1258         [ #  # ]:          0 :     start_loop->insert_after( other_coedge, prev );
    1259                 :            :     
    1260 [ #  # ][ #  # ]:          0 :     assert( end_loop->num_coedges() == 0 );
    1261         [ #  # ]:          0 :     surface->remove( end_loop );
    1262 [ #  # ][ #  # ]:          0 :     delete end_loop;
    1263                 :            :   }
    1264                 :            :   
    1265                 :            :     // split a loop (and create a new surface)
    1266                 :            :   else
    1267                 :            :   {
    1268         [ #  # ]:          0 :     assert( start_loop == end_loop );
    1269                 :            :     
    1270                 :            :       // If the curve we are adding results in a hole that
    1271                 :            :       // intersects the loop we are splitting at a single
    1272                 :            :       // vertex, we need to figure out which of the coedges
    1273                 :            :       // goes in the hole and which is added to the loop
    1274                 :            :       // we are splitting.
    1275 [ #  # ][ #  # ]:          0 :     if( forward->start_point() == forward->end_point() )
                 [ #  # ]
    1276                 :            :     {
    1277         [ #  # ]:          0 :       assert( start_next_coedge == end_next_coedge );
    1278         [ #  # ]:          0 :       assert( start_prev_coedge == end_prev_coedge );
    1279                 :            :       
    1280 [ #  # ][ #  # ]:          0 :       CubitVector prev_tan, forward_tan, reverse_tan, normal, junk;
         [ #  # ][ #  # ]
                 [ #  # ]
    1281 [ #  # ][ #  # ]:          0 :       CubitVector point = forward->start_point()->coordinates();
    1282 [ #  # ][ #  # ]:          0 :       start_prev_coedge->get_curve()->closest_point( point, junk, &prev_tan );
    1283 [ #  # ][ #  # ]:          0 :       if( start_prev_coedge->sense() == CUBIT_FORWARD ) // yes, forward!!!
    1284         [ #  # ]:          0 :         prev_tan *= -1.0;
    1285 [ #  # ][ #  # ]:          0 :       forward->get_curve()->closest_point( point, junk, &forward_tan );
    1286 [ #  # ][ #  # ]:          0 :       reverse_tan = forward_tan * -1.0;
    1287         [ #  # ]:          0 :       surface->closest_point( point, 0, &normal );
    1288                 :            :       
    1289         [ #  # ]:          0 :       double angle1 = normal.vector_angle( prev_tan, forward_tan );
    1290         [ #  # ]:          0 :       double angle2 = normal.vector_angle( prev_tan, reverse_tan );
    1291                 :            :       
    1292         [ #  # ]:          0 :       if( angle2 < angle1 )
    1293                 :            :       {
    1294                 :          0 :         PartitionCoEdge* temp = reverse;
    1295                 :          0 :         reverse = forward;
    1296                 :          0 :         forward = temp;
    1297                 :            :       }
    1298                 :            :     }
    1299                 :            :     
    1300                 :            :     else
    1301                 :            :     {
    1302 [ #  # ][ #  # ]:          0 :       if( forward->end_point() == end_next_coedge->start_point() )
                 [ #  # ]
    1303                 :            :       {
    1304                 :          0 :         PartitionCoEdge* temp = reverse;
    1305                 :          0 :         reverse = forward;
    1306                 :          0 :         forward = temp;
    1307                 :            :       }
    1308                 :            :     }
    1309                 :            :     
    1310 [ #  # ][ #  # ]:          0 :     end_loop = new PartitionLoop();
    1311         [ #  # ]:          0 :     start_loop->insert_after( forward, end_prev_coedge );
    1312         [ #  # ]:          0 :     end_loop->insert_after( reverse, 0 );
    1313                 :            :     
    1314                 :          0 :     PartitionCoEdge* coedge = end_next_coedge;
    1315                 :          0 :     PartitionCoEdge* prev = reverse;
    1316         [ #  # ]:          0 :     while( coedge != start_next_coedge )
    1317                 :            :     {
    1318         [ #  # ]:          0 :       PartitionCoEdge* next = start_loop->next_coedge( coedge );
    1319         [ #  # ]:          0 :       start_loop->remove( coedge );
    1320         [ #  # ]:          0 :       end_loop->insert_after( coedge, prev );
    1321                 :          0 :       prev = coedge;
    1322                 :          0 :       coedge = next;
    1323                 :            :     }
    1324                 :            :     
    1325         [ #  # ]:          0 :     new_surface = split_surface( surface, reverse );
    1326         [ #  # ]:          0 :     new_surface->add( end_loop );
    1327                 :            :   }
    1328                 :            :   
    1329         [ #  # ]:          0 :   if( new_surface )
    1330                 :            :   {
    1331                 :          0 :     PartitionCoSurf* cos = 0;
    1332 [ #  # ][ #  # ]:          0 :     while( (cos = surface->next_co_surface( cos )) )
    1333 [ #  # ][ #  # ]:          0 :       cos->get_shell()->add( new_surface, cos->sense() );
                 [ #  # ]
    1334 [ #  # ][ #  # ]:          0 :     if( surface->owner() )
    1335 [ #  # ][ #  # ]:          0 :       surface->owner()->notify_split( new_surface, surface );
    1336                 :          0 :     return new_surface;
    1337                 :            :   }
    1338                 :            :   else
    1339                 :            :   {
    1340 [ #  # ][ #  # ]:          0 :     if( surface->owner() )
    1341 [ #  # ][ #  # ]:          0 :       surface->owner()->notify_topology_modified( surface );
    1342                 :          0 :     return surface;
    1343                 :            :   }
    1344                 :            : }
    1345                 :            : 
    1346                 :            : 
    1347                 :            : //-------------------------------------------------------------------------
    1348                 :            : // Purpose       : Find where to insert a curve in a loop
    1349                 :            : //
    1350                 :            : // Special Notes : 
    1351                 :            : //
    1352                 :            : // Creator       : Jason Kraftcheck
    1353                 :            : //
    1354                 :            : // Creation Date : 03/24/03
    1355                 :            : //-------------------------------------------------------------------------
    1356                 :          0 : CubitStatus PartitionEngine::find_coedges( PartitionSurface* surface,
    1357                 :            :                                            PartitionCurve* curve,
    1358                 :            :                                            PartitionPoint* point,
    1359                 :            :                                            PartitionCoEdge*& previous,
    1360                 :            :                                            PartitionCoEdge*& next )
    1361                 :            : {
    1362                 :          0 :   const char* const bad_loop_message = "Internal error: Invalid loop. (%s:%d)\n";
    1363                 :            :   
    1364                 :            :     // Find list of all coedges around passed point
    1365                 :            :     // and in passed surface.
    1366         [ #  # ]:          0 :   DLIList<PartitionCoEdge*> point_coedges;
    1367                 :            :   PartitionCoEdge* coedge;
    1368                 :          0 :   PartitionCurve* pt_curve = 0;
    1369 [ #  # ][ #  # ]:          0 :   while ( (pt_curve = point->next_curve(pt_curve)) )
    1370                 :            :   {
    1371                 :          0 :     coedge = 0;
    1372 [ #  # ][ #  # ]:          0 :     while ( (coedge = pt_curve->next_coedge(coedge)) )
    1373                 :            :     {
    1374 [ #  # ][ #  # ]:          0 :       if (coedge->get_loop() &&
                 [ #  # ]
    1375 [ #  # ][ #  # ]:          0 :           coedge->get_loop()->get_surface() == surface &&
         [ #  # ][ #  # ]
    1376 [ #  # ][ #  # ]:          0 :           !dynamic_cast<PartPTCurve*>(coedge->get_curve()))
    1377         [ #  # ]:          0 :         point_coedges.append(coedge);
    1378                 :            :     }
    1379                 :            :   }
    1380                 :            :   
    1381                 :            :     // TBPoint is at end of a sipe/hardline
    1382 [ #  # ][ #  # ]:          0 :   if ( point_coedges.size() == 0 )
    1383                 :            :   {
    1384                 :          0 :     previous = next = 0;
    1385                 :          0 :     return CUBIT_SUCCESS;
    1386                 :            :   }
    1387                 :            :   
    1388                 :            :     // One coedge - closed curve
    1389 [ #  # ][ #  # ]:          0 :   if ( point_coedges.size() == 1 &&
         [ #  # ][ #  # ]
    1390 [ #  # ][ #  # ]:          0 :        point_coedges.get()->start_point() ==
    1391 [ #  # ][ #  # ]:          0 :        point_coedges.get()->end_point() )
    1392                 :            :   {
    1393         [ #  # ]:          0 :     previous = next = point_coedges.get();
    1394                 :          0 :     return CUBIT_SUCCESS;
    1395                 :            :   }
    1396                 :            :   
    1397                 :            :     // Broken loop?
    1398 [ #  # ][ #  # ]:          0 :   if ( point_coedges.size() % 2 != 0 )
    1399                 :            :   {
    1400 [ #  # ][ #  # ]:          0 :     PRINT_ERROR(bad_loop_message,__FILE__,__LINE__);
         [ #  # ][ #  # ]
    1401                 :          0 :     assert(0);
    1402                 :            :     return CUBIT_FAILURE;
    1403                 :            :   }
    1404                 :            :   
    1405                 :            :     // If only two coedges, then we're done
    1406                 :            :     // If closed curve, the answer may be the same coedge for both 
    1407                 :            :     // prev and next.  E.g. A torus cracked along the outside major
    1408                 :            :     // radius and a sipe that intersects that crack curve.  Need
    1409                 :            :     // to fall though to the more complex check below in that case.
    1410 [ #  # ][ #  # ]:          0 :   if ( point_coedges.size() == 2 &&
                 [ #  # ]
    1411 [ #  # ][ #  # ]:          0 :        point_coedges.get()->get_curve()->start_point() != 
                 [ #  # ]
    1412 [ #  # ][ #  # ]:          0 :          point_coedges.get()->get_curve()->end_point() &&
         [ #  # ][ #  # ]
                 [ #  # ]
    1413 [ #  # ][ #  # ]:          0 :        point_coedges.next()->get_curve()->start_point() !=
                 [ #  # ]
    1414 [ #  # ][ #  # ]:          0 :          point_coedges.next()->get_curve()->end_point() )
                 [ #  # ]
    1415                 :            :   {
    1416         [ #  # ]:          0 :     previous = point_coedges.get();
    1417         [ #  # ]:          0 :     next = point_coedges.next();
    1418                 :            :     
    1419 [ #  # ][ #  # ]:          0 :     if ( previous->start_point() == point )
    1420         [ #  # ]:          0 :       std::swap(previous, next);
    1421                 :            :     
    1422                 :          0 :     return CUBIT_SUCCESS;
    1423                 :            :   }
    1424                 :            :   
    1425                 :            :     // Find previous/next coedges by using order of
    1426                 :            :     // facet edges about point in surface facetting.
    1427         [ #  # ]:          0 :   CubitPointData* facet_point = point->facet_point();
    1428 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdgeData*> curve_edges;
    1429         [ #  # ]:          0 :   curve->get_facet_data(curve_edges);
    1430                 :            :   
    1431                 :            :   CubitFacetEdgeData* edge;
    1432                 :            :   //bool edge_reversed;
    1433 [ #  # ][ #  # ]:          0 :   if ( point == curve->start_point() )
    1434                 :            :   {
    1435         [ #  # ]:          0 :     curve_edges.reset();
    1436         [ #  # ]:          0 :     edge = curve_edges.get();
    1437                 :            :   }
    1438                 :            :   else
    1439                 :            :   {
    1440 [ #  # ][ #  # ]:          0 :     assert(curve->end_point() == point);
    1441         [ #  # ]:          0 :     curve_edges.last();
    1442         [ #  # ]:          0 :     edge = curve_edges.get();
    1443                 :            :   }
    1444                 :            :     
    1445                 :            :   PartitionCurve *prev_curve, *next_curve;
    1446         [ #  # ]:          0 :   prev_curve = next_curve_around_point( surface, edge, facet_point, true );
    1447         [ #  # ]:          0 :   next_curve = next_curve_around_point( surface, edge, facet_point, false );
    1448                 :            :   
    1449 [ #  # ][ #  # ]:          0 :   if ( !prev_curve || !next_curve )
    1450                 :            :   {
    1451 [ #  # ][ #  # ]:          0 :     PRINT_ERROR(bad_loop_message,__FILE__,__LINE__);
         [ #  # ][ #  # ]
    1452                 :          0 :     assert(0);
    1453                 :            :     return CUBIT_FAILURE;
    1454                 :            :   }
    1455                 :            :   
    1456                 :          0 :   coedge = 0;
    1457 [ #  # ][ #  # ]:          0 :   while ( (coedge = prev_curve->next_coedge(coedge)) )
    1458                 :            :   {
    1459 [ #  # ][ #  # ]:          0 :     if ( coedge->get_loop() &&  // parent not a partition surface?
                 [ #  # ]
    1460 [ #  # ][ #  # ]:          0 :          coedge->get_loop()->get_surface() == surface &&
         [ #  # ][ #  # ]
    1461         [ #  # ]:          0 :          coedge->end_point() == point )
    1462                 :            :     {
    1463                 :          0 :       previous = coedge;
    1464                 :          0 :       break;
    1465                 :            :     }
    1466                 :            :   }
    1467                 :          0 :   coedge = 0;
    1468 [ #  # ][ #  # ]:          0 :   while ( (coedge = next_curve->next_coedge(coedge)) )
    1469                 :            :   {
    1470 [ #  # ][ #  # ]:          0 :     if ( coedge->get_loop() &&
                 [ #  # ]
    1471 [ #  # ][ #  # ]:          0 :          coedge->get_loop()->get_surface() == surface &&
         [ #  # ][ #  # ]
    1472         [ #  # ]:          0 :          coedge->start_point() == point )
    1473                 :            :     {
    1474                 :          0 :       next = coedge;
    1475                 :          0 :       break;
    1476                 :            :     }
    1477                 :            :   }
    1478                 :            : 
    1479         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    1480                 :            : }
    1481                 :            :     
    1482                 :          0 : PartitionCurve* PartitionEngine::next_curve_around_point(
    1483                 :            :                                PartitionSurface *const surface, 
    1484                 :            :                                CubitFacetEdgeData *const start_edge,
    1485                 :            :                                CubitPointData *const point, 
    1486                 :            :                                const bool backwards )
    1487                 :            : {
    1488                 :            :   //PartitionCoEdge* result = 0;
    1489                 :          0 :   CubitFacetEdge* edge = start_edge;
    1490                 :            :   
    1491         [ #  # ]:          0 :   while ( edge->num_adj_facets() == 2 )
    1492                 :            :   {
    1493                 :          0 :     CubitFacet* facet1 = edge->adj_facet(0);
    1494                 :          0 :     CubitFacet* facet2 = edge->adj_facet(1);
    1495 [ #  # ][ #  # ]:          0 :     assert (TDVGFacetOwner::get(facet1) == surface);
    1496 [ #  # ][ #  # ]:          0 :     assert (TDVGFacetOwner::get(facet2) == surface);
    1497                 :            :     
    1498                 :          0 :     bool edge_reversed = edge->point(1) == point;
    1499         [ #  # ]:          0 :     int facet_sense = edge_reversed == backwards ? -1 : 1;
    1500                 :          0 :     int facet1_index = facet1->edge_index(edge);
    1501                 :            : #ifndef NDEBUG
    1502                 :          0 :     int facet2_index = facet2->edge_index(edge);
    1503         [ #  # ]:          0 :     assert(facet1->edge_use(facet1_index) == -facet2->edge_use(facet2_index));
    1504                 :            : #endif
    1505                 :            : 
    1506         [ #  # ]:          0 :     if ( facet_sense == facet1->edge_use(facet1_index) )
    1507                 :          0 :       edge = facet1->next_edge_at_point( edge, point );
    1508                 :            :     else
    1509                 :          0 :       edge = facet2->next_edge_at_point( edge, point );
    1510                 :            :       
    1511         [ #  # ]:          0 :     assert(edge != start_edge);
    1512                 :            :     
    1513                 :          0 :     PartitionEntity* edge_owner = TDVGFacetOwner::get(edge);
    1514         [ #  # ]:          0 :     PartitionCurve* curve = dynamic_cast<PartitionCurve*>(edge_owner);
    1515         [ #  # ]:          0 :     if ( curve )
    1516                 :          0 :       return curve;
    1517                 :            :   }
    1518                 :            :   
    1519                 :          0 :   return 0;
    1520                 :            : }
    1521                 :            : 
    1522                 :            : 
    1523                 :            : 
    1524                 :            : //-------------------------------------------------------------------------
    1525                 :            : // Purpose       : Un-partition a surface
    1526                 :            : //
    1527                 :            : // Special Notes : 
    1528                 :            : //
    1529                 :            : // Creator       : Jason Kraftcheck
    1530                 :            : //
    1531                 :            : // Creation Date : 02/23/03
    1532                 :            : //-------------------------------------------------------------------------
    1533                 :          0 : Surface* PartitionEngine::remove_curve( PartitionCurve* passed_curve,
    1534                 :            :                                         PartitionSurface* dead_surfs[2] )
    1535                 :            : {
    1536         [ #  # ]:          0 :   if( dead_surfs )
    1537                 :          0 :     dead_surfs[0] = dead_surfs[1] = 0;
    1538                 :            :   
    1539         [ #  # ]:          0 :   PartPTCurve* point_curve = dynamic_cast<PartPTCurve*>(passed_curve);
    1540         [ #  # ]:          0 :   if( point_curve )
    1541                 :            :   {
    1542                 :            :     PartitionSurface* surf = 
    1543 [ #  # ][ #  # ]:          0 :       point_curve->next_coedge(0)->get_loop()->get_surface();
                 [ #  # ]
    1544 [ #  # ][ #  # ]:          0 :     if( !remove_point_curve( point_curve->start_point() ) )
                 [ #  # ]
    1545                 :          0 :       return 0;
    1546                 :            :     
    1547         [ #  # ]:          0 :     SubSurface* subsurf = dynamic_cast<SubSurface*>(surf);
    1548 [ #  # ][ #  # ]:          0 :     if( subsurf && !subsurf->next_co_surface() &&
         [ #  # ][ #  # ]
                 [ #  # ]
    1549 [ #  # ][ #  # ]:          0 :         !subsurf->sub_entity_set().has_lower_order() )
    1550                 :            :     {
    1551         [ #  # ]:          0 :       Surface* result = restore_surface( subsurf );
    1552 [ #  # ][ #  # ]:          0 :       if( result && dead_surfs )
    1553                 :          0 :         dead_surfs[0] = subsurf;
    1554                 :          0 :       return result;
    1555                 :            :     }
    1556                 :            :     else
    1557                 :          0 :       return surf;
    1558                 :            :   }
    1559                 :            :   
    1560         [ #  # ]:          0 :   SegmentedCurve* curve = dynamic_cast<SegmentedCurve*>(passed_curve);
    1561                 :            : 
    1562         [ #  # ]:          0 :   if( !curve )
    1563                 :            :   {
    1564                 :          0 :     assert(0);
    1565                 :            :   }
    1566                 :            : /*
    1567                 :            :     assert( dynamic_cast<SubCurve*>(passed_curve) );
    1568                 :            :     
    1569                 :            :     PartitionCoEdge* coedge1 = passed_curve->next_coedge(0);
    1570                 :            :     PartitionCoEdge* coedge2 = passed_curve->next_coedge(coedge1);
    1571                 :            :     if( !coedge2 || passed_curve->next_coedge(coedge2) )
    1572                 :            :       return 0;
    1573                 :            :       
    1574                 :            :     DLIList<TopologyBridge*> surfaces;
    1575                 :            :     coedge1->find_parent_loop()->get_parents_virt( surfaces );
    1576                 :            :     fix_up_query_results( surfaces );
    1577                 :            :     assert( surfaces.size() == 1 );
    1578                 :            :     Surface* surface1 = dynamic_cast<Surface*>(surfaces.get());
    1579                 :            :     surfaces.clean_out();
    1580                 :            :     coedge2->find_parent_loop()->get_parents_virt( surfaces );
    1581                 :            :     fix_up_query_results( surfaces );
    1582                 :            :     assert( surfaces.size() == 1 );
    1583                 :            :     Surface* surface2 = dynamic_cast<Surface*>(surfaces.get());
    1584                 :            :     
    1585                 :            :     SubSurface* surf1 = dynamic_cast<SubSurface*>(surface1);
    1586                 :            :     SubSurface* surf2 = dynamic_cast<SubSurface*>(surface2);
    1587                 :            :     if( surface1 == surface2 )
    1588                 :            :     {
    1589                 :            :       if( !surf1 )
    1590                 :            :         surf1 = surf2 = replace_surface( surface1 );
    1591                 :            :     }
    1592                 :            :     else
    1593                 :            :     {
    1594                 :            :       if( !surf1 )
    1595                 :            :         surf1 = replace_surface( surface1 );
    1596                 :            :       if( !surf2 )
    1597                 :            :         surf2 = replace_surface( surface2 );
    1598                 :            :     }
    1599                 :            :     
    1600                 :            :       // create SegmentedCurves from SubCurves
    1601                 :            :     
    1602                 :            :     
    1603                 :            :     CompositeEngine::instance()->
    1604                 :            :       remove_curve( dynamic_cast<Curve*>(passed_curve->partitioned_entity()) );
    1605                 :            :   }
    1606                 :            : */  
    1607         [ #  # ]:          0 :   DLIList<TopologyBridge*> tb_list;
    1608                 :            :   
    1609                 :            :     // get two coedges to remove
    1610         [ #  # ]:          0 :   curve->get_parents_virt( tb_list );
    1611 [ #  # ][ #  # ]:          0 :   if( tb_list.size() != 2 )
    1612                 :          0 :     return 0;
    1613 [ #  # ][ #  # ]:          0 :   PartitionCoEdge* coedge1 = dynamic_cast<PartitionCoEdge*>(tb_list.get_and_step());
    1614 [ #  # ][ #  # ]:          0 :   PartitionCoEdge* coedge2 = dynamic_cast<PartitionCoEdge*>(tb_list.get_and_step());
    1615 [ #  # ][ #  # ]:          0 :   assert( coedge1 && coedge2 );
    1616                 :            :   
    1617                 :            :     // get two loops and surfaces
    1618         [ #  # ]:          0 :   PartitionLoop* loop1 = coedge1->get_loop();
    1619         [ #  # ]:          0 :   PartitionLoop* loop2 = coedge2->get_loop();
    1620         [ #  # ]:          0 :   PartitionSurface* surf1 = loop1->get_surface();
    1621         [ #  # ]:          0 :   PartitionSurface* surf2 = loop2->get_surface();
    1622 [ #  # ][ #  # ]:          0 :   assert( surf1 && surf2 );
    1623                 :            :   
    1624                 :            :     // surfaces must be partitions of the same real surface
    1625 [ #  # ][ #  # ]:          0 :   if( surf1->partitioned_entity() != surf2->partitioned_entity() )
                 [ #  # ]
    1626                 :          0 :     return 0;
    1627                 :            :   
    1628                 :            :     // surfaces must have same parent shells
    1629                 :          0 :   PartitionCoSurf* cos = 0;
    1630 [ #  # ][ #  # ]:          0 :   while( (cos = surf1->next_co_surface( cos )) )
    1631 [ #  # ][ #  # ]:          0 :     if( ! surf2->find_first( cos->get_shell(), cos->sense() ) )
         [ #  # ][ #  # ]
    1632                 :          0 :       return 0;
    1633                 :            :     
    1634                 :            :     // same loop : remove a sipe or split a loop
    1635         [ #  # ]:          0 :   if( loop1 == loop2 )
    1636                 :            :   {
    1637 [ #  # ][ #  # ]:          0 :     if( loop1->next_coedge( coedge1 ) != coedge2 &&
         [ #  # ][ #  # ]
    1638         [ #  # ]:          0 :         loop1->prev_coedge( coedge1 ) != coedge2 )
    1639                 :            :     {
    1640 [ #  # ][ #  # ]:          0 :       loop2 = new PartitionLoop();
    1641         [ #  # ]:          0 :       PartitionCoEdge* coedge = loop1->next_coedge( coedge1 );
    1642                 :          0 :       PartitionCoEdge* prev = 0;
    1643         [ #  # ]:          0 :       while( coedge != coedge2 )
    1644                 :            :       {
    1645         [ #  # ]:          0 :         loop1->remove( coedge );
    1646         [ #  # ]:          0 :         loop2->insert_after( coedge, prev );
    1647                 :          0 :         prev = coedge;
    1648         [ #  # ]:          0 :         coedge = loop1->next_coedge( coedge1 );
    1649                 :            :       }
    1650                 :            :       
    1651         [ #  # ]:          0 :       surf1->add( loop2 );
    1652                 :            :     }
    1653                 :            :     
    1654         [ #  # ]:          0 :     loop1->remove( coedge1 );
    1655         [ #  # ]:          0 :     loop1->remove( coedge2 );
    1656 [ #  # ][ #  # ]:          0 :     if( loop1->first_coedge() == 0 )
    1657                 :            :     {
    1658         [ #  # ]:          0 :       surf1->remove( loop1 );
    1659 [ #  # ][ #  # ]:          0 :       delete loop1;
    1660                 :            :     }
    1661                 :            :   }
    1662                 :            :     // stitch loops
    1663                 :            :   else
    1664                 :            :   {
    1665                 :            :       // insert coedges
    1666 [ #  # ][ #  # ]:          0 :     while( loop2->next_coedge(coedge2) != coedge2 ) // all but the dead one
    1667                 :            :     {
    1668         [ #  # ]:          0 :       PartitionCoEdge* coedge = loop2->next_coedge( coedge2 );
    1669         [ #  # ]:          0 :       loop2->remove( coedge );
    1670         [ #  # ]:          0 :       loop1->insert_before( coedge, coedge1 );
    1671                 :            :     }
    1672         [ #  # ]:          0 :     loop1->remove( coedge1 );
    1673         [ #  # ]:          0 :     loop2->remove( coedge2 );
    1674 [ #  # ][ #  # ]:          0 :     assert( loop2->first_coedge() == 0 );
    1675         [ #  # ]:          0 :     surf2->remove( loop2 );
    1676 [ #  # ][ #  # ]:          0 :     if( loop1->num_coedges() == 0 )
    1677                 :            :     {
    1678         [ #  # ]:          0 :       surf1->remove( loop1 );
    1679 [ #  # ][ #  # ]:          0 :       delete loop1;
    1680                 :            :     }
    1681                 :            : 
    1682 [ #  # ][ #  # ]:          0 :     delete loop2;
    1683                 :            :   }
    1684                 :            :   
    1685         [ #  # ]:          0 :   curve->remove( coedge1 );
    1686         [ #  # ]:          0 :   curve->remove( coedge2 );
    1687 [ #  # ][ #  # ]:          0 :   delete coedge1;
    1688 [ #  # ][ #  # ]:          0 :   delete coedge2;
    1689         [ #  # ]:          0 :   PartitionPoint* start_pt = curve->start_point();
    1690         [ #  # ]:          0 :   PartitionPoint* end_pt = curve->end_point();
    1691         [ #  # ]:          0 :   curve->start_point(0);
    1692         [ #  # ]:          0 :   curve->end_point(0);
    1693 [ #  # ][ #  # ]:          0 :   delete curve;
    1694 [ #  # ][ #  # ]:          0 :   if ( !start_pt->next_curve() )
    1695                 :            :   {
    1696 [ #  # ][ #  # ]:          0 :     if ( start_pt->real_point() )
    1697         [ #  # ]:          0 :       restore_point(start_pt);
    1698                 :            :     else
    1699 [ #  # ][ #  # ]:          0 :       delete start_pt;
    1700                 :            :   }
    1701 [ #  # ][ #  # ]:          0 :   if ( end_pt != start_pt && !end_pt->next_curve() )
         [ #  # ][ #  # ]
    1702                 :            :   {
    1703 [ #  # ][ #  # ]:          0 :     if ( end_pt->real_point() )
    1704         [ #  # ]:          0 :       restore_point(end_pt);
    1705                 :            :     else
    1706 [ #  # ][ #  # ]:          0 :       delete end_pt;
    1707                 :            :   }
    1708                 :            :   
    1709                 :            :     // need to combine surfaces?
    1710         [ #  # ]:          0 :   if( surf1 != surf2 )
    1711                 :            :   {
    1712         [ #  # ]:          0 :     surf1->combine( surf2 );
    1713 [ #  # ][ #  # ]:          0 :     while( PartitionLoop* loop = surf2->next_loop() )
    1714                 :            :     { 
    1715         [ #  # ]:          0 :       surf2->remove( loop );
    1716         [ #  # ]:          0 :       surf1->add( loop );
    1717                 :            :     }
    1718                 :            :   
    1719 [ #  # ][ #  # ]:          0 :     while( PartitionCoSurf* cos = surf2->next_co_surface() )
    1720                 :            :     {
    1721 [ #  # ][ #  # ]:          0 :       if( cos->get_shell() )
    1722 [ #  # ][ #  # ]:          0 :         cos->get_shell()->remove( cos );
    1723         [ #  # ]:          0 :       surf2->remove( cos );
    1724 [ #  # ][ #  # ]:          0 :       delete cos;
    1725                 :            :     }
    1726                 :            :     
    1727         [ #  # ]:          0 :     if( dead_surfs )
    1728                 :          0 :       dead_surfs[0] = surf2;
    1729 [ #  # ][ #  # ]:          0 :     delete surf2;
    1730                 :            :   }
    1731                 :            :   
    1732                 :            :     // can remove partition surface?
    1733         [ #  # ]:          0 :   SubSurface* subsurf = dynamic_cast<SubSurface*>(surf1);
    1734 [ #  # ][ #  # ]:          0 :   if( subsurf && !subsurf->next_co_surface() && 
         [ #  # ][ #  # ]
                 [ #  # ]
    1735 [ #  # ][ #  # ]:          0 :       !subsurf->sub_entity_set().has_lower_order() )
    1736                 :            :   {
    1737         [ #  # ]:          0 :     if( dead_surfs )
    1738                 :            :     {
    1739         [ #  # ]:          0 :       if( dead_surfs[0] )
    1740                 :          0 :         dead_surfs[1] = surf1;
    1741                 :            :       else
    1742                 :          0 :         dead_surfs[0] = surf1;
    1743                 :            :     }
    1744         [ #  # ]:          0 :     return restore_surface( subsurf );
    1745                 :            :   }
    1746                 :            :   else
    1747         [ #  # ]:          0 :     return surf1;
    1748                 :            : }
    1749                 :            : 
    1750                 :            : //-------------------------------------------------------------------------
    1751                 :            : // Purpose       : Find the facet that:
    1752                 :            : //                   - contains the passed edge 
    1753                 :            : //                   - uses the passed edge in the specified orientation
    1754                 :            : //                   - is owned by the passed entity 
    1755                 :            : //
    1756                 :            : // Special Notes : 
    1757                 :            : //
    1758                 :            : // Creator       : Jason Kraftcheck
    1759                 :            : //
    1760                 :            : // Creation Date : 02/23/03
    1761                 :            : //-------------------------------------------------------------------------
    1762                 :          0 : static CubitFacetData* find_facet( CubitFacetEdge* edge, 
    1763                 :            :                                    bool sense,
    1764                 :            :                                    PartitionEntity* owner )
    1765                 :            : {
    1766         [ #  # ]:          0 :   DLIList<CubitFacet*> facets(2);
    1767         [ #  # ]:          0 :   edge->facets(facets);
    1768         [ #  # ]:          0 :   facets.reset();
    1769 [ #  # ][ #  # ]:          0 :   for ( int i = facets.size(); i--; ) {
    1770         [ #  # ]:          0 :     CubitFacet* facet = facets.get();
    1771         [ #  # ]:          0 :     int edge_index = facet->edge_index(edge);
    1772         [ #  # ]:          0 :     assert(edge_index >= 0);
    1773 [ #  # ][ #  # ]:          0 :     bool forward = edge->point(0) == facet->point((edge_index+1)%3);
    1774 [ #  # ][ #  # ]:          0 :     if ( forward != sense || TDVGFacetOwner::get(facet) != owner )
         [ #  # ][ #  # ]
    1775         [ #  # ]:          0 :       facets.extract();
    1776                 :            :     else
    1777         [ #  # ]:          0 :       facets.step();
    1778                 :            :   }
    1779                 :            :   
    1780 [ #  # ][ #  # ]:          0 :   return facets.size() == 1 ? dynamic_cast<CubitFacetData*>(facets.get()) : 0;
         [ #  # ][ #  # ]
                 [ #  # ]
    1781                 :            : }
    1782                 :            : 
    1783                 :            : //-------------------------------------------------------------------------
    1784                 :            : // Purpose       : Find a facet adjacent to the passed point and owned by
    1785                 :            : //                 the passed PartitionEntity
    1786                 :            : //
    1787                 :            : // Special Notes : 
    1788                 :            : //
    1789                 :            : // Creator       : Jason Kraftcheck
    1790                 :            : //
    1791                 :            : // Creation Date : 02/23/03
    1792                 :            : //-------------------------------------------------------------------------
    1793                 :          0 : static CubitFacetData* find_facet( CubitPoint* pt, PartitionEntity* owner )
    1794                 :            : {
    1795         [ #  # ]:          0 :   DLIList<CubitFacet*> facets;
    1796         [ #  # ]:          0 :   pt->facets(facets);
    1797         [ #  # ]:          0 :   facets.reset();
    1798 [ #  # ][ #  # ]:          0 :   for ( int i = facets.size(); i--; )
    1799                 :            :   {
    1800 [ #  # ][ #  # ]:          0 :     if ( TDVGFacetOwner::get(facets.get()) == owner )
                 [ #  # ]
    1801         [ #  # ]:          0 :       facets.step();
    1802                 :            :     else
    1803         [ #  # ]:          0 :       facets.extract();
    1804                 :            :   }
    1805                 :            :   
    1806 [ #  # ][ #  # ]:          0 :   return facets.size() == 1 ? dynamic_cast<CubitFacetData*>(facets.get()) : 0;
         [ #  # ][ #  # ]
                 [ #  # ]
    1807                 :            : }
    1808                 :            : 
    1809                 :            : //-------------------------------------------------------------------------
    1810                 :            : // Purpose       : Find the facet adjacent to the passed facet on the
    1811                 :            : //                 specified edge, and owned by the passed PartitionEntity
    1812                 :            : //
    1813                 :            : // Special Notes : 
    1814                 :            : //
    1815                 :            : // Creator       : Jason Kraftcheck
    1816                 :            : //
    1817                 :            : // Creation Date : 02/23/03
    1818                 :            : //-------------------------------------------------------------------------
    1819                 :          0 : static CubitFacetData* other_facet( CubitFacetData* facet,
    1820                 :            :                                     int edge,
    1821                 :            :                                     PartitionEntity* owner )
    1822                 :            : {
    1823         [ #  # ]:          0 :   DLIList<CubitFacet*> facets;
    1824                 :          0 :   facet->shared_facets( facet->point((edge+1)%3), 
    1825                 :          0 :                         facet->point((edge+2)%3),
    1826 [ #  # ][ #  # ]:          0 :                         facets );
                 [ #  # ]
    1827 [ #  # ][ #  # ]:          0 :   for ( int i = facets.size(); i--; )
    1828                 :            :   {
    1829         [ #  # ]:          0 :     CubitFacet* facet = facets.get();
    1830 [ #  # ][ #  # ]:          0 :     if( TDVGFacetOwner::get(facet) != owner )
    1831         [ #  # ]:          0 :       facets.extract();
    1832                 :            :     else
    1833         [ #  # ]:          0 :       facets.step();
    1834                 :            :   }
    1835                 :            :   
    1836 [ #  # ][ #  # ]:          0 :   return facets.size() == 1 ? dynamic_cast<CubitFacetData*>(facets.get()) : 0;
         [ #  # ][ #  # ]
                 [ #  # ]
    1837                 :            : }
    1838                 :            : /*
    1839                 :            : static void draw_facet_edges( CubitFacet* facet, int color )
    1840                 :            : {
    1841                 :            :   float x1, y1, z1, x2, y2, z2;
    1842                 :            :   for ( int i = 0; i < 3; i++ )
    1843                 :            :   {
    1844                 :            :     x1 = (float)facet->point(i)->coordinates().x();
    1845                 :            :     y1 = (float)facet->point(i)->coordinates().y();
    1846                 :            :     z1 = (float)facet->point(i)->coordinates().z();
    1847                 :            :     x2 = (float)facet->point((i+1)%3)->coordinates().x();
    1848                 :            :     y2 = (float)facet->point((i+1)%3)->coordinates().y();
    1849                 :            :     z2 = (float)facet->point((i+1)%3)->coordinates().z();
    1850                 :            :     GfxDebug::draw_line(x1,y1,z1,x2,y2,z2,color);
    1851                 :            :   }
    1852                 :            :   GfxDebug::flush();
    1853                 :            : }
    1854                 :            : 
    1855                 :            : static void draw_facet_point( CubitPoint* pt, int color )
    1856                 :            : {
    1857                 :            :   float x = (float)pt->coordinates().x();
    1858                 :            :   float y = (float)pt->coordinates().y();
    1859                 :            :   float z = (float)pt->coordinates().z();
    1860                 :            :   GfxDebug::draw_point( x, y, z, color );
    1861                 :            :   GfxDebug::flush();
    1862                 :            : }
    1863                 :            : 
    1864                 :            : static void draw_facet_points( CubitFacet* facet, int color )
    1865                 :            : {
    1866                 :            :   draw_facet_point(facet->point(0), color);
    1867                 :            :   draw_facet_point(facet->point(1), color);
    1868                 :            :   draw_facet_point(facet->point(2), color);
    1869                 :            : }
    1870                 :            : */
    1871                 :            : 
    1872                 :            : 
    1873                 :            : //-------------------------------------------------------------------------
    1874                 :            : // Purpose       : Split surface using facet data, given a coedge along
    1875                 :            : //                 the split chain.
    1876                 :            : //
    1877                 :            : // Special Notes : 
    1878                 :            : //
    1879                 :            : // Creator       : Jason Kraftcheck
    1880                 :            : //
    1881                 :            : // Creation Date : 02/23/03
    1882                 :            : //-------------------------------------------------------------------------
    1883                 :          0 : PartitionSurface* PartitionEngine::split_surface( PartitionSurface* surface,
    1884                 :            :                                                   PartitionCoEdge* new_coedge )
    1885                 :            : {
    1886                 :            :   int i;
    1887                 :            : 
    1888                 :            :     // get surface facets and make sure marks are cleared
    1889         [ #  # ]:          0 :   DLIList<CubitFacetData*> faces;
    1890         [ #  # ]:          0 :   surface->get_facet_data(faces);
    1891 [ #  # ][ #  # ]:          0 :   for( i = faces.size(); i--; )
    1892 [ #  # ][ #  # ]:          0 :     faces.get_and_step()->marked(0);
    1893                 :            : 
    1894                 :            : 
    1895                 :            :     // get curve and curve's facet edges
    1896         [ #  # ]:          0 :   PartitionCurve* new_curve = dynamic_cast<PartitionCurve*>(new_coedge->get_curve());
    1897 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdgeData*> edges;
    1898         [ #  # ]:          0 :   new_curve->get_facet_data( edges );
    1899 [ #  # ][ #  # ]:          0 :   assert(edges.size());
    1900                 :            :   
    1901                 :            :     // get the first point in the curve's facet edges
    1902         [ #  # ]:          0 :   edges.reset();
    1903         [ #  # ]:          0 :   CubitFacetEdgeData* edge = edges.get();
    1904         [ #  # ]:          0 :   CubitPoint* pt = edge->point(0);
    1905 [ #  # ][ #  # ]:          0 :   if ( TDVGFacetOwner::get(pt) != new_curve->start_point() )
         [ #  # ][ #  # ]
    1906                 :            :   {
    1907         [ #  # ]:          0 :     pt = edge->point(1);
    1908 [ #  # ][ #  # ]:          0 :     assert(TDVGFacetOwner::get(pt) == new_curve->start_point());
         [ #  # ][ #  # ]
    1909                 :            :   }
    1910                 :            :   
    1911                 :            :     // get the facets on the surface on the inside size of
    1912                 :            :     // the coedge
    1913         [ #  # ]:          0 :   bool coedge_forward = new_coedge->sense() == CUBIT_FORWARD;
    1914 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetData*> front( faces.size() );
                 [ #  # ]
    1915 [ #  # ][ #  # ]:          0 :   for ( i = edges.size(); i--; )
    1916                 :            :   {
    1917         [ #  # ]:          0 :     edge = edges.get_and_step();
    1918         [ #  # ]:          0 :     bool edge_forward = edge->point(0) == pt;
    1919                 :          0 :     bool sense = edge_forward == coedge_forward;
    1920 [ #  # ][ #  # ]:          0 :     CubitFacetData* face = find_facet( edge, sense, surface );
    1921 [ #  # ][ #  # ]:          0 :     if( face->marked() == 0 )
    1922                 :            :     {
    1923                 :            : //draw_facet_edges(face,CUBIT_RED_INDEX);
    1924         [ #  # ]:          0 :       face->marked(1);
    1925         [ #  # ]:          0 :       front.append( face );
    1926                 :            :     }
    1927         [ #  # ]:          0 :     pt = edge->other_point(pt);
    1928                 :            :   }    
    1929                 :            : 
    1930                 :            :     // mark all adjacent facets traversing only over
    1931                 :            :     // edges that are in the interior of the surface
    1932 [ #  # ][ #  # ]:          0 :   while( front.size() )
    1933                 :            :   {
    1934         [ #  # ]:          0 :     CubitFacetData* face = front.pop();
    1935         [ #  # ]:          0 :     for( i = 0; i < 3; i++ )
    1936                 :            :     {
    1937 [ #  # ][ #  # ]:          0 :       if( face->edge(i) && TDVGFacetOwner::get(face->edge(i)) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1938                 :          0 :         continue;
    1939                 :            :         
    1940 [ #  # ][ #  # ]:          0 :       CubitFacetData* other = other_facet( face, i, surface );
    1941 [ #  # ][ #  # ]:          0 :       if ( other->marked() == 0 )
    1942                 :            :       {
    1943                 :            : //draw_facet_edges(face,CUBIT_BLUE_INDEX);
    1944         [ #  # ]:          0 :         other->marked(1);
    1945         [ #  # ]:          0 :         front.append(other);
    1946                 :            :       }
    1947                 :            :     }
    1948                 :            :   }
    1949                 :            :   
    1950                 :            :     // reuse front to hold all the facets we marked
    1951 [ #  # ][ #  # ]:          0 :   for( i = faces.size(); i--; )
    1952                 :            :   {
    1953         [ #  # ]:          0 :     CubitFacetData* face = faces.get_and_step();
    1954 [ #  # ][ #  # ]:          0 :     if( face->marked() )
    1955         [ #  # ]:          0 :       front.append( face );
    1956                 :            :   }
    1957                 :            :   
    1958                 :            :     // if we got back all the facets, then the surface
    1959                 :            :     // was not split!
    1960 [ #  # ][ #  # ]:          0 :   if( front.size() == faces.size() )
                 [ #  # ]
    1961                 :            :   {
    1962 [ #  # ][ #  # ]:          0 :     for( i = faces.size(); i--; )
    1963 [ #  # ][ #  # ]:          0 :       faces.get_and_step()->marked(0);
    1964                 :            :       
    1965                 :          0 :     return surface;
    1966                 :            :   }
    1967                 :            :     // split off a new PartitionSurface
    1968         [ #  # ]:          0 :   PartitionSurface* new_surf = surface->split( front );
    1969                 :            :   
    1970                 :            :     // get list of all loops in surface
    1971 [ #  # ][ #  # ]:          0 :   DLIList<PartitionLoop*> loops( surface->num_loops() );
                 [ #  # ]
    1972                 :          0 :   PartitionLoop* loop = 0;
    1973 [ #  # ][ #  # ]:          0 :   while( (loop = surface->next_loop( loop )) )
    1974         [ #  # ]:          0 :     loops.append( loop );
    1975                 :            :   
    1976                 :            :     // check which loops we need to move to the new surface
    1977 [ #  # ][ #  # ]:          0 :   while( loops.size() )
    1978                 :            :   {
    1979         [ #  # ]:          0 :     loop = loops.pop();
    1980         [ #  # ]:          0 :     PartitionCoEdge* coe = loop->first_coedge();
    1981                 :            : 
    1982         [ #  # ]:          0 :     if( !coe )
    1983                 :          0 :       continue;
    1984                 :            : 
    1985         [ #  # ]:          0 :     PartitionCurve* curve = coe->get_curve();
    1986                 :            :     
    1987                 :          0 :     CubitFacetData* face =0;
    1988 [ #  # ][ #  # ]:          0 :     if( PartPTCurve* ptc = dynamic_cast<PartPTCurve*>(curve) )
    1989                 :            :     {
    1990 [ #  # ][ #  # ]:          0 :       face = find_facet( ptc->start_point()->facet_point(), new_surf );
         [ #  # ][ #  # ]
    1991                 :            :     }
    1992                 :            :     else
    1993                 :            :     {
    1994         [ #  # ]:          0 :       edges.clean_out();
    1995         [ #  # ]:          0 :       curve->get_facet_data( edges );
    1996 [ #  # ][ #  # ]:          0 :       if (edges.size() > 0) // normal facet
    1997                 :            :       {
    1998         [ #  # ]:          0 :         edges.reset();
    1999         [ #  # ]:          0 :         edge = edges.get();
    2000 [ #  # ][ #  # ]:          0 :         CubitPoint* start_pt = curve->start_point()->facet_point();
    2001         [ #  # ]:          0 :         bool forward = edge->point(0) == start_pt;
    2002 [ #  # ][ #  # ]:          0 :         assert( forward || edge->point(1) == start_pt );
                 [ #  # ]
    2003 [ #  # ][ #  # ]:          0 :         if ( coe->sense() == CUBIT_REVERSED )
    2004                 :          0 :           forward = !forward;
    2005 [ #  # ][ #  # ]:          0 :         face = find_facet( edge, forward, new_surf );
    2006                 :            :       }
    2007                 :            :       else // this is a hardpoint there is a curve with no facets (length)
    2008                 :            :            // and the start and end points are the same
    2009                 :            :       {
    2010 [ #  # ][ #  # ]:          0 :         TBPoint* hardpoint = curve->start_point()->real_point();
    2011 [ #  # ][ #  # ]:          0 :         if (hardpoint && curve->start_point() == curve->end_point() )
         [ #  # ][ #  # ]
                 [ #  # ]
    2012                 :            :         {
    2013         [ #  # ]:          0 :           CubitVector hardpoint_coord = hardpoint->coordinates(); 
    2014 [ #  # ][ #  # ]:          0 :           CubitVector new_closest, old_closest;
    2015 [ #  # ][ #  # ]:          0 :           new_surf->closest_point_trimmed( hardpoint_coord, new_closest );
    2016 [ #  # ][ #  # ]:          0 :           surface->closest_point_trimmed( hardpoint_coord,  old_closest );
    2017                 :            :           // It appears that the new_surf is really the original surface
    2018 [ #  # ][ #  # ]:          0 :           if ( new_closest.length_squared() > old_closest.length_squared() )
                 [ #  # ]
    2019                 :          0 :             face = reinterpret_cast<CubitFacetData*>(1); // just set the point to non-zero (true)
    2020                 :            :         }
    2021                 :            :       }
    2022                 :            :     }
    2023                 :            :     
    2024         [ #  # ]:          0 :     if( face )
    2025                 :            :     {
    2026         [ #  # ]:          0 :       surface->remove( loop );
    2027         [ #  # ]:          0 :       new_surf->add( loop );
    2028                 :            :     }
    2029                 :            :   }
    2030                 :            : /*  
    2031                 :            :   PartitionCoSurf* cos = 0;
    2032                 :            :   while( (cos = surface->next_co_surface( cos )) )
    2033                 :            :     cos->get_shell()->add( new_surf, cos->sense() );
    2034                 :            : */  
    2035 [ #  # ][ #  # ]:          0 :   for( i = faces.size(); i--; )
    2036 [ #  # ][ #  # ]:          0 :     faces.get_and_step()->marked(0);
    2037                 :            :   
    2038         [ #  # ]:          0 :   return new_surf;
    2039                 :            : }
    2040                 :            : 
    2041                 :            :     
    2042                 :            : //-------------------------------------------------------------------------
    2043                 :            : // Purpose       : Public interface to surface partitioning.
    2044                 :            : //
    2045                 :            : // Special Notes : 
    2046                 :            : //
    2047                 :            : // Creator       : Jason Kraftcheck
    2048                 :            : //
    2049                 :            : // Creation Date : 02/23/03
    2050                 :            : //-------------------------------------------------------------------------
    2051                 :          0 : Surface* PartitionEngine::insert_curve( Surface* surface,
    2052                 :            :                          DLIList<CubitVector*>& segment_points,
    2053                 :            :                          DLIList<Curve*>& new_curves,
    2054                 :            :                          const double *tolerance_length)
    2055                 :            : {
    2056 [ #  # ][ #  # ]:          0 :   DLIList<Surface*> input_surfs(1), output_surfs(2);
                 [ #  # ]
    2057         [ #  # ]:          0 :   input_surfs.append(surface);
    2058         [ #  # ]:          0 :   if ( ! insert_curve(input_surfs, segment_points, output_surfs, new_curves,
    2059         [ #  # ]:          0 :                 tolerance_length) )
    2060                 :          0 :     return 0;
    2061                 :            : 
    2062 [ #  # ][ #  # ]:          0 :   return output_surfs.size() ? output_surfs.get() : surface;
         [ #  # ][ #  # ]
    2063                 :            : } 
    2064                 :            : 
    2065                 :            : //-------------------------------------------------------------------------
    2066                 :            : // Purpose       : Public interface to surface partitioning
    2067                 :            : //
    2068                 :            : // Special Notes : 
    2069                 :            : //
    2070                 :            : // Creator       : Jason Kraftcheck
    2071                 :            : //
    2072                 :            : // Creation Date : 02/23/03
    2073                 :            : //-------------------------------------------------------------------------
    2074                 :          0 : CubitStatus PartitionEngine::insert_curve( 
    2075                 :            :                                     DLIList<Surface*>& input_surfaces,
    2076                 :            :                                     DLIList<CubitVector*>& segment_points,
    2077                 :            :                                     DLIList<Surface*>& new_surfaces,
    2078                 :            :                                     DLIList<Curve*>& new_curves,
    2079                 :            :                                     const double *tolerance_length,
    2080                 :            :                                     DLIList<Surface*>* surfs_to_reverse)
    2081                 :            : {
    2082                 :            :   int i;
    2083                 :          0 :   CubitStatus result = CUBIT_SUCCESS;
    2084                 :            :   
    2085 [ #  # ][ #  # ]:          0 :   for ( i = input_surfaces.size(); i--; )
    2086 [ #  # ][ #  # ]:          0 :     if ( dynamic_cast<CompositeSurface*>(input_surfaces.get_and_step()) )
         [ #  # ][ #  # ]
    2087         [ #  # ]:          0 :       return CompositeEngine::instance().insert_curve(
    2088         [ #  # ]:          0 :         input_surfaces, segment_points, new_surfaces, new_curves );
    2089                 :            :   
    2090         [ #  # ]:          0 :   DLIList<SubSurface*> replaced_surfaces;
    2091 [ #  # ][ #  # ]:          0 :   DLIList<PartitionSurface*> surface_list, new_part_surfs;
         [ #  # ][ #  # ]
    2092 [ #  # ][ #  # ]:          0 :   DLIList<PartitionCurve*> curve_list;
    2093                 :            :   
    2094                 :            :     // get partition surfaces
    2095 [ #  # ][ #  # ]:          0 :   for ( i = input_surfaces.size(); i--; )
    2096                 :            :   {
    2097                 :          0 :     int reverse_surf = 0;
    2098         [ #  # ]:          0 :     Surface* surf = input_surfaces.get_and_step();
    2099                 :            : 
    2100                 :            :     // We will need to reverse the surface and its facets if it
    2101                 :            :     // is in the passed-in list of surfaces to reverse.
    2102 [ #  # ][ #  # ]:          0 :     if(surfs_to_reverse && surfs_to_reverse->is_in_list(surf))
         [ #  # ][ #  # ]
    2103                 :          0 :       reverse_surf = 1;
    2104         [ #  # ]:          0 :     PartitionSurface* partsurf = dynamic_cast<PartitionSurface*>(surf);
    2105         [ #  # ]:          0 :     if( partsurf )
    2106                 :            :     {
    2107         [ #  # ]:          0 :       surface_list.append(partsurf);
    2108         [ #  # ]:          0 :       if(reverse_surf)
    2109         [ #  # ]:          0 :         partsurf->reverse_sense();
    2110                 :            :     }
    2111                 :            :     else
    2112                 :            :     {
    2113         [ #  # ]:          0 :       SubSurface* subsurf = replace_surface(surf);
    2114         [ #  # ]:          0 :       if (!subsurf)
    2115                 :            :       {
    2116                 :          0 :         result = CUBIT_FAILURE;
    2117                 :          0 :         break;
    2118                 :            :       }
    2119                 :            :       
    2120         [ #  # ]:          0 :       replaced_surfaces.append( subsurf );
    2121         [ #  # ]:          0 :       surface_list.append(subsurf);
    2122         [ #  # ]:          0 :       if(reverse_surf)
    2123         [ #  # ]:          0 :         subsurf->reverse_sense();
    2124                 :            :     }
    2125                 :            :   }
    2126                 :            :   
    2127         [ #  # ]:          0 :   if (result)
    2128                 :            :   {
    2129                 :            :     result = insert_curve( surface_list, segment_points, new_part_surfs, curve_list,
    2130         [ #  # ]:          0 :       tolerance_length);
    2131                 :            :   }
    2132         [ #  # ]:          0 :   if (!result)
    2133                 :            :   {
    2134                 :            :     // we replaced the original surface we need to clean up also
    2135 [ #  # ][ #  # ]:          0 :     for ( i = replaced_surfaces.size(); i--;  )
    2136                 :            :     {
    2137         [ #  # ]:          0 :       SubSurface* surf = replaced_surfaces.step_and_get();
    2138         [ #  # ]:          0 :       restore_surface( surf ); // this also deletes the virtual surface
    2139                 :            :     }
    2140                 :            : 
    2141                 :          0 :     return result;
    2142                 :            :   }
    2143                 :            : 
    2144 [ #  # ][ #  # ]:          0 :   CAST_LIST_TO_PARENT(curve_list,new_curves);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2145 [ #  # ][ #  # ]:          0 :   CAST_LIST_TO_PARENT(new_part_surfs,new_surfaces);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2146                 :            :   
    2147                 :            :     // clean up any partition surfaces we created but didn't modify
    2148 [ #  # ][ #  # ]:          0 :   for ( i = replaced_surfaces.size(); i--;  )
    2149                 :            :   {
    2150         [ #  # ]:          0 :     SubSurface* surf = replaced_surfaces.step_and_get();
    2151 [ #  # ][ #  # ]:          0 :     if ( !surf->sub_entity_set().has_lower_order() &&
         [ #  # ][ #  # ]
                 [ #  # ]
    2152         [ #  # ]:          0 :          !surf->next_co_surface(0) )
    2153                 :            :     {
    2154         [ #  # ]:          0 :       restore_surface( surf );
    2155                 :            :     }
    2156                 :            :     else
    2157                 :            :     {
    2158         [ #  # ]:          0 :       new_surfaces.append( surf );
    2159                 :            :     }
    2160                 :            :   }
    2161                 :            :   
    2162         [ #  # ]:          0 :   return result;
    2163                 :            : } 
    2164                 :            : 
    2165                 :          0 : void PartitionEngine::curves_from_surfaces( const DLIList<PartitionSurface*>& surfs,
    2166                 :            :                                             DLIList<PartitionCurve*>& curves )
    2167                 :            : {
    2168                 :            :   int i;
    2169                 :            :   
    2170         [ #  # ]:          0 :   for (i = curves.size(); i--; )
    2171                 :          0 :     curves.step_and_get()->mark = 1;
    2172                 :            :   
    2173         [ #  # ]:          0 :   for (i = surfs.size(); i--; )
    2174                 :            :   {
    2175                 :          0 :     PartitionSurface* surf = surfs.next(i);
    2176                 :          0 :     PartitionLoop* loop = 0;
    2177         [ #  # ]:          0 :     while ( (loop = surf->next_loop(loop)) )
    2178                 :            :     {
    2179                 :          0 :       PartitionCoEdge* coedge = loop->first_coedge();
    2180         [ #  # ]:          0 :       do {
    2181         [ #  # ]:          0 :         PartitionCurve* curve = coedge->get_curve();
    2182         [ #  # ]:          0 :         if (!curve->mark)
    2183                 :            :         {
    2184                 :          0 :           curve->mark = 1;
    2185         [ #  # ]:          0 :           curves.append(curve);
    2186                 :            :         }
    2187                 :            :       
    2188         [ #  # ]:          0 :         coedge = loop->next_coedge(coedge);
    2189                 :          0 :       } while (coedge != loop->first_coedge());
    2190                 :            :     }
    2191                 :            :   }
    2192                 :            :   
    2193         [ #  # ]:          0 :   for ( i = curves.size(); i--; )
    2194                 :          0 :     curves.step_and_get()->mark = 0;
    2195                 :          0 :   curves.reset();
    2196                 :          0 : }
    2197                 :            : 
    2198                 :            : 
    2199                 :          0 : CubitStatus PartitionEngine::insert_curve( DLIList<PartitionSurface*>& surface_list,
    2200                 :            :                                            DLIList<CubitVector*>& segment_points,
    2201                 :            :                                            DLIList<PartitionSurface*>& new_part_surfs,
    2202                 :            :                                            DLIList<PartitionCurve*>& curve_list,
    2203                 :            :                                            const double *tolerance_length)
    2204                 :            : {
    2205                 :            :   int i;
    2206                 :          0 :   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
    2207                 :            :   
    2208                 :            :     // Get curves
    2209         [ #  # ]:          0 :   DLIList<PartitionCurve*> curves;
    2210         [ #  # ]:          0 :   curves_from_surfaces( surface_list, curves );
    2211                 :            :   
    2212                 :            :     // Check for intersections with boundary curves
    2213         [ #  # ]:          0 :   segment_points.reset();
    2214         [ #  # ]:          0 :   curves.reset();
    2215 [ #  # ][ #  # ]:          0 :   for ( i = segment_points.size(); i--;  )
    2216                 :            :   {
    2217         [ #  # ]:          0 :     CubitVector& pos = *segment_points.get_and_step();
    2218                 :          0 :     bool debug = false;
    2219         [ #  # ]:          0 :     if (debug)
    2220                 :            :     {
    2221         [ #  # ]:          0 :       GfxDebug::draw_point(pos, CUBIT_BLUE_INDEX);
    2222         [ #  # ]:          0 :       GfxDebug::mouse_xforms();
    2223                 :            :     }
    2224 [ #  # ][ #  # ]:          0 :     for ( int j = curves.size(); j--; )
    2225                 :            :     {
    2226         [ #  # ]:          0 :       PartitionCurve* curve = curves.get_and_step();
    2227 [ #  # ][ #  # ]:          0 :       if ((curve->start_point()->coordinates() - pos).length_squared() < TOL_SQR)
         [ #  # ][ #  # ]
                 [ #  # ]
    2228                 :            :       {
    2229 [ #  # ][ #  # ]:          0 :         pos = curve->start_point()->coordinates();
                 [ #  # ]
    2230                 :          0 :         break;
    2231                 :            :       }
    2232                 :            :       
    2233 [ #  # ][ #  # ]:          0 :       if ((curve->end_point()->coordinates() - pos).length_squared() < TOL_SQR)
         [ #  # ][ #  # ]
                 [ #  # ]
    2234                 :            :       {
    2235 [ #  # ][ #  # ]:          0 :         pos = curve->end_point()->coordinates();
                 [ #  # ]
    2236                 :          0 :         break;
    2237                 :            :       }
    2238                 :            : 
    2239         [ #  # ]:          0 :       CubitVector closest;
    2240         [ #  # ]:          0 :       curve->closest_point_trimmed( pos, closest );
    2241                 :            :         
    2242 [ #  # ][ #  # ]:          0 :       if ( (pos - closest).length_squared() > TOL_SQR )
                 [ #  # ]
    2243                 :          0 :         continue;
    2244                 :            :       
    2245 [ #  # ][ #  # ]:          0 :       if ((curve->start_point()->coordinates() - closest).length_squared() < TOL_SQR)
         [ #  # ][ #  # ]
                 [ #  # ]
    2246                 :            :       {
    2247 [ #  # ][ #  # ]:          0 :         pos = curve->start_point()->coordinates();
                 [ #  # ]
    2248                 :          0 :         break;
    2249                 :            :       }
    2250                 :            :       
    2251 [ #  # ][ #  # ]:          0 :       if ((curve->end_point()->coordinates() - closest).length_squared() < TOL_SQR)
         [ #  # ][ #  # ]
                 [ #  # ]
    2252                 :            :       {
    2253 [ #  # ][ #  # ]:          0 :         pos = curve->end_point()->coordinates();
                 [ #  # ]
    2254                 :          0 :         break;
    2255                 :            :       }
    2256                 :            : /*      
    2257                 :            :       double u = curve->u_from_position(closest);
    2258                 :            :       TBPoint* point = insert_point( curve, u );
    2259                 :            :       if (!point)
    2260                 :            :       {
    2261                 :            :         PRINT_ERROR("Error splitting curve.  Aborting.\n");
    2262                 :            :         return CUBIT_FAILURE;
    2263                 :            :       }
    2264                 :            :       pos = point->coordinates();
    2265                 :            : */
    2266         [ #  # ]:          0 :       pos = closest;
    2267                 :          0 :       break;
    2268                 :            :     }
    2269                 :            :   }
    2270                 :            :       
    2271                 :            :   
    2272                 :            :     // get surface facets
    2273 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetData*> surf_facets, facet_list;
         [ #  # ][ #  # ]
    2274         [ #  # ]:          0 :   surface_list.reset();
    2275 [ #  # ][ #  # ]:          0 :   for ( i = surface_list.size(); i--; )
    2276                 :            :   {
    2277         [ #  # ]:          0 :     surf_facets.clean_out();
    2278 [ #  # ][ #  # ]:          0 :     surface_list.get_and_step()->get_facet_data( surf_facets );
    2279         [ #  # ]:          0 :     facet_list += surf_facets;
    2280                 :            :   }
    2281                 :            : 
    2282                 :            :     // Do facet projection
    2283 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdgeData*> polyline;
    2284 [ #  # ][ #  # ]:          0 :   DLIList<CubitPointData*> polyline_pts;
    2285         [ #  # ]:          0 :   project_to_surface( facet_list, segment_points, polyline, polyline_pts, tolerance_length);
    2286                 :            : 
    2287 [ #  # ][ #  # ]:          0 :   if(segment_points.size() == polyline_pts.size())
                 [ #  # ]
    2288                 :            :   { 
    2289                 :            :     // Move facet points to real geometry
    2290         [ #  # ]:          0 :     DLIList<CubitFacetEdge*> edge_list;
    2291 [ #  # ][ #  # ]:          0 :     DLIList<CubitFacet*> pt_facets;
    2292         [ #  # ]:          0 :     segment_points.reset();
    2293         [ #  # ]:          0 :     polyline_pts.reset();
    2294                 :          0 :     int count = 0;
    2295 [ #  # ][ #  # ]:          0 :     for ( i = segment_points.size(); i--; )
    2296                 :            :     {
    2297         [ #  # ]:          0 :       CubitPointData* facet_pt = polyline_pts.get_and_step();
    2298 [ #  # ][ #  # ]:          0 :       CubitVector position( *segment_points.get_and_step() );
    2299         [ #  # ]:          0 :       if ( !facet_pt )  
    2300                 :          0 :         continue;
    2301                 :            :     
    2302 [ #  # ][ #  # ]:          0 :       PartitionPoint* point = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(facet_pt));
    2303         [ #  # ]:          0 :       if ( point ) 
    2304                 :            :       {
    2305                 :          0 :         count++;
    2306                 :          0 :         continue;
    2307                 :            :       }
    2308                 :            : 
    2309                 :          0 :       PartitionCurve* curve = 0;
    2310         [ #  # ]:          0 :       edge_list.clean_out();
    2311         [ #  # ]:          0 :       facet_pt->edges( edge_list );      
    2312 [ #  # ][ #  # ]:          0 :       while ( edge_list.size() )
    2313                 :            :       {
    2314                 :            : 
    2315 [ #  # ][ #  # ]:          0 :         PartitionEntity* owner = TDVGFacetOwner::get(edge_list.pop());
    2316         [ #  # ]:          0 :         if ( owner )
    2317                 :            :         {
    2318 [ #  # ][ #  # ]:          0 :           assert(!curve || curve == owner);
                 [ #  # ]
    2319         [ #  # ]:          0 :           curve = dynamic_cast<PartitionCurve*>(owner);
    2320                 :            :         }
    2321                 :            :       }
    2322         [ #  # ]:          0 :       if ( curve )
    2323                 :            :       {
    2324 [ #  # ][ #  # ]:          0 :         Surface* surface = dynamic_cast<Surface*>(curve->partitioned_entity());
    2325         [ #  # ]:          0 :         if ( surface )
    2326                 :            :         {
    2327         [ #  # ]:          0 :           CubitVector surf_pos;
    2328         [ #  # ]:          0 :           surface->closest_point( position, &surf_pos );
    2329 [ #  # ][ #  # ]:          0 :           if (facet_pt->check_inverted_facets(surf_pos))
    2330         [ #  # ]:          0 :             facet_pt->set( surf_pos );
    2331                 :            :         }
    2332                 :            :         else
    2333         [ #  # ]:          0 :           curve->relax_to_geometry( facet_pt, &position );
    2334                 :            : 
    2335                 :          0 :         continue;
    2336                 :            :       }
    2337                 :            :     
    2338                 :          0 :       PartitionSurface* surf = 0;
    2339         [ #  # ]:          0 :       pt_facets.clean_out();
    2340         [ #  # ]:          0 :       facet_pt->facets( pt_facets );
    2341 [ #  # ][ #  # ]:          0 :       while ( pt_facets.size() )
    2342                 :            :       {
    2343 [ #  # ][ #  # ]:          0 :         PartitionEntity* owner = TDVGFacetOwner::get(pt_facets.pop());
    2344         [ #  # ]:          0 :         if ( owner )
    2345                 :            :         {
    2346 [ #  # ][ #  # ]:          0 :           assert(!surf || surf == owner);
                 [ #  # ]
    2347         [ #  # ]:          0 :           surf = dynamic_cast<PartitionSurface*>(owner);
    2348                 :            :         }
    2349                 :            :       }
    2350 [ #  # ][ #  # ]:          0 :       if ( surf && dynamic_cast<SubSurface*>(surf) )
         [ #  # ][ #  # ]
    2351                 :            :       {
    2352         [ #  # ]:          0 :         surf->relax_to_geometry( facet_pt, &position );
    2353                 :            :       }
    2354         [ #  # ]:          0 :     }        
    2355                 :            :   }  
    2356                 :            : 
    2357 [ #  # ][ #  # ]:          0 :   if ( !polyline.size() )
    2358                 :          0 :     return CUBIT_FAILURE;
    2359                 :            :   
    2360                 :            :   //In the following lines we see if we need to split curves on 
    2361                 :            :   //the boundary of the surface.  This is necessary when the endpoints of 
    2362                 :            :   //the polylines used for partitioning are not coincident with 
    2363                 :            :   //boundary curves.
    2364                 :            : 
    2365                 :            :   //get all the facet points of the polyline
    2366 [ #  # ][ #  # ]:          0 :   DLIList<CubitPoint*> points_on_polyline;  
    2367 [ #  # ][ #  # ]:          0 :   for( int k=polyline.size(); k--; )
    2368                 :            :   {
    2369         [ #  # ]:          0 :     CubitFacetEdgeData *tmp_edge = polyline.get_and_step();
    2370         [ #  # ]:          0 :     if( !tmp_edge )
    2371                 :          0 :       continue;
    2372 [ #  # ][ #  # ]:          0 :     points_on_polyline.append_unique( tmp_edge->start_node() );
    2373 [ #  # ][ #  # ]:          0 :     points_on_polyline.append_unique( tmp_edge->end_node() );
    2374                 :            :   }
    2375                 :            :   
    2376                 :            :   //get all the resulting facets
    2377 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacet*> facets_after;
    2378 [ #  # ][ #  # ]:          0 :   for ( i = surface_list.size(); i--; )
    2379                 :            :   {
    2380         [ #  # ]:          0 :     surf_facets.clean_out();
    2381 [ #  # ][ #  # ]:          0 :     surface_list.get_and_step()->get_facet_data( surf_facets );
    2382 [ #  # ][ #  # ]:          0 :     for( int s=surf_facets.size(); s--; )
    2383 [ #  # ][ #  # ]:          0 :       facets_after.append( surf_facets.get_and_step() );    
    2384                 :            :   }
    2385                 :            : 
    2386                 :            :   //from the facets, collect all the boundary points
    2387 [ #  # ][ #  # ]:          0 :   DLIList<CubitPoint*> boundary_pts;
    2388         [ #  # ]:          0 :   FacetDataUtil::get_boundary_points( facets_after, boundary_pts );
    2389                 :            : 
    2390                 :            :   //for each polyline points...
    2391 [ #  # ][ #  # ]:          0 :   for( int k=points_on_polyline.size(); k--; )
    2392                 :            :   {
    2393         [ #  # ]:          0 :     CubitPoint *tmp_pt = points_on_polyline.get_and_step();
    2394                 :            : 
    2395                 :            :     //if the point is on the boundary...
    2396 [ #  # ][ #  # ]:          0 :     if( boundary_pts.is_in_list( tmp_pt ) )
    2397                 :            :     {
    2398 [ #  # ][ #  # ]:          0 :       PartitionPoint* point = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(tmp_pt));
    2399         [ #  # ]:          0 :       if( !point ) //if the point is not already a vertex on the boundary...
    2400                 :            :       {
    2401                 :            :         //find the adjacent boundary curve that we'll insert these points into
    2402         [ #  # ]:          0 :         DLIList<CubitFacetEdge*> adj_edges;
    2403         [ #  # ]:          0 :         tmp_pt->edges( adj_edges );
    2404                 :            : 
    2405 [ #  # ][ #  # ]:          0 :         for( int s=adj_edges.size(); s--; )
    2406                 :            :         {
    2407         [ #  # ]:          0 :           CubitFacetEdge *tmp_edge = adj_edges.get_and_step();
    2408 [ #  # ][ #  # ]:          0 :           PartitionCurve* curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(tmp_edge));
    2409         [ #  # ]:          0 :           if( curve )
    2410                 :            :           {
    2411         [ #  # ]:          0 :             DLIList<TopologyBridge*> bridges;
    2412         [ #  # ]:          0 :             get_tbs_with_bridge_manager_as_owner(curve, bridges );
    2413                 :            : 
    2414 [ #  # ][ #  # ]:          0 :             if( bridges.size() == 0 )
    2415 [ #  # ][ #  # ]:          0 :               CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( curve, bridges );
    2416                 :            : 
    2417 [ #  # ][ #  # ]:          0 :             RefEdge *ref_edge = dynamic_cast<RefEdge*>(bridges.get()->topology_entity());         
                 [ #  # ]
    2418                 :            :             RefEdge *edge1, *edge2;
    2419                 :            : 
    2420                 :            :             //now do the split
    2421 [ #  # ][ #  # ]:          0 :             PartitionTool::instance()->partition( ref_edge, tmp_pt->coordinates(), edge1, edge2  );
                 [ #  # ]
    2422         [ #  # ]:          0 :             break;
    2423                 :            :           }
    2424         [ #  # ]:          0 :         }
    2425                 :            :       }
    2426                 :            :     }
    2427                 :            :   }    
    2428                 :            :   
    2429                 :            :     // construct the curves
    2430 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdgeData*> cubit_edges;
    2431 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdge*> pt_edges;
    2432         [ #  # ]:          0 :   polyline.reset();
    2433 [ #  # ][ #  # ]:          0 :   for ( i = polyline.size(); i > 0; )
    2434                 :            :   {
    2435                 :            :       // get list of FacetPoints for Curve
    2436         [ #  # ]:          0 :     cubit_edges.clean_out();
    2437         [ #  # ]:          0 :     CubitFacetEdgeData* edge = polyline.get_and_step();
    2438         [ #  # ]:          0 :     if (!edge) { i--; continue; } 
    2439                 :            :     
    2440 [ #  # ][ #  # ]:          0 :     assert(!TDVGFacetOwner::get(edge) && 
         [ #  # ][ #  # ]
                 [ #  # ]
    2441                 :            :            edge->num_adj_facets() < 3 &&
    2442         [ #  # ]:          0 :            edge->num_adj_facets() > 0);
    2443                 :            :            
    2444 [ #  # ][ #  # ]:          0 :     PartitionEntity* owner = TDVGFacetOwner::get(edge->adj_facet(0));
    2445 [ #  # ][ #  # ]:          0 :     assert( edge->num_adj_facets() == 1 ||
         [ #  # ][ #  # ]
    2446         [ #  # ]:          0 :             TDVGFacetOwner::get(edge->adj_facet(1)) == owner );
    2447                 :            :             
    2448         [ #  # ]:          0 :     cubit_edges.append( edge );
    2449                 :            :     
    2450 [ #  # ][ #  # ]:          0 :     while( polyline.get() )
    2451                 :            :     {
    2452 [ #  # ][ #  # ]:          0 :       CubitPoint* pt = edge->shared_point(polyline.get());
    2453         [ #  # ]:          0 :       edge = polyline.get();
    2454                 :            :       
    2455 [ #  # ][ #  # ]:          0 :       assert(!TDVGFacetOwner::get(edge) && 
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2456                 :            :              edge->num_adj_facets() < 3 &&
    2457         [ #  # ]:          0 :              edge->num_adj_facets() > 0 && pt);
    2458                 :            :            
    2459 [ #  # ][ #  # ]:          0 :       PartitionEntity* tmp = TDVGFacetOwner::get(edge->adj_facet(0));
    2460 [ #  # ][ #  # ]:          0 :       assert( edge->num_adj_facets() == 1 ||
         [ #  # ][ #  # ]
    2461         [ #  # ]:          0 :             TDVGFacetOwner::get(edge->adj_facet(1)) == tmp );
    2462                 :            :             
    2463                 :          0 :       bool edge_owner = false;
    2464         [ #  # ]:          0 :       pt->edges(pt_edges);
    2465 [ #  # ][ #  # ]:          0 :       while (pt_edges.size())
    2466 [ #  # ][ #  # ]:          0 :         if (TDVGFacetOwner::get(pt_edges.pop()))
                 [ #  # ]
    2467                 :          0 :           edge_owner = true;
    2468                 :            :             
    2469 [ #  # ][ #  # ]:          0 :       if ( tmp != owner || TDVGFacetOwner::get(pt) || edge_owner )
         [ #  # ][ #  # ]
                 [ #  # ]
    2470                 :          0 :         break;
    2471                 :            :         
    2472 [ #  # ][ #  # ]:          0 :       cubit_edges.append( polyline.get_and_step() );
    2473                 :            :     }
    2474 [ #  # ][ #  # ]:          0 :     if (NULL == polyline.get())
    2475                 :            :     {
    2476         [ #  # ]:          0 :       polyline.step();
    2477                 :          0 :       i -= 1;
    2478                 :            :     }
    2479         [ #  # ]:          0 :     i -= cubit_edges.size();
    2480                 :            : 
    2481                 :            :       // create curve and partition surface
    2482         [ #  # ]:          0 :     PartitionCurve* new_curve = insert_curve( cubit_edges, &segment_points );
    2483         [ #  # ]:          0 :     if ( new_curve )
    2484         [ #  # ]:          0 :       curve_list.append(new_curve);
    2485                 :            :   }  
    2486                 :            :   
    2487                 :            :     // find new surfaces to return
    2488 [ #  # ][ #  # ]:          0 :   for ( i = curve_list.size(); i--; )
    2489                 :            :   {
    2490         [ #  # ]:          0 :     PartitionCurve* curve = curve_list.step_and_get();
    2491                 :          0 :     PartitionCoEdge* coedge = 0;
    2492 [ #  # ][ #  # ]:          0 :     while( (coedge = curve->next_coedge(coedge)) )
    2493                 :            :     {
    2494 [ #  # ][ #  # ]:          0 :       new_part_surfs.append( coedge->get_loop()->get_surface() );
                 [ #  # ]
    2495                 :            :     }
    2496                 :            :   }
    2497                 :            :   
    2498 [ #  # ][ #  # ]:          0 :   if ( curve_list.size() )
    2499                 :            :   {
    2500                 :            :       // do facet cleanup
    2501 [ #  # ][ #  # ]:          0 :     for ( i = curve_list.size(); i--; )
    2502 [ #  # ][ #  # ]:          0 :       curve_list.get_and_step()->do_facet_cleanup();
    2503                 :            :     //for ( i = new_part_surfs.size(); i--; )
    2504                 :            :     //  new_part_surfs.get_and_step()->do_facet_cleanup();
    2505                 :            :   }
    2506                 :            :     
    2507                 :            :   
    2508 [ #  # ][ #  # ]:          0 :   for ( i = new_part_surfs.size(); i--; )
    2509         [ #  # ]:          0 :     new_part_surfs.step_and_get()->mark = 1;
    2510 [ #  # ][ #  # ]:          0 :   for ( i = surface_list.size(); i--; )
    2511         [ #  # ]:          0 :     surface_list.step_and_get()->mark = 0;
    2512 [ #  # ][ #  # ]:          0 :   for ( i = new_part_surfs.size(); i--; )
    2513 [ #  # ][ #  # ]:          0 :     if ( new_part_surfs.step_and_get()->mark )
    2514         [ #  # ]:          0 :       new_part_surfs.get()->mark = 0;
    2515                 :            :     else 
    2516         [ #  # ]:          0 :       new_part_surfs.change_to(0);
    2517         [ #  # ]:          0 :   new_part_surfs.remove_all_with_value(0);
    2518                 :            : 
    2519 [ #  # ][ #  # ]:          0 :   return curve_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
                 [ #  # ]
    2520                 :            : } 
    2521                 :            : 
    2522                 :            : //-------------------------------------------------------------------------
    2523                 :            : // Purpose       : Given a polyline-imprint on the surface facetting,
    2524                 :            : //                 construct a new and insert it in the surface topology.
    2525                 :            : //
    2526                 :            : // Special Notes : 
    2527                 :            : //
    2528                 :            : // Creator       : Jason Kraftcheck
    2529                 :            : //
    2530                 :            : // Creation Date : 02/23/03
    2531                 :            : //-------------------------------------------------------------------------
    2532                 :          0 : SegmentedCurve* PartitionEngine::insert_curve( 
    2533                 :            :                          DLIList<CubitFacetEdgeData*>& segments,
    2534                 :            :                          DLIList<CubitVector*>* /*curve_geom*/ )
    2535                 :            : {
    2536                 :            :   int i;
    2537                 :            :   
    2538                 :            :     // find surface
    2539                 :          0 :   PartitionSurface* surface = 0;
    2540         [ #  # ]:          0 :   DLIList<CubitFacet*> facets;
    2541 [ #  # ][ #  # ]:          0 :   for ( i = segments.size(); i--; )
    2542                 :            :   {
    2543         [ #  # ]:          0 :     CubitFacetEdgeData* edge = segments.get_and_step();
    2544         [ #  # ]:          0 :     facets.clean_out();
    2545         [ #  # ]:          0 :     edge->facets(facets);
    2546 [ #  # ][ #  # ]:          0 :     assert(facets.size() == 2);
    2547 [ #  # ][ #  # ]:          0 :     for (int j = 0; j < facets.size(); j++ )
    2548                 :            :     {
    2549         [ #  # ]:          0 :       CubitFacet* facet = facets.get_and_step();
    2550         [ #  # ]:          0 :       PartitionEntity* fowner = TDVGFacetOwner::get(facet);
    2551         [ #  # ]:          0 :       PartitionSurface* surf = dynamic_cast<PartitionSurface*>(fowner);
    2552 [ #  # ][ #  # ]:          0 :       if ( !surf || (surface && surf != surface) )
                 [ #  # ]
    2553                 :            :       {
    2554 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Internal Error in PartitionEngine.  Corrupt facet data.\n");
         [ #  # ][ #  # ]
    2555                 :          0 :         assert(0);
    2556                 :            :         return 0;
    2557                 :            :       }
    2558                 :          0 :       surface = surf;
    2559                 :            :     }
    2560                 :            :   }
    2561                 :            :   
    2562                 :            :     // if there is a real surface, relax facet points to surface
    2563 [ #  # ][ #  # ]:          0 :   Surface* real_surf = dynamic_cast<Surface*>(surface->partitioned_entity());
    2564                 :            :   
    2565                 :            :     // find start and end facet points
    2566                 :            :   CubitPointData* pts[2];
    2567                 :            :   CubitPoint* pt;
    2568                 :            :   
    2569 [ #  # ][ #  # ]:          0 :   if( segments.size() == 1 )
    2570                 :            :   {
    2571 [ #  # ][ #  # ]:          0 :     pts[0] = dynamic_cast<CubitPointData*>(segments.get()->point(0));
                 [ #  # ]
    2572 [ #  # ][ #  # ]:          0 :     pts[1] = dynamic_cast<CubitPointData*>(segments.get()->point(1));
                 [ #  # ]
    2573                 :            :   }
    2574                 :            :   else
    2575                 :            :   {
    2576         [ #  # ]:          0 :     segments.last();
    2577 [ #  # ][ #  # ]:          0 :     pt = segments.get()->shared_point( segments.prev() );
                 [ #  # ]
    2578 [ #  # ][ #  # ]:          0 :     pt = segments.get()->other_point( pt );
    2579         [ #  # ]:          0 :     pts[1] = dynamic_cast<CubitPointData*>(pt);
    2580         [ #  # ]:          0 :     segments.reset();
    2581 [ #  # ][ #  # ]:          0 :     pt = segments.get()->shared_point( segments.next() );
                 [ #  # ]
    2582 [ #  # ][ #  # ]:          0 :     pt = segments.get()->other_point( pt );
    2583         [ #  # ]:          0 :     pts[0] = dynamic_cast<CubitPointData*>(pt);
    2584                 :            :   }
    2585                 :            :   
    2586                 :            :     // create end points (partition curves if necessary)
    2587                 :          0 :   bool okay = true;
    2588 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdge*> edges;
    2589                 :          0 :   bool created_pts[2] = {false,false};
    2590                 :          0 :   PartitionPoint* end_pts[2] = {0,0};
    2591 [ #  # ][ #  # ]:          0 :   for ( i = 0; okay && i < 2; i++ )
    2592                 :            :   {
    2593 [ #  # ][ #  # ]:          0 :     end_pts[i] = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(pts[i]));
    2594         [ #  # ]:          0 :     if( end_pts[i] ) continue;
    2595                 :            :     
    2596         [ #  # ]:          0 :     edges.clean_out();
    2597         [ #  # ]:          0 :     pts[i]->edges(edges);
    2598                 :          0 :     PartitionCurve* curve = 0;
    2599 [ #  # ][ #  # ]:          0 :     for ( int j = edges.size(); !curve && j--; )
         [ #  # ][ #  # ]
    2600 [ #  # ][ #  # ]:          0 :       curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edges.get_and_step()));
                 [ #  # ]
    2601                 :            :     
    2602         [ #  # ]:          0 :     if( curve )
    2603                 :            :     {
    2604         [ #  # ]:          0 :       curve->relax_to_geometry( pts[i] );
    2605 [ #  # ][ #  # ]:          0 :       PartitionPoint* new_pt = new PartitionPoint( pts[i]->coordinates(), curve );
         [ #  # ][ #  # ]
    2606 [ #  # ][ #  # ]:          0 :       if ( insert_point( curve, new_pt ) )
    2607                 :            :       {
    2608                 :          0 :         end_pts[i] = new_pt;
    2609                 :          0 :         created_pts[i] = true;
    2610 [ #  # ][ #  # ]:          0 :         assert( TDVGFacetOwner::get(pts[i]) == new_pt );
                 [ #  # ]
    2611                 :            :       }
    2612                 :            :       else
    2613                 :            :       {
    2614 [ #  # ][ #  # ]:          0 :         delete new_pt;
    2615                 :          0 :         okay = false;
    2616                 :            :       }
    2617                 :          0 :       continue;
    2618                 :            :     }
    2619                 :            :     
    2620         [ #  # ]:          0 :     facets.clean_out();
    2621         [ #  # ]:          0 :     pts[i]->facets(facets);
    2622 [ #  # ][ #  # ]:          0 :     for ( int k = facets.size(); k--; )
    2623 [ #  # ][ #  # ]:          0 :       if( TDVGFacetOwner::get(facets.get_and_step()) != surface )
         [ #  # ][ #  # ]
    2624                 :            :       {
    2625 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Internal Error in PartitionEngine.  Corrupt facet data.\n");
         [ #  # ][ #  # ]
    2626                 :          0 :         okay = false;
    2627                 :          0 :         break;
    2628                 :            :       }
    2629                 :            :       
    2630         [ #  # ]:          0 :     if( okay )
    2631                 :            :     {
    2632         [ #  # ]:          0 :       if( real_surf )
    2633         [ #  # ]:          0 :         surface->relax_to_geometry( pts[i] );
    2634                 :            :       
    2635 [ #  # ][ #  # ]:          0 :       end_pts[i] = new PartitionPoint( pts[i]->coordinates(), surface );
         [ #  # ][ #  # ]
    2636         [ #  # ]:          0 :       end_pts[i]->facet_point( pts[i] );
    2637                 :            :     }
    2638                 :            :   }
    2639                 :            :   
    2640                 :            :     // create curve
    2641                 :          0 :   SegmentedCurve* curve = 0;
    2642         [ #  # ]:          0 :   if( okay )
    2643                 :            :   {
    2644 [ #  # ][ #  # ]:          0 :     DLIList<CubitVector*> vectors(segments.size()+1), *curve_geom_ptr;
    2645                 :            : //    if( curve_geom )
    2646                 :            : //    {
    2647                 :            : //      curve_geom_ptr = curve_geom;
    2648                 :            : //    }
    2649                 :            : //    else
    2650                 :            :     {
    2651         [ #  # ]:          0 :       segments.reset();
    2652                 :          0 :       pt = pts[0];
    2653 [ #  # ][ #  # ]:          0 :       vectors.append( new CubitVector( pt->coordinates() ) );
                 [ #  # ]
    2654 [ #  # ][ #  # ]:          0 :       for( i = segments.size(); i--; )
    2655                 :            :       {
    2656 [ #  # ][ #  # ]:          0 :         pt = segments.get_and_step()->other_point(pt);
    2657 [ #  # ][ #  # ]:          0 :         if ( real_surf && i > 0 )
    2658                 :            :         {
    2659         [ #  # ]:          0 :           surface->relax_to_geometry( pt );
    2660                 :            :         }
    2661         [ #  # ]:          0 :         assert(!!pt);
    2662 [ #  # ][ #  # ]:          0 :         vectors.append( new CubitVector( pt->coordinates() ) );
                 [ #  # ]
    2663                 :            :       }
    2664                 :          0 :       curve_geom_ptr = &vectors;
    2665                 :            :     }
    2666                 :            :     
    2667 [ #  # ][ #  # ]:          0 :     curve = new SegmentedCurve( surface, *curve_geom_ptr );
    2668                 :            :     
    2669 [ #  # ][ #  # ]:          0 :     while( vectors.size() ) delete vectors.pop();
                 [ #  # ]
    2670                 :            :     
    2671         [ #  # ]:          0 :     curve->start_point( end_pts[0] );
    2672         [ #  # ]:          0 :     curve->end_point( end_pts[1] );
    2673         [ #  # ]:          0 :     curve->set_facet_data(segments);
    2674                 :            :   
    2675 [ #  # ][ #  # ]:          0 :     if( insert_curve( surface, curve ) )
    2676 [ #  # ][ #  # ]:          0 :       return curve;
    2677                 :            :   }
    2678                 :            :   
    2679                 :            :   // If we got this far, then something went wrong.
    2680                 :            :   // Try to clean up.
    2681                 :            :     
    2682         [ #  # ]:          0 :   if( curve )
    2683                 :            :   {
    2684         [ #  # ]:          0 :     curve->start_point(0);
    2685         [ #  # ]:          0 :     curve->end_point(0);
    2686         [ #  # ]:          0 :     segments.clean_out();
    2687         [ #  # ]:          0 :     curve->set_facet_data(segments);
    2688 [ #  # ][ #  # ]:          0 :     delete curve;
    2689                 :            :   }
    2690                 :            :   
    2691         [ #  # ]:          0 :   for( i = 0; i < 2; i++ )
    2692                 :            :   {
    2693         [ #  # ]:          0 :     if( ! created_pts[i] ) continue;
    2694                 :            :     
    2695         [ #  # ]:          0 :     end_pts[i]->facet_point(0);
    2696 [ #  # ][ #  # ]:          0 :     if( dynamic_cast<Curve*>(end_pts[i]->partitioned_entity()) )
         [ #  # ][ #  # ]
    2697         [ #  # ]:          0 :       remove_point( end_pts[i] );
    2698                 :            :     else
    2699 [ #  # ][ #  # ]:          0 :       delete end_pts[i];
    2700                 :            :   }
    2701                 :            :   
    2702         [ #  # ]:          0 :   return 0;
    2703                 :            : }
    2704                 :            : 
    2705                 :            : /*
    2706                 :            : //-------------------------------------------------------------------------
    2707                 :            : // Purpose       : Partition a curve using a facet point on the curve.
    2708                 :            : //
    2709                 :            : // Special Notes : 
    2710                 :            : //
    2711                 :            : // Creator       : Jason Kraftcheck
    2712                 :            : //
    2713                 :            : // Creation Date : 02/23/03
    2714                 :            : //-------------------------------------------------------------------------
    2715                 :            : PartitionPoint* PartitionEngine::insert_point( CubitPointData* pt )
    2716                 :            : {
    2717                 :            :   DLIList<CubitFacetEdge*> edges;
    2718                 :            :   pt->edges(edges);
    2719                 :            :   
    2720                 :            :   PartitionCurve* curve = 0;
    2721                 :            :   for ( int i = edges.size(); i--; )
    2722                 :            :   {
    2723                 :            :     CubitFacetEdge* edge = edges.step_and_get();
    2724                 :            :     PartitionCurve* c = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edge));
    2725                 :            :     if( c )
    2726                 :            :     {
    2727                 :            :       if( !curve )
    2728                 :            :         curve = c;
    2729                 :            :       else if( curve != c )
    2730                 :            :       {
    2731                 :            :         PRINT_ERROR("Internal Error in PartitionEngine.  Corrupt facet data.\n");
    2732                 :            :         return 0;
    2733                 :            :       }
    2734                 :            :     }
    2735                 :            :   }
    2736                 :            :       
    2737                 :            :   DLIList<CubitFacetEdgeData*> segments, other_segments;
    2738                 :            :   curve->get_facet_data(segments);
    2739                 :            :   segments.last();
    2740                 :            :   while( !segments.get()->contains( pt ) )
    2741                 :            :   {
    2742                 :            :     other_segments.append( segments.pop() );
    2743                 :            :     segments.last();
    2744                 :            :   }
    2745                 :            :   other_segments.reverse();
    2746                 :            :   
    2747                 :            :   PartitionPoint* new_point = new PartitionPoint( pt->coordinates(), curve );
    2748                 :            :   PartitionCurve* curve2 = insert_point( curve, new_point );
    2749                 :            :   if( !curve2 )
    2750                 :            :   {
    2751                 :            :     delete new_point;
    2752                 :            :     return 0;
    2753                 :            :   }
    2754                 :            :   
    2755                 :            :   curve->set_facet_data(segments);
    2756                 :            :   curve2->set_facet_data(other_segments);
    2757                 :            :   new_point->facet_point(pt);
    2758                 :            :   return new_point;
    2759                 :            : }
    2760                 :            : */
    2761                 :            : 
    2762                 :            : //-------------------------------------------------------------------------
    2763                 :            : // Purpose       : Add point to surface facetting.
    2764                 :            : //
    2765                 :            : // Special Notes : 
    2766                 :            : //
    2767                 :            : // Creator       : Jason Kraftcheck
    2768                 :            : //
    2769                 :            : // Creation Date : 02/23/03
    2770                 :            : //-------------------------------------------------------------------------
    2771                 :          0 : CubitPointData* PartitionEngine::project_to_surface( 
    2772                 :            :                                  PartitionSurface* surface,
    2773                 :            :                                  const CubitVector& position )
    2774                 :            : {
    2775                 :            :   
    2776         [ #  # ]:          0 :   CubitVector pos;
    2777         [ #  # ]:          0 :   CubitFacet* facet = surface->closest_facet( position, pos );
    2778         [ #  # ]:          0 :   surface->closest_point( position, &pos );
    2779         [ #  # ]:          0 :   CubitFacetData* facet_d = dynamic_cast<CubitFacetData*>(facet);
    2780         [ #  # ]:          0 :   DLIList<CubitFacetEdge*> pt_edges;
    2781         [ #  # ]:          0 :   assert(!!facet_d);
    2782                 :            : 
    2783 [ #  # ][ #  # ]:          0 :   CubitVector p[3], v[3], d[3];
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2784                 :            :   int i;
    2785                 :            :   
    2786                 :            :     // Initialize data
    2787                 :          0 :   double dist_tol_sqr = CUBIT_DBL_MAX;
    2788         [ #  # ]:          0 :   for ( i = 0; i < 3; i++ ) {
    2789 [ #  # ][ #  # ]:          0 :     p[i] = facet_d->point(i)->coordinates();
                 [ #  # ]
    2790 [ #  # ][ #  # ]:          0 :     v[i] = facet_d->point((i+1)%3)->coordinates() - p[i];
         [ #  # ][ #  # ]
    2791         [ #  # ]:          0 :     double dist_sqr = v[i].length_squared();
    2792         [ #  # ]:          0 :     if ( dist_sqr < dist_tol_sqr )
    2793                 :          0 :       dist_tol_sqr = dist_sqr;
    2794 [ #  # ][ #  # ]:          0 :     d[i] = pos - p[i];
    2795                 :            :   }
    2796                 :          0 :   dist_tol_sqr *= 0.2;
    2797         [ #  # ]:          0 :   if( dist_tol_sqr < GEOMETRY_RESABS*GEOMETRY_RESABS )
    2798                 :          0 :     dist_tol_sqr = GEOMETRY_RESABS*GEOMETRY_RESABS;
    2799                 :            :   
    2800                 :            :     // Check if we are within GEOMETRY_RESABS of a vertex of the
    2801                 :            :     // triangle or if one of the triangle vertices can be moved
    2802                 :            :     // to the input location.
    2803                 :          0 :   int closest_pt = -1;
    2804                 :          0 :   double closest_dist = dist_tol_sqr;
    2805         [ #  # ]:          0 :   for ( i = 0; i < 3; i++ ) {
    2806         [ #  # ]:          0 :     double dist_sqr = d[i].length_squared();
    2807 [ #  # ][ #  # ]:          0 :     bool has_owner = (0 != TDVGFacetOwner::get(facet->point(i)));
    2808 [ #  # ][ #  # ]:          0 :     if( !has_owner && dist_sqr < closest_dist ) {
    2809         [ #  # ]:          0 :       pt_edges.clean_out();
    2810 [ #  # ][ #  # ]:          0 :       facet->point(i)->edges( pt_edges);
    2811 [ #  # ][ #  # ]:          0 :       while( pt_edges.size() )
    2812 [ #  # ][ #  # ]:          0 :         if ( TDVGFacetOwner::get(pt_edges.pop()) )
                 [ #  # ]
    2813                 :          0 :           has_owner = true;
    2814                 :            :     }
    2815                 :            :     
    2816 [ #  # ][ #  # ]:          0 :     if ( (!has_owner && dist_sqr < closest_dist) ||
                 [ #  # ]
    2817                 :            :          dist_sqr < GEOMETRY_RESABS*GEOMETRY_RESABS ) {
    2818                 :          0 :       closest_pt = i;
    2819                 :          0 :       closest_dist = dist_sqr;
    2820                 :            :     }
    2821                 :            :   }
    2822                 :            :   
    2823         [ #  # ]:          0 :   if( closest_pt >= 0 )
    2824                 :            :   {
    2825 [ #  # ][ #  # ]:          0 :     facet->point(closest_pt)->set(pos);
    2826 [ #  # ][ #  # ]:          0 :     return dynamic_cast<CubitPointData*>(facet->point(closest_pt));
    2827                 :            :   }
    2828                 :            :   
    2829                 :            :     // Check if the input position is within GEOMETRY_RESABS of one
    2830                 :            :     // of the triangle edges or if the edge can be 'bent' such that
    2831                 :            :     // the split point is the input position.
    2832                 :          0 :   int closest_edge = -1;
    2833         [ #  # ]:          0 :   for ( i = 0; i < 3; i++ ) {
    2834 [ #  # ][ #  # ]:          0 :     double t = (v[i] % d[i]) / v[i].length_squared();
    2835 [ #  # ][ #  # ]:          0 :     double dist_sqr = (d[i] - t * v[i]).length_squared();
                 [ #  # ]
    2836 [ #  # ][ #  # ]:          0 :     CubitFacetEdge* edge = facet->point(i)->shared_edge(facet->point((i+1)%3));
                 [ #  # ]
    2837                 :            : 
    2838 [ #  # ][ #  # ]:          0 :     bool has_owner = edge && TDVGFacetOwner::get(edge);
                 [ #  # ]
    2839                 :            :     
    2840 [ #  # ][ #  # ]:          0 :     if( (!has_owner && dist_sqr < closest_dist) ||
                 [ #  # ]
    2841                 :            :          dist_sqr < GEOMETRY_RESABS*GEOMETRY_RESABS )
    2842                 :            :     {
    2843                 :          0 :       CubitFacet* other_facet = 0;
    2844 [ #  # ][ #  # ]:          0 :       for ( int j = 0; j < edge->num_adj_facets(); j++ )
    2845                 :            :       {
    2846 [ #  # ][ #  # ]:          0 :         if (edge->adj_facet(j) != facet && 
         [ #  # ][ #  # ]
    2847 [ #  # ][ #  # ]:          0 :             TDVGFacetOwner::get(edge->adj_facet(j)) == surface)
                 [ #  # ]
    2848                 :            :         {
    2849         [ #  # ]:          0 :           other_facet = edge->adj_facet(j);
    2850                 :          0 :           break;
    2851                 :            :         }
    2852                 :            :       }
    2853                 :            :       
    2854         [ #  # ]:          0 :       if (other_facet)
    2855                 :            :       {
    2856                 :            :           // check if splitting the edge will invert some other facet
    2857         [ #  # ]:          0 :         int edge_index = other_facet->edge_index( edge );
    2858 [ #  # ][ #  # ]:          0 :         CubitVector other_pt = other_facet->point(edge_index)->coordinates();
    2859 [ #  # ][ #  # ]:          0 :         CubitVector prev_pt = other_facet->point((edge_index+1)%3)->coordinates();
    2860 [ #  # ][ #  # ]:          0 :         CubitVector next_pt = other_facet->point((edge_index+2)%3)->coordinates();
    2861         [ #  # ]:          0 :         prev_pt -= other_pt;
    2862         [ #  # ]:          0 :         next_pt -= other_pt;
    2863         [ #  # ]:          0 :         CubitVector norm = prev_pt * next_pt;
    2864         [ #  # ]:          0 :         CubitVector new_e = pos - other_pt;
    2865                 :            :         
    2866 [ #  # ][ #  # ]:          0 :         if ( norm.vector_angle_quick(prev_pt, new_e) > CUBIT_PI ||
         [ #  # ][ #  # ]
    2867         [ #  # ]:          0 :              norm.vector_angle_quick(new_e, next_pt) > CUBIT_PI )
    2868                 :          0 :           continue;
    2869                 :            :         
    2870                 :            :           // don't create adjacent sliver facets
    2871 [ #  # ][ #  # ]:          0 :         double prev_t = prev_pt % new_e / prev_pt.length_squared();
    2872         [ #  # ]:          0 :         prev_pt *= prev_t;
    2873         [ #  # ]:          0 :         prev_pt += other_pt;
    2874 [ #  # ][ #  # ]:          0 :         if ( (prev_pt - pos).length_squared() < dist_sqr )
                 [ #  # ]
    2875                 :          0 :           continue;
    2876                 :            :         
    2877 [ #  # ][ #  # ]:          0 :         double next_t = next_pt % new_e / next_pt.length_squared();
    2878         [ #  # ]:          0 :         next_pt *= next_t;
    2879         [ #  # ]:          0 :         next_pt += other_pt;
    2880 [ #  # ][ #  # ]:          0 :         if ( (next_pt - pos).length_squared() < dist_sqr )
                 [ #  # ]
    2881                 :          0 :           continue;
    2882                 :            :       }
    2883                 :            :         
    2884                 :            :       
    2885                 :          0 :       closest_dist = dist_sqr;
    2886                 :          0 :       closest_edge = i;
    2887                 :            :     }
    2888                 :            :   }
    2889                 :            : 
    2890         [ #  # ]:          0 :   if( closest_edge >= 0 )
    2891                 :            :   {      
    2892         [ #  # ]:          0 :     CubitPoint* pt1 = facet->point(closest_edge);
    2893         [ #  # ]:          0 :     CubitPoint* pt2 = facet->point((closest_edge+1)%3);
    2894         [ #  # ]:          0 :     CubitFacetEdge* edge = pt1->shared_edge(pt2);
    2895                 :            :     CubitFacetEdge* new_edge;
    2896                 :            :     CubitFacet* new_facet;
    2897                 :            :     CubitPoint* new_point;
    2898         [ #  # ]:          0 :     PartSurfFacetTool::split_edge(edge, pos, 0, new_point, new_edge, new_facet );
    2899 [ #  # ][ #  # ]:          0 :     if (dynamic_cast<SubSurface*>(surface))
                 [ #  # ]
    2900         [ #  # ]:          0 :       surface->relax_to_geometry( new_point, &position );
    2901         [ #  # ]:          0 :     return dynamic_cast<CubitPointData*>(new_point);
    2902                 :            :   }
    2903                 :            :   
    2904                 :          0 :   CubitFacet *new_tri1 = 0, *new_tri2 = 0;
    2905         [ #  # ]:          0 :   CubitPoint* pt1 = facet->point(0);
    2906         [ #  # ]:          0 :   CubitPoint* pt2 = facet->point(1);
    2907         [ #  # ]:          0 :   CubitPoint* pt3 = facet->point(2);
    2908         [ #  # ]:          0 :   CubitPoint* new_pt = facet->insert_point( pos, new_tri1, new_tri2 );
    2909 [ #  # ][ #  # ]:          0 :   new CubitFacetEdgeData( new_pt, pt1 );
    2910 [ #  # ][ #  # ]:          0 :   new CubitFacetEdgeData( new_pt, pt2 );
    2911 [ #  # ][ #  # ]:          0 :   new CubitFacetEdgeData( new_pt, pt3 );
    2912         [ #  # ]:          0 :   surface->notify_split( facet, new_tri1 );
    2913         [ #  # ]:          0 :   surface->notify_split( facet, new_tri2 );
    2914                 :            : 
    2915 [ #  # ][ #  # ]:          0 :   if (dynamic_cast<SubSurface*>(surface))
                 [ #  # ]
    2916         [ #  # ]:          0 :     surface->relax_to_geometry( new_pt, &position );
    2917                 :            : 
    2918 [ #  # ][ #  # ]:          0 :   return dynamic_cast<CubitPointData*>(new_pt);
    2919                 :            : }
    2920                 :            : 
    2921                 :          0 : void PartitionEngine::delete_facet( CubitFacet* p_dead )
    2922                 :            : {
    2923 [ #  # ][ #  # ]:          0 : assert(!TDVGFacetOwner::get(p_dead));
    2924 [ #  # ][ #  # ]:          0 : assert(dynamic_cast<CubitFacetData*>(p_dead) != NULL);
    2925                 :            : 
    2926 [ #  # ][ #  # ]:          0 :   CubitFacetEdge* edges[3] = {p_dead->edge(0), p_dead->edge(1), p_dead->edge(2)};
                 [ #  # ]
    2927 [ #  # ][ #  # ]:          0 :   CubitPoint* pts[3] = {p_dead->point(0), p_dead->point(1), p_dead->point(2)};
                 [ #  # ]
    2928                 :            : 
    2929                 :            :   int k;
    2930         [ #  # ]:          0 :   for( k = 0; k < 3; k++ )
    2931                 :            :   {
    2932         [ #  # ]:          0 :     if( pts[k] )
    2933                 :            :     {  
    2934         [ #  # ]:          0 :       pts[k]->remove_facet( p_dead );
    2935                 :          0 :       CubitFacetData *facet_data = static_cast<CubitFacetData*>(p_dead);
    2936         [ #  # ]:          0 :       facet_data->set_point( NULL, k);
    2937                 :            :       
    2938 [ #  # ][ #  # ]:          0 :       if( !pts[k]->num_adj_facets() )
    2939 [ #  # ][ #  # ]:          0 :         delete pts[k];
    2940                 :            :     }
    2941                 :            :   }
    2942                 :            : 
    2943         [ #  # ]:          0 :   for( k = 0; k < 3; k++ )
    2944                 :            :   {
    2945         [ #  # ]:          0 :     if( edges[k] )
    2946                 :            :     {
    2947         [ #  # ]:          0 :       edges[k]->remove_facet(p_dead);
    2948         [ #  # ]:          0 :       p_dead->edge(NULL, k);
    2949 [ #  # ][ #  # ]:          0 :       if(!edges[k]->num_adj_facets())
    2950 [ #  # ][ #  # ]:          0 :         delete edges[k];
    2951                 :            :     }
    2952                 :            :   }
    2953                 :            :   
    2954 [ #  # ][ #  # ]:          0 :   delete p_dead;
    2955                 :          0 : }        
    2956                 :            : 
    2957                 :            : //-------------------------------------------------------------------------
    2958                 :            : // Purpose       : Create projection of a polyline in surface facetting.
    2959                 :            : //
    2960                 :            : // Special Notes : 
    2961                 :            : //
    2962                 :            : // Creator       : Jason Kraftcheck
    2963                 :            : //
    2964                 :            : // Creation Date : 02/23/03
    2965                 :            : //-------------------------------------------------------------------------
    2966                 :          0 : CubitStatus PartitionEngine::project_to_surface( 
    2967                 :            :                                  DLIList<CubitFacetData*>& cubit_facets,
    2968                 :            :                                  DLIList<CubitVector*>& polyline,
    2969                 :            :                                  DLIList<CubitFacetEdgeData*>& polyline_out,
    2970                 :            :                                  DLIList<CubitPointData*>& polyline_points,
    2971                 :            :                                  const double *tolerance_length)
    2972                 :            : {
    2973                 :            :   int i, j;
    2974                 :            :   unsigned u;
    2975                 :            :   PartitionSurface* p_adj_surf;
    2976                 :          0 :   PartitionCurve* p_curve = 0;
    2977                 :            :   PartitionEntity* p_owner;
    2978                 :            : 
    2979         [ #  # ]:          0 :   DLIList<PartitionSurface*> surfaces;
    2980 [ #  # ][ #  # ]:          0 :   for (i = cubit_facets.size(); i--; )
    2981 [ #  # ][ #  # ]:          0 :     surfaces.append_unique( dynamic_cast<PartitionSurface*>(TDVGFacetOwner::get(cubit_facets.step_and_get())));
         [ #  # ][ #  # ]
    2982                 :            : 
    2983                 :            :     // get points
    2984                 :            : 
    2985 [ #  # ][ #  # ]:          0 :   DLIList<CubitPoint*> cubit_points(cubit_facets.size() * 3);
                 [ #  # ]
    2986 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacet*> orig_facets;
    2987 [ #  # ][ #  # ]:          0 :   CAST_LIST_TO_PARENT(cubit_facets, orig_facets);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2988         [ #  # ]:          0 :   FacetDataUtil::get_facet_points(orig_facets, cubit_points);
    2989                 :            : 
    2990                 :            :   // get bounding curves from the facets
    2991 [ #  # ][ #  # ]:          0 :   std::set<PartitionCurve*> boundary_curves;
    2992 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetEdge*> free_edges;
    2993         [ #  # ]:          0 :   FacetDataUtil::edges_by_count(orig_facets, 1, free_edges);
    2994         [ #  # ]:          0 :   free_edges.reset();
    2995 [ #  # ][ #  # ]:          0 :   for (i=free_edges.size(); i>0; i--)
    2996                 :            :   {
    2997 [ #  # ][ #  # ]:          0 :     p_owner = TDVGFacetOwner::get(free_edges.get_and_step());
    2998         [ #  # ]:          0 :     p_curve = CAST_TO(p_owner, PartitionCurve);
    2999         [ #  # ]:          0 :     assert(!!p_curve); // every bounding edge should be owned by a curve
    3000         [ #  # ]:          0 :     boundary_curves.insert(p_curve);
    3001                 :            :   }
    3002                 :            :   
    3003 [ #  # ][ #  # ]:          0 :   std::vector<double> facet_points(cubit_points.size() * 3);
                 [ #  # ]
    3004 [ #  # ][ #  # ]:          0 :   std::vector<int> simple_facets(cubit_facets.size() * 3);
                 [ #  # ]
    3005         [ #  # ]:          0 :   cubit_points.reset();
    3006 [ #  # ][ #  # ]:          0 :   for ( i = 0; i < cubit_points.size(); i++ )
    3007                 :            :   {
    3008         [ #  # ]:          0 :     CubitPoint* pt = cubit_points.get_and_step();
    3009         [ #  # ]:          0 :     pt->marked( i );
    3010                 :            :     
    3011                 :          0 :     int j = i * 3;
    3012 [ #  # ][ #  # ]:          0 :     facet_points[j  ] = pt->coordinates().x();
                 [ #  # ]
    3013 [ #  # ][ #  # ]:          0 :     facet_points[j+1] = pt->coordinates().y();
                 [ #  # ]
    3014 [ #  # ][ #  # ]:          0 :     facet_points[j+2] = pt->coordinates().z();
                 [ #  # ]
    3015 [ #  # ][ #  # ]:          0 :     if (DEBUG_FLAG(145))
                 [ #  # ]
    3016                 :            :     {
    3017 [ #  # ][ #  # ]:          0 :       GfxDebug::draw_point(pt->coordinates(), CUBIT_WHITE_INDEX);
    3018 [ #  # ][ #  # ]:          0 :       GfxDebug::draw_label(i, (float)(pt->coordinates().x()),
    3019 [ #  # ][ #  # ]:          0 :                               (float)(pt->coordinates().y()),
    3020 [ #  # ][ #  # ]:          0 :                               (float)(pt->coordinates().z()),
    3021         [ #  # ]:          0 :                               CUBIT_WHITE_INDEX);
    3022                 :            :     }
    3023                 :            :   }
    3024                 :            :   
    3025         [ #  # ]:          0 :   cubit_facets.reset();
    3026 [ #  # ][ #  # ]:          0 :   for ( i = 0; i < cubit_facets.size(); i++ )
    3027                 :            :   {
    3028         [ #  # ]:          0 :     CubitFacetData* facet = cubit_facets.get_and_step();
    3029                 :          0 :     int j = i * 3;
    3030 [ #  # ][ #  # ]:          0 :     simple_facets[j  ] = facet->point(0)->marked();
                 [ #  # ]
    3031 [ #  # ][ #  # ]:          0 :     simple_facets[j+1] = facet->point(1)->marked();
                 [ #  # ]
    3032 [ #  # ][ #  # ]:          0 :     simple_facets[j+2] = facet->point(2)->marked();
                 [ #  # ]
    3033 [ #  # ][ #  # ]:          0 :     if (DEBUG_FLAG(145))
                 [ #  # ]
    3034                 :            :     {
    3035         [ #  # ]:          0 :       GfxDebug::draw_facet( facet, CUBIT_CYAN_INDEX );
    3036         [ #  # ]:          0 :       CubitVector c = facet->center();
    3037         [ #  # ]:          0 :       GfxDebug::draw_label( i, (float)(c.x()),
    3038         [ #  # ]:          0 :                                (float)(c.y()),
    3039         [ #  # ]:          0 :                                (float)(c.z()),
    3040         [ #  # ]:          0 :                                CUBIT_CYAN_INDEX);
    3041 [ #  # ][ #  # ]:          0 :       PRINT_DEBUG_145("%2d : %2d %2d %2d\n", i,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3042                 :            :                                              facet->point(0)->marked(),
    3043                 :            :                                              facet->point(1)->marked(),
    3044         [ #  # ]:          0 :                                              facet->point(2)->marked());
    3045                 :            :     }
    3046                 :            :   }
    3047                 :            : 
    3048                 :            :     // clear point marks
    3049 [ #  # ][ #  # ]:          0 :   for ( i = 0; i < cubit_points.size(); i++ )
    3050 [ #  # ][ #  # ]:          0 :     cubit_points.step_and_get()->marked(0);  
    3051                 :            : /*
    3052                 :            :     // reduce polyline resolution
    3053                 :            :   const double dist_tol = GEOMETRY_RESABS*GEOMETRY_RESABS;
    3054                 :            :   const double COS15 = 0.96592582628906831;
    3055                 :            :   const double angle_tol = COS15*COS15;
    3056                 :            :   DLIList<CubitVector*> polyline2;
    3057                 :            :   polyline.reset();
    3058                 :            :   CubitVector *prev = polyline.get_and_step();
    3059                 :            :   polyline2.append(prev);
    3060                 :            :   for( i = polyline.size() - 2; i--; )
    3061                 :            :   {
    3062                 :            :     CubitVector *pt = polyline.get_and_step();
    3063                 :            :     CubitVector *next = polyline.get();
    3064                 :            :     CubitVector v1(*pt - *prev);
    3065                 :            :     CubitVector v2(*next - *pt);
    3066                 :            :     double len1 = v1.length_squared();
    3067                 :            :     double len2 = v2.length_squared();
    3068                 :            :     double dot = v1 % v2;
    3069                 :            :     if( len1 > dist_tol && len2 > dist_tol &&
    3070                 :            :         ((dot*dot)/(len1*len2)) < angle_tol )
    3071                 :            :     {
    3072                 :            :       polyline2.append(pt);
    3073                 :            :       prev = pt;
    3074                 :            :     }
    3075                 :            :   }
    3076                 :            :   polyline2.append(polyline.get());
    3077                 :            : */
    3078                 :            :     // Call tool to do projection
    3079                 :            : 
    3080 [ #  # ][ #  # ]:          0 :   std::vector<double> new_facet_points;
    3081 [ #  # ][ #  # ]:          0 :   std::vector<int> dead_simple_facets, new_simple_facets, 
         [ #  # ][ #  # ]
    3082 [ #  # ][ #  # ]:          0 :                    facet_replacement, new_polyline, seg_pts;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3083 [ #  # ][ #  # ]:          0 :   FacetProjectTool tool;
    3084         [ #  # ]:          0 :   if ( !tool.project( polyline, facet_points, simple_facets,
    3085                 :            :                       dead_simple_facets, new_simple_facets,
    3086                 :            :                       facet_replacement, new_facet_points, 
    3087         [ #  # ]:          0 :                       new_polyline, seg_pts, tolerance_length ) )
    3088                 :            :   {
    3089                 :            :     // output the map between input polyline positions and
    3090                 :            :     // facet points
    3091         [ #  # ]:          0 :     std::vector<int>::iterator iitor;
    3092 [ #  # ][ #  # ]:          0 :     for ( iitor = seg_pts.begin(); iitor != seg_pts.end(); ++iitor )
         [ #  # ][ #  # ]
                 [ #  # ]
    3093                 :            :     {
    3094         [ #  # ]:          0 :       int pt_index = *iitor;
    3095         [ #  # ]:          0 :       if ( pt_index == -1 )
    3096                 :            :       {
    3097         [ #  # ]:          0 :         polyline_points.append(NULL);
    3098                 :            :       }
    3099                 :            :       else
    3100                 :            :       {
    3101                 :          0 :         CubitPointData* ptd = NULL;
    3102 [ #  # ][ #  # ]:          0 :         if(pt_index >= 0 && pt_index < cubit_points.size())
         [ #  # ][ #  # ]
    3103                 :            :         {
    3104         [ #  # ]:          0 :           CubitPoint* pt = cubit_points.next( pt_index );
    3105         [ #  # ]:          0 :           ptd = dynamic_cast<CubitPointData*>(pt);
    3106                 :            :         }
    3107         [ #  # ]:          0 :         polyline_points.append(ptd);
    3108                 :            :       }
    3109                 :            :     }
    3110                 :            : 
    3111                 :          0 :     return CUBIT_FAILURE;
    3112                 :            :   }
    3113                 :            : 
    3114                 :            :     // Convert back to CubitFacet rep
    3115                 :            :    
    3116                 :            :     // make new points
    3117 [ #  # ][ #  # ]:          0 :   assert( new_facet_points.size() % 3 == 0 );
    3118 [ #  # ][ #  # ]:          0 :   std::vector<CubitPointData*> new_cubit_points(new_facet_points.size()/3);
                 [ #  # ]
    3119         [ #  # ]:          0 :   std::vector<CubitPointData*>::iterator cpitor = new_cubit_points.begin();
    3120         [ #  # ]:          0 :   std::vector<double>::iterator ditor = new_facet_points.begin();
    3121 [ #  # ][ #  # ]:          0 :   for ( ; cpitor != new_cubit_points.end(); ++cpitor )
         [ #  # ][ #  # ]
    3122                 :            :   {
    3123 [ #  # ][ #  # ]:          0 :     double x = *ditor++;
    3124 [ #  # ][ #  # ]:          0 :     double y = *ditor++;
    3125 [ #  # ][ #  # ]:          0 :     double z = *ditor++;
    3126 [ #  # ][ #  # ]:          0 :     *cpitor = new CubitPointData(x,y,z);
                 [ #  # ]
    3127 [ #  # ][ #  # ]:          0 :     cubit_points.append(*cpitor);
    3128                 :            :   }
    3129                 :            : 
    3130                 :            :     // make new facets
    3131         [ #  # ]:          0 :   cubit_facets.reset();
    3132         [ #  # ]:          0 :   cubit_points.reset();
    3133                 :          0 :   int prev_index = 0;
    3134 [ #  # ][ #  # ]:          0 :   assert( new_simple_facets.size() % 3 == 0 );
    3135                 :            : 
    3136 [ #  # ][ #  # ]:          0 :   std::vector<CubitFacetData*> facet_list;
    3137         [ #  # ]:          0 :   std::vector<CubitFacetData*>::iterator fitor;
    3138         [ #  # ]:          0 :   std::vector<int>::iterator iitor = new_simple_facets.begin();
    3139                 :            : 
    3140                 :          0 :   int id=0; // dummy for CubitFacetData constructor
    3141                 :            : 
    3142 [ #  # ][ #  # ]:          0 :   for( u = 0; u < dead_simple_facets.size(); u++ )
    3143                 :            :   {
    3144                 :            :       // get number of replacement facets
    3145         [ #  # ]:          0 :     int index = facet_replacement[u];
    3146                 :          0 :     int count = (index - prev_index) / 3;
    3147         [ #  # ]:          0 :     assert(((index - prev_index) % 3) == 0);
    3148                 :            : 
    3149                 :            :       // make a new list to hold data
    3150         [ #  # ]:          0 :     facet_list.clear();
    3151         [ #  # ]:          0 :     facet_list.resize(count+1);
    3152         [ #  # ]:          0 :     fitor = facet_list.begin();
    3153                 :            : 
    3154                 :            :       // put dead facet at beginning of list
    3155 [ #  # ][ #  # ]:          0 :     CubitFacetData* p_dead = cubit_facets.next(dead_simple_facets[u]);
    3156 [ #  # ][ #  # ]:          0 :     *fitor++ = p_dead;
    3157                 :            : 
    3158                 :            :     // get the surface that owns the dead facet
    3159         [ #  # ]:          0 :     p_owner = TDVGFacetOwner::get(p_dead);
    3160         [ #  # ]:          0 :     PartitionSurface* p_dead_surf = CAST_TO(p_owner, PartitionSurface);
    3161         [ #  # ]:          0 :     assert(!!p_dead_surf);
    3162                 :            : 
    3163                 :            :       // construct and append replacement facets
    3164         [ #  # ]:          0 :     for ( j=0; j < count; j++ )
    3165                 :            :     {
    3166 [ #  # ][ #  # ]:          0 :       CubitPoint* pt1 = cubit_points.next( *iitor++ );
                 [ #  # ]
    3167 [ #  # ][ #  # ]:          0 :       CubitPoint* pt2 = cubit_points.next( *iitor++ );
                 [ #  # ]
    3168 [ #  # ][ #  # ]:          0 :       CubitPoint* pt3 = cubit_points.next( *iitor++ );
                 [ #  # ]
    3169 [ #  # ][ #  # ]:          0 :       *fitor++ = new CubitFacetData(pt1, pt2, pt3, &id);
         [ #  # ][ #  # ]
    3170                 :            :     }
    3171                 :            : 
    3172                 :            :       // set up for next iteration
    3173 [ #  # ][ #  # ]:          0 :     assert(fitor == facet_list.end());
         [ #  # ][ #  # ]
    3174                 :          0 :     prev_index = index;
    3175                 :            : 
    3176                 :            :       // do something with "facet_list"
    3177                 :            : 
    3178         [ #  # ]:          0 :     DLIList<CubitFacetData*> old_facet_list;
    3179                 :            : 
    3180                 :            :     // fill edge replacement lists
    3181 [ #  # ][ #  # ]:          0 :     std::vector<CubitFacetEdgeData*> edge_lists[3];
         [ #  # ][ #  # ]
           [ #  #  #  # ]
    3182         [ #  # ]:          0 :     get_edge_replacements(facet_list, edge_lists);
    3183                 :            : 
    3184                 :            :     // update edges/facets on curves and adjacent surfaces
    3185                 :            :     CubitFacetEdgeData* old_edge;
    3186         [ #  # ]:          0 :     for (j=0; j<3; j++)
    3187                 :            :     {
    3188         [ #  # ]:          0 :       DLIList<CubitFacetEdgeData*> new_edges;
    3189 [ #  # ][ #  # ]:          0 :       if (edge_lists[j].size()) // check for replacements
    3190                 :            :       {
    3191         [ #  # ]:          0 :         std::vector<CubitFacetEdgeData*>::iterator eitor = edge_lists[j].begin();
    3192 [ #  # ][ #  # ]:          0 :         old_edge = *eitor++;
    3193                 :            : 
    3194         [ #  # ]:          0 :         p_owner = TDVGFacetOwner::get(old_edge);
    3195         [ #  # ]:          0 :         p_curve = CAST_TO(p_owner, PartitionCurve);
    3196                 :            : 
    3197 [ #  # ][ #  # ]:          0 :         for (; eitor != edge_lists[j].end(); eitor++)
         [ #  # ][ #  # ]
    3198 [ #  # ][ #  # ]:          0 :           new_edges.append(*eitor);
    3199                 :            : 
    3200 [ #  # ][ #  # ]:          0 :         assert(new_edges.size() > 1); // shouldn't ever get 1 to 1 replacement here
    3201                 :            : 
    3202                 :            :         // split facets on adjacent surfaces if the split crosses a curve
    3203                 :            :         // on the outside boundary of the facets
    3204 [ #  # ][ #  # ]:          0 :         if (boundary_curves.find(p_curve) != boundary_curves.end())
         [ #  # ][ #  # ]
    3205                 :            :         {
    3206                 :            :           // get facets to be replaced on adjacent surf
    3207         [ #  # ]:          0 :           DLIList<CubitFacetData*> adj_facets;
    3208 [ #  # ][ #  # ]:          0 :           DLIList<CubitFacet*> tmp_list;
    3209         [ #  # ]:          0 :           old_edge->facets(tmp_list);
    3210 [ #  # ][ #  # ]:          0 :           CAST_LIST(tmp_list, adj_facets, CubitFacetData);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    3211                 :            : 
    3212 [ #  # ][ #  # ]:          0 :           if (adj_facets.size() > 1)
    3213                 :            :           {
    3214         [ #  # ]:          0 :             DLIList<CubitFacetData*> adj_replacements;
    3215                 :            :             int i_adj;
    3216 [ #  # ][ #  # ]:          0 :             for (i_adj=adj_facets.size(); i_adj>0; i_adj--)
    3217                 :            :             {
    3218         [ #  # ]:          0 :               CubitFacetData* p_adjacent = adj_facets.get_and_step();
    3219         [ #  # ]:          0 :               if (p_adjacent == p_dead)
    3220                 :          0 :                 continue;
    3221                 :            : 
    3222                 :            :               // create replacement facets
    3223         [ #  # ]:          0 :               adj_replacements.clean_out();
    3224                 :            : 
    3225                 :            :               // get the point opposite the edge being replaced
    3226         [ #  # ]:          0 :               int e_index = p_adjacent->edge_index(old_edge);
    3227         [ #  # ]:          0 :               bool old_reversed = -1 == p_adjacent->edge_use(e_index);
    3228                 :          0 :               CubitPoint* prev_pt = NULL;
    3229                 :            :               //if old_reversed is false, the new_edge' reversed flag is true
    3230                 :            :               int old_prev_pt_index;
    3231         [ #  # ]:          0 :               if (old_reversed)
    3232                 :            :               {
    3233         [ #  # ]:          0 :                  prev_pt = old_edge->point(0);
    3234                 :          0 :                  old_prev_pt_index = 0;
    3235                 :            :               }
    3236                 :            :               else
    3237                 :            :               {
    3238         [ #  # ]:          0 :                  prev_pt = old_edge->point(1);
    3239                 :          0 :                  old_prev_pt_index = 1;
    3240                 :            :               }
    3241         [ #  # ]:          0 :               CubitPoint* opposite_pt = p_adjacent->point(e_index);
    3242                 :            :               //CubitPoint* opposite_pt = p_adjacent->point(p_adjacent->edge_index(old_edge)); // opposite edge and point have same index
    3243         [ #  # ]:          0 :               new_edges.reset();
    3244                 :            :               int i_new;
    3245 [ #  # ][ #  # ]:          0 :               for (i_new=new_edges.size(); i_new>0; i_new--)
    3246                 :            :               {
    3247         [ #  # ]:          0 :                 CubitFacetEdge* p_edge = new_edges.get_and_step();
    3248                 :            :                 
    3249         [ #  # ]:          0 :                 prev_pt = p_edge->other_point(prev_pt);
    3250         [ #  # ]:          0 :                 assert(!!prev_pt);
    3251         [ #  # ]:          0 :                 bool new_reversed = p_edge->point(old_prev_pt_index) == prev_pt;
    3252                 :          0 :                 int reversed = (int)(new_reversed != old_reversed);
    3253                 :            :                 
    3254                 :          0 :                 CubitFacetData* p_facet = new CubitFacetData(p_edge->point(reversed),
    3255                 :          0 :                                                              p_edge->point(1-reversed),
    3256 [ #  # ][ #  # ]:          0 :                                                              opposite_pt, &id);
         [ #  # ][ #  # ]
    3257         [ #  # ]:          0 :                 adj_replacements.append(p_facet);
    3258                 :            :               }
    3259                 :            : 
    3260         [ #  # ]:          0 :               p_owner = TDVGFacetOwner::get(p_adjacent);
    3261         [ #  # ]:          0 :               p_adj_surf = CAST_TO(p_owner, PartitionSurface);
    3262         [ #  # ]:          0 :               assert(!!p_adj_surf);
    3263         [ #  # ]:          0 :               old_facet_list.clean_out();
    3264         [ #  # ]:          0 :               old_facet_list.append(p_adjacent);
    3265         [ #  # ]:          0 :               p_adj_surf->replace_facets(old_facet_list, adj_replacements);
    3266         [ #  # ]:          0 :               delete_facet( p_adjacent );
    3267         [ #  # ]:          0 :             }
    3268         [ #  # ]:          0 :           }
    3269                 :            :         }
    3270                 :            : 
    3271                 :            :         // replace the curve edges
    3272         [ #  # ]:          0 :         p_curve->replace_facet(old_edge, new_edges);
    3273                 :            :         
    3274                 :            :         // Don't delete edge yet.  It's still connected to
    3275                 :            :         // at least one facet.  Wait 'till the facet is deleted.
    3276                 :            :         //delete old_edge;
    3277                 :            :       }
    3278         [ #  # ]:          0 :     }
    3279                 :            : 
    3280                 :            :     // replace dead facet
    3281         [ #  # ]:          0 :     fitor = facet_list.begin();
    3282         [ #  # ]:          0 :     fitor++; // skip dead facet
    3283 [ #  # ][ #  # ]:          0 :     DLIList<CubitFacetData*> new_facets;
    3284 [ #  # ][ #  # ]:          0 :     for (; fitor != facet_list.end(); fitor++)
         [ #  # ][ #  # ]
    3285 [ #  # ][ #  # ]:          0 :       new_facets.append(*fitor);
    3286         [ #  # ]:          0 :     old_facet_list.clean_out();
    3287         [ #  # ]:          0 :     old_facet_list.append(p_dead);
    3288         [ #  # ]:          0 :     p_dead_surf->replace_facets(old_facet_list, new_facets);
    3289         [ #  # ]:          0 :     delete_facet(p_dead);
    3290         [ #  # ]:          0 :   }
    3291                 :            : 
    3292 [ #  # ][ #  # ]:          0 :   assert(iitor == new_simple_facets.end());
                 [ #  # ]
    3293                 :            : 
    3294                 :            :   // output the edges that make up the projected curve
    3295         [ #  # ]:          0 :   cubit_points.reset();
    3296         [ #  # ]:          0 :   iitor = new_polyline.begin();
    3297 [ #  # ][ #  # ]:          0 :   while( *iitor )
    3298                 :            :   {
    3299 [ #  # ][ #  # ]:          0 :     int count = *iitor++;
    3300 [ #  # ][ #  # ]:          0 :     CubitPoint* prev_point = cubit_points.next( *iitor++ );
                 [ #  # ]
    3301         [ #  # ]:          0 :     for ( i = 1; i < count; i++ ) {
    3302 [ #  # ][ #  # ]:          0 :       CubitPoint* pt = cubit_points.next( *iitor++ );
                 [ #  # ]
    3303         [ #  # ]:          0 :       CubitFacetEdge* edge = prev_point->shared_edge(pt);
    3304         [ #  # ]:          0 :       CubitFacetEdgeData* edge_d = dynamic_cast<CubitFacetEdgeData*>(edge);
    3305         [ #  # ]:          0 :       assert(!!edge_d);
    3306 [ #  # ][ #  # ]:          0 :       if (TDVGFacetOwner::get(edge_d)) 
    3307         [ #  # ]:          0 :         polyline_out.append(0);
    3308                 :            :       else
    3309                 :            :       {
    3310 [ #  # ][ #  # ]:          0 :         if (edge_d->point(0) == pt)
    3311         [ #  # ]:          0 :           edge_d->flip();
    3312         [ #  # ]:          0 :         polyline_out.append(edge_d);
    3313                 :            :       }
    3314                 :          0 :       prev_point = pt;
    3315                 :            :     }
    3316         [ #  # ]:          0 :     polyline_out.append(0);
    3317                 :            :   }
    3318                 :            :   
    3319                 :            :   // output the map between input polyline positions and 
    3320                 :            :   // facet points
    3321 [ #  # ][ #  # ]:          0 :   for ( iitor = seg_pts.begin(); iitor != seg_pts.end(); ++iitor )
         [ #  # ][ #  # ]
                 [ #  # ]
    3322                 :            :   {
    3323         [ #  # ]:          0 :     int pt_index = *iitor;
    3324         [ #  # ]:          0 :     if ( pt_index == -1 )
    3325                 :            :     {
    3326         [ #  # ]:          0 :       polyline_points.append(NULL);
    3327                 :            :     }
    3328                 :            :     else
    3329                 :            :     {
    3330 [ #  # ][ #  # ]:          0 :       assert(pt_index >= 0 && pt_index < cubit_points.size());
                 [ #  # ]
    3331         [ #  # ]:          0 :       CubitPoint* pt = cubit_points.next( pt_index );
    3332         [ #  # ]:          0 :       CubitPointData* ptd = dynamic_cast<CubitPointData*>(pt);
    3333         [ #  # ]:          0 :       assert(!!ptd);
    3334         [ #  # ]:          0 :       polyline_points.append(ptd);
    3335                 :            :     }
    3336                 :            :   }  
    3337                 :            :   
    3338                 :            : 
    3339         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    3340                 :            : }
    3341                 :            :   
    3342                 :            : //-------------------------------------------------------------------------
    3343                 :            : // Purpose       : Create a point-curve
    3344                 :            : //
    3345                 :            : // Special Notes : 
    3346                 :            : //
    3347                 :            : // Creator       : Jason Kraftcheck
    3348                 :            : //
    3349                 :            : // Creation Date : 02/23/03
    3350                 :            : //-------------------------------------------------------------------------
    3351                 :          0 : TBPoint* PartitionEngine::insert_point_curve( Surface* surf,
    3352                 :            :                                             const CubitVector& position,
    3353                 :            :                                             Surface *&partitioned_surf )
    3354                 :            : {
    3355 [ #  # ][ #  # ]:          0 :   if ( CompositeSurface* csurf = dynamic_cast<CompositeSurface*>(surf) )
    3356                 :            :   { 
    3357                 :            :     TBPoint* result = 
    3358                 :          0 :       CompositeEngine::instance().insert_point_curve(csurf, position); 
    3359                 :          0 :     partitioned_surf = csurf;
    3360                 :          0 :     return result;
    3361                 :            :   }
    3362                 :            :   
    3363                 :          0 :   bool replaced_surface = false;
    3364         [ #  # ]:          0 :   PartitionSurface* psurf = dynamic_cast<PartitionSurface*>(surf);
    3365         [ #  # ]:          0 :   if ( ! psurf ) {
    3366                 :          0 :     psurf = replace_surface(surf);
    3367                 :          0 :     replaced_surface = true;
    3368         [ #  # ]:          0 :     if ( ! psurf ) return 0;
    3369                 :            :   }
    3370                 :            :   
    3371                 :          0 :   CubitPointData* facet_point = project_to_surface( psurf, position );
    3372         [ #  # ]:          0 :   if ( !facet_point ) {
    3373         [ #  # ]:          0 :     if( replaced_surface )
    3374         [ #  # ]:          0 :       restore_surface( dynamic_cast<SubSurface*>(psurf) );
    3375                 :          0 :     partitioned_surf = NULL;
    3376                 :          0 :     return 0;
    3377                 :            :   }
    3378                 :            :   
    3379                 :          0 :   PartitionPoint* result = insert_point_curve( psurf, facet_point );
    3380         [ #  # ]:          0 :   if ( !result ) {
    3381         [ #  # ]:          0 :     if( replaced_surface )
    3382         [ #  # ]:          0 :       restore_surface( dynamic_cast<SubSurface*>(psurf) );
    3383                 :          0 :     return 0;
    3384                 :            :   }
    3385                 :            :   
    3386                 :          0 :   PartitionCurve* curve = result->next_curve(0);
    3387 [ #  # ][ #  # ]:          0 :   if (replaced_surface && !dynamic_cast<PartPTCurve*>(curve))
         [ #  # ][ #  # ]
    3388                 :            :   {
    3389                 :          0 :     TBPoint* real = result->real_point();
    3390         [ #  # ]:          0 :     partitioned_surf = restore_surface( dynamic_cast<SubSurface*>(psurf) );
    3391         [ #  # ]:          0 :     if (real)
    3392                 :            :     {
    3393         [ #  # ]:          0 :       result = dynamic_cast<PartitionPoint*>(real->owner());
    3394         [ #  # ]:          0 :       return result ? result : real;
    3395                 :            :     }
    3396                 :            :   }
    3397                 :            :   else 
    3398                 :          0 :     partitioned_surf = psurf; 
    3399                 :            : 
    3400                 :          0 :   return result;
    3401                 :            : }
    3402                 :            : 
    3403                 :            : 
    3404                 :            : 
    3405                 :            : //-------------------------------------------------------------------------
    3406                 :            : // Purpose       : Create point-curve
    3407                 :            : //
    3408                 :            : // Special Notes : 
    3409                 :            : //
    3410                 :            : // Creator       : Jason Kraftcheck
    3411                 :            : //
    3412                 :            : // Creation Date : 02/23/03
    3413                 :            : //-------------------------------------------------------------------------
    3414                 :          0 : PartitionPoint* PartitionEngine::insert_point_curve( PartitionSurface* surf,
    3415                 :            :                                                      CubitPointData* point )
    3416                 :            : {
    3417                 :            :     // If imprint at existing vertex, just return that vertex
    3418 [ #  # ][ #  # ]:          0 :   if ( TDVGFacetOwner::get(point) )
    3419 [ #  # ][ #  # ]:          0 :     return dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(point));
    3420                 :            :   
    3421                 :            :     // Check if imprint point is on a curve of the surface
    3422         [ #  # ]:          0 :   DLIList<CubitFacetEdge*> edges;
    3423         [ #  # ]:          0 :   point->edges(edges);
    3424                 :          0 :   PartitionEntity* owner = 0;
    3425                 :          0 :   int owner_count = 0;
    3426                 :          0 :   int owner_edges = 0;
    3427 [ #  # ][ #  # ]:          0 :   while (edges.size())
    3428                 :            :   {
    3429 [ #  # ][ #  # ]:          0 :     if (PartitionEntity* ent = TDVGFacetOwner::get(edges.pop()))
                 [ #  # ]
    3430                 :            :     {
    3431         [ #  # ]:          0 :       if (owner != ent)
    3432                 :          0 :         owner_count++;
    3433                 :          0 :       owner = ent;
    3434                 :          0 :       owner_edges++;
    3435                 :            :     }
    3436                 :            :   }
    3437                 :            :   
    3438                 :            :     // If imprint is on curve, split the curve
    3439         [ #  # ]:          0 :   if (owner)
    3440                 :            :   {
    3441         [ #  # ]:          0 :     PartitionCurve* curve = dynamic_cast<PartitionCurve*>(owner);
    3442                 :            : 
    3443                 :            :       // check valid facet configuration.  should be only one
    3444                 :            :       // owner, and owner should own exactly two of the adjacent
    3445                 :            :       // edges.  And owner should be a partition curve.
    3446 [ #  # ][ #  # ]:          0 :     if (!curve || owner_count != 1 || owner_edges != 2)
                 [ #  # ]
    3447                 :            :     {
    3448 [ #  # ][ #  # ]:          0 :       PRINT_ERROR("Internal error at %s:%d\n  Invalid state.\n", __FILE__, __LINE__ );
         [ #  # ][ #  # ]
    3449                 :          0 :       assert(0);
    3450                 :            :       return NULL;
    3451                 :            :     }
    3452                 :            :     
    3453 [ #  # ][ #  # ]:          0 :     PartitionPoint* new_point = new PartitionPoint(point->coordinates(), curve);
         [ #  # ][ #  # ]
    3454         [ #  # ]:          0 :     new_point->facet_point(point);
    3455         [ #  # ]:          0 :     curve = insert_point( curve, new_point );
    3456         [ #  # ]:          0 :     if (!curve)
    3457                 :            :     {
    3458 [ #  # ][ #  # ]:          0 :       delete new_point;
    3459                 :          0 :       return 0;
    3460                 :            :     }
    3461                 :            :     
    3462                 :          0 :     return new_point;
    3463                 :            :   }
    3464                 :            :       
    3465                 :            :     // If here, point is in surface interior.  Create point-curve.
    3466 [ #  # ][ #  # ]:          0 :   PartitionPoint* new_point = new PartitionPoint( point->coordinates(), surf );
         [ #  # ][ #  # ]
    3467         [ #  # ]:          0 :   new_point->facet_point(point);
    3468 [ #  # ][ #  # ]:          0 :   PartPTCurve* new_curve = new PartPTCurve( surf );
    3469         [ #  # ]:          0 :   new_curve->start_point( new_point );
    3470         [ #  # ]:          0 :   new_curve->end_point( new_point );
    3471                 :            :   
    3472         [ #  # ]:          0 :   insert_point_curve( surf, new_curve );
    3473                 :            :   
    3474         [ #  # ]:          0 :   return new_point;
    3475                 :            : }
    3476                 :            : 
    3477                 :          0 : CubitStatus PartitionEngine::insert_point_curve( PartitionSurface* surf,
    3478                 :            :                                                  PartPTCurve* new_curve,
    3479                 :            :                                                  bool update_topology )
    3480                 :            : {
    3481         [ #  # ]:          0 :   PartitionCoEdge* new_coedge = new PartitionCoEdge( surf, CUBIT_FORWARD );
    3482                 :          0 :   new_curve->add( new_coedge );
    3483         [ #  # ]:          0 :   PartitionLoop* new_loop = new PartitionLoop();
    3484                 :          0 :   new_loop->insert_after( new_coedge, 0 );
    3485                 :            :   
    3486                 :          0 :   surf->add( new_loop );
    3487 [ #  # ][ #  # ]:          0 :   if ( surf->owner() && update_topology )
                 [ #  # ]
    3488                 :          0 :     surf->owner()->notify_topology_modified(surf);
    3489                 :          0 :   return CUBIT_SUCCESS;
    3490                 :            : }
    3491                 :            :   
    3492                 :            : 
    3493                 :            : 
    3494                 :            : //-------------------------------------------------------------------------
    3495                 :            : // Purpose       : Construct surface for volume partitioning
    3496                 :            : //
    3497                 :            : // Special Notes : 
    3498                 :            : //
    3499                 :            : // Creator       : Jason Kraftcheck
    3500                 :            : //
    3501                 :            : // Creation Date : 01/13/03
    3502                 :            : //-------------------------------------------------------------------------
    3503                 :          0 : Lump* PartitionEngine::insert_surface( Surface* surface, Lump* lump)
    3504                 :            : {
    3505         [ #  # ]:          0 :   GMem gmem;
    3506                 :            :   int i;
    3507         [ #  # ]:          0 :   CubitStatus status = surface->get_geometry_query_engine()->
    3508         [ #  # ]:          0 :     get_graphics( surface, &gmem );
    3509                 :            :   
    3510         [ #  # ]:          0 :   if( !status )
    3511                 :            :   {
    3512 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("PartitionEngine::insert_surface: GeometryEngine::"
                 [ #  # ]
    3513         [ #  # ]:          0 :                 "get_graphics failed for surface.\n");
    3514                 :          0 :     return 0;
    3515                 :            :   }
    3516                 :            : 
    3517                 :          0 :   int num_pts = gmem.pointListCount;
    3518                 :            :   
    3519 [ #  # ][ #  # ]:          0 :   CubitPointData** ptarray = new CubitPointData*[num_pts];
    3520         [ #  # ]:          0 :   GPoint *p_itor = gmem.point_list();
    3521                 :          0 :   GPoint *p_end = p_itor + num_pts;
    3522                 :          0 :   CubitPointData** array_itor = ptarray;
    3523         [ #  # ]:          0 :   for( ; p_itor < p_end; p_itor++, array_itor++ )
    3524 [ #  # ][ #  # ]:          0 :     *array_itor = new CubitPointData(CubitVector(p_itor->x,p_itor->y,p_itor->z));
                 [ #  # ]
    3525                 :            :   
    3526 [ #  # ][ #  # ]:          0 :   DLIList<CubitFacetData*> facets;
    3527         [ #  # ]:          0 :   int* f_itor = gmem.facet_list();
    3528                 :          0 :   int* f_end = f_itor + gmem.fListCount;
    3529                 :          0 :   i = 0;
    3530         [ #  # ]:          0 :   for( ; f_itor < f_end ; f_itor += (1 + *f_itor) )
    3531                 :            :   {
    3532         [ #  # ]:          0 :     if( *f_itor != 3 )
    3533 [ #  # ][ #  # ]:          0 :       PRINT_ERROR("Non-triangular facet in PartitionEngine::insert_surface\n");
         [ #  # ][ #  # ]
    3534                 :            :     else
    3535                 :          0 :       facets.append( new CubitFacetData(ptarray[f_itor[1]],
    3536                 :          0 :                                         ptarray[f_itor[2]],
    3537 [ #  # ][ #  # ]:          0 :                                         ptarray[f_itor[3]], &i) );
                 [ #  # ]
    3538                 :            :   }
    3539                 :            :     
    3540                 :            :     // clean up any unused points
    3541         [ #  # ]:          0 :   for( i = 0; i < num_pts; i++ )
    3542 [ #  # ][ #  # ]:          0 :     if( ptarray[i]->num_adj_facets() == 0 )
    3543 [ #  # ][ #  # ]:          0 :       delete ptarray[i];
    3544         [ #  # ]:          0 :   delete [] ptarray;
    3545                 :            :   
    3546                 :            :   
    3547                 :            :     // create partition lump
    3548                 :          0 :   bool created_lump = false;
    3549         [ #  # ]:          0 :   PartitionLump* partlump = dynamic_cast<PartitionLump*>(lump);
    3550         [ #  # ]:          0 :   if( !partlump )
    3551                 :            :   {
    3552                 :          0 :     created_lump = true;
    3553         [ #  # ]:          0 :     partlump = replace_lump(lump);
    3554         [ #  # ]:          0 :     assert(partlump != NULL);
    3555                 :            :   }
    3556                 :            :   
    3557                 :            :     // Get vertex locations
    3558 [ #  # ][ #  # ]:          0 :   DLIList<CubitVector> coords;
    3559 [ #  # ][ #  # ]:          0 :   DLIList<TopologyBridge*> loops, coedges, curves, points, all_points;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3560         [ #  # ]:          0 :   surface->get_children_virt(loops);
    3561 [ #  # ][ #  # ]:          0 :   while( loops.size() )
    3562                 :            :   {
    3563 [ #  # ][ #  # ]:          0 :     loops.pop()->get_children( coedges, true, layer() - 1 );
                 [ #  # ]
    3564 [ #  # ][ #  # ]:          0 :     while ( coedges.size() )
    3565                 :            :     {
    3566 [ #  # ][ #  # ]:          0 :       coedges.pop()->get_children_virt(curves);
    3567 [ #  # ][ #  # ]:          0 :       assert(curves.size() == 1);
    3568         [ #  # ]:          0 :       TopologyBridge* curve = curves.pop();
    3569 [ #  # ][ #  # ]:          0 :       curve->get_children( points, true, layer() - 1 );
    3570 [ #  # ][ #  # ]:          0 :       assert ( points.size() < 3 );
    3571         [ #  # ]:          0 :       all_points.merge_unique( points );
    3572         [ #  # ]:          0 :       points.clean_out();
    3573                 :            :     }
    3574                 :            :   }
    3575 [ #  # ][ #  # ]:          0 :   while( all_points.size() )
    3576 [ #  # ][ #  # ]:          0 :     coords.append(CubitVector( dynamic_cast<TBPoint*>(all_points.pop())->coordinates() ) );
         [ #  # ][ #  # ]
    3577                 :            :   
    3578 [ #  # ][ #  # ]:          0 :   PartitionLumpImprint tool( partlump );
    3579 [ #  # ][ #  # ]:          0 :   DLIList<PartitionEntity*> new_entities;
    3580         [ #  # ]:          0 :   PartitionSurface* new_surf = tool.imprint( facets, coords, new_entities );
    3581         [ #  # ]:          0 :   if ( !new_surf )
    3582                 :            :   {
    3583 [ #  # ][ #  # ]:          0 :     if( created_lump ) restore_lump(partlump);
    3584                 :          0 :     return 0;
    3585                 :            :   }
    3586                 :            :   
    3587         [ #  # ]:          0 :   PartitionLump* result = insert_surface( partlump, new_surf );
    3588         [ #  # ]:          0 :   if( !result )
    3589                 :            :   {
    3590         [ #  # ]:          0 :     destroy_surface( new_surf );
    3591 [ #  # ][ #  # ]:          0 :     if( created_lump ) restore_lump( partlump );
    3592                 :          0 :     return 0;
    3593                 :            :   }
    3594                 :            : 
    3595         [ #  # ]:          0 :   return result;
    3596                 :            : }
    3597                 :            : 
    3598                 :          0 : Surface* PartitionEngine::insert_surface( DLIList<CubitFacet*>& facets, Lump* lump)
    3599                 :            : {
    3600                 :            :   
    3601                 :            :     // create partition lump and surface
    3602                 :          0 :   bool created_lump = false;
    3603         [ #  # ]:          0 :   PartitionLump* partlump = dynamic_cast<PartitionLump*>(lump);
    3604         [ #  # ]:          0 :   if( !partlump )
    3605                 :            :   {
    3606                 :          0 :     created_lump = true;
    3607         [ #  # ]:          0 :     partlump = replace_lump(lump);
    3608         [ #  # ]:          0 :     if (!partlump)
    3609                 :          0 :       return 0;
    3610                 :            :   }
    3611                 :            :   
    3612         [ #  # ]:          0 :   PartitionLumpImprint tool( partlump );
    3613 [ #  # ][ #  # ]:          0 :   DLIList<PartitionEntity*> new_list;
    3614         [ #  # ]:          0 :   PartitionSurface* new_surf = tool.imprint( facets, new_list );
    3615         [ #  # ]:          0 :   if ( !new_surf )
    3616                 :            :   {
    3617 [ #  # ][ #  # ]:          0 :     if( created_lump ) restore_lump(partlump);
    3618                 :          0 :     return 0;
    3619                 :            :   }
    3620                 :            :   
    3621         [ #  # ]:          0 :   PartitionLump* result = insert_surface( partlump, new_surf );
    3622         [ #  # ]:          0 :   if( !result )
    3623                 :            :   {
    3624         [ #  # ]:          0 :     destroy_surface( new_surf );
    3625 [ #  # ][ #  # ]:          0 :     if( created_lump ) restore_lump( partlump );
    3626                 :          0 :     return 0;
    3627                 :            :   }
    3628                 :            :   
    3629         [ #  # ]:          0 :   return new_surf;
    3630                 :            : }
    3631                 :            : 
    3632                 :            : 
    3633                 :            :   
    3634                 :            : //-------------------------------------------------------------------------
    3635                 :            : // Purpose       : Insert a surface into a volume
    3636                 :            : //
    3637                 :            : // Special Notes : 
    3638                 :            : //
    3639                 :            : // Creator       : Jason Kraftcheck
    3640                 :            : //
    3641                 :            : // Creation Date : 01/12/03
    3642                 :            : //-------------------------------------------------------------------------
    3643                 :          0 : PartitionLump* PartitionEngine::insert_surface( PartitionLump* lump, 
    3644                 :            :                                            PartitionSurface* surface )
    3645                 :            : {
    3646 [ #  # ][ #  # ]:          0 :   assert( &(lump->sub_entity_set()) == &(surface->sub_entity_set()) );
                 [ #  # ]
    3647                 :            :   
    3648                 :            :     // Find all affected shells.  If any curve is not part of an
    3649                 :            :     // existing shell in the volume, set all_curves_connected to
    3650                 :            :     // false.  If any curve does not intersect the volume, then
    3651                 :            :     // the volume does not need to be split into two (or the surface
    3652                 :            :     // forms a new void in the volume.)
    3653                 :          0 :   bool all_curves_connected = true;
    3654         [ #  # ]:          0 :   DLIList<PartitionShell*> modified_list;
    3655                 :          0 :   PartitionLoop* loop = 0;
    3656                 :            :   PartitionCoEdge *coedge, *curve_coedge;
    3657                 :            :   PartitionCurve* curve;
    3658                 :            :   PartitionShell* shell;
    3659                 :            :   PartitionCoSurf* cosurf;
    3660 [ #  # ][ #  # ]:          0 :   while( (loop = surface->next_loop(loop)) )
    3661                 :            :   {
    3662         [ #  # ]:          0 :     coedge = loop->first_coedge();
    3663         [ #  # ]:          0 :     do {
    3664         [ #  # ]:          0 :       curve = coedge->get_curve();
    3665                 :          0 :       curve_coedge = 0;
    3666                 :          0 :       shell = 0;
    3667 [ #  # ][ #  # ]:          0 :       while( (curve_coedge = curve->next_coedge(curve_coedge)) )
    3668                 :            :       {
    3669 [ #  # ][ #  # ]:          0 :         PartitionSurface* surf = curve_coedge->get_loop()->get_surface();
    3670                 :          0 :         cosurf = 0;
    3671 [ #  # ][ #  # ]:          0 :         while( (cosurf = surf->next_co_surface( cosurf )) )
    3672                 :            :         {
    3673 [ #  # ][ #  # ]:          0 :           if( cosurf->get_shell()->get_lump() == lump )
                 [ #  # ]
    3674                 :            :           {
    3675 [ #  # ][ #  # ]:          0 :             assert( !shell || cosurf->get_shell() == shell );
                 [ #  # ]
    3676         [ #  # ]:          0 :             shell = cosurf->get_shell();
    3677                 :            :           }
    3678                 :            :         }
    3679                 :            :       }
    3680                 :            :       
    3681         [ #  # ]:          0 :       if( shell )
    3682         [ #  # ]:          0 :         modified_list.append_unique(shell);
    3683                 :            :       else
    3684                 :          0 :         all_curves_connected = false;
    3685                 :            :       
    3686         [ #  # ]:          0 :       coedge = loop->next_coedge(coedge);
    3687         [ #  # ]:          0 :     } while( coedge != loop->first_coedge() );
    3688                 :            :   }
    3689                 :            : 
    3690                 :            :     // Construct CoSurfaces
    3691 [ #  # ][ #  # ]:          0 :   PartitionCoSurf* cosurf1 = new PartitionCoSurf(CUBIT_FORWARD);
    3692 [ #  # ][ #  # ]:          0 :   PartitionCoSurf* cosurf2 = new PartitionCoSurf(CUBIT_REVERSED);
    3693         [ #  # ]:          0 :   surface->add(cosurf1);
    3694         [ #  # ]:          0 :   surface->add(cosurf2);
    3695                 :            :   
    3696                 :            :     // If there were no affected shells, we need to make a new
    3697                 :            :     // shell for a possible void in the volume.
    3698                 :          0 :   PartitionShell* shell_to_split = 0;
    3699 [ #  # ][ #  # ]:          0 :   if( modified_list.size() == 0 )
    3700                 :            :   {
    3701 [ #  # ][ #  # ]:          0 :     shell_to_split = new PartitionShell();
    3702         [ #  # ]:          0 :     lump->add(shell_to_split);
    3703                 :            :     
    3704                 :            :       // If surface is closed, set all_curves_connected
    3705                 :            :       // to true to indicate that volume needs to be split.
    3706                 :            :       // (Creating a one-surface void in the volume.)
    3707                 :          0 :     loop = 0;
    3708                 :          0 :     all_curves_connected = true;
    3709 [ #  # ][ #  # ]:          0 :     while( (loop = surface->next_loop(loop)) )
    3710                 :            :     {
    3711         [ #  # ]:          0 :       coedge = loop->first_coedge();
    3712         [ #  # ]:          0 :       do
    3713                 :            :       {
    3714         [ #  # ]:          0 :         curve = coedge->get_curve();
    3715                 :          0 :         curve_coedge = 0;
    3716                 :          0 :         int coedge_count = 0;
    3717 [ #  # ][ #  # ]:          0 :         while( (curve_coedge = curve->next_coedge(curve_coedge)) )
    3718                 :            :         {
    3719 [ #  # ][ #  # ]:          0 :           if( curve_coedge->get_loop() == loop )
    3720                 :          0 :             coedge_count++;
    3721                 :            :           else 
    3722 [ #  # ][ #  # ]:          0 :             assert(curve_coedge->get_loop()->get_surface() != surface);
                 [ #  # ]
    3723                 :            :         }
    3724                 :            :     
    3725         [ #  # ]:          0 :         if( coedge_count == 1 )
    3726                 :          0 :           all_curves_connected = false;
    3727                 :            :         else
    3728         [ #  # ]:          0 :           assert(coedge_count == 2);
    3729                 :            :       
    3730         [ #  # ]:          0 :         coedge = loop->next_coedge(coedge);
    3731         [ #  # ]:          0 :       } while( coedge != loop->first_coedge() );
    3732                 :            :     }
    3733                 :            :   }
    3734                 :            :   
    3735                 :            :     // Otherwise combine all the affected shells
    3736                 :            :   else
    3737                 :            :   {
    3738         [ #  # ]:          0 :     modified_list.reverse();
    3739         [ #  # ]:          0 :     shell_to_split = modified_list.pop();
    3740 [ #  # ][ #  # ]:          0 :     while( modified_list.size() )
    3741                 :            :     {
    3742         [ #  # ]:          0 :       shell = modified_list.pop();
    3743 [ #  # ][ #  # ]:          0 :       while( PartitionCoSurf* cosurf = shell->next_co_surface() )
    3744                 :            :       {
    3745         [ #  # ]:          0 :         shell->remove(cosurf);
    3746         [ #  # ]:          0 :         shell_to_split->add(cosurf);
    3747                 :            :       }
    3748         [ #  # ]:          0 :       lump->remove(shell);
    3749 [ #  # ][ #  # ]:          0 :       delete shell;
    3750                 :          0 :     }
    3751                 :            :   }
    3752                 :            :   
    3753         [ #  # ]:          0 :   shell_to_split->add(cosurf1);
    3754         [ #  # ]:          0 :   shell_to_split->add(cosurf2);
    3755                 :            :   
    3756                 :            :     // If we don't need to split the volume, we are done
    3757         [ #  # ]:          0 :   if( !all_curves_connected )
    3758                 :          0 :     return lump;
    3759                 :            :     // We probably need to split the the lump...
    3760                 :            :   else    
    3761 [ #  # ][ #  # ]:          0 :     return split_lump( shell_to_split );
    3762                 :            : }
    3763                 :            : 
    3764                 :            : //-------------------------------------------------------------------------
    3765                 :            : // Purpose       : Test if a PartitionShell needs to be split, and
    3766                 :            : //                 if so partition the shell and owning lump
    3767                 :            : //
    3768                 :            : // Special Notes : 
    3769                 :            : //
    3770                 :            : // Creator       : Jason Kraftcheck
    3771                 :            : //
    3772                 :            : // Creation Date : 01/13/03
    3773                 :            : //-------------------------------------------------------------------------
    3774                 :          0 : PartitionLump* PartitionEngine::split_lump( PartitionShell* shell_to_split )
    3775                 :            : {
    3776                 :            :     // Split shell
    3777                 :          0 :   PartitionShell* new_shell = split_shell(shell_to_split);
    3778         [ #  # ]:          0 :   if( !new_shell )
    3779                 :            :   {
    3780                 :            :       // shell did not need to be split
    3781                 :          0 :     return shell_to_split->get_lump();
    3782                 :            :   }
    3783                 :            :    
    3784                 :            :     // Create the new lump and shell
    3785         [ #  # ]:          0 :   PartitionLump* new_lump = new PartitionLump( shell_to_split->get_lump() );
    3786                 :          0 :   new_lump->add( new_shell );
    3787                 :            :   
    3788                 :            :     // Check for any remaining shells that need to be moved
    3789                 :            :     // from the old lump to the new lump.
    3790                 :          0 :   PartitionShell* shell = 0;
    3791                 :          0 :   PartitionLump* lump = shell_to_split->get_lump();
    3792         [ #  # ]:          0 :   while( (shell = lump->next_shell(shell)) )
    3793                 :            :   {
    3794         [ #  # ]:          0 :     if( shell == shell_to_split )
    3795                 :          0 :       continue;
    3796                 :            :     
    3797                 :          0 :     bool some_contained = false;
    3798                 :          0 :     bool all_contained = true;
    3799                 :          0 :     bool all_tested = true;
    3800                 :          0 :     PartitionCoSurf* cosurf = 0;
    3801         [ #  # ]:          0 :     while( (cosurf = shell->next_co_surface(cosurf)) )
    3802                 :            :     {
    3803         [ #  # ]:          0 :       PartitionSurface* surf = cosurf->get_surface();
    3804 [ #  # ][ #  # ]:          0 :       CubitVector pt, tmp = surf->bounding_box().center();
         [ #  # ][ #  # ]
    3805 [ #  # ][ #  # ]:          0 :       surf->closest_point_trimmed( tmp, pt );
    3806         [ #  # ]:          0 :       switch( new_shell->point_containment(pt) )
              [ #  #  # ]
    3807                 :            :       {
    3808                 :            :         case CUBIT_PNT_INSIDE:
    3809                 :          0 :           some_contained = true;
    3810                 :          0 :           break;
    3811                 :            :         case CUBIT_PNT_OUTSIDE:
    3812                 :          0 :           all_contained = false;
    3813                 :          0 :          break;
    3814                 :            :         default:
    3815                 :          0 :           all_tested = false;
    3816                 :          0 :           break;
    3817                 :            :       }
    3818                 :            :     }
    3819                 :            :     
    3820                 :            :     
    3821 [ #  # ][ #  # ]:          0 :     if( !all_tested || (some_contained && !all_contained) )
                 [ #  # ]
    3822                 :            :     {
    3823         [ #  # ]:          0 :       PRINT_ERROR("Error splitting volume.  Could not determine\n"
    3824                 :            :                   "which volume shell belongs in.  Geometry may be\n"
    3825         [ #  # ]:          0 :                   "invalid.\n");
    3826                 :            :     }
    3827                 :            :     
    3828 [ #  # ][ #  # ]:          0 :     if(some_contained && all_contained)
    3829                 :            :     {
    3830                 :          0 :       lump->remove(shell);
    3831                 :          0 :       new_lump->add(shell);
    3832                 :            :     }
    3833                 :            :   }
    3834                 :            :   
    3835                 :          0 :   return new_lump;
    3836                 :            : }
    3837                 :            : 
    3838                 :            : /*
    3839                 :            : #include "GfxDebug.hpp"
    3840                 :            : static void draw_curve( PartitionCurve* curve, int color, bool flush = true )
    3841                 :            : {
    3842                 :            :   GMem graphics;
    3843                 :            :   int i;
    3844                 :            :   curve->get_geometry_query_engine()->get_graphics( curve, i, &graphics );
    3845                 :            :   GfxDebug::draw_polyline(graphics.point_list(),
    3846                 :            :                                           graphics.pointListCount,
    3847                 :            :                                           color);
    3848                 :            :   if(flush) GfxDebug::flush();
    3849                 :            : }
    3850                 :            : 
    3851                 :            : static void draw_surface( PartitionSurface* surface, int color, bool flush = true )
    3852                 :            : {
    3853                 :            : //  RefEntity* re = dynamic_cast<RefEntity*>(surface->owner());
    3854                 :            : //  if( re )
    3855                 :            : //    GfxDebug::draw_ref_entity( re, color, true, false );
    3856                 :            : //  else 
    3857                 :            :   for( PartitionLoop* loop = 0; loop = surface->next_loop(loop); )
    3858                 :            :   {
    3859                 :            :     PartitionCoEdge* coe = loop->first_coedge();
    3860                 :            :     do {
    3861                 :            :       draw_curve(coe->get_curve(), color, false);
    3862                 :            :       coe = loop->next_coedge(coe);
    3863                 :            :     } while(coe != loop->first_coedge());
    3864                 :            :   }
    3865                 :            :   if(flush) GfxDebug::flush();
    3866                 :            : }
    3867                 :            : 
    3868                 :            : static void draw_cosurface( PartitionCoSurf* cosurf, int color, bool flush = true )
    3869                 :            : {
    3870                 :            :   //draw_surface(cosurf->get_surface(), color, false);
    3871                 :            :   CubitVector p, n;
    3872                 :            :   n = cosurf->get_surface()->bounding_box().center();
    3873                 :            :   cosurf->get_surface()->closest_point_trimmed( n, p );
    3874                 :            :   cosurf->get_surface()->closest_point( p, 0, &n );
    3875                 :            :   double l = cosurf->get_surface()->bounding_box().diagonal().length() * 0.1;
    3876                 :            :   n.length(l);
    3877                 :            :   if(cosurf->sense() == CUBIT_REVERSED)
    3878                 :            :     n *= -1.0;
    3879                 :            :     GfxDebug::draw_vector(p, p+n, color);
    3880                 :            :   if(flush) GfxDebug::flush();
    3881                 :            : }
    3882                 :            : */
    3883                 :            : 
    3884                 :            : //-------------------------------------------------------------------------
    3885                 :            : // Purpose       : Test if a PartitionShell needs to be split, and
    3886                 :            : //                 split it
    3887                 :            : //
    3888                 :            : // Special Notes : 
    3889                 :            : //
    3890                 :            : // Creator       : Jason Kraftcheck
    3891                 :            : //
    3892                 :            : // Creation Date : 01/13/03
    3893                 :            : //-------------------------------------------------------------------------
    3894                 :          0 : PartitionShell* PartitionEngine::split_shell( PartitionShell* shell_to_split )
    3895                 :            : {
    3896                 :            :     // Make sure all cosurface surface marks are cleared
    3897                 :          0 :   PartitionCoSurf* cosurf = 0;
    3898 [ #  # ][ #  # ]:          0 :   while( (cosurf = shell_to_split->next_co_surface( cosurf )) )
    3899                 :            :   {
    3900                 :          0 :     cosurf->mark = 0;
    3901         [ #  # ]:          0 :     cosurf->get_surface()->mark = 0;
    3902                 :            :   }
    3903                 :            :   
    3904                 :            :     // Identify non-manifold surfaces, marking them either
    3905                 :            :     // with a 2 if they can be used to split the volume
    3906                 :            :     // (if they are part of a connected patch for which the
    3907                 :            :     // bounadary of that patch intersects the volume boundary
    3908                 :            :     // at all curves) or a 3 if they are other non-manifold
    3909                 :            :     // surfaces.  This will get a bit tricky if there are
    3910                 :            :     // non-manifold surfaces hanging off of the patch of
    3911                 :            :     // split surfaces.
    3912                 :            :   
    3913                 :            :     // First for all non-manifold surfaces, if the surface has
    3914                 :            :     // a curve that is not shared with any other surface, mark
    3915                 :            :     // it with a 3.  Otherwise mark it with a 2.
    3916                 :          0 :   cosurf = 0;
    3917         [ #  # ]:          0 :   DLIList<PartitionSurface*> surf_stack;
    3918 [ #  # ][ #  # ]:          0 :   while ( (cosurf = shell_to_split->next_co_surface(cosurf)) )
    3919                 :            :   {
    3920         [ #  # ]:          0 :     PartitionSurface* surf = cosurf->get_surface();
    3921                 :            :       // If we haven't done this surface yet and it is non-manifold
    3922 [ #  # ][ #  # ]:          0 :     if ( !surf->mark && surf->find_next(cosurf) )
         [ #  # ][ #  # ]
    3923                 :            :     {
    3924                 :          0 :       surf->mark = 2;
    3925                 :          0 :       bool no_free_curve = true;
    3926                 :          0 :       PartitionLoop* loop = 0;
    3927 [ #  # ][ #  # ]:          0 :       while( no_free_curve && (loop = surf->next_loop(loop)) ) 
         [ #  # ][ #  # ]
    3928                 :            :       {
    3929         [ #  # ]:          0 :         PartitionCoEdge* coedge = loop->first_coedge();
    3930         [ #  # ]:          0 :         do 
    3931                 :            :         {
    3932         [ #  # ]:          0 :           PartitionCurve* curve = coedge->get_curve();
    3933                 :            :             // If the curve has more than one coedge, it 
    3934                 :            :             // is not a free curve (this also accounts for
    3935                 :            :             // the case where the curve is a non-manifold 
    3936                 :            :             // curve on the surface interioir -- e.g. a sipe)
    3937 [ #  # ][ #  # ]:          0 :           if ( !curve->next_coedge(coedge) && 
         [ #  # ][ #  # ]
    3938         [ #  # ]:          0 :                curve->next_coedge(0) == coedge )
    3939                 :            :           {
    3940                 :          0 :             no_free_curve = false;
    3941                 :          0 :             break;
    3942                 :            :           }
    3943         [ #  # ]:          0 :           coedge = loop->next_coedge(coedge);
    3944         [ #  # ]:          0 :         } while( coedge != loop->first_coedge() );
    3945                 :            :       }
    3946                 :            :       
    3947         [ #  # ]:          0 :       if( !no_free_curve )
    3948                 :            :       {
    3949                 :          0 :         surf->mark = 3;
    3950         [ #  # ]:          0 :         surf_stack.append( surf );
    3951                 :            :       }
    3952                 :            :     }
    3953                 :            :   }
    3954                 :            :   
    3955                 :            :     // Now for each surface we marked with a three, traverse
    3956                 :            :     // and mark adjacent surfaces until we come to a curve
    3957                 :            :     // connected to more that two surfaces.
    3958 [ #  # ][ #  # ]:          0 :   while( surf_stack.size() ) 
    3959                 :            :   {
    3960         [ #  # ]:          0 :     PartitionSurface* surf = surf_stack.pop();
    3961                 :          0 :     PartitionLoop* loop = 0;
    3962 [ #  # ][ #  # ]:          0 :     while ( (loop = surf->next_loop(loop)) )
    3963                 :            :     {
    3964         [ #  # ]:          0 :       PartitionCoEdge* coedge = loop->first_coedge();
    3965         [ #  # ]:          0 :       do 
    3966                 :            :       {
    3967         [ #  # ]:          0 :         PartitionCurve* curve = coedge->get_curve();
    3968                 :          0 :         int split_count = 0;
    3969                 :          0 :         int boundary_count = 0;
    3970                 :          0 :         PartitionCoEdge* curve_coe = 0;
    3971 [ #  # ][ #  # ]:          0 :         while ( (curve_coe = curve->next_coedge(curve_coe) ) != NULL )
    3972                 :            :         {
    3973 [ #  # ][ #  # ]:          0 :           PartitionSurface* curve_surf = curve_coe->get_loop()->get_surface();
    3974      [ #  #  # ]:          0 :           switch ( curve_surf->mark ) 
    3975                 :            :           {
    3976                 :          0 :             case 0: boundary_count++; break;
    3977                 :          0 :             case 2: split_count++;    break;
    3978                 :            :           }
    3979                 :            :         }
    3980                 :            :         
    3981 [ #  # ][ #  # ]:          0 :         if ( split_count == 1 && !boundary_count )
    3982                 :            :         {
    3983                 :          0 :           curve_coe = 0;
    3984 [ #  # ][ #  # ]:          0 :           while ( (curve_coe = curve->next_coedge(curve_coe) ) != NULL )
    3985                 :            :           {
    3986 [ #  # ][ #  # ]:          0 :             PartitionSurface* curve_surf = curve_coe->get_loop()->get_surface();
    3987         [ #  # ]:          0 :             if ( curve_surf->mark == 2 )
    3988                 :            :             {
    3989                 :          0 :               curve_surf->mark = 3;
    3990         [ #  # ]:          0 :               surf_stack.append(curve_surf);
    3991                 :            :             }
    3992                 :            :           }
    3993                 :            :         }
    3994                 :            :         
    3995         [ #  # ]:          0 :         coedge = loop->next_coedge( coedge );
    3996         [ #  # ]:          0 :       } while( coedge != loop->first_coedge() );
    3997                 :            :     }
    3998                 :            :   }
    3999                 :            :   
    4000                 :            :     // Now build a new shell by traversing cofaces, marking
    4001                 :            :     // each with that will go in a new shell with a 1.
    4002                 :            :   
    4003                 :            :     // Start with any cosurf that does not have a free
    4004                 :            :     // non-manifold surface (marked with a 3).  We'll handle
    4005                 :            :     // free non-manifold surfaces later.
    4006         [ #  # ]:          0 :   DLIList<PartitionCoSurf*> cosurf_stack;
    4007                 :          0 :   cosurf = 0;
    4008 [ #  # ][ #  # ]:          0 :   while ( (cosurf = shell_to_split->next_co_surface(cosurf)) )
    4009 [ #  # ][ #  # ]:          0 :     if ( cosurf->get_surface()->mark != 3 )
    4010                 :          0 :       break;
    4011         [ #  # ]:          0 :   if ( cosurf )
    4012                 :            :   {
    4013                 :          0 :     cosurf->mark = 1;
    4014         [ #  # ]:          0 :     cosurf_stack.append( cosurf );
    4015                 :            :   }
    4016                 :            :   
    4017                 :            :     // Traverse over adjacent cosurfaces, marking them with a 1
    4018 [ #  # ][ #  # ]:          0 :   while (cosurf_stack.size())
    4019                 :            :   {
    4020         [ #  # ]:          0 :     cosurf = cosurf_stack.pop();
    4021         [ #  # ]:          0 :     PartitionSurface* surf = cosurf->get_surface();
    4022                 :          0 :     PartitionLoop* loop = 0;
    4023 [ #  # ][ #  # ]:          0 :     while ( (loop = surf->next_loop(loop)) )
    4024                 :            :     {
    4025         [ #  # ]:          0 :       PartitionCoEdge* coedge = loop->first_coedge();
    4026         [ #  # ]:          0 :       do
    4027                 :            :       {
    4028         [ #  # ]:          0 :         PartitionCurve* curve = coedge->get_curve();
    4029                 :          0 :         PartitionCoEdge* curve_coe = 0;
    4030                 :          0 :         PartitionCoSurf *boundary_cosurf = 0, *split_cosurf = 0;
    4031                 :          0 :         int split_cosurf_count = 0;
    4032 [ #  # ][ #  # ]:          0 :         while ( (curve_coe = curve->next_coedge(curve_coe)) )
    4033                 :            :         {
    4034         [ #  # ]:          0 :           if ( curve_coe == coedge )
    4035                 :          0 :             continue;
    4036                 :            :           
    4037 [ #  # ][ #  # ]:          0 :           bool same_coe_sense = curve_coe->sense() == coedge->sense();
    4038 [ #  # ][ #  # ]:          0 :           PartitionSurface* curve_surf = curve_coe->get_loop()->get_surface();
    4039                 :          0 :           PartitionCoSurf* curve_cosurf = 0;
    4040 [ #  # ][ #  # ]:          0 :           while ( (curve_cosurf = curve_surf->next_co_surface(curve_cosurf)) )
    4041                 :            :           {
    4042 [ #  # ][ #  # ]:          0 :             if ( curve_cosurf->get_shell() != shell_to_split )
    4043                 :          0 :               continue;
    4044                 :            :             
    4045 [ #  # ][ #  # ]:          0 :             bool same_cos_sense = curve_cosurf->sense() == cosurf->sense();
    4046         [ #  # ]:          0 :             if ( same_cos_sense == same_coe_sense )
    4047                 :          0 :               continue;
    4048                 :            :             
    4049                 :            :               // Always choose split surface first if we
    4050                 :            :               // found one
    4051 [ #  # ][ #  # ]:          0 :             if ( curve_cosurf->get_surface()->mark == 2 ) {
    4052                 :          0 :               split_cosurf_count++;
    4053                 :          0 :               split_cosurf = curve_cosurf;
    4054                 :            :             }
    4055                 :            :             
    4056                 :            :               // Skip other non-manifold surfaces.  We'll
    4057                 :            :               // handle those later.
    4058 [ #  # ][ #  # ]:          0 :             else if( curve_cosurf->get_surface()->mark != 3 )
    4059                 :          0 :               boundary_cosurf = curve_cosurf;
    4060                 :            :           }
    4061                 :            :         }
    4062                 :            :         
    4063         [ #  # ]:          0 :         PartitionCoSurf* next_cosurf = split_cosurf ? split_cosurf : boundary_cosurf;
    4064 [ #  # ][ #  # ]:          0 :         if ( !next_cosurf->mark && split_cosurf_count < 2 )
    4065                 :            :         {
    4066                 :          0 :           next_cosurf->mark = 1;
    4067         [ #  # ]:          0 :           cosurf_stack.append(next_cosurf);
    4068                 :            :         }
    4069                 :            :       
    4070         [ #  # ]:          0 :         coedge = loop->next_coedge(coedge);
    4071         [ #  # ]:          0 :       } while( coedge != loop->first_coedge() );
    4072                 :            :     } // end while (loop)
    4073                 :            :   } // end while (cosurf_stack.size())
    4074                 :            :     
    4075                 :            :   
    4076                 :            :     // build lists of cosurfaces, one for each shell and
    4077                 :            :     // one of other non-manifold surfaces
    4078 [ #  # ][ #  # ]:          0 :   DLIList<PartitionCoSurf*> marked_list, unmarked_list, other_list;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4079 [ #  # ][ #  # ]:          0 :   while( (cosurf = shell_to_split->next_co_surface(0)) )
    4080                 :            :   {
    4081         [ #  # ]:          0 :     shell_to_split->remove(cosurf);
    4082 [ #  # ][ #  # ]:          0 :     if ( cosurf->get_surface()->mark == 3 )
    4083         [ #  # ]:          0 :       other_list.append( cosurf );
    4084         [ #  # ]:          0 :     else if( cosurf->mark )
    4085         [ #  # ]:          0 :       marked_list.append( cosurf );
    4086                 :            :     else
    4087         [ #  # ]:          0 :       unmarked_list.append( cosurf );
    4088                 :            :   }
    4089                 :            :   
    4090                 :            :     // If one of marked_list or unmarked_list is empty,
    4091                 :            :     // we can't split the shell yet.  Put cofaces back in
    4092                 :            :     // shell and exit.
    4093 [ #  # ][ #  # ]:          0 :   if ( !marked_list.size() || !unmarked_list.size() )
         [ #  # ][ #  # ]
                 [ #  # ]
    4094                 :            :   {
    4095         [ #  # ]:          0 :     marked_list += unmarked_list;
    4096         [ #  # ]:          0 :     marked_list += other_list;
    4097         [ #  # ]:          0 :     marked_list.reverse();
    4098 [ #  # ][ #  # ]:          0 :     while ( marked_list.size() )
    4099                 :            :     {
    4100         [ #  # ]:          0 :       cosurf = marked_list.pop();
    4101                 :          0 :       cosurf->mark = 0;
    4102         [ #  # ]:          0 :       cosurf->get_surface()->mark = 0;
    4103         [ #  # ]:          0 :       shell_to_split->add( cosurf );
    4104                 :            :     }
    4105                 :          0 :     return 0;
    4106                 :            :   }
    4107                 :            :   
    4108                 :            :     // Put unmarked list back in old shell
    4109         [ #  # ]:          0 :   unmarked_list.reverse();
    4110 [ #  # ][ #  # ]:          0 :   while ( unmarked_list.size() )
    4111                 :            :   {
    4112         [ #  # ]:          0 :     cosurf = unmarked_list.pop();
    4113         [ #  # ]:          0 :     cosurf->get_surface()->mark = 0;
    4114         [ #  # ]:          0 :     shell_to_split->add(cosurf);
    4115                 :            :   }
    4116                 :            :   
    4117                 :            :     // Put marked list in new shell
    4118 [ #  # ][ #  # ]:          0 :   PartitionShell* new_shell = new PartitionShell;
    4119         [ #  # ]:          0 :   marked_list.reverse();
    4120 [ #  # ][ #  # ]:          0 :   while ( marked_list.size() )
    4121                 :            :   {
    4122         [ #  # ]:          0 :     cosurf = marked_list.pop();
    4123                 :          0 :     cosurf->mark = 0;
    4124         [ #  # ]:          0 :     cosurf->get_surface()->mark = 0;
    4125         [ #  # ]:          0 :     new_shell->add(cosurf);
    4126                 :            :   }
    4127                 :            :   
    4128                 :            :     // Now sort out other non-manifold surfaces
    4129                 :            :   
    4130                 :            :     // Clear marks and get list of surface from cosurfaces
    4131         [ #  # ]:          0 :   surf_stack.clean_out();
    4132 [ #  # ][ #  # ]:          0 :   while( other_list.size() )
    4133                 :            :   {
    4134         [ #  # ]:          0 :     cosurf = other_list.pop();
    4135         [ #  # ]:          0 :     PartitionSurface* surf = cosurf->get_surface();
    4136         [ #  # ]:          0 :     if ( surf->mark )
    4137                 :            :     {
    4138                 :          0 :       surf->mark = 0;
    4139         [ #  # ]:          0 :       surf_stack.append(surf);
    4140                 :            :     }
    4141                 :            :   }
    4142                 :            :   
    4143         [ #  # ]:          0 :   insert_nonmanifold_surfaces( surf_stack, shell_to_split, new_shell );
    4144 [ #  # ][ #  # ]:          0 :   return new_shell;
    4145                 :            : }
    4146                 :            :   
    4147                 :            :   
    4148                 :            : //-------------------------------------------------------------------------
    4149                 :            : // Purpose       : After a shell is split, determine which of the two
    4150                 :            : //                 resulting shells each non-manifold surface belongs in.
    4151                 :            : //
    4152                 :            : // Special Notes : 
    4153                 :            : //
    4154                 :            : // Creator       : Jason Kraftcheck
    4155                 :            : //
    4156                 :            : // Creation Date : 02/23/03
    4157                 :            : //-------------------------------------------------------------------------
    4158                 :          0 : void PartitionEngine::insert_nonmanifold_surfaces( 
    4159                 :            :                                    DLIList<PartitionSurface*>& surf_stack,
    4160                 :            :                                    PartitionShell* shell1,
    4161                 :            :                                    PartitionShell* shell2 )
    4162                 :            : {
    4163 [ #  # ][ #  # ]:          0 :   DLIList<PartitionSurface*> known_list(surf_stack.size()), 
    4164 [ #  # ][ #  # ]:          0 :                            unknown_list(surf_stack.size());
                 [ #  # ]
    4165                 :            :   
    4166                 :            :   PartitionCoSurf* cosurf;
    4167                 :            :   PartitionSurface* surf;
    4168                 :            :   PartitionLoop* loop;
    4169                 :            :   PartitionCoEdge *coedge, *curve_coe;
    4170                 :            :   PartitionCurve* curve;
    4171                 :            :   
    4172                 :            :     // Loop until we've placed all the surfaces in one
    4173                 :            :     // shell or the other.
    4174 [ #  # ][ #  # ]:          0 :   while ( surf_stack.size() )
    4175                 :            :   {
    4176                 :          0 :     bool did_some = false;
    4177                 :            :     
    4178                 :            :       // Put any surfaces for which we immediately
    4179                 :            :       // know the shell into the appropriate shell.
    4180                 :            :       // Put others in known_list or unknown_list
    4181                 :            :       // depending on if we can determine which shell
    4182                 :            :       // they go in using a geometric comparison.
    4183         [ #  # ]:          0 :     known_list.clean_out();
    4184         [ #  # ]:          0 :     unknown_list.clean_out();
    4185                 :            : 
    4186                 :            :       // Take all surfaces out of stack in this loop.
    4187                 :            :       // We might put some back in after the loop (thus
    4188                 :            :       // the outer loop.)
    4189 [ #  # ][ #  # ]:          0 :     while ( surf_stack.size() )
    4190                 :            :     {
    4191         [ #  # ]:          0 :       surf = surf_stack.pop();
    4192                 :            :       
    4193                 :          0 :       PartitionShell* known_shell = 0;
    4194                 :          0 :       bool found_shell = false;
    4195                 :          0 :       loop = 0;
    4196 [ #  # ][ #  # ]:          0 :       while ( (loop = surf->next_loop(loop)) )
    4197                 :            :       {
    4198         [ #  # ]:          0 :         coedge = loop->first_coedge();
    4199         [ #  # ]:          0 :         do
    4200                 :            :         {
    4201         [ #  # ]:          0 :           curve = coedge->get_curve();
    4202                 :          0 :           curve_coe = 0;
    4203 [ #  # ][ #  # ]:          0 :           while ( (curve_coe = curve->next_coedge(curve_coe)) )
    4204                 :            :           {
    4205 [ #  # ][ #  # ]:          0 :             PartitionSurface* surf = curve_coe->get_loop()->get_surface();
    4206                 :          0 :             cosurf = 0;
    4207 [ #  # ][ #  # ]:          0 :             while ( (cosurf = surf->next_co_surface( cosurf )) )
    4208                 :            :             {
    4209 [ #  # ][ #  # ]:          0 :               if( cosurf->get_shell() == shell1 ||
         [ #  # ][ #  # ]
    4210         [ #  # ]:          0 :                   cosurf->get_shell() == shell2 )
    4211                 :            :               {
    4212                 :          0 :                 found_shell = true;
    4213 [ #  # ][ #  # ]:          0 :                 if ( known_shell && known_shell != cosurf->get_shell() )
         [ #  # ][ #  # ]
    4214                 :          0 :                   known_shell = 0;
    4215                 :            :                 else
    4216         [ #  # ]:          0 :                   known_shell = cosurf->get_shell();
    4217                 :            :               }
    4218                 :            :             }
    4219                 :            :           }
    4220                 :            :         
    4221         [ #  # ]:          0 :           coedge = loop->next_coedge(coedge);
    4222         [ #  # ]:          0 :         } while( coedge != loop->first_coedge() );
    4223                 :            :       } // end while(loop)
    4224                 :            :         
    4225                 :            :         // This surface does not intersect the shell at
    4226                 :            :         // any curve.  We can't do this one yet.
    4227         [ #  # ]:          0 :       if ( !found_shell )
    4228                 :            :       {
    4229         [ #  # ]:          0 :         unknown_list.append( surf );
    4230                 :          0 :         continue;
    4231                 :            :       }
    4232                 :            :       
    4233                 :            :         // This surface intersected both shells at some
    4234                 :            :         // curves, but did not have a curve that intersected
    4235                 :            :         // only one shell.  We can do this one geometricly
    4236                 :            :         // if we have to.
    4237         [ #  # ]:          0 :       if ( !known_shell )
    4238                 :            :       {
    4239         [ #  # ]:          0 :         known_list.append( surf );
    4240                 :          0 :         continue;
    4241                 :            :       }
    4242                 :            :       
    4243                 :            :         // If we got this far, then the surface had at least
    4244                 :            :         // one curve that intersected only one of the shells.
    4245                 :            :         // We know it goes in that shell.
    4246                 :          0 :       did_some = true;
    4247         [ #  # ]:          0 :       PartitionCoSurf* cosurf1 = surf->find_first((PartitionShell*)0);
    4248         [ #  # ]:          0 :       PartitionCoSurf* cosurf2 = surf->find_next(cosurf1);
    4249         [ #  # ]:          0 :       known_shell->add(cosurf1);
    4250         [ #  # ]:          0 :       known_shell->add(cosurf2);
    4251                 :            :     
    4252                 :            :     } // while(surf_stack)  -- the inside one
    4253                 :            :     
    4254                 :            :       // Unknown_list always goes back in surf_stack to
    4255                 :            :       // try again.
    4256         [ #  # ]:          0 :     surf_stack += unknown_list;
    4257                 :            :     
    4258                 :            :       // If we did some surfaces, then put the rest back
    4259                 :            :       // in surf_stack and try again.  If they intersect
    4260                 :            :       // one of the surfaces we did place in this iteration,
    4261                 :            :       // we can avoid needing to do geometric checks.
    4262         [ #  # ]:          0 :     if ( did_some )
    4263                 :            :     {
    4264         [ #  # ]:          0 :       surf_stack += known_list;
    4265                 :          0 :       continue;
    4266                 :            :     }
    4267                 :            :     
    4268                 :            :       // If known_list is empty, somethings wrong (we're
    4269                 :            :       // going to loop forever.)  Abort the loop and try
    4270                 :            :       // to recover as best we can.
    4271 [ #  # ][ #  # ]:          0 :     if( !known_list.size() )
    4272                 :          0 :       break;
    4273                 :            :     
    4274                 :            :       // choose a single surface in do a geometric comparison
    4275                 :            :       // for, and put the rest back in surf_stack
    4276         [ #  # ]:          0 :     surf = known_list.pop();
    4277         [ #  # ]:          0 :     surf_stack += known_list;
    4278                 :            :     
    4279                 :          0 :     bool in_shell = false;
    4280 [ #  # ][ #  # ]:          0 :     if ( ! inside_shell( shell2, surf, in_shell ) )
    4281                 :            :     {
    4282                 :            :         // if inside_shell failed, abort.
    4283         [ #  # ]:          0 :       surf_stack.append(surf);
    4284                 :          0 :       break;
    4285                 :            :     }
    4286                 :            :     
    4287         [ #  # ]:          0 :     PartitionShell* shell = in_shell ? shell2 : shell1;
    4288 [ #  # ][ #  # ]:          0 :     shell->add(surf->find_first((PartitionShell*)0));
    4289 [ #  # ][ #  # ]:          0 :     shell->add(surf->find_first((PartitionShell*)0));
    4290                 :            :   }
    4291                 :            :   
    4292                 :            :     // something went wrong
    4293 [ #  # ][ #  # ]:          0 :   if( surf_stack.size() )
    4294                 :            :   {
    4295 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Internal error splitting volume at %s:%d\n"
                 [ #  # ]
    4296                 :            :                 "Topology may be invalid.  Please report this.\n",
    4297         [ #  # ]:          0 :                 __FILE__, __LINE__);
    4298 [ #  # ][ #  # ]:          0 :     while( surf_stack.size() ) 
    4299                 :            :     {
    4300         [ #  # ]:          0 :       PartitionSurface* surf = surf_stack.pop();
    4301                 :          0 :       cosurf = 0;
    4302 [ #  # ][ #  # ]:          0 :       while( (cosurf = surf->next_co_surface(cosurf)) )
    4303 [ #  # ][ #  # ]:          0 :         if( !cosurf->get_shell() )
    4304         [ #  # ]:          0 :           shell1->add(cosurf);
    4305                 :            :     }
    4306         [ #  # ]:          0 :   }
    4307                 :          0 : }
    4308                 :            : 
    4309                 :            : 
    4310                 :          0 : CubitStatus PartitionEngine::inside_shell( PartitionShell* const shell,
    4311                 :            :                                            PartitionSurface* const surf,
    4312                 :            :                                            bool& result )
    4313                 :            : {
    4314                 :            :     // Find the curve and coedge at which the nonmanifold surface
    4315                 :            :     // intersects the shells
    4316                 :          0 :   PartitionLoop* loop = 0;
    4317                 :          0 :   PartitionCoEdge *nonman_coedge = 0;
    4318 [ #  # ][ #  # ]:          0 :   while ( !nonman_coedge && (loop = surf->next_loop(loop)) )
         [ #  # ][ #  # ]
    4319                 :            :   {
    4320         [ #  # ]:          0 :     PartitionCoEdge* loop_coedge = loop->first_coedge();
    4321         [ #  # ]:          0 :     do 
    4322                 :            :     {
    4323                 :            :         // Check if this curve is the curve of intersection
    4324                 :            :         // Iterate through curve coedges.
    4325         [ #  # ]:          0 :       PartitionCurve* curve = loop_coedge->get_curve();
    4326                 :          0 :       PartitionCoEdge* curve_coedge = 0;
    4327 [ #  # ][ #  # ]:          0 :       while ( (curve_coedge = curve->next_coedge(curve_coedge)) )
    4328                 :            :       {
    4329                 :            :         
    4330 [ #  # ][ #  # ]:          0 :         PartitionSurface* coedge_surf = curve_coedge->get_loop()->get_surface();
    4331 [ #  # ][ #  # ]:          0 :         if( coedge_surf->find_first(shell) )
    4332                 :            :         {
    4333                 :          0 :           nonman_coedge = curve_coedge;
    4334                 :          0 :           break;
    4335                 :            :         }
    4336                 :            :       }
    4337                 :            :     
    4338         [ #  # ]:          0 :       loop_coedge = loop->next_coedge(loop_coedge);
    4339 [ #  # ][ #  # ]:          0 :     } while( !nonman_coedge && loop_coedge != loop->first_coedge() );
                 [ #  # ]
    4340                 :            :   }
    4341                 :            :   
    4342         [ #  # ]:          0 :   if ( !nonman_coedge ) // bad input!
    4343                 :          0 :     return CUBIT_FAILURE;
    4344                 :            : 
    4345                 :            :     // There must exist two surfaces in the shell that are manifold 
    4346                 :            :     // in the shell and that are adjacent to the curve
    4347         [ #  # ]:          0 :   PartitionCurve* common_curve = nonman_coedge->get_curve();
    4348                 :          0 :   PartitionCoSurf *cosurf1 = 0, *cosurf2 = 0, *cosurf;
    4349                 :          0 :   PartitionCoEdge *coedge1 = 0, *coedge2 = 0, *coedge = 0;
    4350 [ #  # ][ #  # ]:          0 :   while ( (coedge = common_curve->next_coedge(coedge)) )
    4351                 :            :   {
    4352 [ #  # ][ #  # ]:          0 :     PartitionSurface* surf = coedge->get_loop()->get_surface();
    4353 [ #  # ][ #  # ]:          0 :     if ( (cosurf = surf->find_first(shell)) && !surf->find_next(cosurf) )
         [ #  # ][ #  # ]
                 [ #  # ]
    4354                 :            :     {
    4355         [ #  # ]:          0 :       if( coedge1 ) {
    4356                 :          0 :         coedge2 = coedge;
    4357                 :          0 :         cosurf2 = cosurf;
    4358                 :            :       } else {
    4359                 :          0 :         coedge1 = coedge;
    4360                 :          0 :         cosurf1 = cosurf;
    4361                 :            :       }
    4362                 :            :     }
    4363                 :            :   }
    4364 [ #  # ][ #  # ]:          0 :   if ( !coedge1 || !coedge2 )
    4365                 :          0 :     return CUBIT_FAILURE;
    4366                 :            :   
    4367                 :            :     // Evaluate normals at midpoint of curve
    4368 [ #  # ][ #  # ]:          0 :   CubitVector base, tangent, point;
                 [ #  # ]
    4369 [ #  # ][ #  # ]:          0 :   double u = (common_curve->start_param()+common_curve->end_param())/2.0;
    4370         [ #  # ]:          0 :   common_curve->position_from_u( u, base );
    4371         [ #  # ]:          0 :   common_curve->closest_point( base, point, &tangent );
    4372         [ #  # ]:          0 :   tangent.normalize();
    4373                 :            :   
    4374 [ #  # ][ #  # ]:          0 :   CubitVector normal1, normal2, normal;
                 [ #  # ]
    4375         [ #  # ]:          0 :   surf->closest_point( base, 0, &normal );
    4376 [ #  # ][ #  # ]:          0 :   cosurf1->get_surface()->closest_point( base, 0, &normal1 );
    4377 [ #  # ][ #  # ]:          0 :   cosurf2->get_surface()->closest_point( base, 0, &normal2 );
    4378                 :            :   
    4379                 :            :     // Try to handle tangencies
    4380 [ #  # ][ #  # ]:          0 :   bool fix1 = (normal1 * normal).length_squared() < CUBIT_RESABS;
    4381 [ #  # ][ #  # ]:          0 :   bool fix2 = (normal2 * normal).length_squared() < CUBIT_RESABS;
    4382 [ #  # ][ #  # ]:          0 :   if ( fix1 || fix2 )
    4383                 :            :   {
    4384         [ #  # ]:          0 :     CubitVector dir = tangent * normal;
    4385         [ #  # ]:          0 :     double len = dir.length();
    4386         [ #  # ]:          0 :     assert(len > GEOMETRY_RESABS);
    4387         [ #  # ]:          0 :     dir /= len;
    4388 [ #  # ][ #  # ]:          0 :     if ( nonman_coedge->sense() == CUBIT_FORWARD )
    4389 [ #  # ][ #  # ]:          0 :       dir = -dir;
    4390                 :            :       
    4391 [ #  # ][ #  # ]:          0 :     CubitVector diag = surf->bounding_box().diagonal();
                 [ #  # ]
    4392         [ #  # ]:          0 :     if ( fix1 )
    4393                 :            :     {
    4394 [ #  # ][ #  # ]:          0 :       CubitVector d = cosurf1->get_surface()->bounding_box().diagonal();
         [ #  # ][ #  # ]
    4395 [ #  # ][ #  # ]:          0 :       if ( diag.x() < d.x() ) diag.x(d.x());
         [ #  # ][ #  # ]
                 [ #  # ]
    4396 [ #  # ][ #  # ]:          0 :       if ( diag.y() < d.y() ) diag.y(d.y());
         [ #  # ][ #  # ]
                 [ #  # ]
    4397 [ #  # ][ #  # ]:          0 :       if ( diag.z() < d.z() ) diag.z(d.z());
         [ #  # ][ #  # ]
                 [ #  # ]
    4398                 :            :     }
    4399         [ #  # ]:          0 :     if( fix2 )
    4400                 :            :     {
    4401 [ #  # ][ #  # ]:          0 :       CubitVector d = cosurf2->get_surface()->bounding_box().diagonal();
         [ #  # ][ #  # ]
    4402 [ #  # ][ #  # ]:          0 :       if ( diag.x() < d.x() ) diag.x(d.x());
         [ #  # ][ #  # ]
                 [ #  # ]
    4403 [ #  # ][ #  # ]:          0 :       if ( diag.y() < d.y() ) diag.y(d.y());
         [ #  # ][ #  # ]
                 [ #  # ]
    4404 [ #  # ][ #  # ]:          0 :       if ( diag.z() < d.z() ) diag.z(d.z());
         [ #  # ][ #  # ]
                 [ #  # ]
    4405                 :            :     }
    4406                 :            :     
    4407         [ #  # ]:          0 :     double step = 1e-3 * fabs( diag % dir );
    4408         [ #  # ]:          0 :     if ( step < 2*GEOMETRY_RESABS )
    4409                 :          0 :       step = 2*GEOMETRY_RESABS;
    4410                 :            :     
    4411         [ #  # ]:          0 :     for ( int i = 0; i < 1000; i++ )
    4412                 :            :     {
    4413 [ #  # ][ #  # ]:          0 :       point = base + i * step * dir;
                 [ #  # ]
    4414         [ #  # ]:          0 :       surf->closest_point( base, 0, &normal );
    4415         [ #  # ]:          0 :       if( fix1 )
    4416 [ #  # ][ #  # ]:          0 :         cosurf1->get_surface()->closest_point( base, 0, &normal1 );
    4417         [ #  # ]:          0 :       if( fix2 )
    4418 [ #  # ][ #  # ]:          0 :         cosurf2->get_surface()->closest_point( base, 0, &normal2 );
    4419                 :            :       
    4420 [ #  # ][ #  # ]:          0 :       bool done1 = !fix1 || (normal1 * normal).length_squared() > CUBIT_RESABS;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4421 [ #  # ][ #  # ]:          0 :       bool done2 = !fix2 || (normal2 * normal).length_squared() > CUBIT_RESABS;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4422 [ #  # ][ #  # ]:          0 :       if ( done1 && done2 )
    4423                 :            :       {
    4424                 :          0 :         fix1 = fix2 = false;
    4425                 :          0 :         break;
    4426                 :            :       }
    4427                 :            :     }
    4428                 :            :   }
    4429                 :            :   
    4430 [ #  # ][ #  # ]:          0 :   if ( fix1 || fix2 )
    4431                 :            :   {
    4432 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Failed to adjust for surface tangencies.\n"
                 [ #  # ]
    4433         [ #  # ]:          0 :                 "This is a BUG.  %s:%d\n", __FILE__, __LINE__ );
    4434                 :          0 :     return CUBIT_FAILURE;
    4435                 :            :   }
    4436                 :            :   
    4437 [ #  # ][ #  # ]:          0 :   if ( nonman_coedge->sense() == CUBIT_FORWARD )
    4438 [ #  # ][ #  # ]:          0 :     normal = -normal;
    4439 [ #  # ][ #  # ]:          0 :   if ( cosurf1->sense() == coedge1->sense() )
                 [ #  # ]
    4440 [ #  # ][ #  # ]:          0 :     normal1 = -normal1;
    4441 [ #  # ][ #  # ]:          0 :   if ( cosurf2->sense() == coedge2->sense() )
                 [ #  # ]
    4442 [ #  # ][ #  # ]:          0 :     normal2 = -normal2;
    4443                 :            :   
    4444         [ #  # ]:          0 :   result = tangent.vector_angle(normal1, normal ) <=
    4445         [ #  # ]:          0 :            tangent.vector_angle(normal1, normal2);
    4446                 :          0 :   return CUBIT_SUCCESS;
    4447                 :            : }
    4448                 :            : 
    4449                 :            :   
    4450                 :            : 
    4451                 :            : 
    4452                 :            : 
    4453                 :            : 
    4454                 :            : //-------------------------------------------------------------------------
    4455                 :            : // Purpose       : Remove a partition surface previously inserted in a
    4456                 :            : //                 lump via insert_surface(..).
    4457                 :            : //
    4458                 :            : // Special Notes : 
    4459                 :            : //
    4460                 :            : // Creator       : Jason Kraftcheck
    4461                 :            : //
    4462                 :            : // Creation Date : 01/13/03
    4463                 :            : //-------------------------------------------------------------------------
    4464                 :          0 : Lump* PartitionEngine::remove_surface( PartitionSurface* surface )
    4465                 :            : {
    4466                 :            :     // If surface belongs to non-partition volumes, we cannot proceed.
    4467         [ #  # ]:          0 :   DLIList<TopologyBridge*> shell_bridges;
    4468         [ #  # ]:          0 :   surface->get_parents_virt( shell_bridges );
    4469 [ #  # ][ #  # ]:          0 :   while( shell_bridges.size() )
    4470 [ #  # ][ #  # ]:          0 :     if( ! dynamic_cast<PartitionShell*>(shell_bridges.pop()) )
         [ #  # ][ #  # ]
    4471                 :          0 :       return 0;
    4472                 :            :   
    4473         [ #  # ]:          0 :   PartitionCoSurf* cosurf1 = surface->next_co_surface(0);
    4474         [ #  # ]:          0 :   if( ! cosurf1 )
    4475                 :          0 :     return 0; // doesn't belong to any PartitionLumps;
    4476                 :            :     
    4477         [ #  # ]:          0 :   PartitionCoSurf* cosurf2 = surface->next_co_surface(cosurf1);
    4478 [ #  # ][ #  # ]:          0 :   if( !cosurf2 || surface->next_co_surface(cosurf2) )
         [ #  # ][ #  # ]
    4479                 :          0 :     return 0; // must have exactly two parent cosurfaces.
    4480                 :            :     
    4481         [ #  # ]:          0 :   PartitionShell* shell1 = cosurf1->get_shell();
    4482         [ #  # ]:          0 :   PartitionShell* shell2 = cosurf2->get_shell();
    4483         [ #  # ]:          0 :   PartitionLump* lump1 = shell1->get_lump();
    4484         [ #  # ]:          0 :   PartitionLump* lump2 = shell2->get_lump();
    4485                 :            :   
    4486 [ #  # ][ #  # ]:          0 :   if( surface->partitioned_entity() != lump1->partitioned_entity() )
                 [ #  # ]
    4487                 :          0 :     return 0; // shouldn't have gotten this far, but just in case ...
    4488                 :            :   
    4489                 :            :     // remove and destroy surface
    4490         [ #  # ]:          0 :   shell1->remove( cosurf1 );
    4491         [ #  # ]:          0 :   shell2->remove( cosurf2 );
    4492         [ #  # ]:          0 :   surface->remove(cosurf1);
    4493         [ #  # ]:          0 :   surface->remove(cosurf2);
    4494 [ #  # ][ #  # ]:          0 :   delete cosurf1;
    4495 [ #  # ][ #  # ]:          0 :   delete cosurf2;
    4496         [ #  # ]:          0 :   destroy_surface(surface);
    4497                 :            :     
    4498                 :            :   
    4499                 :            :     // combine volumes?
    4500         [ #  # ]:          0 :   if( shell1 != shell2 )
    4501                 :            :   {
    4502         [ #  # ]:          0 :     assert(lump1 != lump2);
    4503 [ #  # ][ #  # ]:          0 :     while( PartitionCoSurf* cosurf = shell2->next_co_surface(0) )
    4504                 :            :     {
    4505         [ #  # ]:          0 :       shell2->remove(cosurf);
    4506         [ #  # ]:          0 :       shell1->add(cosurf);
    4507                 :            :     }
    4508         [ #  # ]:          0 :     lump2->remove(shell2);
    4509 [ #  # ][ #  # ]:          0 :     delete shell2;
    4510                 :            :     
    4511 [ #  # ][ #  # ]:          0 :     if( !shell1->next_co_surface(0) )
    4512                 :            :     {
    4513         [ #  # ]:          0 :       lump1->remove(shell1);
    4514 [ #  # ][ #  # ]:          0 :       delete shell1;
    4515                 :            :     }
    4516                 :            :     
    4517 [ #  # ][ #  # ]:          0 :     while( PartitionShell* shell = lump2->next_shell(0) )
    4518                 :            :     {
    4519         [ #  # ]:          0 :       lump2->remove(shell);
    4520         [ #  # ]:          0 :       lump1->add(shell);
    4521                 :            :     }
    4522 [ #  # ][ #  # ]:          0 :     delete lump2;
    4523                 :            :   }
    4524                 :            :     // one-surface shell
    4525 [ #  # ][ #  # ]:          0 :   else if( !shell1->next_co_surface(0) )
    4526                 :            :   {
    4527         [ #  # ]:          0 :     lump1->remove( shell1 );
    4528 [ #  # ][ #  # ]:          0 :     delete shell1;
    4529                 :            :   }
    4530                 :            :     // possibly split shells
    4531                 :            :   else 
    4532                 :            :   {
    4533         [ #  # ]:          0 :     PartitionShell* shell = split_shell( shell1 );
    4534         [ #  # ]:          0 :     if( shell )
    4535         [ #  # ]:          0 :       lump1->add(shell);
    4536                 :            :   }
    4537                 :            :     
    4538 [ #  # ][ #  # ]:          0 :   if( !lump1->sub_entity_set().has_lower_order() )
                 [ #  # ]
    4539         [ #  # ]:          0 :     return restore_lump( lump1 );
    4540                 :            :   else
    4541         [ #  # ]:          0 :     return lump1;
    4542                 :            : }
    4543                 :            : 
    4544                 :            : 
    4545                 :            : //-------------------------------------------------------------------------
    4546                 :            : // Purpose       : tear down and free a surface
    4547                 :            : //
    4548                 :            : // Special Notes : 
    4549                 :            : //
    4550                 :            : // Creator       : Jason Kraftcheck
    4551                 :            : //
    4552                 :            : // Creation Date : 01/14/03
    4553                 :            : //-------------------------------------------------------------------------
    4554                 :          0 : CubitStatus PartitionEngine::destroy_surface( PartitionSurface* surface )
    4555                 :            : {
    4556         [ #  # ]:          0 :   while( PartitionLoop* dead_loop = surface->next_loop(0) )
    4557                 :            :   {
    4558                 :          0 :     surface->remove(dead_loop);
    4559         [ #  # ]:          0 :     while( PartitionCoEdge* dead_coe = dead_loop->first_coedge() )
    4560                 :            :     {
    4561                 :          0 :       PartitionCurve* dead_curve = dead_coe->get_curve();
    4562                 :          0 :       dead_loop->remove(dead_coe);
    4563                 :          0 :       dead_curve->remove(dead_coe);
    4564         [ #  # ]:          0 :       delete dead_coe;
    4565                 :            :       
    4566         [ #  # ]:          0 :       if( dead_curve->partitioned_entity() == surface->partitioned_entity() )
    4567                 :            :       {
    4568         [ #  # ]:          0 :         if( dead_curve->next_coedge(0) == 0 )
    4569                 :            :         {
    4570                 :          0 :           PartitionPoint* start_pt = dead_curve->start_point();
    4571                 :          0 :           PartitionPoint* end_pt = dead_curve->end_point();
    4572         [ #  # ]:          0 :           delete dead_curve;
    4573   [ #  #  #  # ]:          0 :           if( start_pt->partitioned_entity() == surface->partitioned_entity() &&
                 [ #  # ]
    4574                 :          0 :               start_pt->next_curve() == 0 )
    4575         [ #  # ]:          0 :             delete start_pt;
    4576   [ #  #  #  # ]:          0 :           if( end_pt->partitioned_entity() == surface->partitioned_entity() &&
                 [ #  # ]
    4577                 :          0 :               end_pt->next_curve() == 0 )
    4578         [ #  # ]:          0 :             delete end_pt;
    4579                 :            :         }
    4580                 :            :       }
    4581 [ #  # ][ #  # ]:          0 :       else if( SubCurve* subcurve = dynamic_cast<SubCurve*>(dead_curve) )
    4582                 :            :       {
    4583                 :          0 :         restore_curve(subcurve);
    4584                 :            :       }
    4585                 :            :     }
    4586         [ #  # ]:          0 :     delete dead_loop;
    4587                 :          0 :   }
    4588         [ #  # ]:          0 :   delete surface;
    4589                 :          0 :   return CUBIT_SUCCESS;
    4590                 :            : }
    4591                 :            : 
    4592                 :            : 
    4593                 :            : //-------------------------------------------------------------------------
    4594                 :            : // Purpose       : Retreive entity from UID attrib data.
    4595                 :            : //
    4596                 :            : // Special Notes : Used when restoring saved geometry.
    4597                 :            : //
    4598                 :            : // Creator       : Jason Kraftcheck
    4599                 :            : //
    4600                 :            : // Creation Date : 02/23/03
    4601                 :            : //-------------------------------------------------------------------------
    4602                 :          0 : PartitionEntity* PartitionEngine::entity_from_id( int set_id,
    4603                 :            :                                                   int entity_id,
    4604                 :            :                                                   SubEntitySet& default_set )
    4605                 :            : {
    4606         [ #  # ]:          0 :   if( set_id == 0 )
    4607                 :          0 :     return default_set.entity_from_id( entity_id );
    4608                 :            :   
    4609                 :          0 :   SubEntitySet* set = get_from_id_map(set_id);
    4610         [ #  # ]:          0 :   if( set )
    4611                 :          0 :     return set->entity_from_id( entity_id );
    4612                 :            :   
    4613                 :          0 :   return 0;
    4614                 :            : }
    4615                 :            :  
    4616                 :            : //-------------------------------------------------------------------------
    4617                 :            : // Purpose       : Restore curve partitions
    4618                 :            : //
    4619                 :            : // Special Notes : 
    4620                 :            : //
    4621                 :            : // Creator       : Jason Kraftcheck
    4622                 :            : //
    4623                 :            : // Creation Date : 02/23/03
    4624                 :            : //-------------------------------------------------------------------------
    4625                 :      23275 : CubitStatus PartitionEngine::restore_from_attrib( Curve* curve )
    4626                 :            : {
    4627                 :      23275 :   int i, id, dim, max_id = 0;
    4628 [ +  - ][ +  - ]:      46550 :   DLIList<CubitSimpleAttrib> attribs, point_attribs, curve_attribs;
         [ +  - ][ +  - ]
                 [ +  - ]
    4629 [ +  - ][ +  - ]:      46550 :   DLIList<CubitVector*> empty;
    4630 [ +  - ][ +  - ]:      46550 :   DLIList<int> junk, point_conn;
         [ +  - ][ +  - ]
    4631 [ +  - ][ +  - ]:      46550 :   DLIList<PartitionPoint*> new_points;
    4632                 :      23275 :   CubitStatus result = CUBIT_FAILURE;
    4633                 :            :   
    4634                 :            :   {
    4635                 :            :       // Get list of partition attributes.
    4636 [ +  - ][ +  - ]:      23275 :     curve->get_simple_attribute(PARTITION_GEOM_ATTRIB_NAME,attribs);
                 [ +  - ]
    4637 [ +  - ][ +  - ]:      23275 :     if( attribs.size() == 0 )
    4638                 :      23275 :       return CUBIT_SUCCESS;
    4639                 :            : 
    4640                 :            :       // Group attributes into those defining partition points and
    4641                 :            :       // those defining the subcurves.  Also find max ID of all 
    4642                 :            :       // partition geometry on this curve
    4643         [ #  # ]:          0 :     attribs.reset();
    4644 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    4645                 :            :     {
    4646         [ #  # ]:          0 :       const CubitSimpleAttrib& attrib = attribs.get_and_step();
    4647         [ #  # ]:          0 :       dim = SubEntitySet::get_geom_dimension(attrib);
    4648         [ #  # ]:          0 :       if( dim == 0 )
    4649         [ #  # ]:          0 :         point_attribs.append(attrib);
    4650         [ #  # ]:          0 :       else if( dim == 1 )
    4651         [ #  # ]:          0 :         curve_attribs.append(attrib);
    4652                 :            :       else
    4653                 :          0 :         goto CLEANUP_CURVE_FROM_ATTRIB;
    4654                 :            : 
    4655         [ #  # ]:          0 :       id = SubEntitySet::get_geom_id( attrib );
    4656         [ #  # ]:          0 :       if( id > max_id )
    4657                 :          0 :         max_id = id;
    4658                 :            :     }
    4659                 :            : 
    4660                 :            :       // Create first curve (duplicate of input curve)
    4661         [ #  # ]:          0 :     PartitionCurve* first_curve = replace_curve( curve );
    4662         [ #  # ]:          0 :     if( ! first_curve )
    4663                 :          0 :       goto CLEANUP_CURVE_FROM_ATTRIB;
    4664                 :            : 
    4665                 :            :       // Set up SubEntitySet such that new entities get IDs
    4666                 :            :       // larger than max_id as they are created.
    4667 [ #  # ][ #  # ]:          0 :     first_curve->sub_entity_set().renumerate( max_id + 1, false );
    4668                 :            : 
    4669                 :            :       // Create all the partition points
    4670         [ #  # ]:          0 :     point_attribs.reset();
    4671 [ #  # ][ #  # ]:          0 :     for( i = point_attribs.size(); i--; )
    4672                 :            :     {
    4673         [ #  # ]:          0 :       const CubitSimpleAttrib& attrib = point_attribs.get_and_step();
    4674 [ #  # ][ #  # ]:          0 :       PartitionPoint* point = new PartitionPoint( attrib, first_curve );
                 [ #  # ]
    4675         [ #  # ]:          0 :       if( !point )
    4676                 :          0 :         goto CLEANUP_CURVE_FROM_ATTRIB;
    4677                 :            : 
    4678         [ #  # ]:          0 :       curve->remove_simple_attribute_virt(attrib);
    4679                 :            :     }
    4680                 :            : 
    4681                 :            :       // Now partition the curve and assign the ID from each
    4682                 :            :       // curve attribute the the appropriate curve partition.
    4683                 :            :       //
    4684                 :            :       // We're going to do this in order along the curve, such
    4685                 :            :       // that the first subcurve will begin at the start_point() of
    4686                 :            :       // the original curve.
    4687         [ #  # ]:          0 :     PartitionPoint* prev_point = first_curve->start_point();
    4688                 :          0 :     PartitionCurve* next_curve = first_curve;
    4689 [ #  # ][ #  # ]:          0 :     while( curve_attribs.size() )
    4690                 :            :     {
    4691                 :            :         // Search for attribute corresponding to curve
    4692                 :            :         // beginning at prev_point
    4693                 :          0 :       PartitionPoint *start = 0, *end = 0;
    4694         [ #  # ]:          0 :       CubitSimpleAttrib curve_attrib;
    4695         [ #  # ]:          0 :       curve_attribs.last();
    4696 [ #  # ][ #  # ]:          0 :       for( i = curve_attribs.size(); i--; )
    4697                 :            :       {
    4698                 :            :           // Get data from attribute
    4699         [ #  # ]:          0 :         const CubitSimpleAttrib& attrib = curve_attribs.step_and_get();
    4700         [ #  # ]:          0 :         point_conn.clean_out();
    4701 [ #  # ][ #  # ]:          0 :         if( !SubEntitySet::read_geometry(id,dim,empty,junk,point_conn,junk,attrib)
    4702 [ #  # ][ #  # ]:          0 :             || empty.size() || junk.size() || dim != 1 || point_conn.size() != 4)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4703                 :          0 :           goto CLEANUP_CURVE_FROM_ATTRIB;
    4704                 :            : 
    4705                 :            :           // Get start point from IDs
    4706         [ #  # ]:          0 :         point_conn.reset();
    4707         [ #  # ]:          0 :         int sid = point_conn.get_and_step();
    4708         [ #  # ]:          0 :         int eid = point_conn.get_and_step();
    4709 [ #  # ][ #  # ]:          0 :         PartitionEntity* ent = entity_from_id(sid, eid, first_curve->sub_entity_set());
    4710         [ #  # ]:          0 :         start = dynamic_cast<PartitionPoint*>(ent);
    4711                 :            :         
    4712         [ #  # ]:          0 :         if( start == prev_point )
    4713                 :            :         {
    4714                 :            :             // Found the attrib we want. 
    4715                 :            :             // Get the end point and break the loop.
    4716         [ #  # ]:          0 :           sid = point_conn.get_and_step();
    4717         [ #  # ]:          0 :           eid = point_conn.get_and_step();
    4718 [ #  # ][ #  # ]:          0 :           ent = entity_from_id(sid, eid, first_curve->sub_entity_set());
    4719         [ #  # ]:          0 :           end = dynamic_cast<PartitionPoint*>(ent);
    4720                 :            : 
    4721 [ #  # ][ #  # ]:          0 :           curve_attrib = curve_attribs.extract();
                 [ #  # ]
    4722                 :          0 :           break;
    4723                 :            :         }
    4724                 :            :       }
    4725                 :            : 
    4726                 :            :         // Make sure we found an attrib to do
    4727 [ #  # ][ #  # ]:          0 :       if( curve_attrib.isEmpty() || !start || !end )
         [ #  # ][ #  # ]
                 [ #  # ]
    4728                 :          0 :         goto CLEANUP_CURVE_FROM_ATTRIB;
    4729                 :            : 
    4730                 :            :         // Unless this is the last partition (no more splitting
    4731                 :            :         // required), split the curve at the end point.  Make
    4732                 :            :         // next_curve point to the (unpartitioned) remainder of
    4733                 :            :         // the curve.
    4734                 :          0 :       PartitionCurve* new_curve = next_curve;
    4735 [ #  # ][ #  # ]:          0 :       if( next_curve->end_point() != end )
    4736                 :            :       {
    4737         [ #  # ]:          0 :         next_curve = insert_point( new_curve, end );
    4738         [ #  # ]:          0 :         if( !next_curve )
    4739                 :          0 :           goto CLEANUP_CURVE_FROM_ATTRIB;
    4740                 :            :       }
    4741                 :            : 
    4742                 :            :         // Set the new curve's ID to whatever it is stored
    4743                 :            :         // as in the attribute.
    4744         [ #  # ]:          0 :       new_curve->sub_entity_set().set_id( new_curve, 
    4745 [ #  # ][ #  # ]:          0 :         SubEntitySet::get_geom_id( curve_attrib ) );
                 [ #  # ]
    4746                 :            : 
    4747                 :            :         // Remove processed attributes.
    4748         [ #  # ]:          0 :       curve->remove_simple_attribute_virt( curve_attrib );
    4749                 :            :       
    4750                 :            :         // Next iteration
    4751 [ #  # ][ #  # ]:          0 :       prev_point = end;
    4752                 :          0 :     }
    4753                 :            : 
    4754                 :            :       // Compress SubEntitySet ID space
    4755 [ #  # ][ #  # ]:          0 :     next_curve->sub_entity_set().renumerate( max_id + 1, true );
    4756                 :          0 :     result = CUBIT_SUCCESS;
    4757                 :            :   }
    4758                 :            :   
    4759                 :            : CLEANUP_CURVE_FROM_ATTRIB:
    4760                 :            : 
    4761 [ #  # ][ #  # ]:          0 :   for( i = new_points.size(); i--; )
    4762                 :            :   {
    4763         [ #  # ]:          0 :     PartitionPoint* pt = new_points.get_and_step();
    4764 [ #  # ][ #  # ]:          0 :     if( !pt->next_curve(0) )
    4765 [ #  # ][ #  # ]:          0 :       delete pt;
    4766                 :            :   }
    4767                 :            :   
    4768         [ #  # ]:          0 :   if (!result)
    4769 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Error restoring curve partitions from attributes.\n");
         [ #  # ][ #  # ]
    4770                 :            :     
    4771         [ +  - ]:      23275 :   return result;
    4772                 :            : }  
    4773                 :            : 
    4774                 :            : 
    4775                 :            : //-------------------------------------------------------------------------
    4776                 :            : // Purpose       : Restore surface partitions
    4777                 :            : //
    4778                 :            : // Special Notes : 
    4779                 :            : //
    4780                 :            : // Creator       : Jason Kraftcheck
    4781                 :            : //
    4782                 :            : // Creation Date : 02/23/03
    4783                 :            : //-------------------------------------------------------------------------
    4784                 :      11189 : CubitStatus PartitionEngine::restore_from_attrib( Surface* surf )
    4785                 :            : {
    4786                 :      11189 :   int i, j, k, id, dim, max_id = 0;
    4787         [ +  - ]:      11189 :   DLIList<CubitSimpleAttrib> attribs;
    4788 [ +  - ][ +  - ]:      22378 :   DLIList<CubitFacetEdgeData*> polyline_edges;
    4789 [ +  - ][ +  - ]:      22378 :   DLIList<CubitPointData*> polyline_pts;
    4790 [ +  - ][ +  - ]:      22378 :   DLIList<CubitFacetData*> surf_facets;
    4791 [ +  - ][ +  - ]:      22378 :   DLIList<CubitVector*> positions;
    4792 [ +  - ][ +  - ]:      22378 :   DLIList<PartitionEntity*> new_geom;
    4793 [ +  - ][ +  - ]:      22378 :   DLIList<PartitionLoop*> loops;
    4794 [ +  - ][ +  - ]:      22378 :   DLIList<int> facets(0), connectivity, pt_owners;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    4795                 :      11189 :   CubitStatus result = CUBIT_FAILURE;
    4796                 :      11189 :   SubSurface* first_surf = 0;
    4797                 :            :   
    4798                 :            :   
    4799                 :            :   {
    4800                 :            :       // Get partition attributes from entity.  Return if there aren't any.
    4801 [ +  - ][ +  - ]:      11189 :     surf->get_simple_attribute(PARTITION_GEOM_ATTRIB_NAME,attribs);
                 [ +  - ]
    4802 [ +  - ][ +  - ]:      11189 :     if( attribs.size() == 0 )
    4803                 :      11189 :       return CUBIT_SUCCESS;
    4804                 :            : 
    4805 [ #  # ][ #  # ]:          0 :     PRINT_DEBUG_86("Reading partition geometry on %s %p\n", 
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    4806         [ #  # ]:          0 :       fix_type_name( typeid(*surf).name() ), (void*)surf );
    4807                 :            :       
    4808                 :            :       // Find max ID
    4809         [ #  # ]:          0 :     attribs.reset();
    4810 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    4811                 :            :     {
    4812 [ #  # ][ #  # ]:          0 :       id = SubEntitySet::get_geom_id( attribs.get_and_step() );
    4813         [ #  # ]:          0 :       if( id > max_id )
    4814                 :          0 :         max_id = id;
    4815                 :            :     }
    4816                 :            : 
    4817                 :            :       // Create first partition surface (initially a duplicate of
    4818                 :            :       // the input surface)
    4819         [ #  # ]:          0 :     first_surf = replace_surface( surf );
    4820         [ #  # ]:          0 :     if( ! first_surf )
    4821                 :            :     {  
    4822 [ #  # ][ #  # ]:          0 :       PRINT_ERROR("Internal Error: PartitionEngine::replace_surface() failed.\n");
         [ #  # ][ #  # ]
    4823                 :          0 :       goto CLEANUP_SURF_FROM_ATTRIB;
    4824                 :            :     }
    4825                 :            :     
    4826                 :            :       // Update SubEntitySet such that new entities get assigned
    4827                 :            :       // IDs greater than max_id when they are created.  This
    4828                 :            :       // leaves the range 0->max_id free so that we can reassign
    4829                 :            :       // the saved IDs after the entities are created.
    4830 [ #  # ][ #  # ]:          0 :     first_surf->sub_entity_set().renumerate( max_id + 1, false );
    4831                 :            : 
    4832                 :            :       // create all interior vertices
    4833         [ #  # ]:          0 :     attribs.reset();
    4834 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    4835                 :            :     {
    4836                 :            :         // Only want point attributes (dimension of zero)
    4837 [ #  # ][ #  # ]:          0 :       CubitSimpleAttrib attrib = attribs.get();
    4838 [ #  # ][ #  # ]:          0 :       if( SubEntitySet::get_geom_dimension(attrib) != 0 )
    4839                 :            :       {
    4840         [ #  # ]:          0 :         attribs.step();
    4841                 :          0 :         continue;
    4842                 :            :       }
    4843                 :            : 
    4844                 :            :         // Create the point at the location specified in the attrib.
    4845 [ #  # ][ #  # ]:          0 :       attribs.extract();
    4846         [ #  # ]:          0 :       surf->remove_simple_attribute_virt(attrib);
    4847 [ #  # ][ #  # ]:          0 :       PartitionPoint* new_pt = new PartitionPoint( attrib, first_surf );
                 [ #  # ]
    4848 [ #  # ][ #  # ]:          0 :       CubitPointData* data = project_to_surface( first_surf, new_pt->coordinates() );
    4849         [ #  # ]:          0 :       new_pt->facet_point(data);
    4850 [ #  # ][ #  # ]:          0 :       new_geom.append(new_pt);
    4851 [ #  # ][ #  # ]:          0 :       PRINT_DEBUG_86("  Created Point %p (%d in subset) at (%f,%f,%f)\n", 
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    4852                 :            :         (void*)new_pt, new_pt->sub_entity_set().get_id(new_pt),
    4853                 :            :         new_pt->coordinates().x(), new_pt->coordinates().y(), 
    4854         [ #  # ]:          0 :         new_pt->coordinates().z() );
    4855 [ #  # ][ #  # ]:          0 :       if (DEBUG_FLAG(86))
                 [ #  # ]
    4856                 :            :       {
    4857 [ #  # ][ #  # ]:          0 :         GfxDebug::draw_point(new_pt->coordinates(), new_pt->sub_entity_set().get_id(new_pt));
         [ #  # ][ #  # ]
                 [ #  # ]
    4858 [ #  # ][ #  # ]:          0 :         GfxDebug::flush();
                 [ #  # ]
    4859                 :            :       }
    4860                 :          0 :     }
    4861                 :            : 
    4862                 :            :       // create all interior curves
    4863         [ #  # ]:          0 :     attribs.reset();
    4864 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    4865                 :            :     {
    4866                 :            :         // Only want curve attributes (dimension of one)
    4867 [ #  # ][ #  # ]:          0 :       CubitSimpleAttrib attrib = attribs.get();
    4868 [ #  # ][ #  # ]:          0 :       if( SubEntitySet::get_geom_dimension(attrib) != 1 )
    4869                 :            :       {
    4870         [ #  # ]:          0 :         attribs.step();
    4871                 :          0 :         continue;
    4872                 :            :       }
    4873                 :            : 
    4874                 :            :         // Remove this attrib from the real geom, as we are
    4875                 :            :         // handling it
    4876 [ #  # ][ #  # ]:          0 :       attribs.extract();
    4877         [ #  # ]:          0 :       surf->remove_simple_attribute_virt(attrib);
    4878                 :            :       
    4879 [ #  # ][ #  # ]:          0 :       if ( SubEntitySet::get_segment_count(attrib) == 0 )
    4880                 :            :       {
    4881         [ #  # ]:          0 :         PartPTCurve* pt_curve = PartPTCurve::construct(attrib, first_surf);
    4882         [ #  # ]:          0 :         if (!pt_curve)
    4883                 :            :         {
    4884 [ #  # ][ #  # ]:          0 :           PRINT_ERROR("point-curve construction failed -- corrupt data?\n");
         [ #  # ][ #  # ]
    4885                 :          0 :           goto CLEANUP_SURF_FROM_ATTRIB;
    4886                 :            :         }
    4887 [ #  # ][ #  # ]:          0 :         new_geom.append( pt_curve );
    4888 [ #  # ][ #  # ]:          0 :         PRINT_DEBUG_86("  Created point-curve %p (%d in subset) with\n"
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4889                 :            :                        "    point %p (%d in subset) at (%f,%f,%f)\n", 
    4890                 :            :           (void*)pt_curve,
    4891                 :            :           pt_curve->sub_entity_set().get_id(pt_curve), 
    4892                 :            :           (void*)pt_curve->start_point(),
    4893                 :            :           pt_curve->start_point()->sub_entity_set().get_id(pt_curve->start_point()),
    4894                 :            :           pt_curve->start_point()->coordinates().x(),
    4895                 :            :           pt_curve->start_point()->coordinates().y(), 
    4896         [ #  # ]:          0 :           pt_curve->start_point()->coordinates().z() );
    4897                 :            : 
    4898 [ #  # ][ #  # ]:          0 :         CubitPointData* pt = project_to_surface( first_surf, pt_curve->start_point()->coordinates() );
                 [ #  # ]
    4899         [ #  # ]:          0 :         if ( !pt )
    4900                 :            :         {
    4901 [ #  # ][ #  # ]:          0 :           PRINT_ERROR("projection of position onto surface facets failed.\n");
         [ #  # ][ #  # ]
    4902                 :          0 :           goto CLEANUP_SURF_FROM_ATTRIB;
    4903                 :            :         }
    4904                 :            :           
    4905 [ #  # ][ #  # ]:          0 :         pt_curve->start_point()->facet_point( pt );
    4906                 :          0 :         continue;
    4907                 :            :       }
    4908                 :            :       
    4909                 :            :         // Create the curve
    4910 [ #  # ][ #  # ]:          0 :       SegmentedCurve* new_curve = SegmentedCurve::construct( attrib, first_surf );
    4911         [ #  # ]:          0 :       if( !new_curve ) 
    4912                 :            :       {
    4913 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("segmented curve construction failed -- corrupt data?\n");
         [ #  # ][ #  # ]
    4914                 :          0 :         goto CLEANUP_SURF_FROM_ATTRIB;
    4915                 :            :       }
    4916 [ #  # ][ #  # ]:          0 :       new_geom.append(new_curve);
    4917 [ #  # ][ #  # ]:          0 :       PRINT_DEBUG_86("  Created polyline curve %p (%d in subset) with %d segments.\n"
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4918                 :            :                      "    start point %p (%d in subset) at (%f,%f,%f)\n" 
    4919                 :            :                      "      end point %p (%d in subset) at (%f,%f,%f)\n", 
    4920                 :            :           (void*)new_curve,
    4921                 :            :           new_curve->sub_entity_set().get_id(new_curve),
    4922                 :            :           new_curve->point_count() - 1, 
    4923                 :            :           (void*)new_curve->start_point(),
    4924                 :            :           new_curve->start_point()->sub_entity_set().get_id(new_curve->start_point()),
    4925                 :            :           new_curve->start_point()->coordinates().x(),
    4926                 :            :           new_curve->start_point()->coordinates().y(), 
    4927                 :            :           new_curve->start_point()->coordinates().z(),
    4928                 :            :           (void*)new_curve->end_point(),
    4929                 :            :           new_curve->end_point()->sub_entity_set().get_id(new_curve->end_point()),
    4930                 :            :           new_curve->end_point()->coordinates().x(),
    4931                 :            :           new_curve->end_point()->coordinates().y(), 
    4932         [ #  # ]:          0 :           new_curve->end_point()->coordinates().z() );
    4933                 :            :  
    4934                 :            :         // Get curve segments
    4935         [ #  # ]:          0 :       positions.clean_out();
    4936         [ #  # ]:          0 :       polyline_edges.clean_out();
    4937         [ #  # ]:          0 :       new_curve->get_segments( positions );
    4938                 :            :       
    4939 [ #  # ][ #  # ]:          0 :       if (DEBUG_FLAG(86))
                 [ #  # ]
    4940                 :            :       {
    4941 [ #  # ][ #  # ]:          0 :         GPoint* array = new GPoint[positions.size()];
                 [ #  # ]
    4942         [ #  # ]:          0 :         positions.reset();
    4943 [ #  # ][ #  # ]:          0 :         for (int dd = 0; dd < positions.size(); dd++ )
    4944                 :            :         {
    4945 [ #  # ][ #  # ]:          0 :           array[dd].x = (float)positions.next(dd)->x(); 
    4946 [ #  # ][ #  # ]:          0 :           array[dd].y = (float)positions.next(dd)->y();
    4947 [ #  # ][ #  # ]:          0 :           array[dd].z = (float)positions.next(dd)->z();
    4948                 :            :         }
    4949                 :            :         
    4950                 :            :         GfxDebug::draw_polyline(array, positions.size(),
    4951 [ #  # ][ #  # ]:          0 :                                 new_curve->sub_entity_set().get_id(new_curve));
         [ #  # ][ #  # ]
                 [ #  # ]
    4952         [ #  # ]:          0 :         GfxDebug::flush();
    4953                 :            :       }
    4954                 :            :       
    4955                 :            :         // Make sure segment end points are on curve end points
    4956         [ #  # ]:          0 :       positions.last();
    4957 [ #  # ][ #  # ]:          0 :       *positions.get() = new_curve->end_point()->coordinates();
         [ #  # ][ #  # ]
    4958         [ #  # ]:          0 :       positions.reset();
    4959 [ #  # ][ #  # ]:          0 :       *positions.get() = new_curve->start_point()->coordinates();
         [ #  # ][ #  # ]
    4960                 :            :       
    4961                 :            :         // Project curve into surface facets
    4962         [ #  # ]:          0 :       surf_facets.clean_out();
    4963         [ #  # ]:          0 :       first_surf->get_facet_data( surf_facets );
    4964                 :            :       CubitStatus s = project_to_surface( surf_facets, positions, 
    4965         [ #  # ]:          0 :                               polyline_edges, polyline_pts );
    4966 [ #  # ][ #  # ]:          0 :       while( positions.size() ) 
    4967                 :            :       {
    4968         [ #  # ]:          0 :         CubitVector* position = positions.pop();
    4969         [ #  # ]:          0 :         if(s)
    4970                 :            :         {
    4971                 :            :    //       assert(polyline_pts.size());
    4972         [ #  # ]:          0 :           CubitPointData* point = polyline_pts.pop();
    4973 [ #  # ][ #  # ]:          0 :           if (point && point->check_inverted_facets(*position))
         [ #  # ][ #  # ]
    4974         [ #  # ]:          0 :             point->set(*position);
    4975                 :            :         }
    4976                 :          0 :         delete position;
    4977                 :            :       }
    4978 [ #  # ][ #  # ]:          0 :       if( !s || !polyline_edges.size() ) 
         [ #  # ][ #  # ]
    4979                 :            :       {
    4980 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Imprint of polyline onto surface facets failed.\n");
         [ #  # ][ #  # ]
    4981                 :          0 :         goto CLEANUP_SURF_FROM_ATTRIB;
    4982                 :            :       }
    4983                 :            :       
    4984                 :            :       
    4985                 :            :         // move facet points onto surface
    4986         [ #  # ]:          0 :       for ( j = 0; j < 2; j++ )
    4987 [ #  # ][ #  # ]:          0 :         for ( k = polyline_edges.size(); k--; )
    4988 [ #  # ][ #  # ]:          0 :           if ( CubitFacetEdgeData* edge = polyline_edges.get_and_step() )
    4989 [ #  # ][ #  # ]:          0 :             edge->point(j)->marked(1);
    4990                 :            :       
    4991 [ #  # ][ #  # ]:          0 :       for ( j = polyline_edges.size(); j--; )
    4992                 :            :       {
    4993         [ #  # ]:          0 :         CubitFacetEdgeData* edge = polyline_edges.get_and_step();
    4994         [ #  # ]:          0 :         if ( !edge ) continue;
    4995         [ #  # ]:          0 :         for ( k = 0; k < 2; k++ )
    4996                 :            :         {
    4997         [ #  # ]:          0 :           CubitPoint* pt = edge->point(k);
    4998 [ #  # ][ #  # ]:          0 :           if ( pt->marked() ) 
    4999                 :            :           {
    5000         [ #  # ]:          0 :             pt->marked(0);
    5001         [ #  # ]:          0 :             first_surf->relax_to_geometry(pt);
    5002                 :            :           }
    5003                 :            :         }
    5004                 :            :       }
    5005                 :            :         
    5006                 :            :       
    5007                 :            :         // Associate facet data with geometry
    5008                 :            :         
    5009                 :            :       CubitPoint *last_pt, *first_pt;
    5010         [ #  # ]:          0 :       polyline_edges.last();
    5011 [ #  # ][ #  # ]:          0 :       assert(!polyline_edges.get());
    5012         [ #  # ]:          0 :       polyline_edges.pop();
    5013                 :            :       
    5014 [ #  # ][ #  # ]:          0 :       if( polyline_edges.size() == 1 )
    5015                 :            :       {
    5016 [ #  # ][ #  # ]:          0 :         last_pt = polyline_edges.get()->point(1);
    5017 [ #  # ][ #  # ]:          0 :         first_pt = polyline_edges.get()->point(0);
    5018                 :            :       }
    5019                 :            :       else
    5020                 :            :       {
    5021                 :            :         CubitFacetEdgeData *edge, *neighbor;
    5022                 :            :         
    5023         [ #  # ]:          0 :         polyline_edges.last();
    5024         [ #  # ]:          0 :         edge = polyline_edges.get();
    5025         [ #  # ]:          0 :         neighbor = polyline_edges.prev();
    5026 [ #  # ][ #  # ]:          0 :         if( !edge || !neighbor )
    5027                 :            :         {
    5028 [ #  # ][ #  # ]:          0 :           PRINT_ERROR("Bad surface facets.\n");
         [ #  # ][ #  # ]
    5029                 :          0 :           goto CLEANUP_SURF_FROM_ATTRIB;
    5030                 :            :         }
    5031         [ #  # ]:          0 :         last_pt = edge->shared_point(neighbor);
    5032         [ #  # ]:          0 :         last_pt = edge->other_point(last_pt);
    5033                 :            : 
    5034         [ #  # ]:          0 :         polyline_edges.reset();
    5035         [ #  # ]:          0 :         edge = polyline_edges.get();
    5036         [ #  # ]:          0 :         neighbor = polyline_edges.next();
    5037 [ #  # ][ #  # ]:          0 :         if( !edge || !neighbor )
    5038                 :            :         {
    5039 [ #  # ][ #  # ]:          0 :           PRINT_ERROR("Bad surface facets.\n");
         [ #  # ][ #  # ]
    5040                 :          0 :           goto CLEANUP_SURF_FROM_ATTRIB;
    5041                 :            :         }
    5042         [ #  # ]:          0 :         first_pt = edge->shared_point(neighbor);
    5043         [ #  # ]:          0 :         first_pt = edge->other_point(first_pt);
    5044                 :            :       }
    5045                 :            : 
    5046         [ #  # ]:          0 :       PartitionEntity* owner1 = TDVGFacetOwner::get( first_pt );
    5047         [ #  # ]:          0 :       PartitionEntity* owner2 = TDVGFacetOwner::get( last_pt );
    5048                 :            : 
    5049 [ #  # ][ #  # ]:          0 :       if ( new_curve->start_point() == new_curve->end_point() )
                 [ #  # ]
    5050                 :            :       {
    5051 [ #  # ][ #  # ]:          0 :         if ( owner1 == owner2 && owner1 == new_curve->start_point() )
         [ #  # ][ #  # ]
                 [ #  # ]
    5052                 :            :         {
    5053 [ #  # ][ #  # ]:          0 :           first_pt = polyline_edges.get()->other_point( first_pt );
    5054         [ #  # ]:          0 :           polyline_edges.last();
    5055 [ #  # ][ #  # ]:          0 :           last_pt = polyline_edges.get()->other_point( last_pt );
    5056 [ #  # ][ #  # ]:          0 :           double u1 = new_curve->u_from_position( first_pt->coordinates() );
    5057 [ #  # ][ #  # ]:          0 :           double u2 = new_curve->u_from_position( last_pt->coordinates() );
    5058         [ #  # ]:          0 :           if ( u2 < u1 )
    5059         [ #  # ]:          0 :             polyline_edges.reverse();
    5060         [ #  # ]:          0 :           polyline_edges.reset();
    5061                 :            :         }
    5062                 :            :         else
    5063                 :            :         {
    5064                 :          0 :           s = CUBIT_FAILURE;
    5065                 :            :         }
    5066                 :            :       }
    5067 [ #  # ][ #  # ]:          0 :       else if ( owner1 == new_curve->end_point() &&
         [ #  # ][ #  # ]
                 [ #  # ]
    5068 [ #  # ][ #  # ]:          0 :                 owner2 == new_curve->start_point() )
    5069                 :            :       {
    5070         [ #  # ]:          0 :         polyline_edges.reverse();
    5071         [ #  # ]:          0 :         polyline_edges.reset();
    5072                 :            :       }
    5073 [ #  # ][ #  # ]:          0 :       else if( owner1 != new_curve->start_point() ||
         [ #  # ][ #  # ]
                 [ #  # ]
    5074 [ #  # ][ #  # ]:          0 :                owner2 != new_curve->end_point() )
    5075                 :            :       {
    5076                 :          0 :         s = CUBIT_FAILURE;
    5077                 :            :       }
    5078                 :            :      
    5079         [ #  # ]:          0 :       if (!s) 
    5080                 :            :       {
    5081 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Tolerance problems when restoring surface partitions.\n");
         [ #  # ][ #  # ]
    5082                 :          0 :         goto CLEANUP_SURF_FROM_ATTRIB;
    5083                 :            :       }
    5084                 :            :       
    5085 [ #  # ][ #  # ]:          0 :       new_curve->set_facet_data( polyline_edges );
              [ #  #  # ]
    5086                 :          0 :     }
    5087                 :            : 
    5088                 :            :       // while there are more surface partitions to create
    5089                 :          0 :     PartitionEntity* ent = 0;
    5090 [ #  # ][ #  # ]:          0 :     while( attribs.size() )
    5091                 :            :     {
    5092                 :            :         // read attribute
    5093         [ #  # ]:          0 :       CubitSimpleAttrib surf_attr = attribs.pop();
    5094         [ #  # ]:          0 :       connectivity.clean_out();
    5095                 :            :       CubitStatus s = SubEntitySet::
    5096         [ #  # ]:          0 :         read_geometry( id, dim, positions, facets, connectivity, pt_owners, surf_attr );
    5097                 :            :       
    5098 [ #  # ][ #  # ]:          0 :       if( !s || dim != 2 || positions.size() || facets.size() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    5099                 :            :       {
    5100 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Corrupt/inconsistent subsurface data.\n");
         [ #  # ][ #  # ]
    5101                 :          0 :         goto CLEANUP_SURF_FROM_ATTRIB;
    5102                 :            :       }
    5103                 :            :       
    5104 [ #  # ][ #  # ]:          0 :       PRINT_DEBUG_86("  Constructing SubSurface (%d in subset)\n", id);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    5105                 :            : 
    5106                 :            :         // construct surface loops
    5107         [ #  # ]:          0 :       int j = connectivity.size();
    5108                 :          0 :       PartitionCoEdge* curve_coedge = 0; // save one non-point-curve coedge
    5109         [ #  # ]:          0 :       while ( j > 0 )
    5110                 :            :       {
    5111         [ #  # ]:          0 :         int loop = connectivity.get_and_step();
    5112                 :          0 :         j--;
    5113                 :            : 
    5114 [ #  # ][ #  # ]:          0 :         PartitionLoop* new_loop = new PartitionLoop();
    5115         [ #  # ]:          0 :         loops.append( new_loop );
    5116                 :          0 :         PartitionCoEdge* prev_coedge = 0;
    5117 [ #  # ][ #  # ]:          0 :         PRINT_DEBUG_86("   Loop: ");
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    5118                 :            : 
    5119         [ #  # ]:          0 :         while( loop-- )
    5120                 :            :         {
    5121         [ #  # ]:          0 :           int set_id = connectivity.get_and_step();
    5122         [ #  # ]:          0 :           int ent_id = connectivity.get_and_step();
    5123         [ #  # ]:          0 :           int sense = ent_id < 0 ? -1 : 1;
    5124                 :          0 :           ent_id *= sense;
    5125                 :          0 :           j -= 2;
    5126                 :            : 
    5127 [ #  # ][ #  # ]:          0 :           ent = entity_from_id( set_id, ent_id, first_surf->sub_entity_set() );
    5128         [ #  # ]:          0 :           PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent);
    5129 [ #  # ][ #  # ]:          0 :           PRINT_DEBUG_86(" %p,%d,%d%c", (void*)curve, set_id, ent_id*sense, loop?',':'\n');
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    5130         [ #  # ]:          0 :           if(!curve)
    5131                 :            :           {
    5132 [ #  # ][ #  # ]:          0 :             PRINT_ERROR("Nonexistant curve specified in saved connectivity.\n");
         [ #  # ][ #  # ]
    5133                 :          0 :             goto CLEANUP_SURF_FROM_ATTRIB;
    5134                 :            :           }
    5135                 :            : 
    5136         [ #  # ]:          0 :           CubitSense cubit_sense = sense == -1 ? CUBIT_REVERSED : CUBIT_FORWARD;
    5137                 :          0 :           PartitionCoEdge* coedge = 0;
    5138 [ #  # ][ #  # ]:          0 :           while ( (coedge = curve->next_coedge(coedge)) )
    5139                 :            :           {
    5140 [ #  # ][ #  # ]:          0 :             if ( coedge->sense() == cubit_sense &&
                 [ #  # ]
    5141 [ #  # ][ #  # ]:          0 :                  coedge->get_loop() &&
                 [ #  # ]
    5142 [ #  # ][ #  # ]:          0 :                  coedge->get_loop()->get_surface() == first_surf )
    5143                 :            :             {
    5144 [ #  # ][ #  # ]:          0 :               coedge->get_loop()->remove( coedge );
    5145                 :          0 :               break;
    5146                 :            :             }
    5147                 :            :           }
    5148         [ #  # ]:          0 :           if ( !coedge )
    5149                 :            :           {
    5150 [ #  # ][ #  # ]:          0 :             coedge = new PartitionCoEdge( first_surf, cubit_sense );
    5151         [ #  # ]:          0 :             curve->add(coedge);
    5152                 :            :           }
    5153                 :            :           
    5154 [ #  # ][ #  # ]:          0 :           if (!curve_coedge && curve->geometry_type() != POINT_CURVE_TYPE)
         [ #  # ][ #  # ]
    5155                 :          0 :             curve_coedge = coedge;
    5156                 :            :             
    5157         [ #  # ]:          0 :           new_loop->insert_after( coedge, prev_coedge );
    5158                 :          0 :           prev_coedge = coedge;
    5159                 :            :         }
    5160                 :            :       }
    5161                 :            :       
    5162         [ #  # ]:          0 :       if (!curve_coedge)
    5163                 :            :       {
    5164 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Nonexistant co-edge specified in saved connectivity.\n");
         [ #  # ][ #  # ]
    5165                 :          0 :         goto CLEANUP_SURF_FROM_ATTRIB;
    5166                 :            :       }
    5167                 :            :       
    5168         [ #  # ]:          0 :       PartitionSurface* new_surf = split_surface( first_surf, curve_coedge );
    5169 [ #  # ][ #  # ]:          0 :       if (new_surf == first_surf && attribs.size() > 0)
         [ #  # ][ #  # ]
    5170                 :            :       {
    5171 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Surface splitting failed -- bad topology?.\n");
         [ #  # ][ #  # ]
    5172                 :          0 :         goto CLEANUP_SURF_FROM_ATTRIB;
    5173                 :            :       }
    5174                 :            :             
    5175 [ #  # ][ #  # ]:          0 :       new_surf->sub_entity_set().set_id( new_surf, id );
                 [ #  # ]
    5176 [ #  # ][ #  # ]:          0 :       while ( loops.size() )
         [ #  # ][ #  # ]
    5177 [ #  # ][ #  # ]:          0 :         new_surf->add( loops.pop() );
    5178                 :          0 :     }
    5179                 :            : 
    5180                 :          0 :     result = CUBIT_SUCCESS;
    5181                 :            :   }
    5182                 :            :   
    5183                 :            : CLEANUP_SURF_FROM_ATTRIB:
    5184                 :            : 
    5185                 :            :     // clean up any unused loops from failed surface creation
    5186 [ #  # ][ #  # ]:          0 :   while ( loops.size() )
    5187                 :            :   {
    5188         [ #  # ]:          0 :     PartitionLoop* loop = loops.pop();
    5189 [ #  # ][ #  # ]:          0 :     while ( loop->first_coedge() )
    5190                 :            :     {
    5191         [ #  # ]:          0 :       PartitionCoEdge* coedge = loop->first_coedge();
    5192         [ #  # ]:          0 :       loop->remove(coedge);
    5193 [ #  # ][ #  # ]:          0 :       if (coedge->get_curve())
    5194 [ #  # ][ #  # ]:          0 :         coedge->get_curve()->remove(coedge);
    5195 [ #  # ][ #  # ]:          0 :       delete coedge;
    5196                 :            :     }
    5197 [ #  # ][ #  # ]:          0 :     delete loop;
    5198                 :            :   }  
    5199                 :            :     
    5200                 :            :     // first_surf will contain dead loops - clean them up
    5201                 :          0 :   PartitionLoop* surf_loop = 0;
    5202 [ #  # ][ #  # ]:          0 :   while ( (surf_loop = first_surf->next_loop( surf_loop ) ) != NULL )
    5203 [ #  # ][ #  # ]:          0 :     if ( !surf_loop->first_coedge() )
    5204         [ #  # ]:          0 :       loops.append( surf_loop );
    5205 [ #  # ][ #  # ]:          0 :   while ( loops.size() )
    5206                 :            :   {
    5207         [ #  # ]:          0 :     surf_loop = loops.pop();
    5208         [ #  # ]:          0 :     first_surf->remove( surf_loop );
    5209 [ #  # ][ #  # ]:          0 :     delete surf_loop;
    5210                 :            :   }
    5211                 :            :     
    5212         [ #  # ]:          0 :   new_geom.reset();
    5213 [ #  # ][ #  # ]:          0 :   while( new_geom.size() )
    5214                 :            :   {
    5215         [ #  # ]:          0 :     PartitionEntity* ent = new_geom.pop();
    5216 [ #  # ][ #  # ]:          0 :     if( PartitionPoint* pt = dynamic_cast<PartitionPoint*>(ent) )
    5217                 :            :     {
    5218 [ #  # ][ #  # ]:          0 :       if( !pt->next_curve(0) )
    5219 [ #  # ][ #  # ]:          0 :         delete pt;
    5220                 :            :     }
    5221 [ #  # ][ #  # ]:          0 :     else if( PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent) )
    5222                 :            :     {
    5223 [ #  # ][ #  # ]:          0 :       if( !curve->next_coedge(0) )
    5224 [ #  # ][ #  # ]:          0 :         delete curve;
    5225                 :            :     }
    5226                 :            :   }
    5227                 :            :   
    5228 [ #  # ][ #  # ]:          0 :   first_surf->sub_entity_set().renumerate( max_id + 1, true );
    5229                 :            :   
    5230         [ #  # ]:          0 :   if (!result)
    5231 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Error restoring surface partitions from attributes.\n");
         [ #  # ][ #  # ]
    5232                 :            :     
    5233         [ +  - ]:      11189 :   return result;
    5234                 :            : }
    5235                 :            : 
    5236                 :            : //-------------------------------------------------------------------------
    5237                 :            : // Purpose       : Restore volume partitions from an attribute
    5238                 :            : //
    5239                 :            : // Special Notes : 
    5240                 :            : //
    5241                 :            : // Creator       : Jason Kraftcheck
    5242                 :            : //
    5243                 :            : // Creation Date : 01/22/03
    5244                 :            : //-------------------------------------------------------------------------
    5245                 :       1613 : CubitStatus PartitionEngine::restore_from_attrib( Lump* lump )
    5246                 :            : {
    5247                 :       1613 :   int i, id, dim, max_id = 0;
    5248         [ +  - ]:       1613 :   DLIList<CubitSimpleAttrib> attribs;
    5249 [ +  - ][ +  - ]:       3226 :   DLIList<CubitVector*> positions;
    5250 [ +  - ][ +  - ]:       3226 :   DLIList<int> facets, connectivity, pt_owners;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    5251 [ +  - ][ +  - ]:       3226 :   DLIList<PartitionEntity*> new_geom;
    5252                 :       1613 :   CubitStatus result = CUBIT_FAILURE;
    5253                 :       1613 :   PartitionLump* first_lump = 0;
    5254                 :       1613 :   PartitionLump* new_lump = 0;
    5255                 :            :   
    5256                 :            :   { // pseudo-'try'-block
    5257                 :            :   
    5258                 :            :       // get partition attributes from entity.  Return if none.
    5259 [ +  - ][ +  - ]:       1613 :     lump->get_simple_attribute(PARTITION_GEOM_ATTRIB_NAME,attribs);
                 [ +  - ]
    5260 [ +  - ][ +  - ]:       1613 :     if( attribs.size() == 0 )
    5261                 :       1613 :       return CUBIT_SUCCESS;
    5262                 :            : 
    5263                 :            :       // find max ID
    5264         [ #  # ]:          0 :     attribs.reset();
    5265 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    5266                 :            :     {
    5267 [ #  # ][ #  # ]:          0 :       id = SubEntitySet::get_geom_id( attribs.get_and_step() );
    5268         [ #  # ]:          0 :       if( id > max_id )
    5269                 :          0 :         max_id = id;
    5270                 :            :     }
    5271                 :            : 
    5272                 :            :       // Create first parition lump (initially a duplicate of
    5273                 :            :       // the input lump)
    5274         [ #  # ]:          0 :     first_lump = replace_lump( lump );
    5275         [ #  # ]:          0 :     if( ! first_lump )
    5276                 :          0 :       goto CLEANUP_LUMP_FROM_ATTRIB;
    5277                 :            :     
    5278                 :            :       // Update SubEntitySet such that new entities get assigned
    5279                 :            :       // IDs greater than max_id when they are created.  This
    5280                 :            :       // leaves the range 0->max_id free so that we can reassign
    5281                 :            :       // the saved IDs after the entities are created.
    5282 [ #  # ][ #  # ]:          0 :     first_lump->sub_entity_set().renumerate( max_id + 1, false );
    5283                 :            : 
    5284                 :            :       // create all interior vertices
    5285         [ #  # ]:          0 :     attribs.reset();
    5286 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    5287                 :            :     {
    5288                 :            :         // skip any non-point geometry
    5289 [ #  # ][ #  # ]:          0 :       CubitSimpleAttrib attrib = attribs.get();
    5290 [ #  # ][ #  # ]:          0 :       if( SubEntitySet::get_geom_dimension(attrib) != 0 )
    5291                 :            :       {
    5292         [ #  # ]:          0 :         attribs.step();
    5293                 :          0 :         continue;
    5294                 :            :       }
    5295                 :            : 
    5296                 :            :         // create the point as specified in the attrib
    5297 [ #  # ][ #  # ]:          0 :       attribs.extract();
    5298         [ #  # ]:          0 :       lump->remove_simple_attribute_virt(attrib);
    5299 [ #  # ][ #  # ]:          0 :       PartitionPoint* new_pt = new PartitionPoint( attrib, first_lump );
                 [ #  # ]
    5300 [ #  # ][ #  # ]:          0 :       new_geom.append(new_pt);
         [ #  # ][ #  # ]
    5301                 :          0 :     }
    5302                 :            : 
    5303                 :            :       // create all interior curves
    5304         [ #  # ]:          0 :     attribs.reset();
    5305 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    5306                 :            :     {
    5307                 :            :         // skip attribs for anything but curves
    5308 [ #  # ][ #  # ]:          0 :       CubitSimpleAttrib attrib = attribs.get();
    5309 [ #  # ][ #  # ]:          0 :       if( SubEntitySet::get_geom_dimension(attrib) != 1 )
    5310                 :            :       {
    5311         [ #  # ]:          0 :         attribs.step();
    5312                 :          0 :         continue;
    5313                 :            :       }
    5314                 :            : 
    5315                 :            :         // create curve from attrib
    5316 [ #  # ][ #  # ]:          0 :       attribs.extract();
    5317         [ #  # ]:          0 :       lump->remove_simple_attribute_virt(attrib);
    5318 [ #  # ][ #  # ]:          0 :       SegmentedCurve* new_curve = SegmentedCurve::construct( attrib, first_lump );
    5319         [ #  # ]:          0 :       if( !new_curve )
    5320                 :          0 :         goto CLEANUP_LUMP_FROM_ATTRIB;
    5321                 :            : 
    5322 [ #  # ][ #  # ]:          0 :       new_geom.append(new_curve);
                 [ #  # ]
              [ #  #  # ]
    5323                 :          0 :     }
    5324                 :            : 
    5325                 :            :       // create all interior surfaces
    5326         [ #  # ]:          0 :     attribs.reset();
    5327 [ #  # ][ #  # ]:          0 :     for( i = attribs.size(); i--; )
    5328                 :            :     {
    5329                 :            :         // skip non-surface attributes
    5330 [ #  # ][ #  # ]:          0 :       CubitSimpleAttrib attrib = attribs.get();
    5331 [ #  # ][ #  # ]:          0 :       if( SubEntitySet::get_geom_dimension(attrib) != 2 )
    5332                 :            :       {
    5333         [ #  # ]:          0 :         attribs.step();
    5334                 :          0 :         continue;
    5335                 :            :       }
    5336                 :            : 
    5337                 :            :         // create surface from attribute
    5338 [ #  # ][ #  # ]:          0 :       attribs.extract();
    5339         [ #  # ]:          0 :       lump->remove_simple_attribute_virt(attrib);
    5340         [ #  # ]:          0 :       PartitionSurface* new_surf = PartitionSurface::construct( attrib, first_lump );
    5341         [ #  # ]:          0 :       if( !new_surf )
    5342                 :          0 :         goto CLEANUP_LUMP_FROM_ATTRIB;
    5343                 :            : 
    5344 [ #  # ][ #  # ]:          0 :       new_geom.append(new_surf);
                 [ #  # ]
              [ #  #  # ]
    5345                 :          0 :     }
    5346                 :            : 
    5347                 :            : 
    5348                 :            :       // while there are more volume partitions to create
    5349                 :          0 :     PartitionEntity* ent = 0;
    5350 [ #  # ][ #  # ]:          0 :     while( attribs.size() )
    5351                 :            :     {
    5352                 :            :         // Read data from attribute
    5353         [ #  # ]:          0 :       const CubitSimpleAttrib& attr = attribs.pop();
    5354         [ #  # ]:          0 :       connectivity.clean_out();
    5355                 :            :       CubitStatus s = SubEntitySet::
    5356         [ #  # ]:          0 :         read_geometry( id, dim, positions, facets, connectivity, pt_owners, attr );
    5357 [ #  # ][ #  # ]:          0 :       if( !s || dim != 3 || positions.size() || facets.size() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    5358                 :            :       {
    5359                 :          0 :         new_lump = 0;
    5360                 :          0 :         goto CLEANUP_LUMP_FROM_ATTRIB;
    5361                 :            :       }
    5362                 :            :       
    5363 [ #  # ][ #  # ]:          0 :       new_lump = new PartitionLump( first_lump );
    5364                 :            : 
    5365                 :            :         // Get list of bounding co-surfaces from attrib data
    5366         [ #  # ]:          0 :       int j = connectivity.size();
    5367         [ #  # ]:          0 :       while( j > 0 )
    5368                 :            :       {
    5369         [ #  # ]:          0 :         int shell = connectivity.get_and_step();
    5370                 :          0 :         j--;
    5371 [ #  # ][ #  # ]:          0 :         PartitionShell* new_shell = new PartitionShell();
    5372         [ #  # ]:          0 :         new_lump->add(new_shell);
    5373         [ #  # ]:          0 :         while( shell-- )
    5374                 :            :         {
    5375         [ #  # ]:          0 :           int set_id = connectivity.get_and_step();
    5376         [ #  # ]:          0 :           int ent_id = connectivity.get_and_step();
    5377                 :          0 :           j -= 2;
    5378                 :            :           
    5379                 :          0 :           CubitSense sense = CUBIT_FORWARD;
    5380         [ #  # ]:          0 :           if ( ent_id < 0 )
    5381                 :            :           {
    5382                 :          0 :             ent_id = -ent_id;
    5383                 :          0 :             sense = CUBIT_REVERSED;
    5384                 :            :           }
    5385                 :            : 
    5386 [ #  # ][ #  # ]:          0 :           ent = entity_from_id( set_id, ent_id, first_lump->sub_entity_set() );
    5387         [ #  # ]:          0 :           PartitionSurface* surf = dynamic_cast<PartitionSurface*>(ent);
    5388         [ #  # ]:          0 :           if(!surf)
    5389                 :          0 :             goto CLEANUP_LUMP_FROM_ATTRIB;
    5390                 :            : 
    5391 [ #  # ][ #  # ]:          0 :           PartitionCoSurf* new_cosurf = new PartitionCoSurf(sense);
    5392         [ #  # ]:          0 :           surf->add(new_cosurf);
    5393         [ #  # ]:          0 :           new_shell->add(new_cosurf);
    5394                 :            :         }
    5395                 :            :       }
    5396                 :            : 
    5397 [ #  # ][ #  # ]:          0 :       new_lump->sub_entity_set().set_id( new_lump, id );
                 [ #  # ]
    5398 [ #  # ][ #  # ]:          0 :       new_lump = 0;  // we succeeded with this one, so don't try to 
    5399                 :            :                      // destroy it if we fail before creating the next.
    5400                 :          0 :     }
    5401                 :            :     
    5402                 :          0 :     result = CUBIT_SUCCESS;
    5403                 :            :   }
    5404                 :            :   
    5405                 :            : CLEANUP_LUMP_FROM_ATTRIB:
    5406                 :            : 
    5407         [ #  # ]:          0 :   if( new_lump ) // created a lump but didn't successfully complete it
    5408                 :            :   {
    5409                 :          0 :     PartitionShell* shell = 0;
    5410         [ #  # ]:          0 :     while ( shell )
    5411                 :            :     {
    5412         [ #  # ]:          0 :       new_lump->remove(shell);
    5413         [ #  # ]:          0 :       shell->remove_all_surfaces();
    5414                 :          0 :       PartitionShell* old_shell = shell;
    5415         [ #  # ]:          0 :       shell = new_lump->next_shell(shell);
    5416 [ #  # ][ #  # ]:          0 :       delete old_shell;
    5417                 :            :     }
    5418                 :            :   }
    5419                 :            :   
    5420         [ #  # ]:          0 :   DLIList<PartitionEntity*> lump_list;
    5421         [ #  # ]:          0 :   if( first_lump )
    5422                 :            :   {
    5423                 :            :       // Get list of other lumps created
    5424 [ #  # ][ #  # ]:          0 :     first_lump->sub_entity_set().get_sub_entities( lump_list );
    5425 [ #  # ][ #  # ]:          0 :     lump_list.move_to(first_lump);
    5426 [ #  # ][ #  # ]:          0 :     assert( lump_list.get() == first_lump );
                 [ #  # ]
    5427         [ #  # ]:          0 :     lump_list.extract();
    5428                 :            :     
    5429                 :            :       // Destroy first_lump (it is the union of all the partitions)
    5430         [ #  # ]:          0 :     DLIList<PartitionSurface*> surfaces;
    5431                 :          0 :     PartitionShell* shell = 0;
    5432         [ #  # ]:          0 :     while ( shell )
    5433                 :            :     {
    5434         [ #  # ]:          0 :       first_lump->remove(shell);
    5435         [ #  # ]:          0 :       shell->remove_all_surfaces( &surfaces );
    5436                 :          0 :       PartitionShell* old_shell = shell;
    5437         [ #  # ]:          0 :       shell = first_lump->next_shell(shell);
    5438 [ #  # ][ #  # ]:          0 :       delete old_shell;
    5439 [ #  # ][ #  # ]:          0 :       while( surfaces.size() )
    5440                 :            :       {
    5441 [ #  # ][ #  # ]:          0 :         SubSurface* surf = dynamic_cast<SubSurface*>(surfaces.pop());
    5442 [ #  # ][ #  # ]:          0 :         if ( surf && !surf->next_co_surface(0) && 
         [ #  # ][ #  # ]
                 [ #  # ]
    5443 [ #  # ][ #  # ]:          0 :              !surf->sub_entity_set().has_lower_order() )
    5444         [ #  # ]:          0 :           restore_surface( surf );
    5445                 :            :       }
    5446                 :            :     }
    5447 [ #  # ][ #  # ]:          0 :     delete first_lump;
                 [ #  # ]
    5448                 :            :   }
    5449                 :            :   
    5450                 :            :     // destroy any unused split geometry
    5451         [ #  # ]:          0 :   new_geom.reset();
    5452 [ #  # ][ #  # ]:          0 :   while( new_geom.size() )
    5453                 :            :   {
    5454         [ #  # ]:          0 :     PartitionEntity* ent = new_geom.pop();
    5455 [ #  # ][ #  # ]:          0 :     if( PartitionPoint* pt = dynamic_cast<PartitionPoint*>(ent) )
    5456                 :            :     {
    5457 [ #  # ][ #  # ]:          0 :       if( !pt->next_curve(0) )
    5458 [ #  # ][ #  # ]:          0 :         delete pt;
    5459                 :            :     }
    5460 [ #  # ][ #  # ]:          0 :     else if( PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent) )
    5461                 :            :     {
    5462 [ #  # ][ #  # ]:          0 :       if( !curve->next_coedge(0) )
    5463 [ #  # ][ #  # ]:          0 :         delete curve;
    5464                 :            :     }
    5465 [ #  # ][ #  # ]:          0 :     else if( PartitionSurface* surf = dynamic_cast<PartitionSurface*>(ent) )
    5466                 :            :     {
    5467 [ #  # ][ #  # ]:          0 :       if( !surf->next_co_surface(0) )
    5468         [ #  # ]:          0 :         destroy_surface( surf );
    5469                 :            :     }
    5470                 :            :   }
    5471                 :            :   
    5472                 :            :     // if there are any remaining partitions of the volume,
    5473                 :            :     // compress the ID space
    5474 [ #  # ][ #  # ]:          0 :   if ( lump_list.size() )
    5475                 :            :   {
    5476 [ #  # ][ #  # ]:          0 :     lump_list.get()->sub_entity_set().renumerate( max_id + 1, true );
                 [ #  # ]
    5477                 :            :   }
    5478                 :            :   
    5479         [ #  # ]:          0 :   if (!result)
    5480 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Error restoring volume partitions from attributes.\n");
         [ #  # ][ #  # ]
    5481                 :            :     
    5482 [ #  # ][ +  - ]:       1613 :   return result;
    5483                 :            : }  
    5484                 :            : 
    5485                 :            :       
    5486                 :            : 
    5487                 :            : //-------------------------------------------------------------------------
    5488                 :            : // Purpose       : Save partition geometry
    5489                 :            : //
    5490                 :            : // Special Notes : 
    5491                 :            : //
    5492                 :            : // Creator       : Jason Kraftcheck
    5493                 :            : //
    5494                 :            : // Creation Date : 02/23/03
    5495                 :            : //-------------------------------------------------------------------------
    5496                 :        615 : CubitStatus PartitionEngine::export_geometry( DLIList<TopologyBridge*>& list )
    5497                 :            : {
    5498                 :            :   int i;
    5499                 :        615 :   CubitStatus result = CUBIT_SUCCESS;
    5500                 :            : 
    5501   [ +  +  +  - ]:       1032 :   if ( CGMApp::instance()->attrib_manager()->auto_update_flag(CA_PARTITION_VG) &&
                 [ +  + ]
    5502                 :        417 :        CGMApp::instance()->attrib_manager()->auto_write_flag(CA_PARTITION_VG) )
    5503                 :            :   {
    5504                 :            : 
    5505                 :            :       // Get all child topology to export
    5506                 :            : 
    5507         [ +  - ]:        417 :     DLIList<Curve*> curve_list;
    5508 [ +  - ][ +  - ]:        834 :     DLIList<Surface*> surface_list;
    5509 [ +  - ][ +  - ]:        834 :     DLIList<Lump*> lump_list;
    5510 [ +  - ][ +  - ]:        834 :     DLIList<BodySM*> body_list;
    5511 [ +  - ][ +  - ]:        834 :     DLIList<TopologyBridge*> bridge_list, temp_list, coe_curves(1), surf_curves;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    5512                 :            : 
    5513 [ +  - ][ +  - ]:       1149 :     CAST_LIST( list, curve_list, Curve );
         [ +  - ][ -  + ]
         [ -  + ][ #  # ]
                 [ +  + ]
    5514 [ +  - ][ +  - ]:       1149 :     CAST_LIST( list, surface_list, Surface );
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
                 [ +  + ]
    5515 [ +  - ][ +  - ]:       1149 :     CAST_LIST( list, lump_list, Lump );
         [ +  - ][ -  + ]
         [ -  + ][ #  # ]
                 [ +  + ]
    5516 [ +  - ][ +  - ]:       1149 :     CAST_LIST( list, body_list, BodySM );
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
                 [ +  + ]
    5517                 :            : 
    5518 [ +  - ][ +  + ]:       1138 :     for( i = body_list.size(); i--; )
    5519                 :            :     {
    5520         [ +  - ]:        721 :       BodySM* body = body_list.get_and_step();
    5521 [ +  - ][ +  - ]:        721 :       body->get_children( bridge_list, true, layer() );
    5522 [ +  - ][ +  + ]:       1452 :       while( bridge_list.size() )
    5523 [ +  - ][ -  + ]:        731 :         lump_list.append( dynamic_cast<Lump*>(bridge_list.pop()) );
                 [ +  - ]
    5524                 :            :     }
    5525                 :            : 
    5526 [ +  - ][ +  + ]:       1148 :     for( i = lump_list.size(); i--; )
    5527                 :            :     {
    5528         [ +  - ]:        731 :       Lump* lump = lump_list.get_and_step();
    5529 [ +  - ][ +  - ]:        731 :       lump->get_children( bridge_list, true, layer() );
    5530 [ +  - ][ +  + ]:       1462 :       while( bridge_list.size() )
    5531                 :            :       {
    5532 [ +  - ][ +  - ]:        731 :         bridge_list.pop()->get_children( temp_list, true, layer() );
                 [ +  - ]
    5533 [ +  - ][ +  + ]:       4294 :         while( temp_list.size() )
    5534 [ +  - ][ -  + ]:       3563 :           surface_list.append( dynamic_cast<Surface*>(temp_list.pop()) );
                 [ +  - ]
    5535                 :            :       }
    5536                 :            :     }
    5537                 :            : 
    5538 [ +  - ][ +  + ]:       3991 :     for( i = surface_list.size(); i--; )
    5539                 :            :     {
    5540         [ +  - ]:       3574 :       Surface* surf = surface_list.get_and_step();
    5541 [ +  - ][ +  - ]:       3574 :       surf->get_children( bridge_list, true, layer() );
    5542 [ +  - ][ +  + ]:       7384 :       while( bridge_list.size() )
    5543                 :            :       {
    5544 [ +  - ][ +  - ]:       3810 :         bridge_list.pop()->get_children( temp_list, true, layer() );
                 [ +  - ]
    5545 [ +  - ][ +  + ]:      17109 :         while( temp_list.size() )
    5546                 :            :         {
    5547 [ +  - ][ +  - ]:      13299 :           temp_list.pop()->get_children_virt( coe_curves );
    5548 [ +  - ][ -  + ]:      13299 :           assert(coe_curves.size() == 1);
    5549 [ +  - ][ +  - ]:      13299 :           surf_curves.append(coe_curves.pop());
    5550                 :            :         }
    5551                 :            :       }
    5552         [ +  - ]:       3574 :       surf_curves.uniquify_ordered();
    5553 [ +  - ][ +  + ]:      16445 :       while( surf_curves.size() )
    5554 [ +  - ][ -  + ]:      12871 :         curve_list.append( dynamic_cast<Curve*>(surf_curves.pop()) );
                 [ +  - ]
    5555                 :            :     }
    5556                 :            : 
    5557                 :            : 
    5558                 :            :       // save curve partitions
    5559                 :            : 
    5560 [ +  - ][ +  - ]:        834 :     DLIList<SubEntitySet*> set_list;
    5561 [ +  - ][ +  + ]:      13288 :     for( i = curve_list.size(); i--; )
    5562                 :            :     {
    5563 [ +  - ][ -  + ]:      12871 :       SubCurve* curve = dynamic_cast<SubCurve*>(curve_list.get_and_step());
    5564         [ -  + ]:      12871 :       if( curve )
    5565 [ #  # ][ #  # ]:          0 :         set_list.append( &(curve->sub_entity_set()) );
    5566                 :            :     }
    5567         [ +  - ]:        417 :     set_list.uniquify_ordered();
    5568 [ +  - ][ -  + ]:        417 :     for( i = set_list.size(); i--; )
    5569 [ #  # ][ #  # ]:          0 :       if( ! set_list.get_and_step()->save_geometry() )
                 [ #  # ]
    5570                 :          0 :         result = CUBIT_FAILURE;
    5571                 :            : 
    5572                 :            : 
    5573                 :            :       // save surface partitions
    5574                 :            : 
    5575         [ +  - ]:        417 :     set_list.clean_out();
    5576 [ +  - ][ +  + ]:       3991 :     for( i = surface_list.size(); i--; )
    5577                 :            :     {
    5578 [ +  - ][ -  + ]:       3574 :       SubSurface* surf = dynamic_cast<SubSurface*>(surface_list.get_and_step());
    5579         [ -  + ]:       3574 :       if( surf )
    5580 [ #  # ][ #  # ]:          0 :         set_list.append( &(surf->sub_entity_set()) );
    5581                 :            :     }
    5582         [ +  - ]:        417 :     set_list.uniquify_ordered();
    5583 [ +  - ][ -  + ]:        417 :     for( i = set_list.size(); i--; )
    5584 [ #  # ][ #  # ]:          0 :       if( ! set_list.get_and_step()->save_geometry() )
                 [ #  # ]
    5585                 :          0 :         result = CUBIT_FAILURE;
    5586                 :            : 
    5587                 :            : 
    5588                 :            :       // save volume partitions
    5589                 :            : 
    5590         [ +  - ]:        417 :     set_list.clean_out();
    5591 [ +  - ][ +  + ]:       1148 :     for( i = lump_list.size(); i--; )
    5592                 :            :     {
    5593 [ +  - ][ -  + ]:        731 :       PartitionLump* lump = dynamic_cast<PartitionLump*>(lump_list.get_and_step());
    5594         [ -  + ]:        731 :       if( lump )
    5595 [ #  # ][ #  # ]:          0 :         set_list.append( &(lump->sub_entity_set()) );
    5596                 :            :     }
    5597         [ +  - ]:        417 :     set_list.uniquify_ordered();
    5598 [ +  - ][ -  + ]:        417 :     for( i = set_list.size(); i--; )
    5599 [ #  # ][ #  # ]:          0 :       if( ! set_list.get_and_step()->save_geometry() )
                 [ #  # ]
    5600         [ +  - ]:        417 :         result = CUBIT_FAILURE;
    5601                 :            :   }
    5602                 :            :     
    5603                 :            :     // replace partitions in passed list with the real
    5604                 :            :     // entities they partition
    5605                 :            :   
    5606                 :        615 :   PartitionEntity* p_ent = 0; 
    5607                 :        615 :   list.last() ;
    5608         [ +  + ]:       2711 :   for ( i = list.size(); i--; )
    5609                 :            :   {
    5610 [ -  + ][ -  + ]:       2096 :     if( (p_ent = dynamic_cast<PartitionEntity*>(list.step_and_get())) )
    5611                 :            :     {
    5612 [ #  # ][ #  # ]:          0 :       if( list.is_in_list(p_ent->partitioned_entity()) )
    5613                 :          0 :         list.change_to(0);
    5614                 :            :       else
    5615                 :          0 :         list.change_to(p_ent->partitioned_entity());
    5616                 :            :     }
    5617                 :            :   }
    5618         [ +  - ]:        615 :   list.remove_all_with_value(0);
    5619                 :            :   
    5620                 :        615 :   return result;
    5621                 :            : }
    5622                 :            : 
    5623                 :            : 
    5624                 :            : //-------------------------------------------------------------------------
    5625                 :            : // Purpose       : Restore form attributes
    5626                 :            : //
    5627                 :            : // Special Notes : 
    5628                 :            : //
    5629                 :            : // Creator       : Jason Kraftcheck
    5630                 :            : //
    5631                 :            : // Creation Date : 01/23/03
    5632                 :            : //-------------------------------------------------------------------------
    5633                 :       1257 : CubitStatus PartitionEngine::import_geometry( DLIList<TopologyBridge*>& list )
    5634                 :            : {
    5635                 :            :   int i;
    5636                 :       1257 :   CubitStatus result = CUBIT_SUCCESS;
    5637                 :            :   
    5638 [ +  - ][ +  - ]:       2514 :   DLIList<Curve*> curve_list, temp_curves;
                 [ +  - ]
    5639 [ +  - ][ +  - ]:       2514 :   DLIList<Surface*> surface_list, temp_surfaces;
         [ +  - ][ +  - ]
    5640 [ +  - ][ +  - ]:       2514 :   DLIList<Lump*> lump_list, temp_lumps;
         [ +  - ][ +  - ]
    5641 [ +  - ][ +  - ]:       2514 :   DLIList<BodySM*> body_list;
    5642                 :            :   
    5643 [ +  - ][ +  - ]:       3410 :   CAST_LIST( list, curve_list, Curve );
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
                 [ +  + ]
    5644 [ +  - ][ +  - ]:       3410 :   CAST_LIST( list, surface_list, Surface );
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
                 [ +  + ]
    5645 [ +  - ][ +  - ]:       3410 :   CAST_LIST( list, lump_list, Lump );
         [ +  - ][ -  + ]
         [ -  + ][ #  # ]
                 [ +  + ]
    5646 [ +  - ][ +  - ]:       3410 :   CAST_LIST( list, body_list, BodySM );
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
                 [ +  + ]
    5647                 :            :   
    5648 [ +  - ][ +  + ]:       3201 :   for( i = body_list.size(); i--; )
    5649                 :            :   {
    5650         [ +  - ]:       1944 :     temp_lumps.clean_out();
    5651 [ +  - ][ +  - ]:       1944 :     body_list.get_and_step()->lumps( temp_lumps );
    5652         [ +  - ]:       1944 :     lump_list += temp_lumps;
    5653                 :            :   }
    5654                 :            :   
    5655 [ +  - ][ +  + ]:       3397 :   for( i = lump_list.size(); i--; )
    5656                 :            :   {
    5657         [ +  - ]:       2140 :     temp_surfaces.clean_out();
    5658 [ +  - ][ +  - ]:       2140 :     lump_list.get_and_step()->surfaces( temp_surfaces );
    5659         [ +  - ]:       2140 :     surface_list += temp_surfaces;
    5660                 :            :   }
    5661                 :            :   
    5662 [ +  - ][ +  + ]:      15091 :   for( i = surface_list.size(); i--; )
    5663                 :            :   {
    5664         [ +  - ]:      13834 :     temp_curves.clean_out();
    5665 [ +  - ][ +  - ]:      13834 :     surface_list.get_and_step()->curves( temp_curves );
    5666         [ +  - ]:      13834 :     curve_list += temp_curves;
    5667                 :            :   }
    5668                 :            :   
    5669                 :            :   
    5670 [ +  - ][ +  - ]:       2317 :   if ( CGMApp::instance()->attrib_manager()->auto_actuate_flag(CA_PARTITION_VG) &&
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
    5671 [ +  - ][ +  - ]:       1060 :        CGMApp::instance()->attrib_manager()->auto_read_flag(CA_PARTITION_VG) )
                 [ +  - ]
    5672                 :            :   {
    5673                 :            :   
    5674         [ +  - ]:       1060 :     curve_list.uniquify_ordered();
    5675 [ +  - ][ +  + ]:      24335 :     for( i = curve_list.size(); i--; )
    5676 [ +  - ][ +  - ]:      23275 :       if( ! restore_from_attrib( curve_list.get_and_step() ) )
                 [ -  + ]
    5677                 :          0 :         result = CUBIT_FAILURE;
    5678                 :            : 
    5679         [ +  - ]:       1060 :     surface_list.uniquify_ordered();
    5680 [ +  - ][ +  + ]:      12249 :     for( i = surface_list.size(); i--; )
    5681 [ +  - ][ +  - ]:      11189 :       if( ! restore_from_attrib( surface_list.get_and_step() ) )
                 [ -  + ]
    5682                 :          0 :         result = CUBIT_FAILURE;
    5683                 :            : 
    5684         [ +  - ]:       1060 :     lump_list.uniquify_ordered();
    5685 [ +  - ][ +  + ]:       2673 :     for( i = lump_list.size(); i--; )
    5686 [ +  - ][ +  - ]:       1613 :       if( ! restore_from_attrib( lump_list.get_and_step() ) )
                 [ -  + ]
    5687                 :          0 :         result = CUBIT_FAILURE;
    5688                 :            : 
    5689                 :            :       // update imported list
    5690         [ +  - ]:       1060 :     list.last();
    5691         [ +  - ]:       1060 :     DLIList<PartitionEntity*> entity_list;
    5692 [ +  - ][ +  - ]:       2120 :     DLIList<TopologyBridge*> temp_list;
    5693 [ +  - ][ +  + ]:       2499 :     for( i = list.size(); i--; )
    5694                 :            :     {
    5695         [ +  - ]:       1439 :       TopologyBridge* bridge = list.step_and_get();
    5696 [ +  - ][ +  + ]:       1439 :       SubEntitySet* set = dynamic_cast<SubEntitySet*>(bridge->owner());
    5697         [ +  - ]:       1439 :       if( !set ) continue;
    5698                 :            : 
    5699         [ #  # ]:          0 :       entity_list.clean_out();
    5700         [ #  # ]:          0 :       temp_list.clean_out();
    5701         [ #  # ]:          0 :       set->get_sub_entities( entity_list );
    5702 [ #  # ][ #  # ]:          0 :       CAST_LIST( entity_list, temp_list, TopologyBridge );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    5703                 :            : 
    5704         [ #  # ]:          0 :       temp_list.reset();
    5705 [ #  # ][ #  # ]:          0 :       list.change_to( temp_list.get_and_step() );
    5706 [ #  # ][ #  # ]:          0 :       for( int j = temp_list.size(); j > 1; j-- )
    5707 [ #  # ][ #  # ]:          0 :         list.append( temp_list.get_and_step() );
    5708         [ +  - ]:       1060 :     }
    5709                 :            :   }
    5710                 :            :   else
    5711                 :            :   {
    5712         [ +  - ]:        197 :     curve_list.uniquify_ordered();
    5713         [ +  - ]:        197 :     surface_list.uniquify_ordered();
    5714         [ +  - ]:        197 :     lump_list.uniquify_ordered();
    5715                 :            :     
    5716 [ +  - ][ +  - ]:        394 :     DLIList<TopologyBridge*> point_list(curve_list.size()*2), tmp_points(2);
         [ +  - ][ +  - ]
    5717 [ +  - ][ +  + ]:       7621 :     for ( i = curve_list.size(); i--; )
    5718                 :            :     {
    5719         [ +  - ]:       7424 :       tmp_points.clean_out();
    5720 [ +  - ][ +  - ]:       7424 :       curve_list.get()->get_children(tmp_points);
    5721         [ +  - ]:       7424 :       point_list += tmp_points;
    5722 [ +  - ][ +  - ]:       7424 :       SubEntitySet::strip_attributes( curve_list.get_and_step() );
    5723                 :            :     }
    5724         [ +  - ]:        197 :     point_list.uniquify_ordered();
    5725 [ +  - ][ +  + ]:       6019 :     for ( i = point_list.size(); i--; )
    5726 [ +  - ][ +  - ]:       5822 :       SubEntitySet::strip_attributes( point_list.get_and_step() );
    5727 [ +  - ][ +  + ]:       2842 :     for ( i = surface_list.size(); i--; )
    5728 [ +  - ][ +  - ]:       2645 :       SubEntitySet::strip_attributes( surface_list.get_and_step() );
    5729 [ +  - ][ +  + ]:        724 :     for ( i = lump_list.size(); i--; )
    5730 [ +  - ][ +  - ]:        724 :       SubEntitySet::strip_attributes( lump_list.get_and_step() );
                 [ +  - ]
    5731                 :            :   }
    5732                 :            :     
    5733         [ +  - ]:       1257 :   return result;
    5734                 :            : }
    5735                 :            : /*
    5736                 :            : void PartitionEngine::destroy_facet( CubitFacetData* facet )
    5737                 :            : {
    5738                 :            :   int i;
    5739                 :            : 
    5740                 :            :   for( i = 0; i < 3; i++ )
    5741                 :            :   {
    5742                 :            :     CubitFacetEdgeData* edge = dynamic_cast<CubitFacetEdgeData*>(facet->edge(i));
    5743                 :            :     if( edge )
    5744                 :            :     {
    5745                 :            :       facet->edge(0, i);
    5746                 :            :       if( edge->number_tris() == 0 )
    5747                 :            :         delete edge;
    5748                 :            :     }
    5749                 :            :   }
    5750                 :            : 
    5751                 :            :   for( i = 0; i < 3; i++ )
    5752                 :            :   {
    5753                 :            :     CubitPointData* point = dynamic_cast<CubitPointData*>(facet->point(0));
    5754                 :            :     assert(point);
    5755                 :            :     point->remove_facet( facet );
    5756                 :            :     if( point->num_adj_facets() == 0 )
    5757                 :            :       delete point;
    5758                 :            :   }
    5759                 :            :   
    5760                 :            :   delete facet;
    5761                 :            : }
    5762                 :            : */
    5763                 :            : //-------------------------------------------------------------------------
    5764                 :            : // Purpose       : Core functionality of make_body( X* ) methods.
    5765                 :            : //
    5766                 :            : // Special Notes : 
    5767                 :            : //
    5768                 :            : // Creator       : Jason Kraftcheck
    5769                 :            : //
    5770                 :            : // Creation Date : 02/23/03
    5771                 :            : //-------------------------------------------------------------------------
    5772                 :          0 : PartitionBody* PartitionEngine::make_body_internal( TopologyBridge* bridge )
    5773                 :            : {
    5774                 :            :     // query topology for BodySM
    5775         [ #  # ]:          0 :   DLIList<TopologyBridge*> list;
    5776                 :            :   BodySM* body;
    5777 [ #  # ][ #  # ]:          0 :   while( !(body = dynamic_cast<BodySM*>(bridge)) )
    5778                 :            :   {
    5779         [ #  # ]:          0 :     list.clean_out();
    5780         [ #  # ]:          0 :     bridge->get_parents_virt(list);
    5781 [ #  # ][ #  # ]:          0 :     if( !list.size() )
    5782                 :          0 :       return 0;
    5783         [ #  # ]:          0 :     bridge = list.get();
    5784                 :            :   }
    5785                 :            :   
    5786 [ #  # ][ #  # ]:          0 :   SubEntitySet* set = dynamic_cast<SubEntitySet*>(body->owner());
    5787         [ #  # ]:          0 :   if( set )
    5788         [ #  # ]:          0 :     return set->body();
    5789                 :            :   
    5790 [ #  # ][ #  # ]:          0 :   PartitionBody* result = new PartitionBody(body);
    5791 [ #  # ][ #  # ]:          0 :   if( body->owner() )
    5792 [ #  # ][ #  # ]:          0 :     body->owner()->swap_bridge( body, result, false );
    5793 [ #  # ][ #  # ]:          0 :   body->owner( &(result->sub_entity_set()) );
    5794         [ #  # ]:          0 :   return result;
    5795                 :            : }
    5796                 :            : 
    5797                 :            : //-------------------------------------------------------------------------
    5798                 :            : // Purpose       : Find or make an owning bodySM
    5799                 :            : //
    5800                 :            : // Special Notes : 
    5801                 :            : //
    5802                 :            : // Creator       : Jason Kraftcheck
    5803                 :            : //
    5804                 :            : // Creation Date : 02/23/03
    5805                 :            : //-------------------------------------------------------------------------
    5806                 :          0 : PartitionBody* PartitionEngine::make_body( PartitionLump* lump )
    5807                 :            : {
    5808         [ #  # ]:          0 :   if( lump->get_body() )
    5809                 :          0 :     return lump->get_body();
    5810                 :            :   
    5811                 :          0 :   return make_body_internal( lump );
    5812                 :            : }
    5813                 :            : 
    5814                 :            : //-------------------------------------------------------------------------
    5815                 :            : // Purpose       : Find or make an owning bodySM
    5816                 :            : //
    5817                 :            : // Special Notes : 
    5818                 :            : //
    5819                 :            : // Creator       : Jason Kraftcheck
    5820                 :            : //
    5821                 :            : // Creation Date : 02/23/03
    5822                 :            : //-------------------------------------------------------------------------
    5823                 :          0 : PartitionBody* PartitionEngine::make_body( PartitionSurface* surf )
    5824                 :            : {
    5825         [ #  # ]:          0 :   if( surf->sub_entity_set().body() )
    5826                 :          0 :     return surf->sub_entity_set().body();
    5827                 :            :     
    5828         [ #  # ]:          0 :   if( surf->next_co_surface(0) )
    5829                 :          0 :     return make_body(surf->next_co_surface(0)->get_shell()->get_lump());
    5830                 :            :   
    5831                 :          0 :   return make_body_internal(surf);
    5832                 :            : }
    5833                 :            : 
    5834                 :            : //-------------------------------------------------------------------------
    5835                 :            : // Purpose       : Find or make an owning bodySM
    5836                 :            : //
    5837                 :            : // Special Notes : 
    5838                 :            : //
    5839                 :            : // Creator       : Jason Kraftcheck
    5840                 :            : //
    5841                 :            : // Creation Date : 02/23/03
    5842                 :            : //-------------------------------------------------------------------------
    5843                 :          0 : PartitionBody* PartitionEngine::make_body( PartitionCurve* curve )
    5844                 :            : {
    5845         [ #  # ]:          0 :   if( curve->sub_entity_set().body() )
    5846                 :          0 :     return curve->sub_entity_set().body();
    5847                 :            :     
    5848                 :          0 :   PartitionCoEdge* coedge = 0;
    5849         [ #  # ]:          0 :   while( (coedge = curve->next_coedge(coedge)) )
    5850         [ #  # ]:          0 :     if( coedge->get_loop() )
    5851                 :          0 :       return make_body(coedge->get_loop()->get_surface());
    5852                 :            :   
    5853                 :          0 :   return make_body_internal(curve);
    5854                 :            : }
    5855                 :            :  
    5856                 :            : //-------------------------------------------------------------------------
    5857                 :            : // Purpose       : Find or make an owning bodySM
    5858                 :            : //
    5859                 :            : // Special Notes : 
    5860                 :            : //
    5861                 :            : // Creator       : Jason Kraftcheck
    5862                 :            : //
    5863                 :            : // Creation Date : 02/23/03
    5864                 :            : //-------------------------------------------------------------------------
    5865                 :          0 : PartitionBody* PartitionEngine::make_body( PartitionPoint* pt )
    5866                 :            : {
    5867         [ #  # ]:          0 :   if( pt->sub_entity_set().body() )
    5868                 :          0 :     return pt->sub_entity_set().body();
    5869                 :            :     
    5870         [ #  # ]:          0 :   if( pt->next_curve(0) )
    5871                 :          0 :     return make_body(pt->next_curve(0));
    5872                 :            :  
    5873                 :          0 :   return make_body_internal(pt);
    5874                 :            : }
    5875                 :          0 : static CubitStatus get_edge_replacements(
    5876                 :            :                          std::vector<CubitFacetData*> &facet_list,
    5877                 :            :                          std::vector<CubitFacetEdgeData*> replace_edge_lists[3])
    5878                 :            : {
    5879                 :            :   // first facet is the facet to replace
    5880                 :            :   // make sure more than one facet to replace the first
    5881 [ #  # ][ #  # ]:          0 :   assert(facet_list.size() > 2);
    5882                 :            : 
    5883                 :            :   // make sure the lists of replacement edges are empty
    5884 [ #  # ][ #  # ]:          0 :   assert(replace_edge_lists[0].size() == 0);
    5885 [ #  # ][ #  # ]:          0 :   assert(replace_edge_lists[1].size() == 0);
    5886 [ #  # ][ #  # ]:          0 :   assert(replace_edge_lists[2].size() == 0);
    5887                 :            : 
    5888                 :            : 
    5889         [ #  # ]:          0 :   CubitFacetData* p_dead = facet_list[0]; // facet to be replaced
    5890                 :            : 
    5891                 :            :   // look for edges on the facet that are owned by curves
    5892                 :            :   int i;
    5893                 :            :   //int replace_edge = 0;
    5894                 :            : 
    5895                 :            :   // get the edges
    5896                 :            :   CubitFacetEdgeData *edges[3];
    5897         [ #  # ]:          0 :   for (i=0; i<3; i++)
    5898                 :            :   {
    5899 [ #  # ][ #  # ]:          0 :     edges[i] = CAST_TO(p_dead->edge(i), CubitFacetEdgeData);
    5900         [ #  # ]:          0 :     assert(edges[i] != NULL);
    5901                 :            :   }
    5902                 :            : 
    5903                 :            :   PartitionEntity *p_owner;
    5904                 :            :   PartitionCurve *p_curve;
    5905                 :            : 
    5906                 :            :   // see if any are owned by a curve
    5907                 :          0 :   CubitBoolean b_boundary = CUBIT_FALSE;
    5908 [ #  # ][ #  # ]:          0 :   for (i=0; i<3 && !b_boundary; i++)
    5909                 :            :   {
    5910         [ #  # ]:          0 :     p_owner = TDVGFacetOwner::get(edges[i]);
    5911         [ #  # ]:          0 :     p_curve = CAST_TO(p_owner, PartitionCurve);
    5912         [ #  # ]:          0 :     if (p_curve)
    5913                 :          0 :       b_boundary = CUBIT_TRUE;
    5914                 :            :   }
    5915                 :            : 
    5916                 :            :   // if the facet has an edge on a curve, replace the edge with the edges of the
    5917                 :            :   // replacement facets and split the facet on the adjacent surface.
    5918         [ #  # ]:          0 :   if (b_boundary)
    5919                 :            :   {
    5920                 :            :     // make a list with just the new facets -- skip the first facet
    5921 [ #  # ][ #  # ]:          0 :     DLIList<CubitFacet*> new_facets(facet_list.size() - 1);
    5922 [ #  # ][ #  # ]:          0 :     for (unsigned u = 1; u < facet_list.size(); u++)
    5923 [ #  # ][ #  # ]:          0 :       new_facets.append(facet_list[u]);
    5924                 :            : 
    5925                 :            :     // get a point edge chain around the boundary of the replacement facets
    5926 [ #  # ][ #  # ]:          0 :     DLIList<FacetEntity*> point_edge_chain;
                 [ #  # ]
    5927         [ #  # ]:          0 :     FacetDataUtil::ordered_point_edge_bdry(new_facets, point_edge_chain);
    5928                 :            : 
    5929                 :            :     // for each edge on a curve get corresponding points and edges from the
    5930                 :            :     // replacement facets
    5931                 :            :     //std::vector<CubitFacetEdgeData*>::iterator eitor;
    5932 [ #  # ][ #  # ]:          0 :     for (i=0; i<3; i++)
                 [ #  # ]
    5933                 :            :     {
    5934         [ #  # ]:          0 :       p_owner = TDVGFacetOwner::get(edges[i]);
    5935         [ #  # ]:          0 :       p_curve = CAST_TO(p_owner, PartitionCurve);
    5936         [ #  # ]:          0 :       if (p_curve)
    5937                 :            :       {
    5938                 :            :         // fill the replacement list for this edge
    5939                 :            :         // add the edge to be replaced first
    5940                 :            :         //eitor = replace_edge_lists[i].begin();
    5941                 :            : 
    5942                 :            :         // get the points from the edge of the dead facet - in the correct order
    5943                 :            :         CubitPoint* pt1;
    5944                 :            :         CubitPoint* pt2;
    5945                 :            : 
    5946         [ #  # ]:          0 :         p_dead->get_edge_pts(i, pt1, pt2);
    5947                 :            : 
    5948                 :            :         // get the corresponding chain of points and edges from the replacement facets
    5949         [ #  # ]:          0 :         DLIList<FacetEntity*> replacement_chain;
    5950                 :            :         CubitStatus res = FacetDataUtil::partial_chain(point_edge_chain,
    5951         [ #  # ]:          0 :                                          pt1, pt2, replacement_chain);
    5952         [ #  # ]:          0 :         if (CUBIT_FAILURE == res)
    5953                 :          0 :           return CUBIT_FAILURE;
    5954                 :            : 
    5955                 :            :         // there should be an odd number of list entries, since it includes points
    5956                 :            :         // and edges, beginning and ending with a point
    5957 [ #  # ][ #  # ]:          0 :         assert( (replacement_chain.size() % 2) == 1 );
    5958                 :            : 
    5959                 :            :         // if only one replacement edge, it should be the same edge
    5960         [ #  # ]:          0 :         replacement_chain.reset();
    5961 [ #  # ][ #  # ]:          0 :         if (replacement_chain.size() == 3)
    5962                 :            :         {
    5963 [ #  # ][ #  # ]:          0 :           assert(replacement_chain.next(1) == edges[i]);
    5964                 :            :         }
    5965                 :            :         else
    5966                 :            :         {
    5967                 :            :           // add the replacement edges to the list - edge to replace first
    5968                 :            :           //*eitor++ = edges[i];
    5969         [ #  # ]:          0 :           replace_edge_lists[i].push_back(edges[i]);
    5970                 :            :           int j;
    5971                 :            :           CubitFacetEdgeData* p_edge;
    5972 [ #  # ][ #  # ]:          0 :           for (j=1; j<replacement_chain.size(); j+=2)
         [ #  # ][ #  # ]
    5973                 :            :           {
    5974                 :            :             //replacement_chain.step();
    5975 [ #  # ][ #  # ]:          0 :             p_edge = CAST_TO(replacement_chain.next(j), CubitFacetEdgeData);
    5976         [ #  # ]:          0 :             assert(p_edge != NULL);
    5977                 :            :             //*eitor++ = p_edge;
    5978         [ #  # ]:          0 :             replace_edge_lists[i].push_back(p_edge);
    5979                 :            :           }
    5980                 :          0 :         }
    5981                 :            :       }
    5982                 :          0 :     }
    5983                 :            :   }
    5984                 :            : 
    5985                 :          0 :   return CUBIT_SUCCESS;
    5986                 :            : }
    5987                 :            : 
    5988                 :            : //-------------------------------------------------------------------------
    5989                 :            : // Purpose       : clean up for deleted geometry
    5990                 :            : //
    5991                 :            : // Special Notes : 
    5992                 :            : //
    5993                 :            : // Creator       : Jason Kraftcheck
    5994                 :            : //
    5995                 :            : // Creation Date : 04/03/03
    5996                 :            : //-------------------------------------------------------------------------
    5997                 :          0 : CubitStatus PartitionEngine::delete_solid_model_entities( 
    5998                 :            :                                 PartitionBody* body, BodySM*& real_body )
    5999                 :            : {
    6000                 :          0 :   real_body = body->real_body();
    6001                 :          0 :   body->destroy_all_children();
    6002                 :          0 :   return CUBIT_SUCCESS;
    6003                 :            : }
    6004                 :            : 
    6005                 :          0 : CubitStatus PartitionEngine::delete_solid_model_entities(
    6006                 :            :                                 PartitionSurface* surf, 
    6007                 :            :                                 Surface*& real_surf )
    6008                 :            : {
    6009         [ #  # ]:          0 :   DLIList<TopologyBridge*> parents(0);
    6010         [ #  # ]:          0 :   surf->get_parents_virt(parents);
    6011 [ #  # ][ #  # ]:          0 :   if ( parents.size() )
    6012                 :          0 :     return CUBIT_FAILURE;
    6013                 :            :   
    6014                 :          0 :   real_surf = 0;
    6015 [ #  # ][ #  # ]:          0 :   if ( !surf->sub_entity_set().has_multiple_sub_entities() )
                 [ #  # ]
    6016 [ #  # ][ #  # ]:          0 :     real_surf = dynamic_cast<Surface*>(surf->partitioned_entity());
    6017         [ #  # ]:          0 :   destroy_surface(surf);
    6018         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6019                 :            : }
    6020                 :            : 
    6021                 :          0 : CubitStatus PartitionEngine::delete_solid_model_entities(
    6022                 :            :                                 PartitionCurve* curve,
    6023                 :            :                                 Curve*& real_curve )
    6024                 :            : {
    6025         [ #  # ]:          0 :   if( curve->next_coedge(0) )
    6026                 :          0 :     return CUBIT_FAILURE;
    6027                 :            :     
    6028                 :          0 :   real_curve = 0;
    6029         [ #  # ]:          0 :   if ( !curve->sub_entity_set().has_multiple_sub_entities() )
    6030         [ #  # ]:          0 :     real_curve = dynamic_cast<Curve*>(curve->partitioned_entity());
    6031                 :          0 :   PartitionPoint* start = curve->start_point();
    6032                 :          0 :   PartitionPoint* end = curve->end_point();
    6033         [ #  # ]:          0 :   delete curve;
    6034         [ #  # ]:          0 :   if ( start->num_curves() == 0 )
    6035         [ #  # ]:          0 :     delete start;
    6036         [ #  # ]:          0 :   if ( end->num_curves() == 0 )
    6037         [ #  # ]:          0 :     delete end;
    6038                 :          0 :   return CUBIT_SUCCESS;
    6039                 :            : }
    6040                 :            : 
    6041                 :          0 : CubitStatus PartitionEngine::translate( PartitionEntity* ent, 
    6042                 :            :                                         const CubitVector& delta )
    6043                 :            : {
    6044 [ #  # ][ #  # ]:          0 :   GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
    6045 [ #  # ][ #  # ]:          0 :   if (!geom->get_geometry_query_engine()->translate( geom, delta ))
                 [ #  # ]
    6046                 :          0 :     return CUBIT_FAILURE;
    6047                 :            :   
    6048         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6049         [ #  # ]:          0 :   xform.translate( delta );
    6050         [ #  # ]:          0 :   notify_transform_internal( geom, xform );
    6051         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6052                 :            : }
    6053                 :            :   
    6054                 :          0 : CubitStatus PartitionEngine::rotate( PartitionEntity* ent, 
    6055                 :            :                                      const CubitVector& axis, 
    6056                 :            :                                      double degrees )
    6057                 :            : {
    6058 [ #  # ][ #  # ]:          0 :   GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
    6059 [ #  # ][ #  # ]:          0 :   if (!geom->get_geometry_query_engine()->rotate( geom, axis, degrees ))
                 [ #  # ]
    6060                 :          0 :     return CUBIT_FAILURE;
    6061                 :            :   
    6062         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6063         [ #  # ]:          0 :   xform.rotate( degrees, axis );
    6064         [ #  # ]:          0 :   notify_transform_internal( geom, xform );
    6065         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6066                 :            : }
    6067                 :            : 
    6068                 :          0 : CubitStatus PartitionEngine::scale( PartitionEntity* ent, 
    6069                 :            :                                     const CubitVector& factors )
    6070                 :            : {
    6071 [ #  # ][ #  # ]:          0 :   GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
    6072 [ #  # ][ #  # ]:          0 :   if (!geom->get_geometry_query_engine()->scale( geom, factors ))
                 [ #  # ]
    6073                 :          0 :     return CUBIT_FAILURE;
    6074                 :            :   
    6075         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6076         [ #  # ]:          0 :   xform.scale_about_origin( factors );
    6077         [ #  # ]:          0 :   notify_transform_internal( geom, xform );
    6078         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6079                 :            : }
    6080                 :            : 
    6081                 :          0 : CubitStatus PartitionEngine::reflect( PartitionEntity* ent, 
    6082                 :            :                                       const CubitVector& axis )
    6083                 :            : {
    6084 [ #  # ][ #  # ]:          0 :   GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
    6085 [ #  # ][ #  # ]:          0 :   if (!geom->get_geometry_query_engine()->reflect( geom, axis ))
                 [ #  # ]
    6086                 :          0 :     return CUBIT_FAILURE;
    6087                 :            :   
    6088         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6089         [ #  # ]:          0 :   xform.reflect( axis );
    6090         [ #  # ]:          0 :   notify_transform_internal( geom, xform );
    6091         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6092                 :            : }
    6093                 :            : 
    6094                 :          0 : CubitStatus PartitionEngine::translate( PartitionBody* ent, 
    6095                 :            :                                         const CubitVector& delta )
    6096                 :            : {
    6097         [ #  # ]:          0 :   BodySM* body = ent->real_body();
    6098 [ #  # ][ #  # ]:          0 :   if (!body->get_geometry_query_engine()->translate( body, delta ))
                 [ #  # ]
    6099                 :          0 :     return CUBIT_FAILURE;
    6100                 :            :   
    6101         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6102         [ #  # ]:          0 :   xform.translate( delta );
    6103         [ #  # ]:          0 :   notify_transform_internal( ent, xform );
    6104         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6105                 :            : }
    6106                 :            : 
    6107                 :          0 : CubitStatus PartitionEngine::rotate( PartitionBody* ent, 
    6108                 :            :                                      const CubitVector& axis, 
    6109                 :            :                                      double degrees )
    6110                 :            : {
    6111         [ #  # ]:          0 :   BodySM* body = ent->real_body();
    6112 [ #  # ][ #  # ]:          0 :   if (!body->get_geometry_query_engine()->rotate( body, axis, degrees ))
                 [ #  # ]
    6113                 :          0 :     return CUBIT_FAILURE;
    6114                 :            :   
    6115         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6116         [ #  # ]:          0 :   xform.rotate( degrees, axis );
    6117         [ #  # ]:          0 :   notify_transform_internal( ent, xform );
    6118         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6119                 :            : }
    6120                 :            : 
    6121                 :          0 : CubitStatus PartitionEngine::scale( PartitionBody* ent, 
    6122                 :            :                                     const CubitVector& factors )
    6123                 :            : {
    6124         [ #  # ]:          0 :   BodySM* body = ent->real_body();
    6125                 :            : 
    6126 [ #  # ][ #  # ]:          0 :   if( factors.x() != factors.y() ||
         [ #  # ][ #  # ]
    6127 [ #  # ][ #  # ]:          0 :       factors.y() != factors.z() ||
         [ #  # ][ #  # ]
    6128 [ #  # ][ #  # ]:          0 :       factors.x() != factors.z() )
    6129                 :            :   {
    6130 [ #  # ][ #  # ]:          0 :     GeometryModifyEngine *tmp_engine = GeometryModifyTool::instance()->get_engine( body );
    6131         [ #  # ]:          0 :     tmp_engine->scale( body, factors );  
    6132                 :            :   }
    6133 [ #  # ][ #  # ]:          0 :   else if(!body->get_geometry_query_engine()->scale( body, factors ))
                 [ #  # ]
    6134                 :          0 :     return CUBIT_FAILURE;
    6135                 :            :   
    6136         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6137         [ #  # ]:          0 :   xform.scale_about_origin( factors );
    6138         [ #  # ]:          0 :   notify_transform_internal( ent, xform );
    6139         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6140                 :            : }
    6141                 :            : 
    6142                 :          0 : CubitStatus PartitionEngine::reflect( PartitionBody* ent, 
    6143                 :            :                                       const CubitVector& axis )
    6144                 :            : {
    6145         [ #  # ]:          0 :   BodySM* body = ent->real_body();
    6146 [ #  # ][ #  # ]:          0 :   if (!body->get_geometry_query_engine()->reflect( body, axis ))
                 [ #  # ]
    6147                 :          0 :     return CUBIT_FAILURE;
    6148                 :            :   
    6149         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6150         [ #  # ]:          0 :   xform.reflect( axis );
    6151         [ #  # ]:          0 :   notify_transform_internal( ent, xform );
    6152         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6153                 :            : }
    6154                 :            : 
    6155                 :          0 : CubitStatus PartitionEngine::restore_transform( PartitionBody* ent )
    6156                 :            : {
    6157         [ #  # ]:          0 :   BodySM* body = ent->real_body();
    6158         [ #  # ]:          0 :   CubitTransformMatrix xform;
    6159         [ #  # ]:          0 :   body->get_transforms( xform );
    6160 [ #  # ][ #  # ]:          0 :   if (!body->get_geometry_query_engine()->restore_transform( body ))
                 [ #  # ]
    6161                 :          0 :     return CUBIT_FAILURE;
    6162                 :            :   
    6163         [ #  # ]:          0 :   notify_transform_internal( ent, xform );
    6164         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6165                 :            : }
    6166                 :            : 
    6167                 :        444 : CubitStatus PartitionEngine::notify_transform( TopologyBridge* ,
    6168                 :            :                                                const CubitTransformMatrix&  )
    6169                 :            : {
    6170                 :        444 :   return CUBIT_SUCCESS;
    6171                 :            : }
    6172                 :            : 
    6173                 :          0 : CubitStatus PartitionEngine::notify_transform_internal( TopologyBridge* ent,
    6174                 :            :                                                const CubitTransformMatrix& xform )
    6175                 :            : {
    6176                 :            :   int i;
    6177         [ #  # ]:          0 :   DLIList<Surface*> surfaces;
    6178 [ #  # ][ #  # ]:          0 :   DLIList<Curve*> curves;
    6179 [ #  # ][ #  # ]:          0 :   DLIList<TBPoint*> points;
    6180                 :            :   
    6181 [ #  # ][ #  # ]:          0 :   if (PartitionBody* body = dynamic_cast<PartitionBody*>(ent))
    6182                 :            :   {
    6183         [ #  # ]:          0 :     DLIList<PartitionEntity*> ent_list;
    6184         [ #  # ]:          0 :     body->get_all_children( ent_list );
    6185 [ #  # ][ #  # ]:          0 :     CAST_LIST( ent_list, surfaces, PartitionSurface );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    6186 [ #  # ][ #  # ]:          0 :     CAST_LIST( ent_list, curves, PartitionCurve );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    6187 [ #  # ][ #  # ]:          0 :     CAST_LIST( ent_list, points, PartitionPoint );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    6188                 :            :   }
    6189                 :            :   else
    6190                 :            :   {
    6191 [ #  # ][ #  # ]:          0 :     if(BodySM* bodysm = dynamic_cast<BodySM*>(ent))
    6192                 :            :     {
    6193 [ #  # ][ #  # ]:          0 :       DLIList<TopologyBridge*> lumps, shells, tmp_surfs;
         [ #  # ][ #  # ]
                 [ #  # ]
    6194 [ #  # ][ #  # ]:          0 :       bodysm->get_children( lumps, true, layer() );
    6195 [ #  # ][ #  # ]:          0 :       while (lumps.size())
    6196                 :            :       {
    6197 [ #  # ][ #  # ]:          0 :         lumps.pop()->get_children( shells, true, layer() );
                 [ #  # ]
    6198 [ #  # ][ #  # ]:          0 :         while (shells.size())
    6199                 :            :         {
    6200         [ #  # ]:          0 :           tmp_surfs.clean_out();
    6201 [ #  # ][ #  # ]:          0 :           shells.pop()->get_children( tmp_surfs, true, layer() );
                 [ #  # ]
    6202 [ #  # ][ #  # ]:          0 :           while (tmp_surfs.size())
    6203 [ #  # ][ #  # ]:          0 :             surfaces.append( dynamic_cast<Surface*>(tmp_surfs.pop()) );
                 [ #  # ]
    6204                 :            :         }
    6205                 :            :       }
    6206 [ #  # ][ #  # ]:          0 :       surfaces.uniquify_ordered();
    6207                 :            :     }
    6208 [ #  # ][ #  # ]:          0 :     else if(Surface* surf = dynamic_cast<Surface*>(ent))
    6209         [ #  # ]:          0 :       surfaces.append( surf );
    6210 [ #  # ][ #  # ]:          0 :     else if(Curve* curv = dynamic_cast<Curve*>(ent))
    6211         [ #  # ]:          0 :       curves.append( curv );
    6212 [ #  # ][ #  # ]:          0 :     else if(TBPoint* point = dynamic_cast<TBPoint*>(ent))
    6213         [ #  # ]:          0 :       points.append( point );
    6214                 :            : 
    6215 [ #  # ][ #  # ]:          0 :     if (surfaces.size())
    6216                 :            :     {
    6217 [ #  # ][ #  # ]:          0 :       DLIList<TopologyBridge*> loops, coedges, tmp_curves;
         [ #  # ][ #  # ]
                 [ #  # ]
    6218 [ #  # ][ #  # ]:          0 :       for (i = surfaces.size(); i--; )
    6219                 :            :       {
    6220 [ #  # ][ #  # ]:          0 :         surfaces.get_and_step()->get_children( loops, true, layer() );
                 [ #  # ]
    6221 [ #  # ][ #  # ]:          0 :         while( loops.size() )
    6222                 :            :         {
    6223 [ #  # ][ #  # ]:          0 :           loops.pop()->get_children( coedges, true, layer() );
                 [ #  # ]
    6224 [ #  # ][ #  # ]:          0 :           while (coedges.size())
    6225                 :            :           {
    6226 [ #  # ][ #  # ]:          0 :             coedges.pop()->get_children( tmp_curves, true, layer() );
                 [ #  # ]
    6227 [ #  # ][ #  # ]:          0 :             while (tmp_curves.size())
    6228 [ #  # ][ #  # ]:          0 :               curves.append( dynamic_cast<Curve*>(tmp_curves.pop()) );
                 [ #  # ]
    6229                 :            :           }
    6230                 :            :         }
    6231                 :            :       }
    6232 [ #  # ][ #  # ]:          0 :       curves.uniquify_ordered();
    6233                 :            :     }
    6234                 :            :     
    6235 [ #  # ][ #  # ]:          0 :     if (curves.size())
    6236                 :            :     {
    6237         [ #  # ]:          0 :       DLIList<TopologyBridge*> tmp_points;
    6238 [ #  # ][ #  # ]:          0 :       for (i = curves.size(); i--; )
    6239                 :            :       {
    6240 [ #  # ][ #  # ]:          0 :         curves.get_and_step()->get_children( tmp_points, true, layer() );
                 [ #  # ]
    6241 [ #  # ][ #  # ]:          0 :         while (tmp_points.size())
    6242 [ #  # ][ #  # ]:          0 :           points.append( dynamic_cast<TBPoint*>(tmp_points.pop()) );
                 [ #  # ]
    6243                 :            :       }
    6244 [ #  # ][ #  # ]:          0 :       points.uniquify_ordered();
    6245                 :            :     }
    6246                 :            :   }
    6247                 :            : 
    6248                 :            :   // see if the transformation is a reflection
    6249 [ #  # ][ #  # ]:          0 :   double det = xform.sub_matrix( 3, 3 ).determinant();
                 [ #  # ]
    6250                 :          0 :   bool reflection = det < 0.0;
    6251                 :            : 
    6252 [ #  # ][ #  # ]:          0 :   while (surfaces.size())
    6253                 :            :   {
    6254 [ #  # ][ #  # ]:          0 :     PartitionSurface* surf = dynamic_cast<PartitionSurface*>(surfaces.pop());
    6255         [ #  # ]:          0 :     if (surf)
    6256                 :            :     {
    6257         [ #  # ]:          0 :       surf->transform( xform );
    6258                 :            :     }
    6259                 :            :   }
    6260                 :            : 
    6261 [ #  # ][ #  # ]:          0 :   while (curves.size())
    6262                 :            :   {
    6263 [ #  # ][ #  # ]:          0 :     PartitionCurve* curv = dynamic_cast<PartitionCurve*>(curves.pop());
    6264         [ #  # ]:          0 :     if (curv)
    6265                 :            :     {
    6266         [ #  # ]:          0 :       curv->transform( xform );
    6267                 :            : 
    6268         [ #  # ]:          0 :       if (reflection)
    6269                 :            :       {
    6270                 :            :         // PartitionSurface transform above reverses loops and coedges on Partition
    6271                 :            :         // surfaces.  Need to reverse sense of PartitionCoEdges in loops on non
    6272                 :            :         // partition surfaces
    6273                 :            :         // reverse the coedges of this curve
    6274                 :          0 :         PartitionCoEdge* p_coedge = 0;
    6275 [ #  # ][ #  # ]:          0 :         while ((p_coedge = curv->next_coedge(p_coedge)) != NULL)
    6276                 :            :         {
    6277         [ #  # ]:          0 :           TopologyBridge* loop_bridge = p_coedge->find_parent_loop();
    6278         [ #  # ]:          0 :           if (loop_bridge)
    6279                 :            :           {
    6280 [ #  # ][ #  # ]:          0 :             if (0 == dynamic_cast<PartitionLoop*>(loop_bridge))
                 [ #  # ]
    6281                 :            :             {
    6282         [ #  # ]:          0 :               p_coedge->reverse_sense();
    6283                 :            :             }
    6284                 :            :           }
    6285                 :            :         }
    6286                 :            :       }
    6287                 :            :     }
    6288                 :            :   }
    6289                 :            :   
    6290 [ #  # ][ #  # ]:          0 :   while (points.size())
    6291                 :            :   {
    6292 [ #  # ][ #  # ]:          0 :     PartitionPoint* pnt = dynamic_cast<PartitionPoint*>(points.pop());
    6293         [ #  # ]:          0 :     if (pnt)
    6294         [ #  # ]:          0 :       pnt->transform( xform );
    6295                 :            :   }
    6296                 :            : 
    6297         [ #  # ]:          0 :   return CUBIT_SUCCESS;
    6298                 :            : }
    6299                 :            : 
    6300                 :        615 : void PartitionEngine::remove_attributes( DLIList<TopologyBridge*> &list )
    6301                 :            : {
    6302                 :            :   //for each SubEntitySet in map, change it's unique id to zero
    6303         [ +  - ]:        615 :   std::map<int,SubEntitySet*>::iterator itor = uniqueIdMap.begin();
    6304 [ +  - ][ +  - ]:        615 :   while( itor != uniqueIdMap.end() )
                 [ -  + ]
    6305                 :            :   {
    6306 [ #  # ][ #  # ]:          0 :     if(itor->second->get_entity())
                 [ #  # ]
    6307                 :            :     {
    6308 [ #  # ][ #  # ]:          0 :       SubEntitySet::strip_attributes( itor->second->get_entity() );
                 [ #  # ]
    6309 [ #  # ][ #  # ]:          0 :       itor->second->reset_unique_id();
    6310                 :            :     }
    6311         [ #  # ]:          0 :     itor++;
    6312                 :            :   }
    6313                 :            : 
    6314                 :            :   //clean out the map
    6315         [ +  - ]:        615 :   uniqueIdMap.clear();
    6316                 :        615 : }
    6317                 :            : 
    6318                 :          0 : void PartitionEngine::notify_deactivated (PartitionBody* body)
    6319                 :            : {
    6320                 :          0 : }
    6321                 :          0 : void PartitionEngine::notify_deactivated(PartitionLump* vol)
    6322                 :            : {
    6323                 :          0 : }
    6324                 :          0 : void PartitionEngine::add_to_deactivated_list(PartitionLump* vol)
    6325                 :            : {
    6326                 :          0 : }
    6327                 :          0 : void PartitionEngine::add_to_deactivated_list(PartitionBody* body)
    6328                 :            : {
    6329                 :          0 : }
    6330                 :          0 : void PartitionEngine::notify_deactivated (PartitionSurface* surface)
    6331                 :            : {
    6332                 :          0 : }
    6333                 :          0 : void PartitionEngine::add_to_deactivated_list (PartitionSurface* surface)
    6334                 :            : {
    6335                 :          0 : }
    6336                 :          0 : void PartitionEngine::notify_deactivated (PartitionCurve* curve)
    6337                 :            : {
    6338                 :          0 : }
    6339                 :          0 : void PartitionEngine::add_to_deactivated_list (PartitionCurve* curve)
    6340                 :            : {
    6341                 :          0 : }
    6342                 :          0 : void PartitionEngine::notify_deactivated (PartitionPoint* point)
    6343                 :            : {
    6344                 :          0 : }
    6345                 :          0 : void PartitionEngine::add_to_deactivated_list (PartitionPoint* point)
    6346                 :            : {
    6347                 :          0 : }
    6348                 :       1706 : void PartitionEngine::clean_out_deactivated_geometry()
    6349                 :            : {
    6350                 :       1706 : }
    6351                 :        120 : void PartitionEngine::remove_modified(DLIList<Surface*> &all_surfs,
    6352                 :            :     DLIList<Curve*> &all_curves, DLIList<TBPoint*> &all_pts)
    6353                 :            : {
    6354                 :        120 : }
    6355                 :            : 
    6356                 :          0 : void PartitionEngine::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge, 
    6357                 :            :                                                             DLIList<TopologyBridge*> &tbs )
    6358                 :            : {  
    6359 [ #  # ][ #  # ]:          0 :   BridgeManager* bm = dynamic_cast<BridgeManager*>(source_bridge->owner());
    6360         [ #  # ]:          0 :   if( bm )
    6361                 :            :   {
    6362         [ #  # ]:          0 :     tbs.append( source_bridge );
    6363                 :          0 :     return;
    6364                 :            :   }
    6365                 :            : 
    6366 [ #  # ][ #  # ]:          0 :   SubEntitySet* set = dynamic_cast<SubEntitySet*>(source_bridge->owner());
    6367         [ #  # ]:          0 :   if( !set ) 
    6368                 :          0 :     return;
    6369                 :            : 
    6370         [ #  # ]:          0 :   DLIList<PartitionEntity*> entity_list;
    6371         [ #  # ]:          0 :   set->get_sub_entities( entity_list );
    6372 [ #  # ][ #  # ]:          0 :   DLIList<TopologyBridge*> tb_list;
    6373 [ #  # ][ #  # ]:          0 :   CAST_LIST( entity_list, tb_list, TopologyBridge );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    6374                 :            :   
    6375 [ #  # ][ #  # ]:          0 :   while( tb_list.size() )
    6376                 :            :   {
    6377         [ #  # ]:          0 :     TopologyBridge *tb = tb_list.pop();
    6378 [ #  # ][ #  # ]:          0 :     if( tb->bridge_manager() )    
    6379         [ #  # ]:          0 :       tbs.append( tb );          
    6380                 :            :     else
    6381                 :            :     {  
    6382         [ #  # ]:          0 :       TBOwner *owner = tb->owner();
    6383         [ #  # ]:          0 :       TopologyBridge *tmp_tb = CAST_TO( owner, TopologyBridge );
    6384         [ #  # ]:          0 :       if( tmp_tb )
    6385         [ #  # ]:          0 :         tb_list.append( tmp_tb );
    6386                 :            :       else
    6387                 :            :       {
    6388         [ #  # ]:          0 :         CompositePoint *comp_pt = CAST_TO( tb, CompositePoint );
    6389         [ #  # ]:          0 :         if( comp_pt )
    6390 [ #  # ][ #  # ]:          0 :           CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( tb, tb_list );
    6391                 :            :         else
    6392                 :            :         {
    6393         [ #  # ]:          0 :           CompositeCurve *comp_curve = CAST_TO( tb, CompositeCurve );
    6394         [ #  # ]:          0 :           if( comp_curve )
    6395 [ #  # ][ #  # ]:          0 :             CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( tb, tb_list );
    6396                 :            :         }
    6397                 :            :       }
    6398                 :            :     }    
    6399                 :            :   }
    6400                 :            : 
    6401         [ #  # ]:          0 :   tbs.uniquify_ordered();
    6402                 :            : 
    6403         [ #  # ]:          0 :   return;
    6404 [ +  - ][ +  - ]:       6364 : }
    6405                 :            :   

Generated by: LCOV version 1.11