cgma
PartitionLumpImprint.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : PartitionLumpImprint.cpp
00003 //
00004 // Purpose       : Imprint a lump with a polyline-loop
00005 //
00006 // Special Notes : 
00007 //
00008 // Creator       : Jason Kraftcheck
00009 //
00010 // Creation Date : 02/05/03
00011 //-------------------------------------------------------------------------
00012 
00013 #include "PartitionLumpImprint.hpp"
00014 
00015 #include "PartitionLump.hpp"
00016 #include "PartitionSurface.hpp"
00017 #include "PartitionLoop.hpp"
00018 #include "PartitionCoEdge.hpp"
00019 #include "PartitionCurve.hpp"
00020 #include "PartitionPoint.hpp"
00021 
00022 #include "CubitVector.hpp"
00023 #include "PartitionEngine.hpp"
00024 #include "SegmentedCurve.hpp"
00025 #include "PartPTCurve.hpp"
00026 #include "PartSurfFacetTool.hpp"
00027 
00028 #include "CubitFacetData.hpp"
00029 #include "CubitFacetEdgeData.hpp"
00030 #include "CubitPointData.hpp"
00031 
00032 const double DIST_TOL = 1000.0 * GEOMETRY_RESABS;
00033 const double DIST_TOL_SQR = DIST_TOL*DIST_TOL;
00034 
00035 const int PART_LUMP_DEBUG = 88;
00036 #define PART_LUMP_PRINT(...) PRINT_DEBUG(PART_LUMP_DEBUG, __VA_ARGS__)
00037 #include "GfxDebug.hpp"
00038 
00039 //-------------------------------------------------------------------------
00040 // Purpose       : Constructor - initialize some stuff
00041 //
00042 // Special Notes : 
00043 //
00044 // Creator       : Jason Kraftcheck
00045 //
00046 // Creation Date : 02/05/03
00047 //-------------------------------------------------------------------------
00048 PartitionLumpImprint::PartitionLumpImprint( PartitionLump* set_lump )
00049   : lump(set_lump)
00050 {
00051   lump->get_all_children( entityList );
00052   entityList.reset();
00053   
00054   for( int i = 0; i < entityList.size(); i++ )
00055     rTree.add(entityList.get_and_step());
00056   entityList.append(lump);
00057   
00058   newSurface = 0;
00059 }
00060 
00061 //-------------------------------------------------------------------------
00062 // Purpose       : Add an entity to internal structures
00063 //
00064 // Special Notes : 
00065 //
00066 // Creator       : Jason Kraftcheck
00067 //
00068 // Creation Date : 02/05/03
00069 //-------------------------------------------------------------------------
00070 bool PartitionLumpImprint::add( PartitionEntity* entity )
00071 {
00072   if( !entityList.append_unique(entity) )
00073     return false;
00074     
00075   rTree.add(entity);
00076   return true;
00077 }
00078 
00079 
00080 //-------------------------------------------------------------------------
00081 // Purpose       : Set up for imprint
00082 //
00083 // Special Notes : 
00084 //
00085 // Creator       : Jason Kraftcheck
00086 //
00087 // Creation Date : 02/05/03
00088 //-------------------------------------------------------------------------
00089 void PartitionLumpImprint::init( DLIList<CubitFacet*>* facets )
00090 {
00091   int i, j, junk = 0;
00092   PART_LUMP_PRINT("Beginning imprint\n");
00093   
00094   boundaryEdges.clean_out();
00095   newEntities.clean_out();
00096   assert(newSurface == 0);
00097 
00098   if ( facets )
00099   {
00100       // clear all marks
00101     for ( i = facets->size(); i--; )
00102     {
00103       CubitFacet* facet = facets->get_and_step();
00104       facet->point(0)->marked(0);
00105       facet->point(1)->marked(0);
00106       facet->point(2)->marked(0);
00107     }
00108 
00109       // copy facets 
00110     DLIList<CubitPointData*> new_facet_pts;
00111     for ( i = facets->size(); i--; )
00112     {
00113       CubitFacet* facet = facets->get_and_step();
00114       CubitPointData *pts[3];
00115       for ( j = 0; j < 3; j++ )
00116       {
00117         CubitPoint* pt = facet->point(j);
00118         if ( !pt->marked() )
00119         {
00120           pts[j] = new CubitPointData(pt->coordinates());
00121           new_facet_pts.append(pts[j]);
00122           pt->marked(new_facet_pts.size());
00123         }
00124         else
00125         {
00126           new_facet_pts.reset();
00127           pts[j] = new_facet_pts.next(pt->marked()-1);
00128         }
00129       }
00130       facetList.append( new CubitFacetData(pts[0], pts[1], pts[2], &junk ) );
00131     }
00132 
00133       // clear marks on input facets
00134     for ( i = facets->size(); i--; )
00135     {
00136       CubitFacet* facet = facets->get_and_step();
00137       facet->point(0)->marked(0);
00138       facet->point(1)->marked(0);
00139       facet->point(2)->marked(0);
00140     }
00141   }
00142 
00143     // mark boundary edges with a 1, others with a 0
00144   for ( i = facetList.size(); i--; )
00145   {
00146     CubitFacetData* facet = facetList.get_and_step();
00147     for ( j = 0; j < 3; j++ )
00148       facet->edge(j)->marked( facet->edge(j)->marked() + 1 );
00149   }
00150   
00151   for ( i = facetList.size(); i--; )
00152   {
00153     CubitFacetData* facet = facetList.get_and_step();
00154     for ( j = 0; j < 3; j++ )
00155     {
00156       if ( facet->edge(j)->marked() == 1 )
00157         boundaryEdges.append( facet->edge(j) );
00158       facet->edge(j)->marked(0);
00159     }
00160   }
00161   
00162   for ( i = boundaryEdges.size(); i--; )
00163     boundaryEdges.get_and_step()->marked(1);
00164 }
00165 
00166 void PartitionLumpImprint::begin_loop( DLIList<CubitPoint*>& points )
00167 {
00168   loopPoints = points;
00169   
00170     // associate each point with a geometric entity using rtree
00171   DLIList<PartitionEntity*> closest_list;
00172   CubitBox box;
00173   loopPoints.reset();
00174   for( int i = 0; i < loopPoints.size(); i++ )
00175   {
00176     CubitPoint* pt = loopPoints.next(i);
00177     closest_list.clean_out();
00178     CubitVector v = pt->coordinates();
00179     box.reset( CubitVector( v.x() - DIST_TOL,
00180                             v.y() - DIST_TOL,
00181                             v.z() - DIST_TOL ),
00182                CubitVector( v.x() + DIST_TOL,
00183                             v.y() + DIST_TOL,
00184                             v.z() + DIST_TOL ) );
00185                             
00186     rTree.find( box, closest_list );
00187     PartitionEntity* closest = find_closest( v, closest_list );
00188     if ( closest ) {
00189       set_point_owner(pt, closest);
00190     } else {
00191       set_point_owner(pt, lump);
00192     }
00193   }
00194 }
00195     
00196 //-------------------------------------------------------------------------
00197 // Purpose       : Find closest entity in passed list to position
00198 //
00199 // Special Notes : 
00200 //
00201 // Creator       : Jason Kraftcheck
00202 //
00203 // Creation Date : 02/26/03
00204 //-------------------------------------------------------------------------
00205 PartitionEntity* PartitionLumpImprint::find_closest(
00206   const CubitVector& pt, 
00207   DLIList<PartitionEntity*>& closest_list,
00208   bool use_tolerance )
00209 { 
00210   PartitionPoint* ppoint;
00211   PartitionCurve* pcurve;
00212   PartitionSurface* psurf;
00213   closest_list.reset();
00214   double closest_dist_sqr = use_tolerance ? DIST_TOL_SQR : CUBIT_DBL_MAX;
00215   PartitionEntity* closest = 0;
00216   int closest_dim = 3;
00217   CubitVector c;
00218 
00219   for( int i = closest_list.size(); i--; )
00220   {
00221     PartitionEntity* entity = closest_list.get_and_step();
00222     int dim = 3;
00223     if( (ppoint = dynamic_cast<PartitionPoint*>(entity)) )
00224     {
00225       c = ppoint->coordinates();
00226       dim = 0;
00227     }
00228     else if( (pcurve = dynamic_cast<PartitionCurve*>(entity)) )
00229     {
00230       pcurve->closest_point_trimmed( pt, c );
00231       dim = 1;
00232     }
00233     else if( (psurf = dynamic_cast<PartitionSurface*>(entity)) )
00234     {
00235       psurf->closest_point_trimmed( pt, c );
00236       dim = 2;
00237     }
00238     else
00239       assert(0);
00240 
00241 
00242       // want the entity of smallest dimension within
00243       // tolerance of point.
00244     double dist_sqr = (pt - c).length_squared();
00245     if ( use_tolerance ) 
00246     {
00247       if( (dim == closest_dim && dist_sqr <  closest_dist_sqr) || 
00248           (dim <  closest_dim && dist_sqr <= DIST_TOL_SQR ) )
00249       {
00250         closest_dist_sqr = dist_sqr;
00251         closest = entity;
00252         closest_dim = dim;
00253       }
00254     } 
00255     else 
00256     {
00257       double diff = closest_dist_sqr - dist_sqr;
00258       if ( (dim  > closest_dim && diff >  DIST_TOL_SQR) ||
00259            (dim == closest_dim && diff >  0.0         ) ||
00260            (dim  < closest_dim && diff > -DIST_TOL_SQR) )
00261       {
00262         closest_dist_sqr = dist_sqr;
00263         closest = entity;
00264         closest_dim = dim;
00265       }
00266     }
00267   }
00268 
00269   return closest;
00270 }
00271   
00272 //-------------------------------------------------------------------------
00273 // Purpose       : Clean up after imprint
00274 //
00275 // Special Notes : 
00276 //
00277 // Creator       : Jason Kraftcheck
00278 //
00279 // Creation Date : 02/05/03
00280 //-------------------------------------------------------------------------
00281 void PartitionLumpImprint::clean_up_loop()
00282 {
00283   for( int i = entityList.size(); i--; )
00284     entityList.get_and_step()->mark = 0;
00285   entityList.reset();
00286   loopPoints.clean_out();
00287   pointAssoc.clear();
00288 }
00289 
00290 //-------------------------------------------------------------------------
00291 // Purpose       : get the owner of a point in the loop of imprint points
00292 //
00293 // Special Notes : 
00294 //
00295 // Creator       : Jason Kraftcheck
00296 //
00297 // Creation Date : 02/05/03
00298 //-------------------------------------------------------------------------
00299 PartitionEntity* PartitionLumpImprint::point_owner( CubitPoint* pt ) 
00300 {
00301   return pointAssoc[pt];
00302 }
00303 
00304 //-------------------------------------------------------------------------
00305 // Purpose       : Set point owner
00306 //
00307 // Special Notes : 
00308 //
00309 // Creator       : Jason Kraftcheck
00310 //
00311 // Creation Date : 02/07/03
00312 //-------------------------------------------------------------------------
00313 void PartitionLumpImprint::set_point_owner( CubitPoint* pt, 
00314                                             PartitionEntity* owner )
00315 {
00316   CubitVector closest;
00317   PartitionPoint* ppt = 0;
00318   PartitionCurve* pcv = 0;
00319   PartitionSurface* psf = 0;
00320   if( 0 != (ppt = dynamic_cast<PartitionPoint*>(owner)) ) {
00321     pt->set( ppt->coordinates() );
00322   } else if( 0 != (pcv = dynamic_cast<PartitionCurve*>(owner)) ) {
00323     pcv->closest_point( pt->coordinates(), closest );
00324     pt->set( closest );
00325   } else if( 0 != (psf = dynamic_cast<PartitionSurface*>(owner)) ) {
00326     psf->closest_point( pt->coordinates(), &closest );
00327     pt->set( closest );
00328   }
00329 
00330   if( DEBUG_FLAG(PART_LUMP_DEBUG) )
00331   {
00332     const char* type = 0;
00333     int color = 0;
00334     if( ppt ) {
00335       type = "Point";   color = CUBIT_BLUE_INDEX;
00336     } else if( pcv ) {
00337       type = "Curve";   color = CUBIT_CYAN_INDEX;
00338     } else if( psf ) {
00339       type = "Surface"; color = CUBIT_YELLOW_INDEX;
00340     } else {
00341       type = "Lump";    color = CUBIT_RED_INDEX;
00342     }
00343     
00344     int index = -1;
00345     if ( loopPoints.move_to(pt) )
00346       index = loopPoints.get_index();
00347     loopPoints.reset();
00348 
00349     TopologyBridge* tb = dynamic_cast<TopologyBridge*>(owner);
00350     RefEntity* re = dynamic_cast<RefEntity*>(tb->topology_entity());
00351     PART_LUMP_PRINT("%d. (%f,%f,%f) -> %s %p (%d)\n", index,
00352                       pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z(), 
00353                       type, (void*)owner, re?re->id():0 );
00354     GfxDebug::draw_point( pt->coordinates(), color );
00355     GfxDebug::flush();
00356   }
00357 
00358   pointAssoc[pt] = owner;
00359 }
00360 
00361 //-------------------------------------------------------------------------
00362 // Purpose       : Get points owned by passed entity
00363 //
00364 // Special Notes : 
00365 //
00366 // Creator       : Jason Kraftcheck
00367 //
00368 // Creation Date : 03/03/03
00369 //-------------------------------------------------------------------------
00370 void PartitionLumpImprint::get_owned_points( PartitionEntity* owner,
00371                                              DLIList<CubitPoint*>& results )
00372 {
00373   std::map<CubitPoint*,PartitionEntity*>::iterator itor = pointAssoc.begin();
00374   for ( ; itor != pointAssoc.end(); ++itor )
00375     if( itor->second == owner )
00376       results.append(itor->first);
00377 }
00378 
00379 
00380 //-------------------------------------------------------------------------
00381 // Purpose       : Entry point for imprinting
00382 //
00383 // Special Notes : 
00384 //
00385 // Creator       : Jason Kraftcheck
00386 //
00387 // Creation Date : 04/14/03
00388 //-------------------------------------------------------------------------
00389 PartitionSurface* PartitionLumpImprint::imprint( DLIList<CubitFacet*>& facets,
00390                                                  DLIList<PartitionEntity*>& new_list )
00391 {
00392   init(&facets);
00393   DLIList<CubitVector> empty_list;
00394   return imprint( empty_list, new_list );
00395 }
00396 
00397 PartitionSurface* PartitionLumpImprint::imprint( DLIList<CubitFacetData*>& facets,
00398                                                  DLIList<CubitVector>& vertices,
00399                                                  DLIList<PartitionEntity*>& new_list )
00400 {
00401   facetList = facets;
00402   init(0);
00403   return imprint( vertices, new_list );
00404 }
00405 
00406 PartitionSurface* PartitionLumpImprint::imprint( DLIList<CubitVector>& vertices,
00407                                                  DLIList<PartitionEntity*>& new_list )
00408 {
00409   int i, j;
00410   
00411   newSurface = new PartitionSurface( lump );
00412   
00413   
00414     // Make vertices where requested.
00415   DLIList<CubitPoint*> vtx_points, all_points;
00416   for ( j = 0; j < 3; j++ )
00417     for ( i = facetList.size(); i--; )
00418       facetList.get_and_step()->point(j)->marked(1);
00419   
00420   for ( j = 0; j < 3; j++ ) {
00421     for ( i = facetList.size(); i--; ) {
00422       if ( facetList.step_and_get()->point(j)->marked() ) {
00423         facetList.get()->point(j)->marked(0);
00424         all_points.append( facetList.get()->point(j) );
00425       }
00426     }
00427   }
00428   
00429   for ( i = vertices.size(); i--; )
00430   {
00431     double closest_sqr = CUBIT_DBL_MAX;
00432     CubitPoint* closest_pt = 0;
00433     CubitVector vect = vertices.get_and_step();
00434     for ( j = all_points.size(); j--; )
00435     {
00436       CubitPoint* pt = all_points.step_and_get();
00437       double dist_sqr = (pt->coordinates() - vect).length_squared();
00438       if ( dist_sqr < closest_sqr ) 
00439       {
00440         closest_sqr = dist_sqr;
00441         closest_pt = pt;
00442       }
00443     }
00444     vtx_points.append( closest_pt );
00445   }
00446   
00447   
00448 
00449     // For each closed chain of boundary edges
00450   DLIList<CubitFacetEdge*> pt_edges;
00451   DLIList<CubitPoint*> chain, chain_verts;
00452   int unused = boundaryEdges.size();
00453   while( unused )
00454   {
00455       // find first edge
00456     for ( i = boundaryEdges.size(); i--; )
00457       if ( boundaryEdges.step_and_get()->marked() )
00458         break;
00459     
00460     if ( !boundaryEdges.get()->marked() )
00461       break;
00462     
00463     chain.clean_out();
00464     chain_verts.clean_out();
00465     CubitFacetEdge* edge = boundaryEdges.get();
00466     edge->marked(0);
00467     unused--;
00468     CubitPoint* first_pt = edge->point(0);
00469     CubitPoint* point = edge->point(1);
00470     
00471     CubitFacet* facet = edge->adj_facet(0);
00472     int edge_index = facet->edge_index(edge);
00473     if ( facet->edge_use(edge_index) == -1 )
00474       std::swap(first_pt, point);
00475     
00476     while( point != first_pt )
00477     {
00478       chain.append( point );
00479       if ( vtx_points.is_in_list(point) )
00480         chain_verts.append(point);
00481         
00482       pt_edges.clean_out();
00483       point->edges(pt_edges);
00484       for ( j = pt_edges.size(); j--; )
00485         if ( pt_edges.step_and_get()->marked() )
00486           break;
00487       
00488       if ( !pt_edges.get()->marked() )
00489         break;
00490     
00491       edge = pt_edges.get();
00492       edge->marked(0);
00493       unused--;
00494       point = edge->other_point(point);
00495     }
00496     
00497     if ( point != first_pt )
00498       break;
00499     
00500     chain.append( first_pt );
00501     if ( vtx_points.is_in_list(first_pt) )
00502       chain_verts.append(first_pt);
00503       
00504       // remove edges from boundaryList that will be 
00505       // destroyed by merging with other facet edges.
00506     for ( i = boundaryEdges.size(); i--; )
00507       if( boundaryEdges.step_and_get()->marked() == 0 )
00508         boundaryEdges.change_to(0);
00509     boundaryEdges.remove_all_with_value(0);
00510     
00511     
00512     PartitionLoop* new_loop = imprint( chain, chain_verts );
00513     if (!new_loop)
00514     {
00515       unused = 1;
00516       break;
00517     }
00518     
00519     newSurface->add(new_loop);
00520   }
00521   
00522   if ( !unused )
00523   {
00524     new_list = newEntities;
00525     PartitionSurface* result = newSurface;
00526     result->set_facet_data( facetList );
00527     newSurface = 0;
00528     return result;
00529   }
00530   
00531   abort_imprint();
00532   return 0;
00533 }
00534   
00535 
00536 //-------------------------------------------------------------------------
00537 // Purpose       : Imprint one loop onto the volume
00538 //
00539 // Special Notes : 
00540 //
00541 // Creator       : Jason Kraftcheck
00542 //
00543 // Creation Date : 02/05/03
00544 //-------------------------------------------------------------------------
00545 PartitionLoop* PartitionLumpImprint::imprint( DLIList<CubitPoint*>& loop ,
00546                                               DLIList<CubitPoint*>& vtx_points)
00547 {
00548   begin_loop( loop );
00549   DLIList<PartitionCoEdge*> results;
00550   
00551   if( ! make_vertices( vtx_points ) )
00552   {
00553     PRINT_ERROR("PartitionLumpImprint::make_vertices() failed.\n");
00554     return 0;
00555   }
00556   
00557   if( ! do_imprint() )
00558   {
00559     PRINT_ERROR("PartitionLumpImprint::do_imprint() failed.\n");
00560     return 0;
00561   }
00562   
00563   if( ! make_volume_curves() )
00564   {
00565     PRINT_ERROR("PartitionLumpImprint::make_volume_curves() failed.\n");
00566     return 0;
00567    }
00568  
00569   if( ! get_curves(results) )
00570   {
00571     PRINT_ERROR("PartitionLumpImprint::get_curves() failed.\n");
00572     return 0;
00573   }
00574 
00575 //for ( int i = 0; i < results.size(); i++ )
00576 //  results.get_and_step()->draw_facets(CUBIT_RED_INDEX);
00577 
00578   
00579   PartitionLoop* new_loop = new PartitionLoop;
00580   results.reverse();
00581   PartitionCoEdge* prev = 0;
00582   while ( results.size() )
00583   {
00584     PartitionCoEdge* coe = results.pop();
00585     new_loop->insert_after( coe, prev );
00586     prev = coe;
00587   }
00588   
00589   clean_up_loop();
00590   
00591   return new_loop;
00592 }
00593 
00594 //-------------------------------------------------------------------------
00595 // Purpose       : Create vertices where asked to do so
00596 //
00597 // Special Notes : 
00598 //
00599 // Creator       : Jason Kraftcheck
00600 //
00601 // Creation Date : 02/05/03
00602 //-------------------------------------------------------------------------
00603 CubitStatus PartitionLumpImprint::make_vertices( DLIList<CubitPoint*>& vtx_points )
00604 {
00605   for( int i = 0; i < vtx_points.size(); i++ )
00606   {
00607     CubitPoint* pt = vtx_points.get_and_step();
00608     PartitionEntity* entity = point_owner(pt);
00609     if( !entity )
00610       continue;
00611     
00612     
00613     if( dynamic_cast<TBPoint*>(entity) ) {
00614      ; // already a point
00615     }
00616     else if( dynamic_cast<Curve*>(entity) ) {
00617       if( !partitionCurve( pt ) )
00618         return CUBIT_FAILURE;
00619     }
00620     else if( dynamic_cast<Surface*>(entity) ) {
00621       if( !makePointCurve( pt ) )
00622         return CUBIT_FAILURE;
00623     }
00624     else if( !makeFreePoint( pt ) ) {
00625       return CUBIT_FAILURE;
00626     }
00627   }
00628   return CUBIT_SUCCESS;
00629 }
00630 
00631 //-------------------------------------------------------------------------
00632 // Purpose       : Try to clean up failed imprint
00633 //
00634 // Special Notes : Always returns CUBIT_FAILURE
00635 //
00636 // Creator       : Jason Kraftcheck
00637 //
00638 // Creation Date : 02/05/03
00639 //-------------------------------------------------------------------------
00640 CubitStatus PartitionLumpImprint::abort_imprint()
00641 {
00642   PRINT_ERROR("Loop-Volume imprint failed in PartitionLumpImprint\n"
00643               "\tAttempting to restore state.\n");
00644   
00645   clean_up_loop();
00646 
00647   DLIList<PartitionCurve*> curves;
00648   DLIList<PartitionPoint*> points;
00649   CAST_LIST( newEntities, curves, PartitionCurve );
00650   CAST_LIST( newEntities, points, PartitionPoint );  
00651   
00652   while( curves.size() )
00653   {
00654     PartitionCurve* curve = curves.pop();
00655 
00656     // if num curves for the startpoint/endpoint equals one, this point will
00657     // get cleaned up when the curve is deleted or removed
00658     // so remove the point from the list of points to clean up
00659     if (1 == curve->start_point()->num_curves())
00660       points.remove(curve->start_point());
00661     if (1 == curve->end_point()->num_curves())
00662       points.remove(curve->end_point());
00663 
00664     if( &(curve->sub_entity_set()) == &(lump->sub_entity_set()) )
00665       delete curve;
00666     else
00667       PartitionEngine::instance().remove_curve(curve);
00668   }
00669 
00670 
00671   while( points.size() )
00672   {
00673     PartitionPoint* point = points.pop();
00674     if( point->next_curve() == 0 )
00675       delete point;
00676     else if( dynamic_cast<PartPTCurve*>(point->next_curve()) )
00677       PartitionEngine::instance().remove_point_curve(point);
00678     else if( dynamic_cast<Curve*>(point->partitioned_entity()) )
00679       PartitionEngine::instance().remove_point(point);
00680   }
00681   
00682   while( facetList.size() )
00683     PartitionEngine::delete_facet( facetList.pop() );
00684   
00685   return CUBIT_FAILURE;
00686 }
00687 
00688 //-------------------------------------------------------------------------
00689 // Purpose       : Partition a curve and update local data
00690 //
00691 // Special Notes : 
00692 //
00693 // Creator       : Jason Kraftcheck
00694 //
00695 // Creation Date : 02/05/03
00696 //-------------------------------------------------------------------------
00697 CubitStatus PartitionLumpImprint::partitionCurve( CubitPoint* pt )
00698 {
00699     // get entities
00700   PartitionEntity* ent = point_owner(pt);
00701   PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent);
00702   assert(!!curve);
00703   
00704   PART_LUMP_PRINT("Splitting curve %p (%d) at (%f,%f,%f)\n",
00705     (void*)curve, dynamic_cast<RefEntity*>(curve->topology_entity()) ?
00706            dynamic_cast<RefEntity*>(curve->topology_entity())->id() : 0,
00707     pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z() );
00708   
00709     // get list of associated points that will need to be moved
00710     // to the new partition of the curve after the split.
00711   double u_end = curve->u_from_position( pt->coordinates() );
00712   DLIList<CubitPoint*> points_to_move;
00713   get_owned_points( curve, points_to_move );
00714   
00715   CubitPoint* curve_pt;
00716   for( int i = points_to_move.size(); i--; )
00717   {
00718     curve_pt = points_to_move.step_and_get();
00719     double u = curve->u_from_position( curve_pt->coordinates() );
00720     if( u < u_end || curve_pt == pt )
00721       points_to_move.change_to(0);
00722   }
00723   points_to_move.remove_all_with_value(0);
00724   
00725     // partition curve
00726   PartitionPoint* new_pt = new PartitionPoint( pt->coordinates(), curve );
00727   PartitionCurve* new_curve = 
00728     PartitionEngine::instance().insert_point( curve, new_pt );
00729   
00730     // partition failed
00731   if( !new_curve )
00732   {
00733     delete new_pt;
00734     return CUBIT_FAILURE;
00735   }
00736   
00737     // update internal lists
00738   add(new_pt);
00739   add(new_curve);
00740   newEntities.append(new_pt);
00741   pt->set( new_pt->coordinates() );
00742   set_point_owner( pt, new_pt );
00743   
00744     // update point associativity
00745   while( points_to_move.size() )
00746     set_point_owner( points_to_move.pop(), new_curve );
00747   
00748   return CUBIT_SUCCESS;
00749 }
00750 
00751 
00752 //-------------------------------------------------------------------------
00753 // Purpose       : Partition a surface and update internal data structures
00754 //
00755 // Special Notes : 
00756 //
00757 // Creator       : Jason Kraftcheck
00758 //
00759 // Creation Date : 02/05/03
00760 //-------------------------------------------------------------------------
00761 CubitStatus PartitionLumpImprint::partitionSurface( int first_point_id,
00762                                                     int last_point_id,
00763                                                     PartitionSurface* surface )
00764 {
00765   PartitionEntity* start_owner = point_owner(point(first_point_id));
00766   PartitionEntity* end_owner = point_owner(point(last_point_id));
00767   PartitionPoint* start_point = dynamic_cast<PartitionPoint*>(start_owner);
00768   PartitionPoint* end_point = dynamic_cast<PartitionPoint*>(end_owner);
00769   if ( (start_owner != lump && !start_point) ||
00770        (end_owner != lump && !end_point) ) {
00771     PRINT_ERROR("Facet boundary too coarse to resolve imprint.\n");
00772     return CUBIT_FAILURE;
00773   } 
00774 
00775   int i, next_point_id = (first_point_id + 1) % num_points();
00776   if( !surface )
00777   {
00778     assert(next_point_id != last_point_id);
00779     surface = dynamic_cast<PartitionSurface*>(point_owner(point(next_point_id)));
00780     assert(!!surface);
00781   }
00782   
00783   if ( PART_LUMP_DEBUG ) {
00784     RefEntity* re = dynamic_cast<RefEntity*>(surface->topology_entity());
00785     PART_LUMP_PRINT("Inserting curve into surface %p (%d)\n",
00786       (void*)surface, re ? re->id() : 0 );
00787   }
00788   
00789   DLIList<CubitPoint*> segments;
00790   first_point_id %= num_points();
00791   int last_id = last_point_id % num_points();
00792   
00793   int start, stop;
00794   if ( start_point )
00795     start = first_point_id;
00796   else
00797     start = next_point_id;
00798   if ( end_point )
00799     stop = (last_id + 1) % num_points();
00800   else
00801     stop = last_id;
00802   
00803   if( start == last_id )
00804   {
00805     i = start;
00806     do {
00807       segments.append(point(i));
00808       i = (i+1) % num_points();
00809     } while( i != start );
00810     segments.append(point(start));
00811   }
00812   else
00813   {
00814     for ( i = start; i != stop; i = (i + 1) % num_points() )
00815       segments.append(point(i));
00816   }
00817   
00818   assert(surface&&start_owner&&end_owner && start_owner!=surface && end_owner!=surface );
00819 
00820   DLIList<CubitVector*> segment_points;
00821   segments.reset();
00822   for ( i = segments.size(); i--; )
00823     segment_points.append( new CubitVector( segments.get_and_step()->coordinates() ) );
00824   
00825   DLIList<PartitionSurface*> input_list(1), new_surfs;
00826   DLIList<PartitionCurve*> new_curves;
00827   input_list.append(surface);
00828   CubitStatus result = PartitionEngine::instance().
00829     insert_curve( input_list, segment_points, new_surfs, new_curves );
00830   while( segment_points.size() )
00831     delete segment_points.pop();
00832     
00833   if ( !result )
00834   {
00835     PRINT_ERROR("Surface partitioning failed in PartitionLumpImprint\n");
00836     return CUBIT_FAILURE;
00837   }
00838   
00839     // Add all new geometry to 'entities'.  Append everything except
00840     // the surfaces to curves_and_points.
00841   DLIList<PartitionEntity*> entities;
00842   DLIList<PartitionPoint*> new_points;
00843     
00844     // Do Surfaces
00845   if( new_surfs.move_to( surface ) )
00846     new_surfs.extract();
00847   new_surfs.reset();
00848   for ( i = new_surfs.size(); i--; )
00849     entities.append(new_surfs.get_and_step());
00850     
00851     // Get new points
00852   for ( i = new_curves.size(); i--; )
00853   {
00854     new_curves.get()->start_point()->mark = 1;
00855     new_curves.get()->end_point()->mark = 1;
00856     new_curves.step();
00857   }
00858   if ( start_point )
00859     start_point->mark = 0;
00860   if ( end_point )
00861     end_point->mark = 0;
00862   for ( i = new_curves.size(); i--; )
00863   {
00864     if ( new_curves.get()->start_point()->mark )
00865     {
00866       PartitionPoint* pt = new_curves.get()->start_point();
00867       pt->mark = 0;
00868       new_points.append( pt );
00869       entities.append( pt );
00870     }
00871     if ( new_curves.get()->end_point()->mark )
00872     {
00873       PartitionPoint* pt = new_curves.get()->end_point();
00874       pt->mark = 0;
00875       new_points.append( pt );
00876       entities.append( pt );
00877     }
00878     entities.append( new_curves.get() );
00879     new_curves.step();
00880   }
00881 
00882     // If first and/or last segment points were already
00883     // associated with a vertex, don't search for a new
00884     // entity to associate them with.
00885   if( start_point ) {
00886     segments.reset();
00887     segments.remove();
00888   }
00889   if( end_point ) {
00890     segments.pop();
00891   }
00892 
00893   // Associate split segments with points
00894   for ( i = new_points.size(); i--; )
00895   {
00896     if (segments.size() == 0)
00897     break;
00898 
00899     PartitionPoint* vert = new_points.get_and_step();
00900     CubitPoint* pt = 0;
00901     segments.reset();
00902     int closest_index = -1;
00903     double closest_sqr = CUBIT_DBL_MAX;
00904     for ( int j = 0; j < segments.size(); j++ )
00905     {
00906       pt = segments.get_and_step();
00907       double dist_sqr = (pt->coordinates() - vert->coordinates()).length_squared();
00908       if ( dist_sqr < closest_sqr ) {
00909         closest_sqr = dist_sqr;
00910         closest_index = j;
00911       }
00912     }
00913     assert(closest_index >= 0);
00914     segments.reset();
00915     segments.step(closest_index);
00916     pt = segments.extract();
00917     assert(point_owner(pt) == surface);
00918     pt->set( vert->coordinates() );
00919     set_point_owner( pt, vert );
00920   }
00921 
00922   // Associate remaining segment points with curves
00923   PartitionEntity* entity;
00924   while( segments.size() )
00925   {
00926     CubitPoint* pt = segments.pop();
00927     PartitionCurve* closest = 0;
00928     double closest_sqr = CUBIT_DBL_MAX;
00929     CubitVector pos;
00930     for ( i = new_curves.size(); i--; )
00931     {
00932       PartitionCurve* curve = new_curves.get_and_step();
00933       curve->closest_point_trimmed( pt->coordinates(), pos );
00934       double dist_sqr = (pos - pt->coordinates()).length_squared();
00935       if ( dist_sqr < closest_sqr )
00936       {
00937         closest_sqr = dist_sqr;
00938         closest = curve;
00939       }
00940     }
00941     assert(closest != NULL);
00942     closest->closest_point( pt->coordinates(), pos );
00943     pt->set(pos);
00944     set_point_owner(pt, closest);
00945   }
00946 
00947   
00948     // append everything to newEntites and call add for each
00949   newEntities += entities;
00950   entities.reset();
00951   for ( i = entities.size(); i--; )
00952     add( entities.get_and_step() );
00953     
00954     // now add the orignal surface to entities  -- entities
00955     // becomes the list of entities that other polyline points
00956     // on the surface must lie on after the split
00957   entities.append(surface);
00958     
00959     // Associate any other points on the surface that 
00960     // haven't been used yet with the appropriate 
00961     // sub-region of the surface partitions.
00962   DLIList<CubitPoint*> surf_points;
00963   get_owned_points( surface, surf_points );
00964   for ( i = surf_points.size(); i--; )
00965   {
00966     CubitPoint* pt = surf_points.get_and_step();
00967     entity = find_closest( pt->coordinates(), entities, false );
00968     assert(!!entity);
00969     set_point_owner(pt, entity);
00970   }
00971   
00972   return CUBIT_SUCCESS;
00973 }
00974 
00975 //-------------------------------------------------------------------------
00976 // Purpose       : Create a point-curve on a surface
00977 //
00978 // Special Notes : 
00979 //
00980 // Creator       : Jason Kraftcheck
00981 //
00982 // Creation Date : 02/05/03
00983 //-------------------------------------------------------------------------
00984 CubitStatus PartitionLumpImprint::makePointCurve( CubitPoint* pt )
00985 {
00986   PartitionEntity* ent = point_owner(pt);
00987   PartitionSurface* surf = dynamic_cast<PartitionSurface*>(ent);
00988   CubitPointData* cpd = 
00989     PartitionEngine::instance().project_to_surface(surf, pt->coordinates());
00990   
00991   PART_LUMP_PRINT("Creating vertex on surface %p (%d) at (%f,%f,%f)\n",
00992     (void*)surf, dynamic_cast<RefEntity*>(surf->topology_entity()) ?
00993           dynamic_cast<RefEntity*>(surf->topology_entity())->id() : 0,
00994     pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z() );
00995     
00996   PartitionPoint* new_point = 0;
00997   if( cpd )
00998     new_point = PartitionEngine::instance().insert_point_curve( surf, cpd );
00999   
01000   if ( !new_point )
01001   {
01002    PRINT_ERROR("PartitionLumpImprint: point-curve creation failed.\n");
01003    return CUBIT_FAILURE;
01004   }
01005   
01006   add(new_point);
01007   newEntities.append(new_point);
01008   pt->set(new_point->coordinates());
01009   set_point_owner( pt, new_point );
01010   return CUBIT_SUCCESS;
01011 }
01012 
01013 //-------------------------------------------------------------------------
01014 // Purpose       : Create a free point in the volume
01015 //
01016 // Special Notes : 
01017 //
01018 // Creator       : Jason Kraftcheck
01019 //
01020 // Creation Date : 02/05/03
01021 //-------------------------------------------------------------------------
01022 CubitStatus PartitionLumpImprint::makeFreePoint( CubitPoint* pt )
01023 {
01024   
01025   PART_LUMP_PRINT("Creating free vertex at (%f,%f,%f)\n",
01026     pt->coordinates().x(), pt->coordinates().y(), pt->coordinates().z() );
01027 
01028   assert( point_owner(pt) == lump );
01029   PartitionPoint* new_pt = new PartitionPoint( pt->coordinates(), lump );
01030   add(new_pt);
01031   newEntities.append(new_pt);
01032   set_point_owner( pt, new_pt );
01033   return CUBIT_SUCCESS;
01034 }
01035 
01036 //-------------------------------------------------------------------------
01037 // Purpose       : Create a free curve in the volume
01038 //
01039 // Special Notes : End points must already exist
01040 //
01041 // Creator       : Jason Kraftcheck
01042 //
01043 // Creation Date : 02/05/03
01044 //-------------------------------------------------------------------------
01045 CubitStatus PartitionLumpImprint::makeFreeCurve( int start_id, int end_id )
01046 {
01047   PartitionPoint* start_pt 
01048     = dynamic_cast<PartitionPoint*>(point_owner(point(start_id)));
01049   PartitionPoint* end_pt 
01050     = dynamic_cast<PartitionPoint*>(point_owner(point(end_id)));
01051   if( !start_pt || !end_pt )
01052     return CUBIT_FAILURE;
01053   
01054   PART_LUMP_PRINT("Creating free curve from point %p (%d) (%f,%f,%f)"
01055                   "  to point %p (%d) (%f,%f,%f)\n",
01056     (void*)start_pt, dynamic_cast<RefEntity*>(start_pt->topology_entity()) ?
01057               dynamic_cast<RefEntity*>(start_pt->topology_entity())->id() : 0,
01058     start_pt->coordinates().x(), start_pt->coordinates().y(), start_pt->coordinates().z(),
01059     (void*)end_pt, dynamic_cast<RefEntity*>(end_pt->topology_entity()) ?
01060             dynamic_cast<RefEntity*>(end_pt->topology_entity())->id() : 0,
01061     end_pt->coordinates().x(), end_pt->coordinates().y(), end_pt->coordinates().z());
01062     
01063   bool all_pts = false;
01064   if( start_id == end_id )
01065   {
01066     end_id = (end_id+1)%num_points();
01067     all_pts = true;
01068   }
01069   
01070   int i;
01071   DLIList<CubitPoint*> points;
01072   points.append( point(start_id) );
01073   end_id %= num_points();
01074   for( i = (start_id + 1) % num_points(); i != end_id; i = (i+1)%num_points() )
01075   {
01076     if( point_owner(point(i)) != lump )
01077       return CUBIT_FAILURE;
01078     points.append( point(i) );
01079   }
01080   points.append( point(all_pts ? start_id : end_id) );
01081   
01082   DLIList<CubitVector*> curve_segments;
01083   points.reset();
01084   for( i = points.size(); i--; )
01085     curve_segments.append( new CubitVector(points.get_and_step()->coordinates()));
01086   SegmentedCurve* curve = new SegmentedCurve( lump, curve_segments );
01087   while( curve_segments.size() )
01088     delete curve_segments.pop();
01089   curve->start_point(start_pt);
01090   curve->end_point(end_pt);
01091   add(curve);
01092   newEntities.append(curve);
01093   for( i = (start_id + 1) % num_points(); i != end_id; i = (i+1)%num_points() )
01094     set_point_owner( point(i), curve );
01095 
01096   return CUBIT_SUCCESS;
01097 }
01098 
01099 //-------------------------------------------------------------------------
01100 // Purpose       : Partition curves and surfaces on imprint loop
01101 //
01102 // Special Notes : 
01103 //
01104 // Creator       : Jason Kraftcheck
01105 //
01106 // Creation Date : 02/06/03
01107 //-------------------------------------------------------------------------
01108 CubitStatus PartitionLumpImprint::do_imprint() 
01109 {
01110     // partition curves
01111   int i;
01112   for( i = 0; i <= num_points(); i++ )
01113   {
01114       // If the point owner isn't a curve, skip it.
01115     PartitionEntity* curr = point_owner(point(i));
01116     PartitionCurve* curve = dynamic_cast<PartitionCurve*>(curr);
01117     if( !curve )
01118       continue;
01119       
01120       // Split the curve at any point at which the polyline 
01121       // leaves the curve (except the end points, of course)
01122     PartitionEntity* prev = point_owner(point(i-1));
01123     PartitionEntity* next = point_owner(point(i+1));
01124     if( (prev != curr && 
01125          prev != curve->start_point() && 
01126          prev != curve->end_point()) ||
01127         (next != curr &&
01128          next != curve->start_point() &&
01129          next != curve->end_point()) )
01130     {
01131       if( !partitionCurve( point(i) ) )
01132         return CUBIT_FAILURE;
01133     }
01134   }            
01135       
01136     // partition surfaces
01137   
01138     // find position to start at
01139   for( i = 0; i < num_points(); i++ )
01140     if( point_owner(point(i)) != point_owner(point(i+1)) ||
01141         !dynamic_cast<PartitionSurface*>(point_owner(point(i))) )
01142       break;
01143   
01144     // loop through all points
01145   int index = i + 1;
01146   for( i = 0; i <= num_points(); )
01147   {
01148       // loop until we are at a point on a surface
01149     PartitionSurface* surf = 0;
01150     while( i <= num_points() &&
01151          !(surf = dynamic_cast<PartitionSurface*>(point_owner(point(index)))) )
01152     {
01153       i++;
01154       index++;
01155     }
01156     
01157     if( i > num_points() )
01158       break;
01159     
01160       // need the previous point too
01161     int prev_index = index - 1;
01162     
01163       // find remaining points on surface
01164     index++;
01165     i++;
01166     while( i <= num_points() && (point_owner(point(index)) == surf) )
01167     {
01168       index++;
01169       i++;
01170     }
01171     
01172       // loop stoped past last point on surface
01173       // store it and back up one.
01174     int next_index = index;
01175     index--;
01176     i--;
01177     
01178       // partition the surface
01179     if( ! partitionSurface( prev_index, next_index ) )
01180       return CUBIT_FAILURE;
01181   }
01182   
01183     // check for additional surface partitions where
01184     // the polyline has points on the boundary but
01185     // not the interior of the surface
01186   for( i = 0; i <= num_points(); i++ )
01187   {
01188     PartitionPoint* pt1 = dynamic_cast<PartitionPoint*>(point_owner(point(i)));
01189     PartitionPoint* pt2 = dynamic_cast<PartitionPoint*>(point_owner(point(i+1)));
01190     if( !pt1 || !pt2 || pt1->common_curve(pt2) )
01191       continue;
01192 
01193     CubitVector close, midpt = (pt1->coordinates() + pt2->coordinates()) / 2;
01194     PartitionSurface* surf = 0;
01195     PartitionCurve* curve = 0;
01196     double closest_dist = DIST_TOL_SQR;
01197     while( (curve = pt1->next_curve(curve)) )
01198     {
01199       PartitionCoEdge* coedge = 0;
01200       while( (coedge = curve->next_coedge(coedge)) )
01201       {
01202         PartitionSurface* surface = coedge->get_loop()->get_surface();
01203         if( surface == surf )
01204           continue;
01205           
01206         bool surf_contains_pt2 = false;
01207         PartitionCurve* curve2 = 0;
01208         while( (curve2 = pt2->next_curve(curve2)) && !surf_contains_pt2 )
01209         {
01210           PartitionCoEdge* coedge2 = 0;
01211           while( (coedge2 = curve2->next_coedge(coedge2)) )
01212           {
01213             if( coedge2->get_loop()->get_surface() == surface )
01214             {
01215               surf_contains_pt2 = true;
01216               break;
01217             }
01218           }
01219         }
01220         if( ! surf_contains_pt2 )
01221           continue;
01222           
01223         surface->closest_point( midpt, &close );
01224         double dist_sqr = (close - midpt).length_squared();
01225         if( dist_sqr <= DIST_TOL_SQR &&
01226             (!surf || dist_sqr < closest_dist) )
01227           surf = surface;
01228           closest_dist = dist_sqr;
01229       }
01230     }
01231       
01232     int end = i + 1;
01233     if( surf && !partitionSurface(i, end, surf) )
01234       return CUBIT_FAILURE;
01235     i = end - 1;
01236   }
01237 
01238   return CUBIT_SUCCESS;
01239 }
01240 
01241 //-------------------------------------------------------------------------
01242 // Purpose       : Construct free curves in lump interior to complete
01243 //                 the imprint loop
01244 //
01245 // Special Notes : 
01246 //
01247 // Creator       : Jason Kraftcheck
01248 //
01249 // Creation Date : 02/06/03
01250 //-------------------------------------------------------------------------
01251 CubitStatus PartitionLumpImprint::make_volume_curves()
01252 {
01253     // start at any point not owned by the volume
01254   int i;
01255   for( i = 0; i <= num_points() && point_owner(point(i)) == lump; i++ );
01256    
01257     // if everything is owned by the volume, make one vertex
01258   if( point_owner(point(i)) == lump && !makeFreePoint(point(i)) )
01259     return CUBIT_FAILURE;
01260   
01261     // create free curves from points in volume interior
01262   int index = i % num_points();
01263   for( i = 0; i <= num_points(); )
01264   {
01265       // advance until a point in the volume interior
01266     while( i <= num_points() && point_owner(point(index)) != lump )
01267     {
01268       i++;
01269       index = (index + 1) % num_points();
01270     }
01271     
01272     if( i > num_points() )
01273       break;
01274     
01275       // vertex to begin curve is at previous index
01276     int prev_index = (index + num_points() - 1) % num_points();
01277     
01278       // advance util we find a point not in the volume interior
01279       // (actually until a vertex possibly in the volume interior)
01280     while( i <= num_points() && point_owner(point(index)) == lump )
01281     {
01282       i++;
01283       index = (index + 1) % num_points();
01284     }
01285     
01286       // construct the curve
01287     if( !makeFreeCurve( prev_index, index ) )
01288       return CUBIT_FAILURE;
01289   }
01290   
01291     // create free curves where two points in are on vertices
01292     // but there does not already exist a curve connecting the
01293     // points
01294   for( i = 0; i <= num_points(); i++ )
01295   {
01296     PartitionPoint* pt1 = dynamic_cast<PartitionPoint*>(point_owner(point(i)));
01297     PartitionPoint* pt2 = dynamic_cast<PartitionPoint*>(point_owner(point(i+1)));
01298     if( pt1 && pt2 && !pt1->common_curve(pt2) && !makeFreeCurve(i,i+1) )
01299       return CUBIT_FAILURE;
01300   }
01301   
01302   return CUBIT_SUCCESS;
01303 }
01304 
01305 //-------------------------------------------------------------------------
01306 // Purpose       : Get the curves in the imprint loop
01307 //
01308 // Special Notes : 
01309 //
01310 // Creator       : Jason Kraftcheck
01311 //
01312 // Creation Date : 02/06/03
01313 //-------------------------------------------------------------------------
01314 CubitStatus PartitionLumpImprint::get_curves( DLIList<PartitionCoEdge*>& list )
01315 {
01316   list.clean_out();
01317   DLIList<CubitFacetEdgeData*> facet_edges, curve_edges;
01318   CubitStatus result = CUBIT_SUCCESS;
01319   
01320     // search for a vertex to begin at
01321   int i;
01322   PartitionPoint* pt = 0;
01323   for( i = 0; i < num_points(); i++ )
01324     if( (pt = dynamic_cast<PartitionPoint*>(point_owner(point(i)))) )
01325       break;
01326   if( !pt )
01327     return CUBIT_FAILURE;
01328   CubitPoint* prev_facet_pt = point(i);
01329   
01330   int index = i + 1;
01331   PartitionCurve* curve = 0;
01332   for( i = 0; result && i < num_points(); i++, index++ )
01333   {
01334     CubitPoint* facet_pt = point(index);
01335     CubitFacetEdgeData* edge = 
01336       dynamic_cast<CubitFacetEdgeData*>(prev_facet_pt->shared_edge( facet_pt ));
01337     if ( !edge ) {
01338       result = CUBIT_FAILURE;
01339       break;
01340     }
01341     facet_edges.append(edge);
01342     prev_facet_pt = facet_pt;
01343     
01344     PartitionPoint* pt2;
01345     PartitionCurve* curve2;
01346     if( (pt2 = dynamic_cast<PartitionPoint*>(point_owner(point(index)))) )
01347     {
01348       if( curve )
01349       {
01350         if( curve->other_point(pt) != pt2 )
01351           result = CUBIT_FAILURE;
01352       }
01353       else
01354       {
01355           //find common curves
01356         curve = 0;
01357         PartitionCurve* tmp_curve = 0;
01358         while( (tmp_curve = pt->next_curve(tmp_curve) ) != NULL )
01359         {
01360           if ( tmp_curve->other_point(pt) != pt2 )
01361             continue;
01362           
01363           if( !curve )
01364           {
01365             curve = tmp_curve;
01366             continue;
01367           }
01368           
01369           CubitVector mid = 0.5 * (pt->coordinates() + pt2->coordinates());
01370           CubitVector cpt, tpt;
01371           curve->closest_point( mid, cpt );
01372           tmp_curve->closest_point( mid, tpt );
01373           cpt -= mid;
01374           tpt -= mid;
01375           if ( cpt.length_squared() > tpt.length_squared() )
01376             curve = tmp_curve;
01377         }
01378 
01379         if( !curve )
01380           result = CUBIT_FAILURE;
01381       }
01382       
01383       if ( !result )
01384         break;
01385 
01386       CubitSense sense;
01387       if ( curve->start_point() != curve->end_point() ) {
01388         sense = curve->start_point() == pt ? CUBIT_FORWARD : CUBIT_REVERSED;
01389       } else {
01390         CubitVector junk, tangent;
01391         facet_edges.last();
01392         CubitVector es = facet_edges.get()->point(0)->coordinates();
01393         CubitVector ee = facet_edges.get()->point(1)->coordinates();
01394         curve->closest_point( 0.5*(es+ee), junk, &tangent );
01395         sense = (ee-es)%tangent < 0.0 ? CUBIT_REVERSED : CUBIT_FORWARD;
01396       }
01397 
01398       PartitionCoEdge* new_coedge = new PartitionCoEdge( newSurface, sense );
01399       curve->add(new_coedge);
01400       list.append(new_coedge);
01401       curve = 0;
01402       pt = pt2;
01403       facet_edges.append(0);
01404     }
01405     else 
01406     {
01407       curve2 = dynamic_cast<PartitionCurve*>(point_owner(point(index)));
01408       
01409       if( !curve2 || (curve && curve != curve2) )
01410         result = CUBIT_FAILURE;
01411       else
01412         curve = curve2;
01413     }
01414   }
01415   
01416   if ( result )
01417   {
01418       // seam facet edges
01419     facet_edges.reset();
01420     list.reset();
01421     int used = facet_edges.size();
01422     for ( i = list.size(); i--; )
01423     {
01424       PartitionCurve* curve = list.get_and_step()->get_curve();
01425       curve_edges.clean_out();
01426       CubitFacetEdgeData* edge;
01427       while ( used-- && (edge = facet_edges.get_and_step()) )
01428         curve_edges.append(edge);
01429   
01430       assert(curve_edges.size());
01431       if ( !seam_curve( curve_edges, curve, facetList ) )
01432       {
01433         result = CUBIT_FAILURE;
01434         break;
01435       }
01436     }
01437   }
01438   
01439   if (result)
01440     return CUBIT_SUCCESS;
01441   
01442   while ( list.size() )
01443   {
01444     PartitionCoEdge* coedge = list.pop();
01445     coedge->get_curve()->remove(coedge);
01446     delete coedge;
01447   }
01448   return CUBIT_FAILURE;
01449 }
01450 
01451 CubitStatus PartitionLumpImprint::seam_curve ( DLIList<CubitFacetEdgeData*>& edges,
01452                                                PartitionCurve* curve,
01453                                                DLIList<CubitFacetData*>& facets )
01454 {
01455   // Get start and end facet points for chain of edges
01456   CubitPoint *start_point_t, *end_point_t;
01457   if (edges.size() == 1)
01458   {
01459     start_point_t = edges.get()->point(0);
01460     end_point_t = edges.get()->point(1);
01461   }
01462   else
01463   {
01464     edges.last();
01465     end_point_t = edges.get()->shared_point( edges.prev() );
01466     end_point_t = edges.get()->other_point( end_point_t );
01467     edges.reset();
01468     start_point_t = edges.get()->shared_point( edges.next() );
01469     start_point_t = edges.get()->other_point( start_point_t );
01470   }
01471   
01472   CubitPointData* start_point = dynamic_cast<CubitPointData*>(start_point_t);
01473   CubitPointData*   end_point = dynamic_cast<CubitPointData*>(  end_point_t);
01474   assert(start_point && end_point);
01475   
01476   // If list if edges is backwards on curve, reverse it
01477   if (curve->start_point() == curve->end_point())
01478   {
01479     assert( start_point == end_point );
01480     edges.reset();
01481     CubitVector s = start_point->coordinates();
01482     CubitVector e = edges.get()->other_point(start_point)->coordinates();
01483     CubitVector j, t;
01484     curve->closest_point ( 0.5 * (s + e), j, &t );
01485     if ( (e - s) % t < 0.0 )
01486       edges.reverse();
01487   }
01488   else
01489   {
01490     if (curve->start_point()->facet_point() == end_point ||
01491         curve->end_point()->facet_point() == start_point)
01492     {
01493       std::swap(start_point, end_point);
01494       edges.reverse();
01495     }
01496     else if (curve->start_point()->facet_point() != start_point &&
01497              curve->end_point()->facet_point() != end_point)
01498     {
01499       double fwd = (curve->start_point()->coordinates() - start_point->coordinates()).length()
01500                  + (curve->end_point()->coordinates() - end_point->coordinates()).length();
01501       double rev = (curve->end_point()->coordinates() - start_point->coordinates()).length()
01502                  + (curve->start_point()->coordinates() - end_point->coordinates()).length();
01503       if (fwd > rev)
01504       {
01505         std::swap(start_point, end_point);
01506         edges.reverse();
01507       }
01508     }
01509   }
01510   
01511   // Merge facet points at start and end vertices
01512   if (curve->start_point()->facet_point() != start_point)
01513   {
01514     if (curve->start_point()->facet_point())
01515       curve->start_point()->facet_point()->merge_points(start_point);
01516     else
01517       curve->start_point()->facet_point(start_point);
01518   }
01519   if (curve->start_point() != curve->end_point() &&
01520       curve->end_point()->facet_point() != end_point)
01521   {
01522     if (curve->end_point()->facet_point())
01523       curve->end_point()->facet_point()->merge_points(end_point);
01524     else
01525       curve->end_point()->facet_point(end_point);
01526   }
01527   
01528   // Now seam interior points/edges
01529   return PartSurfFacetTool::seam_curve( edges, curve, facets );
01530 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines