cgma
|
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 }