cgma
PartitionTool.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : PartitionTool.cpp
00003 //
00004 // Purpose       : Functions for splitting geometry using VG
00005 //
00006 // Special Notes : 
00007 //
00008 // Creator       : Jason Kraftcheck
00009 //
00010 // Creation Date : 12/13/98
00011 //-------------------------------------------------------------------------
00012 
00013 //When determining if a RefEdge lies within a Loop, this
00014 //is the number of points on that RefEdge that are checked.  
00015   
00016 #include "PartitionTool.hpp"
00017 //#include "VirtualQueryEngine.hpp"
00018 #include "DLIList.hpp"
00019 #include "GfxDebug.hpp"
00020 #include "GMem.hpp"
00021 #include "CastTo.hpp"
00022 
00023 #include "Body.hpp"
00024 #include "RefFace.hpp"
00025 #include "RefEdge.hpp"
00026 #include "RefVertex.hpp"
00027 #include "Loop.hpp"
00028 #include "Chain.hpp"
00029 #include "Shell.hpp"
00030 
00031 #include "CoEdge.hpp"
00032 #include "CoVertex.hpp"
00033 #include "CoFace.hpp"
00034 #include "CoVolume.hpp"
00035 
00036 #include "Point.hpp"
00037 #include "Curve.hpp"
00038 #include "IntersectionTool.hpp"
00039 
00040 #include "ModelQueryEngine.hpp"
00041 
00042 #include "PartitionLump.hpp"
00043 #include "PartitionSurface.hpp"
00044 #include "PartitionCurve.hpp"
00045 #include "PartPTCurve.hpp"
00046 #include "PartitionPoint.hpp"
00047 //#include "PartitionLump.hpp"
00048 #include "PartitionLoop.hpp"
00049 #include "PartitionCoEdge.hpp"
00050 #include "SegmentedCurve.hpp"
00051 
00052 #include "CompositeTool.hpp"
00053 #include "CompositeEngine.hpp"
00054 #include "CompositePoint.hpp"
00055 #include "GeometryUtil.hpp"
00056 #include "RefEntityName.hpp"
00057 
00058 #include "PartitionEngine.hpp"
00059 
00060 #include "BodySM.hpp"
00061 #include "SubCurve.hpp"
00062 
00063 #include "RefEntityFactory.hpp"
00064 #include "GeometryQueryTool.hpp"
00065 #include "MergeTool.hpp"
00066 #include "CubitUndo.hpp"
00067 
00068 #include "TDUPtr.hpp"
00069 #include <vector>
00070 
00071 #include "AppUtil.hpp"
00072 #include "GeometryEvent.hpp"
00073 
00074 PartitionTool* PartitionTool::instance_ = NULL;
00075 
00076 //Debugging output
00077 void pt_print_bte_list( int debug_flag, DLIList<BasicTopologyEntity*>& edges, 
00078                         const char* trailing_string = "\n"  );
00079 void pt_print_edge_list( int debug_flag, DLIList<RefEdge*>& edges,
00080                          const char* trailing_string = "\n" );
00081 void pt_print_face_list( int debug_flag, DLIList<RefFace*>& faces,
00082                          const char* trailing_string = "\n" );
00083 void pt_print_loop( int debug_flag, Loop* loop_ptr, 
00084                     const char* trailing_string = "\n" );
00085 void pt_print_shell( int debug_flag, Shell* shell_ptr, 
00086                      const char* trailing_string = "\n" );
00087 
00088 //Helper class for surface partitioning.
00089 struct LoopIntersection { 
00090   Loop* loop_ptr; 
00091   RefVertex* vtx_ptr; 
00092     //So we can put it in a DLIList:
00093   LoopIntersection( int i = 0 );
00094 
00095 
00096   bool operator<( const LoopIntersection& ) const { assert(0); return false; }
00097   bool operator>( const LoopIntersection& ) const { assert(0); return false; }
00098   bool operator<=( const LoopIntersection& ) const { assert(0); return false; }
00099   bool operator>=( const LoopIntersection& ) const { assert(0); return false; }
00100   bool operator==( const LoopIntersection& ) const { assert(0); return true; }
00101   bool operator!=( const LoopIntersection& ) const { assert(0); return true; }
00102 };
00103   //So we can put it in a DLIList:
00104 LoopIntersection::LoopIntersection( int ) : loop_ptr(0), vtx_ptr(0) {}
00105 
00106 //-------------------------------------------------------------------------
00107 // Purpose       : constructor/destructor
00108 //
00109 // Special Notes : 
00110 //
00111 // Creator       : Jason Kraftcheck
00112 //
00113 // Creation Date : 12/13/98
00114 //-------------------------------------------------------------------------
00115 PartitionTool::PartitionTool()
00116 {
00117   facetingTolerance = 10;
00118 }
00119 PartitionTool::~PartitionTool()
00120 {
00121   instance_ = NULL;
00122 }
00123 
00124 //-------------------------------------------------------------------------
00125 // Purpose       : Split a curve
00126 //
00127 // Special Notes : 
00128 //
00129 // Creator       : Jason Kraftcheck
00130 //
00131 // Creation Date : 06/15/99
00132 //-------------------------------------------------------------------------
00133 RefVertex* PartitionTool::partition( RefEdge* edge_ptr,
00134                                       const CubitVector& split_point,
00135                                       RefEdge*& first_new_edge,
00136                                       RefEdge*& second_new_edge,
00137                                       CubitBoolean  )
00138 {
00139   int i, j;
00140   first_new_edge = second_new_edge = NULL;
00141 
00142   CubitBoolean is_free_curve = 
00143       edge_ptr->num_parent_ref_entities() == 0 ? CUBIT_TRUE : CUBIT_FALSE;
00144 
00145   DLIList<RefFace*> faces;
00146   edge_ptr->ref_faces( faces );
00147   RefVertex* input_start_vtx = edge_ptr->start_vertex();
00148   RefVertex* input_end_vtx = edge_ptr->end_vertex();
00149 
00150     // partition each merged curve in the refedge
00151   DLIList<TopologyBridge*> bridge_list, curve_bridges, coedge_bridges, point_bridges;
00152   edge_ptr->bridge_manager()->get_bridge_list( bridge_list );
00153   RefVertex* new_vertex = 0;
00154   for( i = bridge_list.size(); i--; )
00155   {
00156     Curve* curve_ptr = dynamic_cast<Curve*>(bridge_list.get_and_step());
00157     double u = curve_ptr->u_from_position( split_point );
00158     TBPoint* pt = PartitionEngine::instance().insert_point( curve_ptr, u );
00159     if( !pt )
00160     {
00161         // try to back out any partitions we've already made.
00162       bridge_list.clean_out();
00163       if( new_vertex )
00164       {
00165         new_vertex->bridge_manager()->get_bridge_list(bridge_list);
00166         new_vertex->deactivated(CUBIT_TRUE);
00167       }
00168       
00169       while( bridge_list.size() )
00170         PartitionEngine::instance().remove_point( 
00171           dynamic_cast<PartitionPoint*>(bridge_list.pop()) );
00172       
00173       break;
00174     }
00175     
00176     if( new_vertex ) 
00177       new_vertex->bridge_manager()->add_bridge( pt );
00178     else
00179       new_vertex = GeometryQueryTool::instance()->make_RefVertex(pt);
00180   }  
00181   
00182   if (!new_vertex) // failed -- no curves split
00183     return 0;
00184     
00185   
00186     // Get two "new" RefEdges to work with
00187   RefEdge* new_edges[2];  // two refedges split from input refedge
00188   RefVertex* vertices[2]; // the to-be other RefVertex on each edge (not new_vtx)
00189   bool start_vtx[2];      // for the first curve, is new_vtx the start of that curve
00190   CubitSense senses[2];   // bridge sense for first curve in each refedge
00191     // For each of two curves adjacent to the first split point
00192   TBPoint* point = new_vertex->get_point_ptr();
00193   point->get_parents(curve_bridges);
00194   assert(curve_bridges.size() == 2);
00195   curve_bridges.reset();
00196   for (i = 0; i < 2; i++)
00197   {
00198     Curve* curve = dynamic_cast<Curve*>(curve_bridges.get_and_step());
00199     new_edges[i] = dynamic_cast<RefEdge*>(curve->topology_entity());
00200     
00201       // need to create new RefEdge
00202     if (!new_edges[i])
00203     {
00204       if (curve->bridge_sense() == CUBIT_REVERSED)
00205         curve->reverse_bridge_sense();  // clear bridge sense
00206       if(is_free_curve)
00207         new_edges[i] = GeometryQueryTool::instance()->make_free_RefEdge(curve);
00208       else
00209         new_edges[i] = GeometryQueryTool::instance()->make_RefEdge(curve);
00210     }
00211     
00212       // get other vertex on refedge, save to use in determining 
00213       // which curve pairs should merge.
00214     bridge_list.clean_out();
00215     curve->get_children(bridge_list);
00216     bridge_list.move_to(point);
00217     bridge_list.reset();
00218     if (bridge_list.get() == point)
00219       start_vtx[i] = true;
00220     else if(bridge_list.step_and_get() == point)
00221       start_vtx[i] = false;
00222     else
00223       assert(0);
00224       
00225       // populate arrays with necessary info to determine relative 
00226       // sense of other curves to be merged with this one.
00227     vertices[i] = dynamic_cast<RefVertex*>(bridge_list.next()->topology_entity());
00228     senses[i] = curve->bridge_sense();
00229   }
00230   
00231     // Merge remaining curve pairs into the two refedges
00232   point_bridges.clean_out();
00233   new_vertex->bridge_manager()->get_bridge_list(point_bridges);
00234   point_bridges.move_to(point);
00235   assert(point_bridges.get() == point);
00236   for (i = point_bridges.size() - 1; i--; )  // for each pair of curves
00237   {
00238     TopologyBridge* point_bridge = point_bridges.step_and_get();
00239     curve_bridges.clean_out();
00240     point_bridge->get_parents(curve_bridges);
00241     assert(curve_bridges.size() == 2);
00242     
00243     while (curve_bridges.size())  // for each curve in the pair
00244     {
00245       Curve* curve = dynamic_cast<Curve*>(curve_bridges.pop());
00246       bridge_list.clean_out();
00247       curve->get_children(bridge_list);
00248       bridge_list.reset();
00249       bool is_start = false;
00250       if (bridge_list.get() == point_bridge)
00251         is_start = true;
00252       else if(bridge_list.step_and_get() == point_bridge)
00253         is_start = false;
00254       else
00255         assert(0);  // bad bridge connectivity
00256       
00257       RefVertex* vtx = dynamic_cast<RefVertex*>(bridge_list.next()->topology_entity());
00258       
00259       for (j = 0; j < 2 && vertices[j] != vtx; j++);
00260       if (j == 2)
00261         continue; // can't merge -- something went wrong
00262       
00263       if (vertices[0] == vertices[1]) // closed curve, need to do geometric check
00264       {
00265         CubitVector center = curve->center_point();
00266         double d1 = (center - new_edges[0]->center_point()).length_squared();
00267         double d2 = (center - new_edges[1]->center_point()).length_squared();
00268         j = d1 < d2 ? 0 : 1;
00269       }
00270 
00271       RefEdge* edge = new_edges[j];
00272       if (curve->topology_entity() != edge) // if not already merged ...
00273       {
00274         if (curve->bridge_manager())  // if in a different edge, unmerge
00275           curve->bridge_manager()->remove_bridge(curve);
00276 
00277         curve->get_parents(coedge_bridges);  // need to unmerge coedges too
00278         while (coedge_bridges.size())
00279         {
00280           TopologyBridge* coe_bridge = coedge_bridges.pop();
00281           if (coe_bridge->owner())  
00282             coe_bridge->bridge_manager()->remove_bridge(coe_bridge);
00283         }
00284 
00285         edge->bridge_manager()->add_bridge(curve); // merge
00286       }
00287       
00288         // set relative sense
00289       bool edge_reversed = (is_start != start_vtx[j]);
00290       bool curv_reversed = curve->bridge_sense() != senses[j];
00291       if (edge_reversed != curv_reversed)
00292         curve->reverse_bridge_sense();
00293     }
00294   }
00295           
00296     // Rebuild TopologyEntity topology
00297   for( i = faces.size(); i--; )
00298   { 
00299     RefFace* face = faces.get_and_step();
00300     bridge_list.clean_out();
00301     face->bridge_manager()->get_bridge_list(bridge_list);
00302     assert(bridge_list.size());
00303     for (int j = bridge_list.size(); j--; )
00304     {
00305       TopologyBridge* bridge = bridge_list.get_and_step();
00306       Surface* surf = dynamic_cast<Surface*>(bridge);
00307       assert(!!surf);
00308       GeometryQueryTool::instance()->make_RefFace(surf);
00309     }
00310   }
00311     // tweak some stuff so the resulting RefEdges have the same
00312     // sense as the input RefEdge.
00313 
00314     // Get the edges in the order we want.
00315     // If curve was not closed, put whichever contains the original start vertex first.
00316   if (input_start_vtx != input_end_vtx)
00317     i = new_edges[0]->other_vertex(input_start_vtx) ? 0 : 1;
00318     //If closed, sense of original edge didn't change so use that to determine the order
00319   else if (new_edges[0] == edge_ptr)
00320     i = new_edges[0]->start_vertex() == input_start_vtx ? 0 : 1;
00321   else
00322     i = new_edges[1]->start_vertex() == input_start_vtx ? 1 : 0;
00323   first_new_edge = new_edges[i];
00324   second_new_edge = new_edges[1-i];
00325   
00326   DLIList<RefEntity*> vtx_list;
00327   vtx_list.append(new_vertex);
00328   notify_partition( vtx_list, first_new_edge, second_new_edge, edge_ptr );
00329 
00330     // Adjust sense of new RefEdge
00331     // The sense of the input edge should not have changed, so don't mess with
00332     // it.  Flip the new edge if it doesn't end with the correct vertex.
00333   if (first_new_edge != edge_ptr && first_new_edge->start_vertex() != input_start_vtx)
00334   {
00335     first_new_edge->reverse_tangent();
00336   }
00337   if (second_new_edge != edge_ptr && second_new_edge->end_vertex() != input_end_vtx)
00338   {
00339     second_new_edge->reverse_tangent();
00340   }
00341 
00342   PRINT_DEBUG_76("First new curve is %d, second new curve is %d.\n",
00343                  first_new_edge ? first_new_edge->id() : 0,
00344                  second_new_edge ? second_new_edge->id() : 0 );
00345   return new_vertex;
00346 }
00347 
00348 RefVertex* PartitionTool::partition( RefEdge* edge_ptr,
00349                                       const CubitVector& position,
00350                                       DLIList<RefEdge*>& result_list,
00351                                       CubitBoolean b )
00352 {
00353   RefEdge *part1 = 0, *part2 = 0;
00354   RefVertex* result = partition( edge_ptr, position, part1, part2, b );
00355   if( result && part1 )
00356     result_list.append(part1);
00357   if( result && part2 )
00358     result_list.append(part2);
00359   return result;
00360 }
00361   
00362 //-------------------------------------------------------------------------
00363 // Purpose       : Split a surface
00364 //
00365 // Special Notes : 
00366 //
00367 // Creator       : Jason Kraftcheck
00368 //
00369 // Creation Date : 09/20/99
00370 //-------------------------------------------------------------------------
00371 CubitStatus PartitionTool::partition( RefFace* face_ptr,
00372                                       RefEdge* edge_ptr, 
00373                                       RefFace*& new_face1,
00374                                       RefFace*& new_face2,
00375                                       CubitBoolean )
00376 {
00377   PRINT_DEBUG_86( "PT:  PartitionTool::partition( RefFace %d, RefEdge %d )\n",
00378                                   face_ptr->id(), edge_ptr->id() );
00379   new_face1 = new_face2 = 0;
00380 
00381   DLIList<CubitVector*> segments;
00382   DLIList<RefEdge*> new_edges;
00383   GMem edge_facets;
00384   
00385   Curve* curve = edge_ptr->get_curve_ptr();
00386   if( ! curve->get_geometry_query_engine()->get_graphics( curve, &edge_facets, facetingTolerance ) )
00387   {
00388     return CUBIT_FAILURE;
00389   }
00390 
00391   int j;
00392     //Use the exact end points to avoid precision problems with faceting.
00393   CubitVector start_coord = edge_ptr->start_vertex()->coordinates();
00394   CubitVector end_coord = edge_ptr->end_vertex()->coordinates();      
00395   segments.append( new CubitVector ( start_coord ) );
00396   for( j = 1; j < (edge_facets.pointListCount-1); j++ )
00397   {
00398     segments.append( new CubitVector( edge_facets.point_list()[j].x,
00399                                       edge_facets.point_list()[j].y,
00400                                       edge_facets.point_list()[j].z ) );
00401   }
00402   segments.append( new CubitVector ( end_coord ) );
00403 
00404   new_face2 = insert_edge( face_ptr, segments, CUBIT_TRUE, new_edges );
00405   new_face1 = face_ptr;
00406 
00407   while( segments.size() )
00408     delete segments.pop();
00409 
00410   return new_face2 ? CUBIT_SUCCESS : CUBIT_FAILURE;
00411 }
00412 
00413 RefFace* PartitionTool::insert_edge( RefFace* face_ptr,
00414                                      DLIList<CubitVector*>& segments,
00415                                      CubitBoolean       is_meshed,
00416                                      DLIList<RefEdge*>& new_edges,
00417                                      int level_of_recursion,
00418                                      const double *tolerance_length)
00419 {
00420   int i,j,k;
00421   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS; 
00422   DLIList<Body*> bodies;
00423   face_ptr->bodies(bodies);
00424   CubitStatus status = CUBIT_SUCCESS;
00425   
00426   //Partition edges first
00427   if (CUBIT_FALSE == is_meshed)
00428   {
00429     DLIList<RefEdge*> edge_list;
00430     face_ptr->ref_edges(edge_list);
00431     CubitVector pos = *segments.get();
00432     CubitVector closest;
00433     RefEdge * the_edge = NULL;
00434     DLIList <CubitVector *> vect_list;
00435     DLIList<RefEdge*> temp_list;
00436     int count = 0;
00437     for (i = 0 ; count < 2 && i < segments.size(); i++)
00438     {
00439       for (j = 0; j < edge_list.size(); j++) 
00440       { 
00441         the_edge = edge_list.get_and_step();
00442         the_edge->closest_point_trimmed(pos, closest);
00443 
00444         if ( (pos - closest).length_squared() > TOL_SQR )
00445           continue;
00446 
00447         //closest point need to be on the edge
00448 /*
00449         the_edge->get_graphics(polyline, 0.0);
00450         int size = polyline.point_list_size();
00451         GPoint* pts = polyline.point_list();
00452         CubitVector pt1(pts[0]);
00453         CubitVector pt2(pts[1]);
00454         CubitBox edge_box (pt1, pt2);
00455         if (size > 1)
00456         {
00457           for (k = 2; k < size; k ++)
00458           {
00459             CubitVector pt3(pts[k]);
00460             CubitVector pt4(pts[k-1]);
00461             CubitBox box2(pt4, pt3);
00462             edge_box |= box2;
00463           }
00464         }
00465 
00466         CubitBox position_box(closest);
00467         if (size == 1 || (size > 1 && !position_box.overlap(0, edge_box)))      
00468             continue;
00469 */  
00470         CubitBox position_box(closest);
00471         CubitBox edge_box = the_edge->bounding_box(); 
00472         if (!position_box.overlap(GEOMETRY_RESABS, edge_box))
00473 //        if (!position_box.overlap(0, edge_box))
00474           continue;
00475 
00476         delete segments.change_to(new CubitVector (closest));
00477         if((the_edge->start_coordinates() - closest).length_squared() < TOL_SQR 
00478           ||(the_edge->end_coordinates() - closest).length_squared() < TOL_SQR)
00479           break;
00480 
00481         vect_list.clean_out();
00482         vect_list.append(&closest);
00483         temp_list.clean_out();
00484         status = partition(the_edge, vect_list, temp_list);
00485 
00486         // explicitly test for status here
00487         if (CUBIT_SUCCESS != status)
00488         {
00489           PRINT_ERROR("PartitionTool::insert_edge failed at partition...\n");
00490         }
00491 
00492         // I've seen cases where the resulting partition position is not
00493         // what we passed in so look at the resulting curves and get
00494         // the end point that is closest to the point we used for 
00495         // partitioning the curve.
00496         double smallest_dist_sq = CUBIT_DBL_MAX;
00497         RefVertex *closest_vert = NULL;
00498         for(k=temp_list.size(); k--;)
00499         {
00500           RefEdge *current_edge = temp_list.get_and_step();
00501           RefVertex *start_vert = current_edge->start_vertex();
00502           RefVertex *end_vert = current_edge->end_vertex();
00503           double len_sq = (start_vert->coordinates()-closest).length_squared();
00504           if(len_sq < smallest_dist_sq)
00505           {
00506             smallest_dist_sq = len_sq;
00507             closest_vert = start_vert;
00508           }
00509           len_sq = (end_vert->coordinates()-closest).length_squared();
00510           if(len_sq < smallest_dist_sq)
00511           {
00512             smallest_dist_sq = len_sq;
00513             closest_vert = end_vert;
00514           }
00515         }
00516 
00517         if(closest_vert)
00518           delete segments.change_to(new CubitVector(closest_vert->coordinates()));
00519 
00520         temp_list.remove(the_edge);
00521         DLIList<RefEntity*> ref_list;
00522         CAST_LIST_TO_PARENT(temp_list, ref_list);
00523         notify_partition( ref_list, the_edge, temp_list.get(), the_edge );
00524 
00525         //need to debug later if this happens.
00526         if (CUBIT_SUCCESS != status)
00527         {
00528           PRINT_ERROR("PartitionTool::insert_edge failed at assert...\n");
00529         }
00530         assert (CUBIT_SUCCESS == status);
00531         edge_list.remove(the_edge);
00532         count ++;
00533         break;
00534       }
00535     pos = *segments.step_and_get();
00536     }
00537   }
00538   
00539   if( CubitUndo::get_undo_enabled() )
00540   {
00541     DLIList<RefFace*> tmp_face_list(1);
00542     tmp_face_list.append( face_ptr );
00543     CubitUndo::save_state_with_cubit_file( tmp_face_list );
00544   }
00545 
00546   DLIList<TopologyBridge*> bridge_list;
00547   face_ptr->bridge_manager()->get_bridge_list( bridge_list );
00548   bridge_list.reset();
00549   bridge_list.step();
00550   for( i = bridge_list.size(); i > 1; i-- )
00551     face_ptr->bridge_manager()->remove_bridge( bridge_list.get_and_step() );
00552   
00553   bridge_list.reset();
00554   DLIList<Surface*> result_surfaces;
00555   DLIList<Curve*> curves(2), new_curves;;
00556   DLIList<Surface*> curve_surfs(2);
00557   int removed_composite_curve = 0;
00558   for( i = bridge_list.size(); i>0; i--)
00559   {
00560     Surface* old_surf = dynamic_cast<Surface*>(bridge_list.get_and_step());
00561 
00562     Surface* new_surf = PartitionEngine::instance().
00563       insert_curve( old_surf, segments, curves, tolerance_length );
00564     
00565     // do it twice in case the segments changed during the first insert_curve
00566     // because the segments intersect with the old_surf boundary. This is to 
00567     // ensure that new vertices are generated at those intersecting points. 
00568     if (!new_surf && level_of_recursion == 0)
00569     {
00570       level_of_recursion++;
00571       RefFace *return_face = insert_edge( face_ptr, segments, CUBIT_FALSE, new_edges, level_of_recursion);
00572       
00573       if( CubitUndo::get_undo_enabled() && return_face == NULL ) 
00574         CubitUndo::remove_last_undo();
00575 
00576       return return_face; 
00577     }
00578 
00579     if(!new_surf)
00580     {
00581       CompositeSurface* cs = dynamic_cast<CompositeSurface*>(old_surf);
00582       if(cs)
00583       {
00584         Surface *tmp_srf = cs->get_surface(0);
00585         GeometryQueryEngine *gqe = tmp_srf->get_geometry_query_engine();
00586         double tmp_tol = gqe->get_sme_resabs_tolerance();
00587         DLIList<Curve*> hidden_curves;
00588         cs->get_hidden_curves(hidden_curves);
00589         int k;
00590         for(k=hidden_curves.size(); k--;)
00591         {
00592           Curve *cur_curve = hidden_curves.get_and_step();
00593           CubitVector start_vec, end_vec;
00594           double min, max;
00595           IntersectionTool int_tool;
00596           int curve_on_polyline = 1;
00597           cur_curve->get_param_range(min, max);
00598           cur_curve->position_from_u(min, start_vec);
00599           if(!int_tool.point_on_polyline(start_vec, segments, &tmp_tol))
00600             curve_on_polyline = 0;
00601           if(curve_on_polyline)
00602           {
00603             cur_curve->position_from_u(max, end_vec);
00604             if(!int_tool.point_on_polyline(end_vec, segments, &tmp_tol))
00605               curve_on_polyline = 0;
00606           }
00607           if(curve_on_polyline)
00608           {
00609             int num_mid_pts = 2;
00610             double dt = ((double)(max-min))/((double)(num_mid_pts+1));
00611             double cur_t = min + dt;
00612             int n;
00613             CubitVector cur_vec;
00614             for(n=0; n<num_mid_pts && curve_on_polyline; ++n)
00615             {
00616               cur_curve->position_from_u(cur_t, cur_vec);
00617               if(!int_tool.point_on_polyline(cur_vec, segments, &tmp_tol))
00618                 curve_on_polyline = 0;
00619               cur_t += dt;
00620             }
00621           }
00622           if(curve_on_polyline)
00623           {
00624             DLIList<Curve*> cur_curve_crvs;
00625             CompositeCurve *ccurve = dynamic_cast<CompositeCurve*>(cur_curve);
00626             if(ccurve)
00627             {
00628               int f, num_crvs = ccurve->num_curves();
00629               for(f=0; f<num_crvs; ++f)
00630                 cur_curve_crvs.append(ccurve->get_curve(f));
00631             }
00632             else
00633             {
00634               cur_curve_crvs.append(cur_curve);
00635             }
00636             CompositeEngine::instance().restore_curve(cur_curve);
00637             ccurve = dynamic_cast<CompositeCurve*>(cur_curve_crvs.get()->owner());
00638             if(ccurve)
00639             {
00640               cur_curve_crvs.clean_out();
00641               cur_curve_crvs.append(ccurve);
00642             }
00643             removed_composite_curve = 1;
00644             int y, z;
00645             for(z=cur_curve_crvs.size(); z--;)
00646             {
00647               cur_curve = cur_curve_crvs.get_and_step();
00648               DLIList<TopologyBridge*> pts;
00649               cur_curve->get_children_virt(pts);
00650               for(y=pts.size(); y--;)
00651               {
00652                 DLIList<TopologyBridge*> crvs;
00653                 pts.get()->get_parents_virt(crvs);
00654                 if(crvs.size() == 2)
00655                 {
00656                   TopologyBridge *other_curve;
00657                   if(crvs.get() == cur_curve)
00658                     other_curve = crvs.step_and_get();
00659                   else
00660                     other_curve = crvs.get();
00661                   int p;
00662                   for(p=curves.size(); p--;)
00663                   {
00664                     if(curves.get() == other_curve)
00665                     {
00666                       CompositeEngine::instance().remove_point(dynamic_cast<TBPoint*>(pts.get()));
00667                       curves.remove(curves.get());
00668                       p = 0;
00669                     }
00670                     else
00671                       curves.step();
00672                   }
00673                 }
00674                 pts.step();
00675               }
00676             }
00677           }
00678         }
00679       }
00680     }
00681     if ( !curves.size() && !removed_composite_curve )
00682     {
00683       status = CUBIT_FAILURE;
00684       break;
00685     }
00686     for ( int j = curves.size(); j--; )
00687     {
00688       curve_surfs.clean_out();
00689       curves.step_and_get()->surfaces(curve_surfs);
00690       result_surfaces.merge_unique(curve_surfs);
00691     }
00692     new_curves += curves;
00693     curves.clean_out();
00694 
00695   }
00696   
00697   for( i = bodies.size(); i--; )
00698   {
00699     Body* body = bodies.get_and_step();
00700     GeometryQueryTool::instance()->make_Body(body->get_body_sm_ptr());
00701   }
00702   
00703   DLIList<RefFace*> result_faces;
00704   for( i = result_surfaces.size(); i--; )
00705     result_faces.append( 
00706       GeometryQueryTool::instance()->make_RefFace(
00707         result_surfaces.get_and_step() ) );
00708   
00709   MergeTool::instance()->merge_reffaces( result_faces );
00710   result_faces.clean_out();
00711   for( i = result_surfaces.size(); i--; )
00712     result_faces.append_unique( dynamic_cast<RefFace*>(result_surfaces.get_and_step()->topology_entity()) );
00713   
00714   result_faces.move_to( face_ptr );
00715   RefFace* result = result_faces.size() ? result_faces.next() : 0;
00716   if(!result && removed_composite_curve)
00717     result = face_ptr;
00718   for( i = new_curves.size(); i--; )
00719   {
00720     Curve* curve = new_curves.get_and_step();
00721     RefEdge* new_edge = dynamic_cast<RefEdge*>(curve->topology_entity());
00722     new_edges.append_unique(new_edge);
00723   }
00724   
00725   if ( !removed_composite_curve && !new_edges.size() )
00726   {
00727     if( CubitUndo::get_undo_enabled() ) 
00728       CubitUndo::remove_last_undo();
00729 
00730     return 0;
00731   }
00732     
00733   DLIList<RefEntity*> ref_list;
00734   CAST_LIST_TO_PARENT(new_edges, ref_list);
00735   notify_partition( ref_list, face_ptr, result, face_ptr );
00736   
00737   if( CubitUndo::get_undo_enabled() && status == CUBIT_FAILURE ) 
00738     CubitUndo::remove_last_undo();
00739 
00740   return status ? result : 0;
00741 }
00742 
00743 DLIList<Surface*>* PartitionTool::group_merged_surfaces(
00744                                     DLIList<RefFace*>& face_list,
00745                                     int& num_result_sets )
00746 {
00747   // make sure all surfaces are merged the same number of times
00748   int i;
00749   num_result_sets = 0;
00750   int bridge_count = face_list.get()->bridge_manager()->number_of_bridges();
00751   for ( i = face_list.size(); i--; )
00752     if( face_list.step_and_get()->bridge_manager()->number_of_bridges() != bridge_count )
00753       return 0;
00754  
00755   // get the bridge list (merged Surface*) for the first RefFace
00756   DLIList<Surface*>* results = new DLIList<Surface*>[bridge_count];
00757   DLIList<Lump*> surf_owners(bridge_count);
00758   face_list.reset();
00759   RefFace* face = face_list.get_and_step();
00760   DLIList<TopologyBridge*> bridge_list(bridge_count);
00761   face->bridge_manager()->get_bridge_list(bridge_list);
00762   
00763   // get the list of lumps involved in the merge from the first RefFace
00764   bridge_list.reset();
00765   DLIList<Lump*> lump_list;
00766   for ( i = 0; i < bridge_list.size(); i++ )
00767   {
00768     Surface* surface = dynamic_cast<Surface*>(bridge_list.get_and_step());
00769     assert(!!surface);
00770     lump_list.clean_out();
00771     surface->lumps(lump_list);
00772     Lump* lump = 0;
00773     if ( lump_list.size() > 1 )
00774     {
00775       delete [] results;
00776       return 0;
00777     }
00778     else if (lump_list.size())
00779       lump = lump_list.get();
00780     
00781     if( surf_owners.is_in_list( lump ) )
00782     {
00783       delete [] results;
00784       return 0;
00785     }
00786     
00787     surf_owners.append(lump);
00788     results[i].append(surface);
00789   }
00790   
00791   // add the rest of the Surfaces into separate lists according to
00792   // the Lump they belong to
00793   for ( i = 1; i < face_list.size(); i++ )
00794   {
00795     face = face_list.get_and_step();
00796   
00797     bridge_list.clean_out();
00798     face->bridge_manager()->get_bridge_list(bridge_list);
00799     bridge_list.reset();
00800     
00801     for ( int j = bridge_list.size(); j--; )
00802     {
00803       Surface* surface = dynamic_cast<Surface*>(bridge_list.get_and_step());
00804       assert(!!surface);
00805       lump_list.clean_out();
00806       surface->lumps(lump_list);
00807       Lump* lump = 0;
00808       if ( lump_list.size() > 1 )
00809       {
00810         delete [] results;
00811         return 0;
00812       }
00813       else if (lump_list.size())
00814         lump = lump_list.get();
00815 
00816       if ( !surf_owners.move_to(lump) ||
00817            results[surf_owners.get_index()].size() != i )
00818       {
00819         delete [] results;
00820         return 0;
00821       }
00822       
00823       results[surf_owners.get_index()].append(surface);
00824     }
00825   }
00826   
00827   // return the number of sets - one set for each Lump that was
00828   // involved in the merge
00829   num_result_sets = bridge_count;
00830   return results;
00831 }
00832 
00833 
00834 CubitStatus PartitionTool::insert_edge( 
00835                                      DLIList<RefFace*>& input_faces,
00836                                      DLIList<CubitVector*>& segments,
00837                                      DLIList<RefFace*>& output_faces,
00838                                      DLIList<RefEdge*>& new_edges,
00839                                      CubitBoolean do_split_curves)
00840 {
00841   int i, j, w, set_count;
00842   const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS; 
00843   
00844   // group surfaces by Lump
00845   DLIList<Surface*> *surface_sets = group_merged_surfaces( input_faces, set_count );
00846   if( !surface_sets )
00847   {
00848     PRINT_ERROR("Failed to group merged Surfaces in PartitionTool::insert_edge()\n");
00849     return CUBIT_FAILURE;
00850   }
00851   
00852   input_faces.reset();
00853   if(do_split_curves)
00854   {
00855     for ( w = input_faces.size(); w--; )
00856     {
00857       RefFace* face_ptr = input_faces.get_and_step();
00858       DLIList<RefEdge*> edge_list;
00859       face_ptr->ref_edges(edge_list);
00860       CubitVector pos = *segments.get();
00861       CubitVector closest;
00862       RefEdge * the_edge = NULL;
00863       DLIList <CubitVector *> vect_list;
00864       DLIList<RefEdge*> temp_list;
00865       int count = 0;
00866       for (i = 0 ; count < 2 && i < segments.size(); i++)
00867       {
00868         for (j = 0; j < edge_list.size(); j++) 
00869         { 
00870           the_edge = edge_list.get_and_step();        
00871           the_edge->closest_point_trimmed(pos, closest );
00872 
00873           if ( (pos - closest).length_squared() > TOL_SQR )
00874             continue;
00875 
00876         //closest point need to be on the edge
00877 /*
00878         the_edge->get_graphics(polyline, 0.0);
00879         int size = polyline.point_list_size();
00880         GPoint* pts = polyline.point_list();
00881         CubitVector pt1(pts[0]);
00882         CubitVector pt2(pts[1]);
00883         CubitBox edge_box (pt1, pt2);
00884         if (size > 1)
00885         {
00886           for (k = 2; k < size; k ++)
00887           {
00888             CubitVector pt3(pts[k]);
00889             CubitVector pt4(pts[k-1]);
00890             CubitBox box2(pt4, pt3);
00891             edge_box |= box2;
00892           }
00893         }
00894 
00895         CubitBox position_box(closest);
00896         if (size == 1 || (size > 1 && !position_box.overlap(0, edge_box)))      
00897             continue;
00898 */  
00899           CubitBox position_box(closest);
00900           CubitBox edge_box = the_edge->bounding_box(); 
00901           if (!position_box.overlap(0, edge_box))
00902             continue;
00903 
00904           delete segments.change_to(new CubitVector (closest));
00905           if((the_edge->start_coordinates() - closest).length_squared() < TOL_SQR 
00906             ||(the_edge->end_coordinates() - closest).length_squared() < TOL_SQR)
00907             break;
00908 
00909           vect_list.clean_out();
00910           vect_list.append(&closest);
00911           CubitStatus status = partition(the_edge, vect_list, temp_list);
00912           //need to debug later if this happens.
00913           //assert (CUBIT_SUCCESS == status);
00914           if( CUBIT_FAILURE == status )
00915              return status;
00916           edge_list.remove(the_edge);
00917           count ++;
00918           break;
00919         }
00920         pos = *segments.step_and_get();
00921       }
00922     }
00923   }
00924 
00925   input_faces.reset();
00926 
00927   // unmerge all the surfaces by removing all but the first Lump's
00928   // surfaces from the bridge manager
00929   DLIList<TopologyBridge*> bridge_list;
00930   DLIList<Surface*> surf_list;
00931   for ( i = input_faces.size(); i--; )
00932   {
00933      RefFace* face_ptr = input_faces.get_and_step();
00934      bridge_list.clean_out();
00935      face_ptr->bridge_manager()->get_bridge_list( bridge_list );
00936      CAST_LIST( bridge_list, surf_list, Surface );
00937      surf_list -= surface_sets[0];
00938      for ( int j = surf_list.size(); j--; )
00939       face_ptr->bridge_manager()->remove_bridge( surf_list.get_and_step() );
00940   }
00941   
00942   // perform the partition operation - insert curve - on each Lump's set of surfaces
00943   DLIList<Surface*> new_surfs, all_new_surfs;
00944   DLIList<Curve*> new_curves, all_new_curves;
00945   CubitStatus result = CUBIT_SUCCESS;
00946   for ( i = 0; i < set_count; i++ )
00947   {
00948     new_surfs.clean_out();
00949     new_curves.clean_out();
00950     if ( !PartitionEngine::instance().
00951       insert_curve( surface_sets[i], segments, new_surfs, new_curves ) )
00952       result = CUBIT_FAILURE;
00953     all_new_surfs += new_surfs;
00954     all_new_curves += new_curves;
00955   }
00956   delete [] surface_sets;  
00957 
00958   // Do not create a new body in the failure case
00959   if (CUBIT_FAILURE == result)
00960     return result;
00961   
00962   // get the list of all bodies involved in the partition operation
00963   DLIList<Body*> bodies, all_bodies;
00964   for ( i = input_faces.size(); i--; )
00965   {
00966     bodies.clean_out();
00967     input_faces.step_and_get()->bodies( bodies );
00968     all_bodies.merge_unique(bodies);
00969   }  
00970   
00971   for( i = all_bodies.size(); i--; )
00972   {
00973     Body* body = all_bodies.get_and_step();
00974     BodySM* bodysm = dynamic_cast<BodySM*>(body->bridge_manager()->topology_bridge());
00975     if( bodysm )
00976       GeometryQueryTool::instance()->make_Body( bodysm );
00977   }
00978   
00979   // re-merge if surfaces were merged before the partition operation
00980   if( set_count > 1 )
00981   {
00982     DLIList<RefFace*> result_faces;
00983     for( i = all_new_surfs.size(); i--; )
00984       result_faces.append( 
00985         GeometryQueryTool::instance()->make_RefFace(
00986           all_new_surfs.get_and_step() ) );
00987     MergeTool::instance()->merge_reffaces( result_faces );
00988   }  
00989   
00990   output_faces.clean_out();
00991 
00992   //make sure you are dealing with top-level TopologyBridges here,
00993   //ones that have a BridgeManager as the TBOwner.
00994   for( i = all_new_surfs.size(); i--; )
00995   {
00996     Surface *new_surface = all_new_surfs.get_and_step();
00997     RefFace *new_face = dynamic_cast<RefFace*>(new_surface->topology_entity());
00998     if( new_face )
00999       output_faces.append_unique( new_face );
01000     else
01001     {    
01002       DLIList<TopologyBridge*> bridges;
01003       PartitionEngine::instance().get_tbs_with_bridge_manager_as_owner(new_surface, bridges );
01004 
01005       if( bridges.size() == 0 )
01006         CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( new_surface, bridges );
01007 
01008       Surface *tmp_surf = NULL;
01009       if( bridges.get() )
01010         tmp_surf = static_cast<Surface*>(bridges.get());
01011 
01012       if( tmp_surf )
01013       { 
01014         new_face = dynamic_cast<RefFace*>(tmp_surf->topology_entity());
01015         output_faces.append_unique( new_face );
01016       }
01017     }
01018   }  
01019 
01020   output_faces.merge_unique(input_faces);    
01021   
01022   for( i = all_new_curves.size(); i--; )
01023   {
01024     Curve* curve = all_new_curves.get_and_step();
01025     new_edges.append( dynamic_cast<RefEdge*>(curve->topology_entity()) );
01026   }
01027   return result;
01028 }
01029   
01030 //-------------------------------------------------------------------------
01031 // Purpose       : Create point curves on RefFace
01032 //
01033 // Special Notes : 
01034 //
01035 // Creator       : 
01036 //
01037 // Creation Date :  
01038 //-------------------------------------------------------------------------
01039 CubitStatus PartitionTool::make_point_curves( RefFace* face_ptr,
01040                                        DLIList<CubitVector> &positions,
01041                                        DLIList<RefVertex*> &new_vertices)
01042 {
01043   int i, j;
01044   DLIList<TopologyBridge*> bridge_list;
01045   DLIList<Surface*> surface_list;
01046   DLIList<TBPoint*> new_points;
01047   CubitStatus rval = CUBIT_SUCCESS;
01048   
01049     // Get list of surfaces from RefFace
01050   face_ptr->bridge_manager()->get_bridge_list( bridge_list );
01051   CAST_LIST(bridge_list, surface_list, Surface);
01052   assert(bridge_list.size() == surface_list.size());
01053   surface_list.reset();
01054   
01055   if( CubitUndo::get_undo_enabled() )
01056   {
01057     DLIList<RefFace*> tmp_faces(1);
01058     tmp_faces.append( face_ptr );
01059     CubitUndo::save_state_with_cubit_file( tmp_faces );
01060   }
01061 
01062     // For each position in the list
01063   positions.reset();
01064   for (i = positions.size(); i--; )
01065   {
01066     CubitVector pos = positions.get_and_step();
01067     RefVertex* result_vtx = 0;
01068     RefEdge* point_curve = 0;
01069     CubitSense bridge_sense = CUBIT_UNKNOWN;
01070     
01071       // Create point-curve on each surface
01072     surface_list.last();
01073     for (j = surface_list.size(); j--; )
01074     {
01075       Surface *new_surf, *old_surf = surface_list.step_and_get();
01076       TBPoint* new_pt = PartitionEngine::instance().
01077                         insert_point_curve( old_surf, pos, new_surf );
01078         
01079       if (!new_pt)
01080       {
01081         PRINT_ERROR("Error imprint surface at position (%f,%f,%f)\n",
01082           pos.x(), pos.y(), pos.z());
01083         rval = CUBIT_FAILURE;
01084         continue;
01085       }
01086       
01087         // If surface was replaced with a virtual surface, update
01088         // the list
01089       new_points.append(new_pt);
01090       surface_list.change_to(new_surf);
01091       
01092         // Merge each result point into a single RefVertex
01093       if (!result_vtx)
01094         result_vtx = GeometryQueryTool::instance()->make_RefVertex(new_pt);
01095       else if (!new_pt->owner())
01096         result_vtx->bridge_manager()->add_bridge(new_pt);
01097         
01098         // Merge each result point-curve into a single RefEdge.
01099         // If the result was not a point-curve (input position was
01100         // on some existing point or curve), just let the merge
01101         // code clean up, merging/unmerging depending on tolerance.
01102       bridge_list.clean_out();
01103       new_pt->get_parents(bridge_list);
01104       if (bridge_list.size() != 1)
01105         continue;
01106       Curve* curve = dynamic_cast<Curve*>(bridge_list.get());
01107       if (curve->geometry_type() != POINT_CURVE_TYPE)
01108         continue;
01109       if (!point_curve)
01110       {
01111         bridge_sense = new_surf->bridge_sense();
01112         if (curve->bridge_sense() != bridge_sense)
01113           curve->reverse_bridge_sense();
01114         RefEdge::suppress_edge_length_warning(true);
01115         point_curve = GeometryQueryTool::instance()->make_RefEdge(curve);
01116         RefEdge::suppress_edge_length_warning(false);
01117       }
01118       else if(!curve->owner())
01119       {
01120         point_curve->bridge_manager()->add_bridge(curve);
01121         CubitSense merge_sense = new_surf->bridge_sense() == bridge_sense ?
01122                                  CUBIT_FORWARD : CUBIT_REVERSED ;
01123         if (curve->bridge_sense() != merge_sense)
01124           curve->reverse_bridge_sense();
01125       }
01126     }
01127   }
01128   
01129     // Update DAG topoloy for TB changes
01130   DLIList<RefFace*> result_faces;
01131   surface_list.reset();
01132   for (i = surface_list.size(); i--; )
01133   {
01134     RefFace* face = GeometryQueryTool::instance()
01135       ->make_RefFace(surface_list.get_and_step());
01136     result_faces.append_unique(face);
01137   }
01138   
01139     // Attempt to re-merge anything that was unmerged
01140     // during DAG update
01141   if( result_faces.size() > 1 )
01142   {
01143     MergeTool::instance()->merge_reffaces( result_faces );
01144   }
01145   
01146     // Get list of RefVertices that were actually created after
01147     // all the merging, unmerging, re-merging, etc.
01148   new_points.reset();
01149   for (i = new_points.size(); i--; )
01150     new_vertices.append( 
01151       dynamic_cast<RefVertex*>(new_points.get_and_step()->topology_entity()));
01152   
01153   if (new_vertices.size() > 1)
01154     new_vertices.uniquify_ordered();  
01155 
01156 
01157   if( CubitUndo::get_undo_enabled() && new_points.size() == 0 )
01158     CubitUndo::remove_last_undo();
01159 
01160   return rval; 
01161 }
01162 
01163 
01164 //-------------------------------------------------------------------------
01165 // Purpose       : Imprint a point on a surface
01166 //
01167 // Special Notes : 
01168 //
01169 // Creator       : Jason Kraftcheck
01170 //
01171 // Creation Date : 02/28/03
01172 //-------------------------------------------------------------------------
01173 RefVertex* PartitionTool::make_point_curve( RefFace* face_ptr,
01174                                      const CubitVector& position )
01175 {
01176   DLIList<CubitVector> positions(1);
01177   DLIList<RefVertex*> results(1);
01178   positions.append(position);
01179   
01180   if( CubitUndo::get_undo_enabled() )
01181     CubitUndo::save_state_with_cubit_file( face_ptr );
01182 
01183   if (make_point_curves(face_ptr, positions, results) && results.size())
01184     return results.get();
01185   else
01186   {
01187     if( CubitUndo::get_undo_enabled() )
01188       CubitUndo::remove_last_undo();
01189     return 0;
01190   }
01191 }
01192 
01193 
01194 //-------------------------------------------------------------------------
01195 // Purpose       : Partition an Edge
01196 //
01197 // Special Notes : 
01198 //
01199 // Creator       : Jason Kraftcheck
01200 //
01201 // Creation Date : 09/24/99
01202 //-------------------------------------------------------------------------
01203 /*
01204 CubitStatus PartitionTool::partition( RefEdge* edge_ptr,
01205                                       DLIList<RefVertex*>& split_points,
01206                                       DLIList<RefEdge*>& new_edges,
01207                                       CubitBoolean ignore_mesh )
01208 {
01209   DLIList<CubitVector*> vect_list;
01210   split_points.reset();
01211   for( int i = split_points.size(); i--; )
01212     vect_list.append( new CubitVector( split_points.get_and_step()->coordinates() ) );
01213   CubitStatus result = partition( edge_ptr, vect_list, new_edges, ignore_mesh );
01214   while( vect_list.size() )
01215     delete vect_list.pop();
01216   return result;
01217 }
01218 */
01219 CubitStatus PartitionTool::partition( RefEdge* edge_ptr,
01220                                       DLIList<CubitVector*>& split_points,
01221                                       DLIList<RefEdge*>& new_edges,
01222                                       CubitBoolean ignore_mesh )
01223 {
01224   DLIList<RefVertex*> new_vertices;
01225   return partition( edge_ptr, split_points, new_vertices, new_edges, ignore_mesh );
01226 }                                      
01227 
01228 CubitStatus PartitionTool::partition( RefEdge* edge_ptr,
01229                                       DLIList<CubitVector*>& split_points,
01230                                       DLIList<RefVertex*>&  new_vertices,
01231                                       DLIList<RefEdge*>& new_edges,
01232                                       CubitBoolean ignore_mesh )
01233 {
01234   if( split_points.size() < 1 ) return CUBIT_FAILURE;
01235   CubitStatus result = CUBIT_SUCCESS;
01236   RefVertex* new_vtx = 0;
01237 
01238   if( split_points.size() == 1 ) {
01239     RefEdge *edge1_ptr = 0, *edge2_ptr = 0;  
01240     new_vtx = partition( edge_ptr, *(split_points.get()), edge1_ptr, edge2_ptr, ignore_mesh );
01241     if( !new_vtx )
01242       return CUBIT_FAILURE;
01243     
01244     new_vertices.append(new_vtx);  
01245     if( edge1_ptr ) new_edges.append( edge1_ptr );
01246     if( edge2_ptr ) new_edges.append( edge2_ptr );
01247     return CUBIT_SUCCESS;
01248   }
01249 
01250   int i, j, count = split_points.size();
01251 
01252   CubitVector** vtx_array = new CubitVector*[count];
01253   double* param_array = new double[count];
01254   for( i = 0; i < count; i++ )
01255   {
01256     vtx_array[i] = split_points.get_and_step();
01257     param_array[i] = edge_ptr->u_from_position( *(vtx_array[i]) );
01258   }
01259 
01260   for( i = 0; i < count - 1; i++ )
01261   {
01262     int index = i;
01263     for( j = i + 1; j < count; j++ )
01264       if( param_array[j] < param_array[index] ) index = j;
01265     double temp_dbl = param_array[i];
01266     CubitVector* temp_vtx = vtx_array[i];
01267     param_array[i] = param_array[index];
01268     vtx_array[i] = vtx_array[index];
01269     param_array[index] = temp_dbl;
01270     vtx_array[index] = temp_vtx;
01271   }
01272   delete [] param_array;
01273   
01274   RefVertex* end_vtx = edge_ptr->end_vertex();
01275   for( i = 0; i < count; i++ )
01276   {
01277     RefEdge *first_new_edge, *secnd_new_edge;
01278     new_vtx = partition( edge_ptr, *(vtx_array[i]), first_new_edge, 
01279                                secnd_new_edge, ignore_mesh );
01280     if( ! new_vtx ) 
01281     {
01282       result = CUBIT_FAILURE;
01283       continue;
01284     }
01285     
01286     new_vertices.append(new_vtx);
01287     
01288     if( ! secnd_new_edge ) secnd_new_edge = edge_ptr;
01289     if( NULL == secnd_new_edge->other_vertex(end_vtx) )
01290     {
01291       edge_ptr = first_new_edge;
01292       new_edges.append( secnd_new_edge );
01293     }
01294     else
01295     {
01296       edge_ptr = secnd_new_edge;
01297       new_edges.append( first_new_edge );
01298     }
01299   }
01300   new_edges.append( edge_ptr );
01301   delete [] vtx_array;
01302   
01303   return result;
01304 }
01305 
01306 
01307     
01308 
01309 //-------------------------------------------------------------------------
01310 // Purpose       : Combine all possible PartitionEdges
01311 //
01312 // Special Notes : 
01313 //
01314 // Creator       : Jason Kraftcheck
01315 //
01316 // Creation Date : 08/23/99
01317 //-------------------------------------------------------------------------
01318 CubitStatus PartitionTool::unpartitionAll( DLIList<RefEdge*>& partition_edges,
01319                                            DLIList<RefEdge*>& restored_edges)
01320 {
01321   int i;
01322   DLIList<RefVertex*> vertex_list, tmp_list;
01323   for ( i = partition_edges.size(); i--; )
01324   {
01325     tmp_list.clean_out();
01326     partition_edges.step_and_get()->ref_vertices( tmp_list );
01327     vertex_list += tmp_list;
01328   }
01329   
01330   for ( i = vertex_list.size(); i--; )
01331     vertex_list.step_and_get()->marked(0);
01332   for ( i = vertex_list.size(); i--; )
01333   {
01334     RefVertex* vtx = vertex_list.step_and_get();
01335     vtx->marked( vtx->marked() + 1 );
01336   }
01337   for ( i = vertex_list.size(); i--; )
01338   {
01339     RefVertex* vtx = vertex_list.step_and_get();
01340     
01341     TBPoint* pt = vtx->get_point_ptr();
01342     CompositePoint* comp = dynamic_cast<CompositePoint*>(pt);
01343     if ( comp )
01344       pt = comp->get_point();
01345     PartitionPoint* part = dynamic_cast<PartitionPoint*>(pt);
01346       
01347     if( vtx->marked() != 2 || !can_remove(vtx) ||
01348         !part || part->real_point() )
01349       vertex_list.change_to(0);
01350     vtx->marked(0);
01351   }
01352   vertex_list.remove_all_with_value(0);
01353   
01354   if (vertex_list.size() == 0)
01355     return CUBIT_SUCCESS;
01356  
01357   RefEdge* edge;
01358   std::vector< TDUPtr<RefEdge> > result_list;
01359   for ( i = vertex_list.size(); i--; )
01360   {
01361     edge = CompositeTool::instance()
01362       ->remove_vertex( vertex_list.get_and_step(), true );
01363     if ( edge )
01364     {
01365       result_list.push_back( edge );
01366     }
01367   }
01368  
01369   unsigned int j;
01370   for ( j = 0; j < result_list.size(); j++ )
01371     if( result_list[j] )
01372       restored_edges.append_unique( result_list[j].ptr() );
01373   
01374   return restored_edges.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
01375 }
01376 
01377 
01378 //-------------------------------------------------------------------------
01379 // Purpose       : Unpartition faces and cleanup.
01380 //
01381 // Special Notes : 
01382 //
01383 // Creator       : Jason Kraftcheck
01384 //
01385 // Creation Date : 07/26/99
01386 //-------------------------------------------------------------------------
01387 CubitStatus PartitionTool::unpartitionAll( 
01388   DLIList<RefFace*>& partition_faces,
01389   DLIList<RefFace*>& restored_faces )
01390 {
01391   DLIList<TopologyEntity*> query_input, query_output;
01392   CAST_LIST_TO_PARENT( partition_faces, query_input );
01393   ModelQueryEngine::instance()->query_model(
01394     query_input, DagType::co_edge_type(), query_output );
01395   
01396   DLIList<CoEdge*> coedge_list;
01397   DLIList<RefEdge*> refedge_list;
01398   CAST_LIST( query_output, coedge_list, CoEdge );
01399   assert( query_output.size() == coedge_list.size() );
01400   int i;
01401   for ( i = coedge_list.size(); i--; )
01402     refedge_list.append( coedge_list.step_and_get()->get_ref_edge_ptr() );
01403   
01404   for ( i = refedge_list.size(); i--; )
01405     refedge_list.step_and_get()->marked(0);
01406   for ( i = refedge_list.size(); i--; )
01407   {
01408     RefEdge* edge = refedge_list.step_and_get();
01409     edge->marked( edge->marked() + 1 );
01410   }
01411   for ( i = refedge_list.size(); i--; )
01412   {
01413     RefEdge* edge = refedge_list.step_and_get();
01414     PartPTCurve* point_curve = dynamic_cast<PartPTCurve*>(edge->get_curve_ptr());
01415     SegmentedCurve* seg_curve = dynamic_cast<SegmentedCurve*>(edge->get_curve_ptr());
01416     if((point_curve || (seg_curve && edge->marked() == 2)) &&
01417                can_remove(edge))
01418     {
01419       // Try to remove this partition.
01420     }
01421     else
01422     {
01423       // Don't try to remove this partition.
01424       refedge_list.change_to(0);
01425     }
01426     edge->marked(0);
01427   }
01428   refedge_list.remove_all_with_value(0);
01429   
01430   if (refedge_list.size() == 0)
01431     return CUBIT_SUCCESS;
01432  
01433   RefFace* face;
01434   std::vector< TDUPtr<RefFace> > result_list;
01435   DLIList<TopologyBridge*> bridge_list;
01436   for ( i = refedge_list.size(); i--; )
01437   {
01438     bool is_partition = false;
01439     RefEdge* edge = refedge_list.get_and_step();
01440     edge->bridge_manager()->get_bridge_list( bridge_list );
01441     while ( bridge_list.size() )
01442     {
01443       TopologyBridge* bridge = bridge_list.pop();
01444       if ( dynamic_cast<PartitionEntity*>(bridge) ) {
01445         is_partition = true;
01446         break;
01447       }
01448       CompositeCurve* comp = dynamic_cast<CompositeCurve*>(bridge);
01449       if ( comp ) {
01450         for ( int j = 0; j < comp->num_curves(); j++ )
01451           bridge_list.append(comp->get_curve(j));
01452       }
01453     }
01454     if ( !is_partition )
01455       continue;
01456     
01457     face = CompositeTool::instance()->remove_edge( edge, true );
01458     if ( face )
01459     {
01460       result_list.push_back( face );
01461     }
01462   }
01463  
01464   unsigned int j;
01465   for ( j = 0; j < result_list.size(); j++ )
01466     if( result_list[j] )
01467       restored_faces.append_unique( result_list[j].ptr() );
01468   
01469   return restored_faces.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
01470 }
01471 
01472 
01473           
01474 
01475 CubitStatus PartitionTool::partition_face_by_curves( RefFace* face_to_split, 
01476                                       const DLIList<Curve*>& split_curves,
01477                                       DLIList<RefFace*>& result_set,
01478                                       CubitBoolean do_split_curves,
01479                                       DLIList<RefEdge*>* new_edges,
01480                                       CubitBoolean )
01481 {
01482   int i, j, numpts;
01483   CubitStatus status = CUBIT_SUCCESS;
01484   bool some_success = false;
01485   DLIList<RefEdge*> new_edge_list;
01486   DLIList<RefFace*> faces[2];
01487   DLIList<CubitVector*> segments;
01488   GMem gmem;
01489   
01490   if( CubitUndo::get_undo_enabled() )
01491   {
01492     DLIList<RefFace*> tmp_ref_face_list(1);
01493     tmp_ref_face_list.append( face_to_split );
01494     CubitUndo::save_state_with_cubit_file( tmp_ref_face_list );
01495   }
01496 
01497   faces[0].append( face_to_split );
01498   for (i = 0; i < split_curves.size(); i++ )
01499   {
01500     Curve* curve = split_curves.next(i);
01501     GeometryQueryEngine* engine = curve->get_geometry_query_engine();
01502 
01503     if (!engine->get_graphics( curve, &gmem, facetingTolerance ))
01504     {
01505       status = CUBIT_FAILURE;
01506       continue;
01507     }
01508 
01509     numpts = gmem.pointListCount;
01510 /*
01511 This code causes a failure in virtual imprint because it compares
01512 against the number of graphics curve facets.  I think this is wrong but
01513 for now I will comment out this code.  In the end, I think that
01514 partitioning should not be done on the faceted model. 
01515 If this hasn't been addressed in 6 months just kill this code. KGM 1/5/06
01516 
01517     // arbitrary # of subdivisions = 20 --KGM
01518     const double NUM_SEGS = 20.0;
01519 
01520     // if the graphics facets give too many points
01521     // (which happens if the model is large right now)
01522     // trim it to some more reasonable number
01523     if ( numpts > static_cast<int>(NUM_SEGS) )
01524     {
01525     
01526       // this independent of the curve sense
01527       double t0 = curve->start_param();
01528       double t1 = curve->end_param();
01529 
01530       double inc = (t1 - t0)/NUM_SEGS;
01531       double t;
01532       CubitVector* p1;
01533       for (t = t0; t < t1;  t+= inc) 
01534       {
01535         p1 = new CubitVector;
01536         CubitStatus status = curve->position_from_u( t, *p1 );
01537         if (status == CUBIT_SUCCESS)
01538           segments.append( p1 );
01539       }
01540 
01541       // make sure the end point is EXACTLY represented
01542       p1 = new CubitVector;
01543       CubitStatus status = curve->position_from_u( t1, *p1 );
01544       if (status == CUBIT_SUCCESS)
01545       {
01546         segments.append( p1 );
01547       }
01548       else
01549       {
01550         PRINT_ERROR("Bad end point evaluation on curve\n");
01551       }
01552       
01553       bool tmp_debug = false;
01554       if ( tmp_debug )  // KGM
01555       {
01556         for ( int i = 0; i < segments.size(); i++ )
01557         {
01558           CubitVector* point = segments.get_and_step();
01559           GfxDebug::draw_point( *point, CUBIT_RED_INDEX );
01560         }
01561         GfxDebug::flush();
01562       }
01563     }
01564     else 
01565       */
01566     {
01567       if (curve->bridge_sense() == CUBIT_REVERSED)
01568       {
01569         CubitVector* p1 = new CubitVector;
01570         curve->position_from_u( curve->end_param(), *p1 );
01571         segments.append( p1 );
01572       }
01573       else
01574       {
01575         CubitVector* p1 = new CubitVector;
01576         curve->position_from_u( curve->start_param(), *p1 );
01577         segments.append( p1 );
01578       }
01579     
01580       --numpts;  
01581       for (j = 1; j < numpts; j++)
01582       {
01583         const GPoint& p = gmem.point_list()[j];
01584         segments.append( new CubitVector( p.x, p.y, p.z ) );
01585       }
01586       
01587       if (curve->bridge_sense() == CUBIT_REVERSED)
01588       {
01589         CubitVector* p1 = new CubitVector;
01590         curve->position_from_u( curve->start_param(), *p1 );
01591         segments.append( p1 );
01592       }
01593       else
01594       {
01595         CubitVector* p1 = new CubitVector;
01596         curve->position_from_u( curve->end_param(), *p1 );
01597         segments.append( p1 );
01598       }
01599     }
01600     
01601     int index = i % 2;
01602     status = insert_edge( faces[index], segments, faces[1-index], new_edge_list, do_split_curves );
01603     if (status)
01604     {
01605       some_success = true;
01606       if (new_edges)
01607         *new_edges += new_edge_list;
01608     }
01609     else
01610     {
01611       faces[1-index] = faces[index];
01612     }
01613     
01614     while (segments.size())
01615       delete segments.pop();
01616   }
01617 
01618   result_set = faces[split_curves.size()%2];
01619 
01620   //surface might not have gotton split
01621   if( CubitUndo::get_undo_enabled() && result_set.size() == 1)
01622     CubitUndo::remove_last_undo();
01623   
01624   if( some_success )
01625     return CUBIT_SUCCESS;
01626   else
01627     return CUBIT_FAILURE;
01628 }
01629 
01630 //-------------------------------------------------------------------------
01631 // Purpose       : Do multiple partitioning of a RefFace
01632 //
01633 // Special Notes : 
01634 //
01635 // Creator       : Jason Kraftcheck
01636 //
01637 // Creation Date : 11/23/99
01638 //-------------------------------------------------------------------------
01639 CubitStatus PartitionTool::partition( RefFace* face_to_split, 
01640                                       const DLIList<RefEdge*>& split_edges,
01641                                       DLIList<RefFace*>& result_set,
01642                                       CubitBoolean do_split_curves,
01643                                       DLIList<RefEdge*>* new_edges,
01644                                       CubitBoolean )
01645 {
01646   int i;
01647   CubitStatus status = CUBIT_SUCCESS;
01648   
01649   // get the curves out of the edge list
01650   DLIList<Curve*> split_curves;
01651   for (i = 0; i < split_edges.size(); i++ )
01652   {
01653     RefEdge* edge = split_edges.next(i);
01654     split_curves.append( edge->get_curve_ptr() );
01655   }
01656 
01657   // partition based on the Curves
01658   status = partition_face_by_curves( face_to_split, split_curves, 
01659                                      result_set, do_split_curves, new_edges );
01660 
01661   return status;
01662 }
01663 
01664 CubitStatus PartitionTool::partition( RefFace* face, 
01665                                       DLIList<RefEdge*>& edges,
01666                       RefFace*& new1,
01667                       RefFace*& new2,
01668                       CubitBoolean im )
01669 {
01670   DLIList<RefFace*> result_faces;
01671   CubitStatus result = partition( face, edges, result_faces, im );
01672   result_faces.reset();
01673   new1 = result_faces.get_and_step();
01674   new2 = result_faces.get_and_step();
01675   return result;
01676 }
01677 
01678 
01679 
01680 //-------------------------------------------------------------------------
01681 // Purpose       : Partition a volume.
01682 //
01683 // Special Notes : 
01684 //
01685 // Creator       : Jason Kraftcheck
01686 //
01687 // Creation Date : 11/24/99
01688 //-------------------------------------------------------------------------
01689 CubitStatus PartitionTool::partition( RefVolume* volume_ptr,
01690                                       DLIList<RefFace*>& split_faces,
01691                                       RefVolume*& first_new_volume,
01692                                       RefVolume*& second_new_volume,
01693                                       CubitBoolean  )
01694 {
01695   int i;
01696   
01697   Lump* lump = volume_ptr->get_lump_ptr();
01698   DLIList<Surface*> surface_list;
01699   for( i = split_faces.size(); i--; )
01700     surface_list.append(split_faces.step_and_get()->get_surface_ptr());
01701   
01702   DLIList<Lump*> result_list;
01703   for( i = surface_list.size(); result_list.size() < 2 && i--; )
01704   {
01705     Lump* result = PartitionEngine::instance().
01706       insert_surface( surface_list.step_and_get(), lump );
01707       
01708     if(!result)
01709     {
01710       RefFace* face = dynamic_cast<RefFace*>(surface_list.get()->topology_entity());
01711       PRINT_ERROR("Insertion of surface %d into volume %d failed.\n",
01712         face ? face->id() : 0, volume_ptr->id() );
01713       continue;
01714     }
01715     
01716     lump = result;      
01717     result_list.append_unique(lump);
01718   }
01719   
01720   DLIList<Body*> body_list;
01721   volume_ptr->bodies(body_list);
01722   assert(body_list.size() == 1);
01723   Body* body_ptr = body_list.get();
01724   BodySM* bodysm = body_ptr->get_body_sm_ptr();
01725   GeometryQueryTool::instance()->make_Body(bodysm);
01726   
01727   result_list.reset();
01728   if( ! result_list.size() )
01729     return CUBIT_FAILURE;
01730 
01731   first_new_volume = volume_ptr;
01732   second_new_volume = dynamic_cast<RefVolume*>(result_list.get()->topology_entity());
01733 
01734   return CUBIT_SUCCESS;
01735 }
01736 CubitStatus PartitionTool::partition( RefVolume* volume_ptr,
01737                                       DLIList<CubitFacet*>& split_faces,
01738                                       RefVolume*& first_new_volume,
01739                                       RefVolume*& second_new_volume,
01740                                       DLIList<RefFace*>& new_surfaces,
01741                                       CubitBoolean  )
01742 {
01743   Lump* lump = volume_ptr->get_lump_ptr();
01744   
01745   Surface* result = PartitionEngine::instance().
01746       insert_surface( split_faces, lump );
01747       
01748   DLIList<Body*> body_list;
01749   volume_ptr->bodies(body_list);
01750   assert(body_list.size() == 1);
01751   Body* body_ptr = body_list.get();
01752   BodySM* bodysm = body_ptr->get_body_sm_ptr();
01753   GeometryQueryTool::instance()->make_Body(bodysm);
01754   
01755   if( ! result )
01756   {
01757     PRINT_ERROR("Failed to insert faceted surface into volume %d\n",
01758       volume_ptr->id());
01759     return CUBIT_FAILURE;
01760   }
01761 
01762   RefFace* result_face = dynamic_cast<RefFace*>(result->topology_entity());
01763   assert(!!result_face);
01764   new_surfaces.append(result_face);
01765   
01766   DLIList<RefVolume*> face_vols;
01767   result_face->ref_volumes(face_vols);
01768   face_vols.reset();
01769   first_new_volume = face_vols.get();
01770   second_new_volume = face_vols.next();
01771   
01772 if ( DEBUG_FLAG(88) ) {
01773   GfxDebug::display_all();
01774   if( PartitionSurface* ps = dynamic_cast<PartitionSurface*>(result) )
01775     ps->draw_facets(CUBIT_GREEN_INDEX);
01776   DLIList<RefEdge*> edges;
01777   DLIList<RefFace*> faces;
01778   result_face->ref_edges(edges);
01779   for ( int i = edges.size(); i--; )
01780   {
01781     faces.clean_out();
01782     RefEdge* edge = edges.get_and_step();
01783     edge->ref_faces(faces);
01784     if ( faces.size() > 1 )
01785       GfxDebug::highlight_ref_edge( edge );
01786   }
01787   GfxDebug::flush();
01788 }
01789 
01790   return CUBIT_SUCCESS;
01791 }
01792 
01793 
01794 //-------------------------------------------------------------------------
01795 // Purpose       : Delete a volume
01796 //
01797 // Special Notes : 
01798 //
01799 // Creator       : Jason Kraftcheck
01800 //
01801 // Creation Date : 02/11/03
01802 //-------------------------------------------------------------------------
01803 CubitStatus PartitionTool::destroy_volume_partition( RefVolume* volume )
01804 {
01805   Body* body = volume->get_body_ptr();
01806   PartitionLump* lump = dynamic_cast<PartitionLump*>(volume->get_lump_ptr());
01807   if( !lump ) return CUBIT_FAILURE;
01808   CubitStatus result = PartitionEngine::instance().destroy_lump(lump);
01809   TopologyBridge* tb = body->bridge_manager()->topology_bridge();
01810   GeometryQueryTool::instance()->make_Body(dynamic_cast<BodySM*>(tb));
01811   return result;
01812 }
01813 
01814 
01815 CubitStatus PartitionTool::unpartitionAll( DLIList<RefVolume*>& passed_list,
01816                                            DLIList<RefVolume*>& restored_list )
01817 {
01818   int i;
01819   
01820   if (!passed_list.size())
01821     return CUBIT_FAILURE;
01822   
01823     // Get owning body
01824   DLIList<Body*> body_list;
01825   Body* body_ptr = 0;
01826   for( i = passed_list.size(); i--; )
01827   {
01828     RefVolume* vol_ptr = passed_list.step_and_get();
01829     body_list.clean_out();
01830     vol_ptr->bodies(body_list);
01831     assert(body_list.size() == 1);
01832     if( !body_ptr )
01833       body_ptr = body_list.get();
01834     else if( body_ptr != body_list.get() )
01835     {
01836       PRINT_ERROR("Invalid volume list passed to PartitionTool::unpartition.\n"
01837                   "All volumes must belong to the same body.\n");
01838       return CUBIT_FAILURE;
01839     }
01840   }
01841   
01842     // Get lump list and real, partitioned lump
01843   DLIList<PartitionLump*> lump_list;
01844   TopologyBridge* real_lump = 0;
01845   for( i = passed_list.size(); i--; )
01846   {
01847     Lump* lump = passed_list.step_and_get()->get_lump_ptr();
01848     PartitionLump* partlump = dynamic_cast<PartitionLump*>(lump);
01849     if( !partlump )
01850     {
01851       PRINT_ERROR("Invalid volume list passed to PartitionTool::unpartition.\n"
01852                   "Volume %d is not a partition.\n", 
01853                   passed_list.get()->id());
01854       return CUBIT_FAILURE;
01855     }
01856     if( !real_lump )
01857       real_lump = partlump->partitioned_entity();
01858     else if( real_lump != partlump->partitioned_entity() )
01859     {
01860       PRINT_ERROR("Invalid volume list passed to PartitionTool::unpartition.\n"
01861                   "All volumes must be partitions of the same real volume.\n");
01862       return CUBIT_FAILURE;
01863     }
01864     
01865     lump_list.append(partlump);
01866   }
01867   
01868     // Find all faces volumes have in common
01869   DLIList<RefFace*> all_faces, vol_faces;
01870   passed_list.last();
01871   for( i = passed_list.size(); i--; )
01872   {
01873     vol_faces.clean_out();
01874     passed_list.step_and_get()->ref_faces( vol_faces );
01875     all_faces += vol_faces;
01876   }
01877   for( i = all_faces.size(); i--; )
01878     all_faces.step_and_get()->marked(-1);
01879   for( i = all_faces.size(); i--; )
01880   {
01881     RefFace* face = all_faces.step_and_get();
01882     face->marked( face->marked() + 1 );
01883   }
01884   for( i = all_faces.size(); i--; )
01885     if( all_faces.step_and_get()->marked() )
01886       all_faces.get()->marked(0);
01887     else
01888       all_faces.change_to(0);
01889   all_faces.remove_all_with_value(0);
01890   
01891   for( i = all_faces.size(); i--; )
01892     if ( !can_remove( all_faces.step_and_get() ) )
01893       all_faces.change_to(0);
01894   all_faces.remove_all_with_value(0);
01895   
01896   
01897     // Find all partition surfaces
01898   DLIList<PartitionSurface*> psurf_list;
01899   DLIList<TopologyBridge*> bridge_list;
01900   for( i = all_faces.size(); i--; )
01901   {
01902     bridge_list.clean_out();
01903     all_faces.step_and_get()->bridge_manager()->get_bridge_list(bridge_list);
01904     for( int j = bridge_list.size(); j--; )
01905     {
01906       PartitionSurface* psurf = dynamic_cast<PartitionSurface*>(bridge_list.step_and_get());
01907       if(psurf && psurf->partitioned_entity() == real_lump)
01908       {
01909         psurf_list.append(psurf);
01910       }
01911     }
01912   }
01913     
01914     // Remove partitioning surfaces
01915   for( i = psurf_list.size(); i--; )
01916   {
01917     PartitionSurface* surf = psurf_list.step_and_get();
01918 
01919     DLIList<Lump*> lumps;
01920     surf->lumps(lumps);
01921     assert(lumps.size() > 0  && lumps.size() <= 2);  // should be one or two surfs
01922 
01923     RefVolume* volume1 = NULL;
01924     RefVolume* volume2 = NULL;
01925 
01926     lumps.reset();
01927     if(lumps.size() == 2)
01928     {
01929       TopologyEntity *topo = lumps.get_and_step()->topology_entity();
01930       volume1 = CAST_TO(topo, RefVolume);
01931       assert(volume1 != NULL);
01932 
01933       topo = lumps.get_and_step()->topology_entity();
01934       volume2 = CAST_TO(topo, RefVolume);
01935       assert(volume2 != NULL);
01936     }
01937     
01938     //RefFace* face = dynamic_cast<RefFace*>(surf->owner());
01939     Lump* lump = PartitionEngine::instance().remove_surface(surf);
01940     if( !lump )
01941     {
01942       RefFace* face = dynamic_cast<RefFace*>(surf->topology_entity());
01943       PRINT_ERROR("Failed to remove surface %d\n", face ? face->id() : 0);
01944     }
01945     else
01946     {
01947       RefVolume *survivor = dynamic_cast<RefVolume*>(lump->topology_entity());
01948       RefVolume *dead = lumps.size() < 2 ? 0 : survivor == volume1 ? volume2 : volume1;
01949       CompositeTool::instance()->update_combined_vols( survivor, dead );
01950     }
01951   }
01952   
01953     // Find a surviving volume to return
01954   for ( i = passed_list.size(); i--; )
01955   {
01956     if( passed_list.step_and_get()->get_lump_ptr() )
01957     {
01958       restored_list.append( passed_list.get() );
01959     }
01960   }
01961     
01962     // update DAG and return
01963   BodySM* bodysm = body_ptr->get_body_sm_ptr();
01964   GeometryQueryTool::instance()->make_Body(bodysm);
01965   GeometryQueryTool::instance()->cleanout_deactivated_geometry();
01966   
01967   return CUBIT_SUCCESS;;
01968 }
01969   
01970 
01971 
01972 /************** Methods for debugging output ******************/
01973 
01974 void pt_print_bte_list( int debug_flag, DLIList<BasicTopologyEntity*>& edges, 
01975                         const char* trailing_string  )
01976 {
01977   if( DEBUG_FLAG( debug_flag ) )
01978   {
01979     PRINT_DEBUG(debug_flag, "{ ");
01980     edges.reset();
01981     for( int i = edges.size(); i > 1; i-- )
01982       PRINT_DEBUG(debug_flag, "%d, ",edges.get_and_step()->id() );
01983     if( edges.size() ) {
01984       PRINT_DEBUG(debug_flag, "%d",edges.get_and_step()->id() );
01985     }
01986     PRINT_DEBUG(debug_flag, " }%s",trailing_string ? trailing_string : "");
01987   }
01988 }
01989 void pt_print_edge_list( int debug_flag, DLIList<RefEdge*>& edges,
01990                          const char* trailing_string )
01991 {
01992   if( DEBUG_FLAG( debug_flag ) )
01993   {
01994     DLIList<BasicTopologyEntity*> bte_list;
01995     bte_list.reset();
01996     CAST_LIST_TO_PARENT( edges, bte_list);
01997     pt_print_bte_list( debug_flag, bte_list, trailing_string );
01998   }
01999 }
02000 void pt_print_face_list( int debug_flag, DLIList<RefFace*>& faces,
02001                          const char* trailing_string )
02002 {
02003   if( DEBUG_FLAG( debug_flag ) )
02004   {
02005     DLIList<BasicTopologyEntity*> bte_list;
02006     bte_list.reset();
02007     CAST_LIST_TO_PARENT( faces, bte_list);
02008     pt_print_bte_list( debug_flag, bte_list, trailing_string );
02009   }
02010 }
02011 void pt_print_loop( int debug_flag, Loop* loop_ptr, 
02012                     const char* trailing_string )
02013 {
02014   if( DEBUG_FLAG( debug_flag ) )
02015   {
02016     DLIList<RefEdge*> edges;
02017     loop_ptr->ordered_ref_edges( edges );
02018     pt_print_edge_list( debug_flag, edges, trailing_string );
02019   }
02020 }
02021 void pt_print_shell( int debug_flag, Shell* shell_ptr, 
02022                      const char* trailing_string )
02023 {
02024   if( DEBUG_FLAG( debug_flag ) )
02025   {
02026     DLIList<RefFace*> faces;
02027     shell_ptr->ref_faces( faces );
02028     pt_print_face_list( debug_flag, faces, trailing_string );
02029   }
02030 }
02031 
02032 void PartitionTool::notify_partition( 
02033   DLIList<RefEntity*> & /*partitioning_entities*/,
02034   BasicTopologyEntity *first_partitioned_entity,
02035   BasicTopologyEntity *second_partitioned_entity,
02036   BasicTopologyEntity *old_entity )
02037 {
02038   int i;
02039 
02040     // are the first and second entities unique?
02041   int first_unique = 
02042     first_partitioned_entity != old_entity &&
02043     first_partitioned_entity != NULL;
02044   
02045   int second_unique = 
02046     second_partitioned_entity != first_partitioned_entity &&
02047     second_partitioned_entity != old_entity &&
02048     second_partitioned_entity != NULL;
02049   
02050       // add unique entities to graphics
02051       // attach names to entities.
02052   if ( first_unique )
02053   {
02054     RefEntityName::instance()
02055       ->copy_refentity_names( old_entity, first_partitioned_entity );
02056   }
02057   if ( second_unique )
02058   {
02059     RefEntityName::instance()
02060       ->copy_refentity_names( old_entity, second_partitioned_entity );
02061   }
02062   
02063     // notify observers of this 
02064   AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_TOPOLOGY_MODIFIED, old_entity));
02065   
02066     // notify containing entities
02067   BasicTopologyEntity* entity_ptr = old_entity;
02068   if( first_unique ) 
02069     entity_ptr = first_partitioned_entity;
02070   else if( second_unique )
02071     entity_ptr = second_partitioned_entity;
02072     
02073   DLIList<RefFace*> face_list;
02074   RefFace *ref_face;
02075   DLIList<RefVolume*> vol_list;
02076   RefVolume *ref_volume;
02077   DLIList<Body*> body_list;
02078   Body *body;
02079   DLIList<RefEdge*> ref_edges;
02080   DLIList<RefVertex*> ref_verts;
02081 
02082   int has_parents = CUBIT_TRUE;
02083   int dim = entity_ptr->dimension();
02084   switch ( dim )
02085   {
02086     case 0:
02087         // ?
02088         // no break
02089     case 1:
02090         // does old_entity still have pointers to the ref_faces?
02091       entity_ptr->ref_faces( face_list );
02092       if ( face_list.size() == 0 && dim == 1 )
02093         has_parents = CUBIT_FALSE;
02094       for( i = face_list.size(); i > 0; i-- )
02095       {
02096         ref_face =  face_list.get_and_step();
02097         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, ref_face));
02098       }
02099       if( first_partitioned_entity ) 
02100         first_partitioned_entity->ref_vertices( ref_verts );
02101       if( second_partitioned_entity )
02102         second_partitioned_entity->ref_vertices( ref_verts );
02103       for( i=0; i<ref_verts.size(); i++ )
02104         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::VIRTUAL_STATUS_CHANGED, ref_verts[i]));
02105 
02106 
02107         // no break      
02108     case 2:
02109       entity_ptr->ref_volumes( vol_list );
02110       if ( vol_list.size() == 0 && dim == 2 )
02111         has_parents = CUBIT_FALSE;
02112       for( i = vol_list.size(); i > 0; i-- )
02113       {
02114         ref_volume = vol_list.get_and_step();
02115         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, ref_volume));
02116       }
02117       if( first_partitioned_entity ) 
02118       {
02119         first_partitioned_entity->ref_vertices( ref_verts );
02120         first_partitioned_entity->ref_edges( ref_edges );
02121       }
02122       if( second_partitioned_entity )
02123       {
02124         second_partitioned_entity->ref_vertices( ref_verts );
02125         second_partitioned_entity->ref_edges( ref_edges );
02126       }
02127       for( i=0; i<ref_verts.size(); i++ )
02128         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::VIRTUAL_STATUS_CHANGED, ref_verts[i]));
02129       for( i=0; i<ref_edges.size(); i++ )
02130         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::VIRTUAL_STATUS_CHANGED, ref_edges[i]));
02131       
02132         // no break      
02133     case 3:
02134       entity_ptr->bodies( body_list );
02135       if ( body_list.size() == 0 && dim == 3 )
02136         has_parents = CUBIT_FALSE;
02137       for( i = body_list.size(); i > 0; i-- )
02138       {
02139         body = body_list.get_and_step();
02140         AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, body));
02141       }
02142       break;
02143     default:
02144       break;
02145   }
02146   
02147   if( !has_parents )
02148   {
02149     // TODO -- should call GMT::make_free_RefEdge where appropriate or
02150     // GQE could be changed to recoginize it is making a free RefEdge.
02151     // When that is done, we no longer need these calls to the static observers.
02152     if( second_unique )
02153     {
02154       AppUtil::instance()->send_event( GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, second_partitioned_entity));
02155     }
02156     if( first_unique )
02157     {
02158       AppUtil::instance()->send_event( GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, first_partitioned_entity));
02159     }
02160   }
02161   
02162 }
02163 
02164 //-------------------------------------------------------------------------
02165 // Purpose       : These are overloaded by PartitionToolMesh
02166 //                 to prevent un-partitioning where the mesh cannot
02167 //                 be updated.
02168 //
02169 // Special Notes : 
02170 //
02171 // Creator       : Jason Kraftcheck
02172 //
02173 // Creation Date : 03/12/03
02174 //-------------------------------------------------------------------------
02175 CubitStatus PartitionTool::can_remove( RefVertex* ) { return CUBIT_SUCCESS; }
02176 CubitStatus PartitionTool::can_remove( RefEdge* ) { return CUBIT_SUCCESS; }
02177 CubitStatus PartitionTool::can_remove( RefFace* ) { return CUBIT_SUCCESS; }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines