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