cgma
|
00001 #include <assert.h> 00002 #include <vector> 00003 00004 #include "CompositeTool.hpp" 00005 00006 #include "DLIList.hpp" 00007 #include "CastTo.hpp" 00008 #include "CubitUtil.hpp" 00009 00010 #include "RefEntityFactory.hpp" 00011 #include "RefEdge.hpp" 00012 #include "RefFace.hpp" 00013 #include "RefVertex.hpp" 00014 #include "RefVolume.hpp" 00015 #include "Loop.hpp" 00016 #include "Shell.hpp" 00017 #include "Chain.hpp" 00018 #include "CoEdge.hpp" 00019 #include "CoFace.hpp" 00020 #include "CoVertex.hpp" 00021 #include "Body.hpp" 00022 00023 #include "CompositeCurve.hpp" 00024 #include "CompositeSurface.hpp" 00025 #include "CompositeLump.hpp" 00026 #include "CompositeBody.hpp" 00027 00028 //#include "VirtualQueryEngine.hpp" 00029 #include "PartitionTool.hpp" 00030 #include "BasicTopologyEntity.hpp" 00031 #include "ModelQueryEngine.hpp" 00032 #include "RefEntityName.hpp" 00033 00034 #include "CompositeEngine.hpp" 00035 #include "Point.hpp" 00036 #include "GeometryQueryTool.hpp" 00037 #include "DAG.hpp" 00038 //#include "CAMergePartner.hpp" 00039 //#include "TDUniqueId.hpp" 00040 #include "CubitAttrib.hpp" 00041 #include "CADefines.hpp" 00042 00043 #include "PartitionEngine.hpp" 00044 #include "PartitionSurface.hpp" 00045 #include "SegmentedCurve.hpp" 00046 #include "PartPTCurve.hpp" 00047 #include "PartitionPoint.hpp" 00048 #include "GMem.hpp" 00049 #include "GfxDebug.hpp" 00050 00051 CompositeTool* CompositeTool::instance_ = NULL; 00052 00053 00054 //------------------------------------------------------------------------- 00055 // Purpose : Constructor 00056 // 00057 // Special Notes : 00058 // 00059 // Creator : Jason Kraftcheck 00060 // 00061 // Creation Date : 10/17/03 00062 //------------------------------------------------------------------------- 00063 CompositeTool::CompositeTool() 00064 { 00065 } 00066 00067 00068 //------------------------------------------------------------------------- 00069 // Purpose : Destructor 00070 // 00071 // Special Notes : 00072 // 00073 // Creator : Jason Kraftcheck 00074 // 00075 // Creation Date : 00076 //------------------------------------------------------------------------- 00077 CompositeTool::~CompositeTool() 00078 { 00079 assert( instance_ == this ); 00080 instance_ = NULL; 00081 } 00082 00083 //------------------------------------------------------------------------- 00084 // Purpose : Create a composite curve 00085 // 00086 // Special Notes : 00087 // 00088 // Creator : Jason Kraftcheck 00089 // 00090 // Creation Date : 00091 //------------------------------------------------------------------------- 00092 RefEdge* CompositeTool::composite( DLIList<RefEdge*>& edge_list, 00093 RefVertex* keep, 00094 RefEdge* survivor ) 00095 { 00096 int i; 00097 DLIList<RefVertex*> vertex_list; 00098 DLIList<RefEdge*> modified_edges; 00099 00100 for( i = edge_list.size(); i--; ) 00101 { 00102 RefEdge* edge = edge_list.get_and_step(); 00103 RefVertex* start_vtx = edge->start_vertex(); 00104 RefVertex* end_vtx = edge->end_vertex(); 00105 start_vtx->marked(0); 00106 end_vtx->marked(0); 00107 vertex_list.append( start_vtx ); 00108 vertex_list.append( end_vtx ); 00109 } 00110 for( i = vertex_list.size(); i--; ) 00111 { 00112 RefVertex* vtx = vertex_list.get_and_step(); 00113 vtx->marked( vtx->marked() + 1 ); 00114 } 00115 // Check for edges that will have both vertices removed. 00116 // If any exist then we want to set the flag to have the 00117 // DAG updated after each vertex is removed. Otherwise 00118 // things get left in a bad state. 00119 bool update_dag = false; 00120 for(i=edge_list.size(); i>0; i--) 00121 { 00122 RefEdge* edge = edge_list.get_and_step(); 00123 if(edge->start_vertex()->marked() == 2 && 00124 edge->end_vertex()->marked() == 2) 00125 { 00126 update_dag = true; 00127 i=0; 00128 } 00129 } 00130 for( i = vertex_list.size(); i--; ) 00131 if( vertex_list.step_and_get()->marked() == 2 ) 00132 vertex_list.get()->marked(0); 00133 else 00134 vertex_list.change_to( 0 ); 00135 vertex_list.remove_all_with_value(0); 00136 00137 if ( keep && vertex_list.move_to(keep) ) 00138 vertex_list.remove(); 00139 00140 if( vertex_list.size() == 0 ) 00141 { 00142 PRINT_ERROR("Cannot create any composites from passed curves.\n"); 00143 return 0; 00144 } 00145 vertex_list.reset(); 00146 RefEdge* result = 0; 00147 DLIList<RefEdge*> vtx_edges; 00148 for( i = vertex_list.size(); i--; ) 00149 { 00150 RefVertex* vtx = vertex_list.get_and_step(); 00151 vtx_edges.clean_out(); 00152 vtx->ref_edges(vtx_edges); 00153 //check to make sure that the two edges resides on the same surface(s) 00154 if ( vtx_edges.size() == 2 ) 00155 { 00156 RefEdge* first_edge = vtx_edges.get(); 00157 RefEdge* second_edge = vtx_edges.step_and_get(); 00158 DLIList <RefFace*> common_faces; 00159 int size = first_edge->common_ref_faces(second_edge, common_faces); 00160 if (first_edge->num_ref_faces() != second_edge->num_ref_faces() || 00161 size != first_edge->num_ref_faces()) 00162 { 00163 PRINT_INFO("Curve %d and curve %d don't reside on the same surfaces.\n", first_edge->id(), second_edge->id()); 00164 continue; 00165 } 00166 00167 result = remove_vertex( vtx, false, update_dag, survivor ); 00168 if (result) 00169 { 00170 // First remove any edges from the list that got destroyed in the 00171 // last remove_vertex operation. 00172 if(result == first_edge && modified_edges.move_to(second_edge)) 00173 { 00174 modified_edges.remove(); 00175 } 00176 else if(result == second_edge && modified_edges.move_to(first_edge)) 00177 { 00178 modified_edges.remove(); 00179 } 00180 modified_edges.append_unique(result); 00181 } 00182 } 00183 } 00184 00185 for ( i = modified_edges.size(); i--; ) 00186 if ( ! modified_edges.step_and_get()->get_curve_ptr() ) 00187 modified_edges.change_to(0); 00188 modified_edges.remove_all_with_value(0); 00189 00190 result = modified_edges.size() ? modified_edges.get() : 0; 00191 00192 DLIList<Surface*> update_surfaces, curve_surfaces; 00193 DLIList<TopologyBridge*> curve_bridges; 00194 for ( i = modified_edges.size(); i--; ) 00195 { 00196 RefEdge* edge = modified_edges.get_and_step(); 00197 edge->set_id( RefEntityFactory::instance()->next_ref_edge_id() ); 00198 edge->bridge_manager()->get_bridge_list(curve_bridges); 00199 curve_bridges.reset(); 00200 for (int j = curve_bridges.size(); j--; ) 00201 { 00202 curve_surfaces.clean_out(); 00203 curve_bridges.get_and_step()->surfaces(curve_surfaces); 00204 update_surfaces.merge_unique(curve_surfaces); 00205 } 00206 } 00207 00208 update_surfaces.reset(); 00209 for ( i = update_surfaces.size(); i--; ) 00210 { 00211 GeometryQueryTool::instance()->make_RefFace(update_surfaces.get_and_step()); 00212 } 00213 assert( !(survivor && survivor->deactivated()) ); 00214 DAG::instance()->cleanout_deactivated_DAG_nodes(); 00215 00216 return result; 00217 } 00218 00219 00220 //------------------------------------------------------------------------- 00221 // Purpose : Composite over a vertex 00222 // 00223 // Special Notes : 00224 // 00225 // Creator : Jason Kraftcheck 00226 // 00227 // Creation Date : 03/12/03 00228 //------------------------------------------------------------------------- 00229 RefEdge* CompositeTool::remove_vertex( RefVertex* vertex, 00230 bool remove_partitions, /* = false */ 00231 bool update_dag , /* = true */ 00232 RefEdge* keep_edge /* = NULL */ ) 00233 { 00234 DLIList<RefEdge*> vertex_edges; 00235 int i; 00236 00237 // Get two ref-edges 00238 vertex->ref_edges( vertex_edges ); 00239 if ( vertex_edges.size() != 2 ) 00240 { 00241 PRINT_ERROR("Cannot composite over valence-%d vertex.\n", vertex_edges.size()); 00242 return 0; 00243 } 00244 00245 DLIList<TopologyBridge*> point_bridges; 00246 DLIList<CoEdgeSM*> coedgesms; 00247 00248 RefEdge *edge = 0, *refedge1 = 0, *refedge2 = 0; 00249 point_bridges.clean_out(); 00250 vertex->bridge_manager()->get_bridge_list( point_bridges ); 00251 00252 00253 int result_interval=-1; 00254 double result_size=-1; 00255 SizeIntervalType result_size_type=NOT_SET; 00256 FirmnessType result_count_type=LIMP; 00257 00258 std::vector<CubitString> names_to_add; 00259 Curve* end_result = 0; 00260 point_bridges.reset(); 00261 while( point_bridges.size() ) 00262 { 00263 Curve* result_curve = 0; 00264 TBPoint* point = dynamic_cast<TBPoint*>(point_bridges.pop()); 00265 00266 // get the RefEdges that will be joined when the vertex is removed 00267 DLIList<Curve*> curves; 00268 point->curves(curves); 00269 curves.reset(); 00270 00271 if (curves.size() == 0) // merged free vertex -- ignore it 00272 continue; 00273 00274 // If only one curve, need to stitch point with some other 00275 // point in same vertex. 00276 if (curves.size() == 1) { 00277 00278 /* Stitching code not complete. Fail for now. */ 00279 return 0; 00280 00281 /* 00282 Curve* first_curve = curves.pop(); 00283 00284 TBPoint* other = 0; 00285 for ( i = point_bridges.size(); i--; ) { 00286 TBPoint* temp = dynamic_cast<TBPoint*>(point_bridges.step_and_get()); 00287 curves.clean_out(); 00288 temp->curves(curves); 00289 if ( curves.size() == 1 && curves.get()->owner() != first_curve->owner() ) 00290 { 00291 point_bridges.extract(); 00292 other = temp; 00293 break; 00294 } 00295 } 00296 00297 if (!other) 00298 return 0; 00299 00300 point = CompositeEngine::instance().stitch_points(point, other); 00301 if (!point) 00302 return 0; 00303 00304 curves.append(first_curve); 00305 00306 */ 00307 } // end if (curves.size() == 1) 00308 00309 00310 // assert(curves.size() == 2); 00311 if(curves.size() != 2) 00312 { 00313 break; 00314 } 00315 00316 00317 TopologyEntity* topo = curves.get()->topology_entity(); 00318 refedge1 = CAST_TO(topo, RefEdge); 00319 assert(refedge1 != NULL); 00320 curves.get()->set_saved_id(refedge1->id()); 00321 DLIList<CubitString> tmp_names; 00322 std::vector<CubitString> edge1_names; 00323 refedge1->entity_names( tmp_names ); 00324 curves.get()->set_saved_names( tmp_names.as_vector() ); 00325 for( int i=tmp_names.size(); i--; ) 00326 edge1_names.push_back( tmp_names.get_and_step() ); 00327 tmp_names.clean_out(); 00328 refedge1->remove_entity_names(); 00329 00330 topo = curves.next()->topology_entity(); 00331 refedge2 = CAST_TO(topo, RefEdge); 00332 assert(refedge2 != NULL); 00333 curves.next()->set_saved_id(refedge2->id()); 00334 std::vector<CubitString> edge2_names; 00335 refedge2->entity_names( tmp_names ); 00336 curves.next()->set_saved_names( tmp_names.as_vector() ); 00337 for( int i=tmp_names.size(); i--; ) 00338 edge2_names.push_back( tmp_names.get_and_step() ); 00339 refedge2->remove_entity_names(); 00340 00341 00342 00343 determine_combined_edges_interval_or_size( refedge1,refedge2,result_interval,result_size,result_count_type,result_size_type); 00344 00345 00346 Curve* keep = 0; 00347 if (keep_edge) 00348 { 00349 if (keep_edge->bridge_manager() == curves.get()->owner()) 00350 keep = curves.get(); 00351 else if (keep_edge->bridge_manager() == curves.next()->owner()) 00352 keep = curves.next(); 00353 } 00354 00355 // remove the point to make the composite curve 00356 PartitionPoint* part = dynamic_cast<PartitionPoint*>(point); 00357 if( remove_partitions && part ) 00358 result_curve = PartitionEngine::instance().remove_point( part ); 00359 if ( !result_curve ) 00360 result_curve = CompositeEngine::instance().remove_point( point, remove_partitions, keep ); 00361 00362 if( !result_curve ) 00363 { 00364 //reapply names 00365 for( int i=edge1_names.size(); i--; ) 00366 refedge1->entity_name( edge1_names[i] ); 00367 for( int i=edge2_names.size(); i--; ) 00368 refedge2->entity_name( edge2_names[i] ); 00369 00370 PRINT_ERROR("Failed to remove vertex %d\n", vertex->id() ); 00371 break; 00372 } 00373 else if( !edge ) 00374 { 00375 edge = dynamic_cast<RefEdge*>(result_curve->topology_entity()); 00376 } 00377 else 00378 { 00379 if( result_curve->owner() ) 00380 result_curve->owner()->remove_bridge( result_curve ); 00381 edge->bridge_manager()->add_bridge( result_curve ); 00382 00383 Curve* curve = edge->get_curve_ptr(); 00384 bool geom_sense = curve->relative_sense( result_curve ) == CUBIT_FORWARD; 00385 bool bridge_sense = curve->bridge_sense() == result_curve->bridge_sense(); 00386 if( geom_sense != bridge_sense ) 00387 result_curve->reverse_bridge_sense(); 00388 00389 coedgesms.clean_out(); 00390 result_curve->coedgesms( coedgesms ); 00391 while( coedgesms.size() ) 00392 { 00393 CoEdgeSM* coe = coedgesms.pop(); 00394 if( coe->owner() ) 00395 coe->owner()->remove_bridge( coe ); 00396 } 00397 } 00398 00399 names_to_add.insert(names_to_add.end(), edge1_names.begin(), edge1_names.end() ); 00400 names_to_add.insert(names_to_add.end(), edge2_names.begin(), edge2_names.end() ); 00401 00402 if ( result_curve ) 00403 end_result = result_curve; 00404 } 00405 00406 RefEdge* result = NULL; 00407 if(end_result) 00408 result = dynamic_cast<RefEdge*>(end_result->topology_entity()); 00409 00410 RefEdge* dead = NULL; 00411 if(result) 00412 { 00413 // notify observers that one edge is being composited into another 00414 // TODO - make a simple function for this notification since it is times???? 00415 dead = result != refedge1 ? refedge1 : result != refedge2 ? refedge2 : 0; 00416 update_combined_edges( result, dead ,result_interval,result_size,result_count_type,result_size_type); 00417 00418 //append all names to this ref entity 00419 for (size_t k = 0; k < names_to_add.size(); k++) 00420 result->entity_name( names_to_add[k] ); 00421 00422 } 00423 00424 if ( result && update_dag ) 00425 { 00426 CubitBoolean flag = CGMApp::instance()->attrib_manager()->auto_actuate_flag(CA_MERGE_PARTNER); 00427 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_MERGE_PARTNER, CUBIT_TRUE); 00428 00429 DLIList<RefFace*> parent_faces; 00430 result->ref_faces( parent_faces ); 00431 00432 for( i = parent_faces.size(); i--; ) 00433 { 00434 Surface* surf = parent_faces.get_and_step()->get_surface_ptr(); 00435 GeometryQueryTool::instance()->make_RefFace( surf ); 00436 } 00437 if ( !parent_faces.size() && end_result) // free curves 00438 { 00439 RefEdge* edge = GeometryQueryTool::instance()->make_RefEdge(end_result); 00440 RefEdge* dead = edge == refedge1 ? refedge2 : edge == refedge2 ? refedge1 : 0; 00441 assert( dead && !dead->get_curve_ptr() ); 00442 dead->remove_from_DAG(); 00443 } 00444 assert( !(keep_edge && keep_edge->deactivated()) ); 00445 DAG::instance()->cleanout_deactivated_DAG_nodes(); 00446 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_MERGE_PARTNER, flag); 00447 } 00448 00449 00450 return result; 00451 } 00452 00453 00454 /* 00455 CubitStatus CompositeTool::make_mergeable( GeometryEntity* bridge1, 00456 GeometryEntity* bridge2 ) 00457 { 00458 BasicTopologyEntity *bte1, *bte2; 00459 bte1 = dynamic_cast<BasicTopologyEntity*>(bridge1->topology_entity()); 00460 bte2 = dynamic_cast<BasicTopologyEntity*>(bridge2->topology_entity()); 00461 if( (!bte1) == (!bte2) ) // 1 must be null and one non-null 00462 return CUBIT_FAILURE; 00463 00464 if( bte2 ) 00465 { 00466 bte1 = bte2; 00467 GeometryEntity* tmp = bridge1; 00468 bridge1 = bridge2; 00469 bridge2 = tmp; 00470 } 00471 00472 DLIList<CubitSimpleAttrib> csa_list; 00473 bridge1->get_simple_attribute( csa_list ); 00474 CubitSimpleAttrib* csa = 0; 00475 for( int i = csa_list.size(); !csa && i--; ) 00476 if( CubitAttrib::attrib_type(csa_list.step_and_get()) == CA_MERGE_PARTNER ) 00477 csa = csa_list.get(); 00478 00479 if( !csa ) 00480 { 00481 int merge_id = TDUniqueId::get_unique_id(bte1); 00482 csa = CAMergePartner::cubit_simple_attrib(merge_id); 00483 bridge1->append_simple_attribute( csa ); 00484 } 00485 00486 assert(csa); 00487 bridge2->append_simple_attribute( csa ); 00488 delete csa; 00489 return CUBIT_SUCCESS; 00490 } 00491 */ 00492 00493 00494 //------------------------------------------------------------------------- 00495 // Purpose : Create a composite surface 00496 // 00497 // Special Notes : 00498 // 00499 // Creator : Jason Kraftcheck 00500 // 00501 // Creation Date : 00502 //------------------------------------------------------------------------- 00503 RefFace* CompositeTool::composite( DLIList<RefFace*>& face_list, 00504 RefFace* keep_face /* = 0 */ ) 00505 { 00506 int i; 00507 DLIList<RefFace*> modified_faces; 00508 00509 // Get all edges in the faces in face_list 00510 DLIList<TopologyEntity*> query_input(face_list.size()), query_output; 00511 CAST_LIST_TO_PARENT(face_list, query_input); 00512 ModelQueryEngine::instance() 00513 ->query_model( query_input, DagType::ref_edge_type(), query_output ); 00514 DLIList<RefEdge*> edge_list(query_output.size()); 00515 CAST_LIST(query_output, edge_list, RefEdge); 00516 00517 // Remove all edges that don't occur in exactly two faces in list 00518 edge_list.last(); 00519 DLIList<CoEdge*> coedges; 00520 for (i = edge_list.size(); i--; ) 00521 { 00522 RefEdge* edge = edge_list.step_and_get(); 00523 coedges.clean_out(); 00524 edge->co_edges(coedges); 00525 if (coedges.size() == 2) 00526 { 00527 RefFace* face1 = coedges.get()->get_ref_face(); 00528 RefFace* face2 = coedges.next()->get_ref_face(); 00529 // Check to make sure both faces are in the faces we are compositing 00530 // and also make sure the faces are not the same otherwise we 00531 // will composite out hardlines in one of the faces. 00532 if (face1 != face2 && 00533 face_list.is_in_list(face1) && face_list.is_in_list(face2)) 00534 continue; 00535 } 00536 00537 edge_list.change_to(0); 00538 } 00539 edge_list.remove_all_with_value(0); 00540 00541 if( edge_list.size() == 0 ) 00542 { 00543 PRINT_ERROR("Cannot create composites from the specified surfaces.\n"); 00544 return 0; 00545 } 00546 00547 edge_list.reset(); 00548 for( i = edge_list.size(); i--; ) 00549 { 00550 RefEdge* edge = edge_list.get_and_step(); 00551 RefFace* face = remove_edge( edge, false, false, keep_face ); 00552 if (face) 00553 modified_faces.append_unique(face); 00554 } 00555 00556 for ( i = modified_faces.size(); i--; ) 00557 if( ! modified_faces.step_and_get()->get_surface_ptr() ) 00558 modified_faces.change_to(0); 00559 modified_faces.remove_all_with_value(0); 00560 00561 RefFace* result = modified_faces.size() ? modified_faces.get() : 0; 00562 00563 #ifdef ALPHA_TREADSWEEP 00564 // Make sure names from all of the faces get added to the 00565 // list of names in the result. 00566 if(result) 00567 { 00568 for(i=face_list.size(); i--;) 00569 { 00570 RefFace *cur_face = face_list.get_and_step(); 00571 if(cur_face != result) 00572 { 00573 result->merge_entity_names(cur_face); 00574 } 00575 } 00576 } 00577 #endif 00578 00579 DLIList<RefVolume*> vol_list, surf_vols; 00580 for ( i = modified_faces.size(); i--; ) 00581 { 00582 RefFace* face = modified_faces.get_and_step(); 00583 face->set_id( RefEntityFactory::instance()->next_ref_face_id() ); 00584 surf_vols.clean_out(); 00585 face->ref_volumes(surf_vols); 00586 vol_list.merge_unique(surf_vols); 00587 } 00588 00589 vol_list.reset(); 00590 for ( i = vol_list.size(); i--; ) 00591 { 00592 RefVolume* vol = vol_list.get_and_step(); 00593 Lump* lump = vol->get_lump_ptr(); 00594 GeometryQueryTool::instance()->make_Body(lump->bodysm()); 00595 } 00596 assert( !(keep_face && keep_face->deactivated()) ); 00597 DAG::instance()->cleanout_deactivated_DAG_nodes(); 00598 00599 return result; 00600 } 00601 00602 //------------------------------------------------------------------------- 00603 // Purpose : Composite over a curve 00604 // 00605 // Special Notes : 00606 // 00607 // Creator : Jason Kraftcheck 00608 // 00609 // Creation Date : 03/12/03 00610 //------------------------------------------------------------------------- 00611 RefFace* CompositeTool::remove_edge( RefEdge* edge, 00612 bool remove_partitions, /* = false */ 00613 bool update_dag, /* = true */ 00614 RefFace* keep_face /* = NULL */ ) 00615 { 00616 int i; 00617 00618 DLIList<CoEdge*> edge_coedges; 00619 edge->co_edges(edge_coedges); 00620 if (edge_coedges.size() != 2 && 00621 (edge->get_curve_ptr()->geometry_type() != POINT_CURVE_TYPE || 00622 edge_coedges.size() != 1)) 00623 { 00624 PRINT_ERROR("Cannot composite over %d-valent curve %d (%s)\n", 00625 edge_coedges.size(), edge->id(), edge->entity_name().c_str()); 00626 return NULL; 00627 } 00628 00629 DLIList<TopologyBridge*> curves(edge->bridge_manager()->number_of_bridges()); 00630 edge->bridge_manager()->get_bridge_list( curves ); 00631 00632 DLIList<Surface*> surfaces; 00633 assert(curves.size()); 00634 curves.get()->surfaces( surfaces ); 00635 if ( surfaces.size() > 2 || surfaces.size() < 1 ) 00636 { 00637 PRINT_ERROR("Cannot composite over %d-valence curve %d\n", 00638 surfaces.size(), edge->id() ); 00639 return 0; 00640 } 00641 00642 RefFace* face = 0; 00643 00644 // These will be the two RefFaces associated with the two 00645 // surfaces being composited. We need to store them before we 00646 // get to the call to remove_curve because after that we won't 00647 // have access to both of them and we need to pass both of them 00648 // down to update_combined_faces. 00649 RefFace *face1 = NULL; 00650 RefFace *face2 = NULL; 00651 00652 std::vector<CubitString> names_to_add; 00653 curves.reset(); 00654 Surface* surface = 0; 00655 for( i = curves.size(); i--; ) 00656 { 00657 Curve* curve = dynamic_cast<Curve*>(curves.get_and_step()); 00658 00659 // get the two Surfaces that will be involved in the composite operation 00660 // when the curve is removed 00661 DLIList<Surface*> surfs; 00662 curve->surfaces(surfs); 00663 assert(surfs.size() > 0 && surfs.size() <= 2); // should be one or two surfs 00664 face1 = dynamic_cast<RefFace*>(surfs.get()->topology_entity()); 00665 face2 = dynamic_cast<RefFace*>(surfs.next()->topology_entity()); 00666 00667 //Save the names and ids 00668 surfs.get()->set_saved_id(face1->id()); 00669 DLIList<CubitString> tmp_names; 00670 face1->entity_names( tmp_names ); 00671 surfs.get()->set_saved_names( tmp_names.as_vector() ); 00672 std::vector<CubitString> face1_names = tmp_names.as_vector(); 00673 tmp_names.clean_out(); 00674 face1->remove_entity_names(); 00675 00676 surfs.next()->set_saved_id(face2->id()); 00677 face2->entity_names( tmp_names ); 00678 surfs.next()->set_saved_names( tmp_names.as_vector() ); 00679 std::vector<CubitString> face2_names = tmp_names.as_vector(); 00680 tmp_names.clean_out(); 00681 face2->remove_entity_names(); 00682 00683 // if only one surface, the edge should be internal to a composite surface 00684 surfs.reset(); 00685 00686 // Composite the surfaces 00687 Surface* result = 0; 00688 PartitionCurve* partcurve = 0; 00689 if ( !(partcurve = dynamic_cast<SegmentedCurve*>(curve)) ) 00690 partcurve = dynamic_cast<PartPTCurve*>(curve); 00691 00692 Surface* keep = 0; 00693 if (keep_face) { 00694 if (surfs.get()->owner() == keep_face->bridge_manager()) 00695 keep = surfs.get(); 00696 else if (surfs.next()->owner() == keep_face->bridge_manager()) 00697 keep = surfs.next(); 00698 } 00699 if( remove_partitions && partcurve ) 00700 result = PartitionEngine::instance().remove_curve( partcurve ); 00701 if( !result ) 00702 result = CompositeEngine::instance().remove_curve( curve, remove_partitions, keep ); 00703 00704 if( !result ) 00705 { 00706 //reapply names 00707 for( int i=face1_names.size(); i--; ) 00708 face1->entity_name( face1_names[i] ); 00709 for( int i=face2_names.size(); i--; ) 00710 face2->entity_name( face2_names[i] ); 00711 00712 PRINT_ERROR("Failed to remove curve %d\n",edge->id()); 00713 break; 00714 } 00715 else if( !face ) // get surviving refface 00716 { 00717 face = dynamic_cast<RefFace*>(result->topology_entity()); 00718 } 00719 00720 else // merge resulting composites into surviving refface 00721 { 00722 RefFace* old_face = dynamic_cast<RefFace*>(result->topology_entity()); 00723 if( old_face != face ) 00724 { 00725 if( old_face ) 00726 old_face->bridge_manager()->remove_bridge( result ); 00727 face->bridge_manager()->add_bridge( result ); 00728 } 00729 } 00730 00731 names_to_add.insert(names_to_add.end(), face1_names.begin(), face1_names.end() ); 00732 names_to_add.insert(names_to_add.end(), face2_names.begin(), face2_names.end() ); 00733 00734 if( result ) 00735 surface = result; 00736 } 00737 00738 if( !surface ) 00739 { 00740 PRINT_ERROR("Failed to remove curve %d\n", edge->id() ); 00741 return 0; 00742 } 00743 00744 RefFace* result = dynamic_cast<RefFace*>(surface->topology_entity()); 00745 assert( result == face ); 00746 00747 //append all names to this ref entity 00748 for (size_t k = 0; k < names_to_add.size(); k++) 00749 result->entity_name( names_to_add[k] ); 00750 00751 // notify observers that one face is being composited into another 00752 00753 // We need to pass the result face and also the one that wasn't chosen 00754 // as the result face. 00755 RefFace *delete_face = face1; 00756 if(result == delete_face) 00757 delete_face = face2; 00758 update_combined_faces( result, edge, delete_face ); 00759 00760 if ( update_dag ) 00761 { 00762 DLIList<RefVolume*> modified_volumes; 00763 result->ref_volumes(modified_volumes); 00764 for( i = modified_volumes.size(); i--; ) 00765 { 00766 RefVolume* volume = modified_volumes.get_and_step(); 00767 Lump* lump = volume->get_lump_ptr(); 00768 GeometryQueryTool::instance()->make_Body(lump->bodysm()); 00769 } 00770 00771 assert( !(keep_face && keep_face->deactivated()) ); 00772 DAG::instance()->cleanout_deactivated_DAG_nodes(); 00773 } 00774 00775 return result; 00776 } 00777 00778 //------------------------------------------------------------------------- 00779 // Purpose : Create a composite volume 00780 // 00781 // Special Notes : 00782 // 00783 // Creator : Jason Kraftcheck 00784 // 00785 // Creation Date : 09/25/01 00786 //------------------------------------------------------------------------- 00787 RefVolume* CompositeTool::composite( DLIList<RefVolume*>& volumes, 00788 Body** body_ptr /* = 0 */ ) 00789 { 00790 int i; 00791 DLIList<RefVolume*> modified_vols; 00792 DLIList<Body*> input_bodies; 00793 for (i = volumes.size(); i--; ) 00794 input_bodies.append_unique( volumes.get_and_step()->get_body_ptr() ); 00795 00796 // Get all faces in the volumes 00797 DLIList<TopologyEntity*> query_input(volumes.size()), query_output; 00798 CAST_LIST_TO_PARENT(volumes, query_input); 00799 ModelQueryEngine::instance() 00800 ->query_model( query_input, DagType::ref_face_type(), query_output ); 00801 DLIList<RefFace*> faces(query_output.size()); 00802 CAST_LIST(query_output, faces, RefFace); 00803 00804 // Remove all faces that don't occur in exactly two volumes in list 00805 faces.last(); 00806 DLIList<CoFace*> cofaces; 00807 for (i = faces.size(); i--; ) 00808 { 00809 RefFace* face = faces.step_and_get(); 00810 cofaces.clean_out(); 00811 face->co_faces(cofaces); 00812 if (cofaces.size() == 2) 00813 { 00814 RefVolume* vol1 = cofaces.get()->get_ref_volume(); 00815 RefVolume* vol2 = cofaces.next()->get_ref_volume(); 00816 if (volumes.is_in_list(vol1) && volumes.is_in_list(vol2)) 00817 continue; 00818 } 00819 00820 faces.change_to(0); 00821 } 00822 faces.remove_all_with_value(0); 00823 00824 if( faces.size() == 0 ) 00825 { 00826 PRINT_ERROR("Cannot create composites from the specified volumes.\n"); 00827 return 0; 00828 } 00829 00830 faces.reset(); 00831 for( i = faces.size(); i--; ) 00832 { 00833 RefFace* face = faces.get_and_step(); 00834 RefVolume* vol = remove_face( face, false, false ); 00835 if (vol) 00836 modified_vols.append_unique(vol); 00837 } 00838 00839 for ( i = modified_vols.size(); i--; ) 00840 if( ! modified_vols.step_and_get()->get_lump_ptr() ) 00841 modified_vols.change_to(0); 00842 modified_vols.remove_all_with_value(0); 00843 00844 RefVolume* result = modified_vols.size() ? modified_vols.get() : 0; 00845 for ( i = modified_vols.size(); i--; ) 00846 { 00847 RefVolume* vol = modified_vols.get_and_step(); 00848 vol->set_id( RefEntityFactory::instance()->next_ref_volume_id() ); 00849 } 00850 00851 input_bodies.reset(); 00852 for ( i = input_bodies.size(); i--; ) 00853 { 00854 Body* body = input_bodies.get_and_step(); 00855 BodySM* sm = body->get_body_sm_ptr(); 00856 if (sm) 00857 GeometryQueryTool::instance()->make_Body(sm); 00858 else 00859 GeometryQueryTool::instance()->destroy_dead_entity( body ); 00860 } 00861 DAG::instance()->cleanout_deactivated_DAG_nodes(); 00862 00863 if (body_ptr) 00864 *body_ptr = result->get_body_ptr(); 00865 return result; 00866 } 00867 00868 //------------------------------------------------------------------------- 00869 // Purpose : Composite over a surface 00870 // 00871 // Special Notes : 00872 // 00873 // Creator : Jason Kraftcheck 00874 // 00875 // Creation Date : 03/12/03 00876 //------------------------------------------------------------------------- 00877 RefVolume* CompositeTool::remove_face( RefFace* face, 00878 bool remove_partitions, /* = false */ 00879 bool update_dag /* = true */) 00880 { 00881 int i; 00882 00883 DLIList<RefVolume*> vol_list(2); 00884 face->ref_volumes( vol_list ); 00885 00886 DLIList<CoFace*> face_cofaces; 00887 face->co_faces(face_cofaces); 00888 if (face_cofaces.size() != 2) 00889 { 00890 PRINT_ERROR("Cannot composite over %d-valent surface %d (%s)\n", 00891 face_cofaces.size(), face->id(), face->entity_name().c_str()); 00892 return NULL; 00893 } 00894 00895 DLIList<TopologyBridge*> surfs(face->bridge_manager()->number_of_bridges()); 00896 face->bridge_manager()->get_bridge_list( surfs ); 00897 00898 // Seam topology 00899 Surface *surf1 = 0, *surf2 = 0; 00900 if (surfs.size() == 2) 00901 { 00902 surfs.reset(); 00903 surf1 = dynamic_cast<Surface*>(surfs.get()); 00904 surf2 = dynamic_cast<Surface*>(surfs.next()); 00905 00906 DLIList<RefEdge*> edge_list; 00907 DLIList<TopologyBridge*> bridges, ptcurves; 00908 DLIList<Surface*> surfaces; 00909 face->ref_edges( edge_list ); 00910 while( edge_list.size() ) 00911 { 00912 RefEdge* edge = edge_list.pop(); 00913 edge->bridge_manager()->get_bridge_list( bridges ); 00914 TopologyBridge *curve1 = 0, *curve2 = 0; 00915 while (bridges.size()) 00916 { 00917 TopologyBridge* curve = bridges.pop(); 00918 surfaces.clean_out(); 00919 curve->surfaces( surfaces ); 00920 if (surfaces.is_in_list(surf1)) 00921 curve1 = curve; 00922 if (surfaces.is_in_list(surf2)) 00923 curve2 = curve; 00924 } 00925 00926 assert(curve1 && curve2); 00927 if (curve1 == curve2) 00928 continue; 00929 00930 for (int i = 0; i < 2; i++) 00931 { 00932 RefVertex* vtx = i ? edge->end_vertex() : edge->start_vertex(); 00933 vtx->bridge_manager()->get_bridge_list( bridges ); 00934 TopologyBridge *point1 = 0, *point2 = 0; 00935 while (bridges.size()) 00936 { 00937 TopologyBridge* point = bridges.pop(); 00938 ptcurves.clean_out(); 00939 point->get_parents(ptcurves); 00940 if (ptcurves.is_in_list( curve1 )) 00941 point1 = point; 00942 if (ptcurves.is_in_list( curve2 )) 00943 point2 = point; 00944 } 00945 00946 if (point1 != point2) 00947 CompositeEngine::instance().stitch_points( 00948 dynamic_cast<TBPoint*>(point1), 00949 dynamic_cast<TBPoint*>(point2) ); 00950 } 00951 00952 CompositeEngine::instance().stitch_curves( 00953 dynamic_cast<Curve*>(curve1), 00954 dynamic_cast<Curve*>(curve2) ); 00955 } 00956 } 00957 else if (surfs.size() == 1) 00958 { 00959 surf1 = dynamic_cast<Surface*>(surfs.get()); 00960 surf2 = 0; 00961 } 00962 else 00963 { 00964 return 0; 00965 } 00966 00967 DLIList<Lump*> lumps, tmp; 00968 surf1->lumps( lumps ); 00969 if (surf2) 00970 { 00971 surf2->lumps(tmp); 00972 lumps.merge_unique(tmp); 00973 } 00974 if ( lumps.size() > 2 || lumps.size() < 1 ) 00975 { 00976 PRINT_ERROR("Cannot composite over %d-valence surface %d\n", 00977 lumps.size(), face->id() ); 00978 return 0; 00979 } 00980 00981 // get the two Lumps that will be involved in the composite operation 00982 // when the surface is removed 00983 Lump* lump = 0; 00984 RefVolume *tmp_vol = dynamic_cast<RefVolume*>(lumps.get()->topology_entity()); 00985 lumps.get()->set_saved_id( tmp_vol->id() ); 00986 DLIList<CubitString> names; 00987 tmp_vol->entity_names( names ); 00988 lumps.get()->set_saved_names( names.as_vector() ); 00989 names.clean_out(); 00990 00991 tmp_vol = dynamic_cast<RefVolume*>(lumps.get()->topology_entity()); 00992 lumps.next()->set_saved_id( tmp_vol->id() ); 00993 tmp_vol->entity_names( names ); 00994 lumps.next()->set_saved_names( names.as_vector() ); 00995 00996 // if only one lump, the surface should be internal to a composite lump 00997 lumps.reset(); 00998 00999 // Composite the lumps 01000 PartitionSurface* partsurf = dynamic_cast<PartitionSurface*>(surf1); 01001 if( surf1 == surf2 && remove_partitions && partsurf ) 01002 lump = PartitionEngine::instance().remove_surface( partsurf ); 01003 if( !lump ) 01004 lump = CompositeEngine::instance().remove_surface( surf1, surf2, remove_partitions ); 01005 01006 if( !lump ) 01007 { 01008 PRINT_ERROR("Failed to remove surface %d\n",face->id()); 01009 return 0; 01010 } 01011 01012 RefVolume* result = dynamic_cast<RefVolume*>(lump->topology_entity()); 01013 01014 // notify observers that one face is being composited into another 01015 RefVolume* dead_vol =0; 01016 if (vol_list.size() > 1) 01017 { 01018 vol_list.move_to( result ); 01019 dead_vol = vol_list.next(); 01020 } 01021 update_combined_vols( result, dead_vol ); 01022 01023 if ( update_dag ) 01024 { 01025 DLIList<Body*> modified_bodies; 01026 result->bodies(modified_bodies); 01027 for( i = modified_bodies.size(); i--; ) 01028 { 01029 Body* body = modified_bodies.get_and_step(); 01030 BodySM* sm = body->get_body_sm_ptr(); 01031 if (sm) 01032 GeometryQueryTool::instance()->make_Body(sm); 01033 else 01034 GeometryQueryTool::instance()->destroy_dead_entity( body ); 01035 } 01036 01037 DAG::instance()->cleanout_deactivated_DAG_nodes(); 01038 } 01039 01040 return result; 01041 } 01042 01043 01044 //------------------------------------------------------------------------- 01045 // Purpose : Create a composite body 01046 // 01047 // Special Notes : 01048 // 01049 // Creator : Jason Kraftcheck 01050 // 01051 // Creation Date : 10/02/01 01052 //------------------------------------------------------------------------- 01053 Body* CompositeTool::composite( DLIList<Body*>& ) 01054 { 01055 return 0; 01056 } 01057 01058 01059 //------------------------------------------------------------------------- 01060 // Purpose : Check for the topological validity of a possible composite 01061 // 01062 // Special Notes : 01063 // 01064 // Creator : Jason Kraftcheck 01065 // 01066 // Creation Date : 01067 //------------------------------------------------------------------------- 01068 CubitBoolean CompositeTool::okayToComposite( 01069 DLIList<BasicTopologyEntity*>& bte_list, 01070 DLIList<BasicTopologyEntity*>* boundary, 01071 DLIList<BasicTopologyEntity*>* internal, 01072 bool print_errors, 01073 bool force_same_parents ) const 01074 { 01075 //check that all entities are of the same type 01076 bte_list.reset(); 01077 DagType type = bte_list.get_and_step()->dag_type(); 01078 if( (type != DagType::ref_face_type()) && 01079 (type != DagType::ref_edge_type()) && 01080 (type != DagType::ref_volume_type()) ) 01081 { 01082 if (print_errors) 01083 PRINT_ERROR("Invalid entities passed to CompositeTool::okayToComposite().\n"); 01084 return CUBIT_FALSE; 01085 } 01086 int i; 01087 for( i = bte_list.size(); i > 1; i-- ) 01088 { 01089 if( bte_list.get_and_step()->dag_type() != type ) 01090 { 01091 if (print_errors) PRINT_ERROR("Cannot combine entities of different dimensionality.\n"); 01092 return CUBIT_FALSE; 01093 } 01094 } 01095 01096 //check that all entities are C0-continous 01097 DLIList<RefEntity*> unchecked_entities, current_entities, 01098 next_entities, child_entities, temp_list ; 01099 CAST_LIST_TO_PARENT( bte_list, unchecked_entities); 01100 current_entities.append( unchecked_entities.pop() ); 01101 01102 while( current_entities.size() > 0 ) 01103 { 01104 next_entities.clean_out(); 01105 child_entities.clean_out(); 01106 01107 01108 // Get all adjacent entities 01109 for( i = current_entities.size(); i > 0; i-- ) 01110 { 01111 temp_list.clean_out(); 01112 current_entities.get_and_step()->get_child_ref_entities( temp_list ); 01113 child_entities.merge_unique( temp_list ); 01114 } 01115 01116 for( i = child_entities.size(); i > 0; i-- ) 01117 { 01118 temp_list.clean_out(); 01119 child_entities.get_and_step()->get_parent_ref_entities( temp_list ); 01120 next_entities.merge_unique( temp_list ); 01121 } 01122 01123 temp_list.clean_out(); 01124 for( i = next_entities.size(); i > 0; i-- ) 01125 { 01126 RefEntity* entity_ptr = next_entities.get_and_step(); 01127 01128 if( unchecked_entities.move_to( entity_ptr ) ) 01129 { 01130 temp_list.append( entity_ptr ); 01131 unchecked_entities.extract(); 01132 } 01133 } 01134 current_entities = temp_list; 01135 } 01136 if( unchecked_entities.size() == 1 ) 01137 { 01138 if (print_errors) 01139 { 01140 PRINT_ERROR("%s is not connected to any others.\n", 01141 unchecked_entities.get()->entity_name().c_str() ); 01142 if( unchecked_entities.get()->dag_type() == DagType::ref_volume_type() ) 01143 PRINT_ERROR("\tTry merging first.\n"); 01144 } 01145 return CUBIT_FALSE; 01146 } 01147 else if( unchecked_entities.size() > 1 ) 01148 { 01149 if (print_errors) { 01150 PRINT_ERROR("Entities \n"); 01151 for( i = unchecked_entities.size(); i > 0; i-- ) 01152 PRINT_INFO("%d, ",unchecked_entities.get_and_step()->id()); 01153 PRINT_INFO("do not appear to be connected to the others.\n"); 01154 } 01155 01156 return CUBIT_FALSE; 01157 } 01158 01159 //Check that all common children have at most two 01160 //parents (and those parents are in the list of entities to 01161 //composite). 01162 unchecked_entities.clean_out(); 01163 child_entities.clean_out(); 01164 CAST_LIST_TO_PARENT( bte_list, unchecked_entities); 01165 for( i = unchecked_entities.size(); i > 0; i-- ) 01166 { 01167 temp_list.clean_out(); 01168 unchecked_entities.get_and_step()->get_child_ref_entities( temp_list ); 01169 child_entities.merge_unique( temp_list ); 01170 } 01171 01172 DLIList<SenseEntity*> sense_entity_list; 01173 for( i = child_entities.size(); i > 0; i-- ) 01174 { 01175 int parent_count = 0; 01176 current_entities.clean_out(); 01177 RefEntity* child_ptr = child_entities.step_and_get(); 01178 sense_entity_list.clean_out(); 01179 CAST_TO(child_ptr,BasicTopologyEntity)->get_sense_entity_list( sense_entity_list ); 01180 for( int k = sense_entity_list.size(); k > 0; k-- ) 01181 current_entities.append( sense_entity_list.get_and_step()-> 01182 get_grouping_entity_ptr()->get_basic_topology_entity_ptr() ); 01183 for( int j = current_entities.size(); j> 0; j-- ) 01184 if( unchecked_entities.move_to( current_entities.get_and_step() ) ) 01185 parent_count++; 01186 switch( parent_count ) 01187 { 01188 case 0: 01189 // assert( parent_count != 0 ); break; 01190 return CUBIT_FALSE; 01191 case 1: 01192 if( boundary != NULL ) boundary-> 01193 append( CAST_TO( child_entities.get(), BasicTopologyEntity) ); 01194 break; 01195 case 2: 01196 if( current_entities.size() != 2 ) 01197 { 01198 if (print_errors) PRINT_ERROR("Child entity %d cannot be removed.\n", 01199 child_entities.get()->id() ); 01200 return CUBIT_FALSE; 01201 } 01202 if( internal != NULL ) internal-> 01203 append( CAST_TO( child_entities.get(), BasicTopologyEntity) ); 01204 break; 01205 default: 01206 if (print_errors) PRINT_ERROR("Entities are not simply connected.\n"); 01207 return CUBIT_FALSE; 01208 } 01209 } 01210 01211 //Check that all entities to merge are common to all parent grouping entities. 01212 if( force_same_parents ) 01213 { 01214 assert( type.functional_type() == DagType::BasicTopologyEntity_TYPE ); 01215 const DagType type_2 = DagType( type.dimension(), DagType::GroupingEntity_TYPE ); 01216 DLIList<TopologyEntity*> first_entity_parents, current_entity_parents; 01217 bte_list.reset(); 01218 ModelQueryEngine::instance()->query_model( 01219 *(bte_list.get_and_step()), type_2, first_entity_parents ); 01220 01221 for( i = bte_list.size(); i > 1; i-- ) 01222 { 01223 current_entity_parents.clean_out(); 01224 ModelQueryEngine::instance()->query_model( 01225 *(bte_list.get_and_step()), type_2, current_entity_parents ); 01226 01227 if( current_entity_parents != first_entity_parents ) 01228 { 01229 if (print_errors) PRINT_ERROR("All entities to be combined must have common " 01230 "topological parents.\n"); 01231 return CUBIT_FALSE; 01232 } 01233 } 01234 } 01235 01236 return CUBIT_TRUE; 01237 } 01238 01239 //------------------------------------------------------------------------- 01240 // Purpose : Classify child topology 01241 // 01242 // Special Notes : 01243 // 01244 // Creator : Jason Kraftcheck 01245 // 01246 // Creation Date : 01247 //------------------------------------------------------------------------- 01248 CubitStatus CompositeTool::classify_children( 01249 DLIList<BasicTopologyEntity*>& bte_list, 01250 DLIList<BasicTopologyEntity*>& boundary_children, 01251 DLIList<BasicTopologyEntity*>& interior_children, 01252 DLIList<BasicTopologyEntity*>& unknown_children ) 01253 { 01254 DLIList<RefEntity*> ref_entity_list, all_children; 01255 RefEntity *child_ptr, *parent_ptr; 01256 BasicTopologyEntity* bte_ptr; 01257 int i, j; 01258 for( i = bte_list.size(); i > 0; i-- ) 01259 { 01260 ref_entity_list.clean_out(); 01261 bte_list.get_and_step()->get_child_ref_entities( ref_entity_list ); 01262 all_children.merge_unique( ref_entity_list ); 01263 } 01264 for( i = all_children.size(); i > 0; i-- ) 01265 { 01266 ref_entity_list.clean_out(); 01267 child_ptr = all_children.get_and_step(); 01268 child_ptr->get_parent_ref_entities( ref_entity_list ); 01269 01270 int parent_count = 0; 01271 for( j = ref_entity_list.size(); j > 0; j-- ) 01272 { 01273 parent_ptr = ref_entity_list.get_and_step(); 01274 bte_ptr = CAST_TO( parent_ptr, BasicTopologyEntity ); 01275 if( bte_list.move_to( bte_ptr ) ) parent_count++; 01276 } 01277 01278 bte_ptr = CAST_TO( child_ptr, BasicTopologyEntity ); 01279 if( parent_count == 1 ) 01280 boundary_children.append( bte_ptr ); 01281 else if( parent_count == ref_entity_list.size() ) 01282 interior_children.append( bte_ptr ); 01283 else 01284 unknown_children.append( bte_ptr ); 01285 } 01286 return CUBIT_SUCCESS; 01287 } 01288 01289 01290 01291 01292 //------------------------------------------------------------------------- 01293 // Purpose : remove a composite edge, restoring the orignial edges. 01294 // 01295 // Special Notes : 01296 // 01297 // Creator : Jason Kraftcheck 01298 // 01299 // Creation Date : 01300 //------------------------------------------------------------------------- 01301 CubitStatus CompositeTool::uncomposite( RefEdge* composite_edge, 01302 DLIList<RefEdge*>* restored_edges) 01303 { 01304 int i; 01305 DLIList<TBPoint*> hidden_points; 01306 DLIList<RefFace*> face_list; 01307 DLIList<Curve*> curve_list; 01308 01309 composite_edge->ref_faces( face_list ); 01310 01311 if( composite_edge->bridge_manager()->number_of_bridges() != 1 ) 01312 { 01313 PRINT_ERROR("Curve %d is a merged curve. Unmerge before removing composite.\n", 01314 composite_edge->id() ); 01315 return CUBIT_FAILURE; 01316 } 01317 01318 CompositeCurve* curve_ptr = dynamic_cast<CompositeCurve*>(composite_edge->get_curve_ptr()); 01319 if( !curve_ptr ) 01320 return CUBIT_FAILURE; 01321 01322 for( i = 0; i < curve_ptr->num_curves(); i++ ) 01323 curve_list.append( curve_ptr->get_curve(i) ); 01324 01325 //remove all names off this ref entity 01326 composite_edge->remove_entity_names(); 01327 01328 curve_ptr->get_hidden_points( hidden_points ); 01329 CubitStatus result = CUBIT_SUCCESS; 01330 hidden_points.reset(); 01331 for( i = hidden_points.size(); i--; ) 01332 { 01333 //remove attributes off the hidden points 01334 CompositeEngine::strip_attributes( hidden_points.get() ); 01335 01336 if( ! CompositeEngine::instance(). 01337 restore_point( hidden_points.get_and_step() ) ) 01338 result = CUBIT_FAILURE; 01339 } 01340 01341 DLIList<TopologyBridge*> bridge_list; 01342 composite_edge->bridge_manager()->get_bridge_list(bridge_list); 01343 int smallest_id = 0; 01344 for ( i = bridge_list.size(); i--; ) 01345 { 01346 GeometryEntity* geom_ptr = dynamic_cast<GeometryEntity*>(bridge_list.get_and_step()); 01347 int saved_id = geom_ptr->get_saved_id(); 01348 if ( saved_id && (!smallest_id || saved_id < smallest_id) && 01349 !RefEntityFactory::instance()->get_ref_edge(saved_id) ) 01350 smallest_id = saved_id; 01351 } 01352 if ( smallest_id && composite_edge->id() != smallest_id ) 01353 composite_edge->set_id( smallest_id ); 01354 01355 01356 for( i = face_list.size(); i--; ) 01357 { 01358 Surface* surf = face_list.get_and_step()->get_surface_ptr(); 01359 GeometryQueryTool::instance()->make_RefFace( surf ); 01360 } 01361 for( i = face_list.size(); i--; ) 01362 GeometryQueryTool::instance()->destroy_dead_entity( face_list.get_and_step() ); 01363 01364 for( i = curve_list.size(); i--; ) 01365 { 01366 //remove attributes off the underlying curves 01367 Curve *tmp_curve = curve_list.get_and_step(); 01368 CompositeEngine::strip_attributes( tmp_curve ); 01369 01370 BridgeManager* bm = dynamic_cast<BridgeManager*>(tmp_curve->owner()); 01371 RefEdge* edge = bm ? dynamic_cast<RefEdge*>(bm->topology_entity()) : 0; 01372 if( restored_edges ) 01373 restored_edges->append( edge ); 01374 std::vector<CubitString> underlying_names; 01375 tmp_curve->get_saved_names( underlying_names ); 01376 for (size_t k = 0; k < underlying_names.size(); k++) 01377 edge->entity_name( underlying_names[k] ); 01378 } 01379 01380 return result; 01381 } 01382 01383 //------------------------------------------------------------------------- 01384 // Purpose : Restore a hidden point, remerging points and 01385 // parent curves if possible. 01386 // 01387 // Special Notes : Helper function for uncomposite(RefFace*,...) 01388 // 01389 // Creator : Jason Kraftcheck 01390 // 01391 // Creation Date : 08/06/03 01392 //------------------------------------------------------------------------- 01393 CubitStatus CompositeTool::restore_merged_point( TBPoint* hidden_pt, 01394 DLIList<RefFace*>& modified, 01395 bool force ) 01396 { 01397 int i; 01398 01399 HiddenEntitySet* hs = dynamic_cast<HiddenEntitySet*>(hidden_pt->owner()); 01400 if (!hs) 01401 return CUBIT_FAILURE; 01402 CompositeCurve* owner = dynamic_cast<CompositeCurve*>(hs->owner()); 01403 if (!owner) 01404 return CUBIT_FAILURE; 01405 01406 RefEdge* old_edge = dynamic_cast<RefEdge*>(owner->topology_entity()); 01407 int num_curves; 01408 DLIList<TopologyBridge*> curve_bridges; 01409 if (old_edge) 01410 { 01411 num_curves = old_edge->bridge_manager()->number_of_bridges(); 01412 old_edge->bridge_manager()->get_bridge_list(curve_bridges); 01413 } 01414 else 01415 { 01416 num_curves = 1; 01417 curve_bridges.append(owner); 01418 } 01419 01420 DLIList<CompositeCurve*> curves(num_curves); 01421 CAST_LIST(curve_bridges, curves, CompositeCurve); 01422 DLIList<TBPoint*> points(curves.size()); 01423 01424 assert(curves.is_in_list(owner)); 01425 CubitVector position = hidden_pt->coordinates(); 01426 01427 DLIList<TBPoint*> curve_pts; 01428 curves.reset(); 01429 GeometryQueryTool* gqt = GeometryQueryTool::instance(); 01430 double factor = gqt->get_geometry_factor(); 01431 for ( i = curves.size(); i--; ) 01432 { 01433 curve_pts.clean_out(); 01434 curves.get_and_step()->get_hidden_points(curve_pts); 01435 for (int j = curve_pts.size(); j--; ) 01436 { 01437 TBPoint* curve_pt = curve_pts.get_and_step(); 01438 if (gqt->about_spatially_equal(position, curve_pt->coordinates(), factor)) 01439 { 01440 points.append(curve_pt); 01441 break; 01442 } 01443 } 01444 } 01445 01446 if (!force && points.size() != curve_bridges.size()) 01447 { 01448 RefEdge* edge = dynamic_cast<RefEdge*>(owner->topology_entity()); 01449 PRINT_ERROR("Cannot restore vertex hidden by curve %d without unmerging " 01450 "curve and possibly adjacent surfaces. Use the 'force' " 01451 "option to force unmerging of geometry.\n", edge ? edge->id() : 0); 01452 return CUBIT_FAILURE; 01453 } 01454 01455 points.last(); 01456 for ( i = points.size(); i--; ) 01457 { 01458 TBPoint* pt = points.step_and_get(); 01459 if (CompositePoint* cp = dynamic_cast<CompositePoint*>(pt)) 01460 pt = cp->get_point(); 01461 01462 if (!CompositeEngine::instance().restore_point(pt)) 01463 points.change_to(0); 01464 else if (CompositePoint* cp = dynamic_cast<CompositePoint*>(pt->owner())) 01465 points.change_to(cp); 01466 else 01467 points.change_to(pt); 01468 } 01469 points.remove_all_with_value(0); 01470 01471 if (!points.size()) 01472 return CUBIT_FAILURE; 01473 01474 points.reset(); 01475 RefVertex* new_vtx = gqt->make_RefVertex(points.get()); 01476 for ( i = points.size(); i--; ) 01477 { 01478 TBPoint* pt = points.get_and_step(); 01479 if (pt->owner()) 01480 assert(pt->topology_entity() == new_vtx); 01481 else 01482 new_vtx->bridge_manager()->add_bridge(pt); 01483 } 01484 01485 CubitVector center_1, center_2; 01486 DLIList<TopologyBridge*> pt_curves(2); 01487 points.reset(); 01488 points.get()->get_parents(pt_curves); 01489 01490 // Ignore composite point-curves. They are transient and will be 01491 // deleted later. Don't try to create RefEdges for them now. 01492 if (pt_curves.size() != 2) 01493 { 01494 #ifndef NDEBUG 01495 assert(pt_curves.size() == 1); 01496 CompositeCurve* ccurve = dynamic_cast<CompositeCurve*>(pt_curves.get()); 01497 assert(ccurve->num_curves() == 0 && ccurve->geometry_type() == POINT_CURVE_TYPE ); 01498 #endif 01499 return CUBIT_SUCCESS; 01500 } 01501 01502 dynamic_cast<Curve*>(pt_curves.get())->position_from_fraction(0.5, center_1); 01503 dynamic_cast<Curve*>(pt_curves.next())->position_from_fraction(0.5, center_2); 01504 01505 DLIList<Curve*> new_edge_1_curves(points.size()), 01506 new_edge_2_curves(points.size()); 01507 01508 points.reset(); 01509 for ( i = points.size(); i--; ) 01510 { 01511 pt_curves.clean_out(); 01512 points.get_and_step()->get_parents(pt_curves); 01513 assert(pt_curves.size() == 2); 01514 Curve* curve_1 = dynamic_cast<Curve*>(pt_curves.get()); 01515 Curve* curve_2 = dynamic_cast<Curve*>(pt_curves.next()); 01516 CubitVector ptc1, ptc2; 01517 curve_1->position_from_fraction( 0.5, ptc1 ); 01518 curve_2->position_from_fraction( 0.5, ptc2 ); 01519 bool close1 = (center_1 - ptc1).length_squared() < (center_2 - ptc1).length_squared(); 01520 bool close2 = (center_1 - ptc2).length_squared() < (center_2 - ptc2).length_squared(); 01521 if (close1 && !close2) 01522 { 01523 new_edge_1_curves.append(curve_1); 01524 new_edge_2_curves.append(curve_2); 01525 } 01526 else if (!close1 && close2) 01527 { 01528 new_edge_2_curves.append(curve_1); 01529 new_edge_1_curves.append(curve_2); 01530 } 01531 else 01532 { 01533 assert(close1 != close2); 01534 } 01535 } 01536 01537 for ( i = 0; i < 2; i++ ) 01538 { 01539 int j; 01540 DLIList<Curve*>& new_edge_curves = i ? new_edge_2_curves : new_edge_1_curves; 01541 DLIList<Curve*>& otr_edge_curves = i ? new_edge_1_curves : new_edge_2_curves; 01542 RefEdge* new_edge = 0; 01543 new_edge_curves.reset(); 01544 for (j = new_edge_curves.size(); j--; ) 01545 { 01546 Curve* curve = new_edge_curves.get_and_step(); 01547 if (curve->owner()) 01548 { 01549 RefEdge* edge = dynamic_cast<RefEdge*>(curve->topology_entity()); 01550 assert(!!edge); 01551 if (!otr_edge_curves.is_in_list(edge->get_curve_ptr())) 01552 new_edge = edge; 01553 } 01554 } 01555 if (!new_edge) 01556 { 01557 Curve* curve = new_edge_curves.get(); 01558 if (curve->owner()) 01559 curve->owner()->remove_bridge(curve); 01560 new_edge = gqt->make_RefEdge(curve); 01561 } 01562 01563 Curve* first = new_edge->get_curve_ptr(); 01564 for (j = new_edge_curves.size(); j--; ) 01565 { 01566 Curve* curve = new_edge_curves.get_and_step(); 01567 if (curve->owner()) 01568 { 01569 if (curve->topology_entity() == new_edge) 01570 continue; 01571 else 01572 curve->owner()->remove_bridge(curve); 01573 } 01574 01575 bool reversed = first->relative_sense(curve) == CUBIT_REVERSED; 01576 bool saved = first->bridge_sense() == curve->bridge_sense(); 01577 if (reversed == saved) 01578 curve->reverse_bridge_sense(); 01579 new_edge->bridge_manager()->add_bridge(curve); 01580 } 01581 } 01582 01583 if (old_edge) 01584 { 01585 DLIList<RefFace*> face_list; 01586 old_edge->ref_faces(face_list); 01587 modified += face_list; 01588 } 01589 return CUBIT_SUCCESS; 01590 } 01591 01592 01593 01594 01595 01596 01597 01598 01599 //------------------------------------------------------------------------- 01600 // Purpose : remove a composite face, restoring the orignial faces. 01601 // 01602 // Special Notes : 01603 // 01604 // Creator : Jason Kraftcheck 01605 // 01606 // Creation Date : 01607 //------------------------------------------------------------------------- 01608 CubitStatus CompositeTool::uncomposite( RefFace* composite_face, 01609 DLIList<RefFace*>* restored_faces, 01610 bool force_unmerge ) 01611 { 01612 int i; 01613 DLIList<Curve*> hidden_curves; 01614 DLIList<RefVolume*> vol_list; 01615 DLIList<Surface*> surface_list; 01616 01617 composite_face->ref_volumes( vol_list ); 01618 01619 if( composite_face->bridge_manager()->number_of_bridges() != 1 ) 01620 { 01621 PRINT_ERROR("Surface %d is a merged curve. Unmerge before removing composite.\n", 01622 composite_face->id() ); 01623 return CUBIT_FAILURE; 01624 } 01625 01626 CompositeSurface* surf_ptr = dynamic_cast<CompositeSurface*>(composite_face->get_surface_ptr()); 01627 if( !surf_ptr ) 01628 return CUBIT_FAILURE; 01629 01630 //remove all names off this ref entity 01631 composite_face->remove_entity_names(); 01632 01633 for( i = 0; i < surf_ptr->num_surfs(); i++ ) 01634 surface_list.append( surf_ptr->get_surface(i) ); 01635 01636 surf_ptr->get_hidden_curves( hidden_curves ); 01637 CubitStatus result = CUBIT_SUCCESS; 01638 hidden_curves.reset(); 01639 DLIList<TopologyBridge*> points(2); 01640 DLIList<RefFace*> modified_faces; 01641 for( i = hidden_curves.size(); i--; ) 01642 { 01643 //remove attributes off the hidden curves 01644 CompositeEngine::strip_attributes( hidden_curves.get() ); 01645 01646 Curve* curve = hidden_curves.get_and_step(); 01647 01648 if(DEBUG_FLAG(87)) 01649 { 01650 GMem gmem; 01651 curve->get_geometry_query_engine()->get_graphics(curve,&gmem); 01652 GfxDebug::draw_polyline(gmem.point_list(),gmem.pointListCount,CUBIT_RED_INDEX); 01653 GfxDebug::flush(); 01654 } 01655 01656 curve->get_children(points, true); 01657 while (points.size()) 01658 { 01659 TBPoint* pt = dynamic_cast<TBPoint*>(points.pop()); 01660 01661 //remove attributes off the underlying points 01662 CompositeEngine::strip_attributes( pt ); 01663 01664 HiddenEntitySet* hs = dynamic_cast<HiddenEntitySet*>(pt->owner()); 01665 if (hs && dynamic_cast<CompositeCurve*>(hs->owner())) 01666 { 01667 if (!restore_merged_point(pt, modified_faces, force_unmerge)) 01668 { 01669 PRINT_ERROR("Failed to restore hidden vertex.\n"); 01670 result = CUBIT_FAILURE; 01671 break; 01672 } 01673 } 01674 } 01675 01676 if (!result) 01677 break; 01678 01679 if( ! CompositeEngine::instance().restore_curve( curve ) ) 01680 result = CUBIT_FAILURE; 01681 } 01682 01683 if (modified_faces.size()) 01684 { 01685 DLIList<TopologyEntity*> query_input(modified_faces.size()); 01686 CAST_LIST_TO_PARENT(modified_faces, query_input); 01687 DLIList<TopologyEntity*> query_output; 01688 ModelQueryEngine::instance()-> 01689 query_model(query_input,DagType::ref_volume_type(),query_output); 01690 while(query_output.size()) 01691 vol_list.append_unique(dynamic_cast<RefVolume*>(query_output.pop())); 01692 } 01693 01694 01695 DLIList<TopologyBridge*> bridge_list; 01696 composite_face->bridge_manager()->get_bridge_list(bridge_list); 01697 int smallest_id = 0; 01698 for ( i = bridge_list.size(); i--; ) 01699 { 01700 GeometryEntity* geom_ptr = dynamic_cast<GeometryEntity*>(bridge_list.get_and_step()); 01701 int saved_id = geom_ptr->get_saved_id(); 01702 if ( saved_id && (!smallest_id || saved_id < smallest_id) && 01703 !RefEntityFactory::instance()->get_ref_face(saved_id) ) 01704 smallest_id = saved_id; 01705 } 01706 if ( smallest_id && composite_face->id() != smallest_id ) 01707 composite_face->set_id( smallest_id ); 01708 01709 for( i = vol_list.size(); i--; ) 01710 { 01711 Lump* lump= dynamic_cast<Lump*>( 01712 vol_list.get_and_step()->bridge_manager()->topology_bridge() ); 01713 GeometryQueryTool::instance()->make_Body( lump->bodysm() ); 01714 } 01715 for( i = vol_list.size(); i--; ) 01716 GeometryQueryTool::instance()->destroy_dead_entity( vol_list.get_and_step() ); 01717 01718 for( i = surface_list.size(); i--; ) 01719 { 01720 Surface *tmp_surf = surface_list.get_and_step(); 01721 //remove attributes off the surfaces 01722 CompositeEngine::strip_attributes( tmp_surf ); 01723 01724 BridgeManager* bm = dynamic_cast<BridgeManager*>(tmp_surf->owner()); 01725 RefFace* face = bm ? dynamic_cast<RefFace*>(bm->topology_entity()) : 0; 01726 if( restored_faces ) 01727 restored_faces->append( face ); 01728 std::vector<CubitString> underlying_names; 01729 tmp_surf->get_saved_names( underlying_names ); 01730 for (size_t k = 0; k < underlying_names.size(); k++) 01731 face->entity_name( underlying_names[k] ); 01732 } 01733 01734 return result; 01735 } 01736 01737 01738 //------------------------------------------------------------------------- 01739 // Purpose : Remove a composite volume 01740 // 01741 // Special Notes : 01742 // 01743 // Creator : Jason Kraftcheck 01744 // 01745 // Creation Date : 09/25/01 01746 //------------------------------------------------------------------------- 01747 CubitStatus CompositeTool::uncomposite( RefVolume* composite_vol, 01748 DLIList<RefVolume*>* restored_vols ) 01749 { 01750 int i; 01751 DLIList<Surface*> hidden_surfs; 01752 DLIList<Body*> body_list; 01753 DLIList<Lump*> lump_list; 01754 01755 composite_vol->bodies( body_list ); 01756 01757 CompositeLump* lump_ptr = dynamic_cast<CompositeLump*>(composite_vol->get_lump_ptr()); 01758 if( !lump_ptr ) 01759 return CUBIT_FAILURE; 01760 01761 for( i = 0; i < lump_ptr->num_lumps(); i++ ) 01762 lump_list.append( lump_ptr->get_lump(i) ); 01763 01764 lump_ptr->get_hidden_surfaces( hidden_surfs ); 01765 CubitStatus result = CUBIT_SUCCESS; 01766 hidden_surfs.reverse(); 01767 while( hidden_surfs.size() ) 01768 { 01769 Surface* surf = hidden_surfs.pop(); 01770 Surface* stitch = 0; 01771 if( ! CompositeEngine::instance().restore_surface( surf, stitch ) ) 01772 result = CUBIT_FAILURE; 01773 if (stitch) 01774 hidden_surfs.remove( stitch ); 01775 } 01776 01777 int saved_id = composite_vol->get_lump_ptr()->get_saved_id(); 01778 if (saved_id && saved_id < composite_vol->id() && 01779 !RefEntityFactory::instance()->get_ref_volume(saved_id)) 01780 composite_vol->set_id( saved_id ); 01781 01782 for( i = body_list.size(); i--; ) 01783 GeometryQueryTool::instance()->make_Body( body_list.get_and_step()->get_body_sm_ptr() ); 01784 for( i = body_list.size(); i--; ) 01785 GeometryQueryTool::instance()->destroy_dead_entity( body_list.get_and_step() ); 01786 01787 if( restored_vols ) 01788 { 01789 for( i = lump_list.size(); i--; ) 01790 { 01791 TBOwner* owner = lump_list.get_and_step()->owner(); 01792 if (BridgeManager* bm = dynamic_cast<BridgeManager*>(owner)) 01793 restored_vols->append( dynamic_cast<RefVolume*>(bm->topology_entity()) ); 01794 else if (CompositeLump* lump = dynamic_cast<CompositeLump*>(owner)) 01795 restored_vols->append_unique( dynamic_cast<RefVolume*>(lump->topology_entity() ) ); 01796 } 01797 } 01798 01799 return result; 01800 } 01801 01802 //------------------------------------------------------------------------- 01803 // Purpose : Remove composite body 01804 // 01805 // Special Notes : 01806 // 01807 // Creator : Jason Kraftcheck 01808 // 01809 // Creation Date : 10/02/01 01810 //------------------------------------------------------------------------- 01811 CubitStatus CompositeTool::uncomposite( Body* , 01812 DLIList<Body*>* ) 01813 { 01814 return CUBIT_FAILURE; 01815 } 01816 01817 01818 01819 01820 //------------------------------------------------------------------------- 01821 // Purpose : Create multiple composite curves 01822 // 01823 // Special Notes : 01824 // 01825 // Creator : Jason Kraftcheck 01826 // 01827 // Creation Date : 12/03/99 01828 //------------------------------------------------------------------------- 01829 CubitStatus CompositeTool::composite( DLIList<RefEdge*>& edges, 01830 DLIList<RefEdge*>& new_edge_list, 01831 DLIList<RefVertex*>* vertices_to_keep, 01832 double max_curve_angle /*radians*/ ) 01833 { 01834 new_edge_list.clean_out(); 01835 double min_cos_angle = cos( max_curve_angle ); 01836 int i; 01837 01838 //check for duplicates 01839 DLIList<RefEdge*> edges_to_composite; 01840 for( i = edges.size(); i > 0; i-- ) 01841 { 01842 RefEdge* edge_ptr = edges.get_and_step(); 01843 if( ! edges_to_composite.append_unique( edge_ptr ) ) 01844 { 01845 PRINT_WARNING("Duplicate curve %d in list of curves to composite.\n", 01846 edge_ptr->id()); 01847 } 01848 } 01849 01850 01851 if( edges_to_composite.size() < 2 ) return CUBIT_SUCCESS; 01852 01853 fast_edge_sort( edges_to_composite, true ); 01854 01855 //look for a place to start (a point that we cannot 01856 //composite across.) 01857 01858 RefVertex *vtx_ptr; 01859 RefEdge* first_edge; 01860 DLIList<RefEdge*> vertex_edges; 01861 01862 edges_to_composite.last(); 01863 RefEdge* prev_edge = edges_to_composite.get(); 01864 edges_to_composite.reset(); 01865 01866 for( i = edges_to_composite.size(); i >= 0; i-- ) 01867 { 01868 first_edge = edges_to_composite.get_and_step(); 01869 vtx_ptr = first_edge->common_ref_vertex( prev_edge ); 01870 if( ! vtx_ptr ) break; 01871 01872 vertex_edges.clean_out(); 01873 vtx_ptr->ref_edges( vertex_edges ); 01874 vertex_edges.remove( first_edge ); 01875 vertex_edges.remove( prev_edge ); 01876 if( vertex_edges.size() > 0 ) break; 01877 01878 prev_edge = first_edge; 01879 } 01880 01881 if( i < 0 ) //if all the edges get composited into one 01882 { 01883 edges_to_composite.reset(); 01884 first_edge = edges_to_composite.get(); 01885 } 01886 01887 //composite chains of consecutive edges 01888 01889 edges_to_composite.move_to( first_edge ); 01890 DLIList<RefEdge*> edge_list, sublist; 01891 int edge_count = edges_to_composite.size(); 01892 while( edge_count > 0 ) 01893 { 01894 edge_list.clean_out(); 01895 RefEdge* edge_ptr = edges_to_composite.get_and_step(); 01896 edge_list.append( edge_ptr ); 01897 edge_count--; 01898 01899 //Find a chain of connected edges that can form a 01900 //topologically valid composite. 01901 01902 while( edge_count > 0 ) 01903 { 01904 RefEdge* next_edge = edges_to_composite.get(); 01905 vtx_ptr = edge_ptr->common_ref_vertex( next_edge ); 01906 if( ! vtx_ptr ) break; 01907 01908 vertex_edges.clean_out(); 01909 vtx_ptr->ref_edges( vertex_edges ); 01910 vertex_edges.remove( edge_ptr ); 01911 vertex_edges.remove( next_edge ); 01912 if( vertex_edges.size() > 0 ) break; 01913 01914 edge_ptr = next_edge; 01915 edges_to_composite.step(); 01916 edge_list.append( edge_ptr ); 01917 edge_count--; 01918 } 01919 01920 if( edge_list.size() == 1 ) continue; 01921 assert( edge_list.size() ); 01922 01923 //Now split that chain of edges further based on 01924 //user-specified constraints (vertices and/or angle.) 01925 //This is done seperatly from the above loop to handle 01926 //cases where the edge_list forms a closed loop, and the 01927 //user specified one position on that loop to keep. 01928 01929 //Find a start point in the chain. 01930 edge_list.last(); 01931 edge_ptr = edge_list.get(); 01932 edge_list.reset(); 01933 RefVertex* keep_vertex = 0; 01934 if( edge_ptr->common_ref_vertex( edge_list.get() ) ) 01935 //if we have a closed loop 01936 { 01937 edge_ptr = edge_list.get_and_step(); 01938 for( i = edge_list.size(); i > 0; i-- ) 01939 { 01940 RefEdge* next_edge = edge_list.get(); 01941 vtx_ptr = edge_ptr->common_ref_vertex( next_edge ); 01942 assert( vtx_ptr != 0 ); 01943 01944 if( vertices_to_keep && vertices_to_keep->is_in_list( vtx_ptr ) ) 01945 { 01946 keep_vertex = vtx_ptr; 01947 break; 01948 } 01949 CubitVector cur_tan = tangent( edge_ptr, vtx_ptr ) * -1.0; 01950 CubitVector next_tan = tangent( next_edge, vtx_ptr ); 01951 double cos_angle = (cur_tan % next_tan) / 01952 (cur_tan.length() * next_tan.length()); 01953 if( cos_angle < min_cos_angle ) 01954 { 01955 keep_vertex = vtx_ptr; 01956 break; 01957 } 01958 01959 edge_ptr = next_edge; 01960 edge_list.step(); 01961 } 01962 } 01963 01964 //If we didn't find any split locations, that's okay. 01965 //We'll let the compositing code choose which vertex to keep. 01966 01967 int subcount = edge_list.size(); 01968 while( subcount > 0 ) 01969 { 01970 sublist.clean_out(); 01971 edge_ptr = edge_list.get_and_step(); 01972 subcount--; 01973 sublist.append( edge_ptr ); 01974 01975 while( subcount > 0 ) 01976 { 01977 RefEdge* next_edge = edge_list.get(); 01978 vtx_ptr = edge_ptr->common_ref_vertex( next_edge ); 01979 assert( vtx_ptr != 0 ); 01980 01981 if( vertices_to_keep && vertices_to_keep->is_in_list( vtx_ptr ) ) 01982 { 01983 keep_vertex = vtx_ptr; 01984 break; 01985 } 01986 CubitVector cur_tan = tangent( edge_ptr, vtx_ptr ) * -1.0; 01987 CubitVector next_tan = tangent( next_edge, vtx_ptr ); 01988 double cos_angle = (cur_tan % next_tan) / 01989 (cur_tan.length() * next_tan.length()); 01990 if( cos_angle < min_cos_angle ) 01991 { 01992 keep_vertex = vtx_ptr; 01993 break; 01994 } 01995 01996 edge_ptr = next_edge; 01997 edge_list.step(); 01998 subcount--; 01999 sublist.append( edge_ptr ); 02000 } 02001 02002 02003 if( sublist.size() > 1 ) 02004 { 02005 edge_ptr = composite( sublist, keep_vertex ); 02006 if( ! edge_ptr ) return CUBIT_FAILURE; 02007 new_edge_list.append( edge_ptr ); 02008 } 02009 } 02010 } 02011 02012 return CUBIT_SUCCESS; 02013 } 02014 02015 //------------------------------------------------------------------------- 02016 // Purpose : Get the tangent along an edge away from a vertex. 02017 // 02018 // Special Notes : 02019 // 02020 // Creator : Jason Kraftcheck 02021 // 02022 // Creation Date : 12/03/99 02023 //------------------------------------------------------------------------- 02024 CubitVector CompositeTool::tangent( RefEdge* edge_ptr, RefVertex* vtx_ptr ) const 02025 { 02026 CubitVector result; 02027 edge_ptr->tangent( vtx_ptr->coordinates(), result ); 02028 if( vtx_ptr == edge_ptr->end_vertex() ) 02029 result *= -1; 02030 return result; 02031 } 02032 02033 //------------------------------------------------------------------------- 02034 // Purpose : Sort edges topologically. 02035 // 02036 // Special Notes : Not safe with secondary links 02037 // 02038 // Creator : Jason Kraftcheck 02039 // 02040 // Creation Date : 12/03/99 02041 //------------------------------------------------------------------------- 02042 CubitStatus CompositeTool::fast_edge_sort( DLIList<RefEdge*>& edge_list, 02043 bool valence2_vertices ) const 02044 { 02045 int i; 02046 if( edge_list.size() < 2 ) return CUBIT_SUCCESS; 02047 02048 //make sure all RefEdges are initially marked as zero. 02049 DLIList<RefVertex*> vtx_list(2), all_vertices(edge_list.size() * 2); 02050 DLIList<RefEdge*> vertex_edges; 02051 RefEdge* edge_ptr; 02052 RefVertex* vtx_ptr; 02053 for( i = edge_list.size(); i > 0; i-- ) 02054 { 02055 edge_ptr = edge_list.get_and_step(); 02056 vtx_list.clean_out(); 02057 edge_ptr->ref_vertices( vtx_list ); 02058 for( int j = vtx_list.size(); j > 0; j-- ) 02059 { 02060 vtx_ptr = vtx_list.get_and_step(); 02061 vtx_ptr->marked( 0 ); 02062 } 02063 } 02064 for( i = edge_list.size(); i > 0; i-- ) 02065 { 02066 edge_ptr = edge_list.get_and_step(); 02067 vtx_list.clean_out(); 02068 edge_ptr->ref_vertices( vtx_list ); 02069 for( int j = vtx_list.size(); j > 0; j-- ) 02070 { 02071 vtx_ptr = vtx_list.get_and_step(); 02072 if( vtx_ptr->marked() ) continue; 02073 02074 all_vertices.append( vtx_ptr ); 02075 vtx_ptr->marked( 1 ); 02076 02077 vertex_edges.clean_out(); 02078 vtx_ptr->ref_edges( vertex_edges ); 02079 for( int k = vertex_edges.size(); k > 0; k-- ) 02080 vertex_edges.get_and_step()->marked( 0 ); 02081 } 02082 } 02083 02084 //now mark all of the edges in the edge list with a 1 02085 for( i = edge_list.size(); i > 0; i-- ) 02086 edge_list.get_and_step()->marked( 1 ); 02087 02088 DLIList<RefEdge*> sorted_edge_list( edge_list.size() ); 02089 02090 int passes = 0; 02091 while( sorted_edge_list.size() < edge_list.size() ) 02092 { 02093 passes++; 02094 RefVertex* start_vtx = 0; 02095 RefEdge* start_edge = 0; 02096 02097 //choose a start_vtx and start_edge 02098 for( i = all_vertices.size(); i > 0; i-- ) 02099 { 02100 vtx_ptr = all_vertices.get_and_step(); 02101 //if( ! vtx_ptr->marked() ) continue; 02102 02103 int edge_count = 0; 02104 vertex_edges.clean_out(); 02105 vtx_ptr->ref_edges( vertex_edges ); 02106 for( int j = vertex_edges.size(); j > 0; j-- ) 02107 { 02108 edge_ptr = vertex_edges.get_and_step(); 02109 if( edge_ptr->marked() ) 02110 { 02111 start_edge = edge_ptr; 02112 edge_count++; 02113 if( (edge_count > 1) || (valence2_vertices && vertex_edges.size() > 2) ) 02114 break; 02115 // If the vertex has more than two edges, consider it a 02116 // valid starting point for the search because it will not 02117 // be possible to create a composite across that vertex 02118 // anyway. 02119 } 02120 } 02121 if( edge_count == 1 ) 02122 { 02123 start_vtx = vtx_ptr; 02124 break; 02125 } 02126 } 02127 02128 //If we have a circular loop, choose any vertex as the start vertex 02129 if( ! start_vtx ) 02130 { 02131 start_edge = 0; 02132 all_vertices.reset(); 02133 for( i = all_vertices.size(); ! start_edge && (i > 0); i-- ) 02134 { 02135 start_vtx = all_vertices.get_and_step(); 02136 vertex_edges.clean_out(); 02137 start_vtx->ref_edges( vertex_edges ); 02138 for( int j = vertex_edges.size(); j > 0; j-- ) 02139 { 02140 edge_ptr = vertex_edges.get_and_step(); 02141 if( edge_ptr->marked() ) 02142 { 02143 start_edge = edge_ptr; 02144 break; 02145 } 02146 } 02147 if( start_vtx->marked() ) break; 02148 } 02149 } 02150 02151 assert( start_edge != 0 ); 02152 assert( start_vtx != 0 ); 02153 02154 02155 start_vtx->marked( 0 ); 02156 edge_ptr = start_edge; 02157 vtx_ptr = start_vtx; 02158 02159 do 02160 { 02161 sorted_edge_list.append( edge_ptr ); 02162 edge_ptr->marked( 0 ); 02163 02164 RefVertex* next_vtx = edge_ptr->other_vertex( vtx_ptr ); 02165 next_vtx->marked( 0 ); 02166 02167 vertex_edges.clean_out(); 02168 next_vtx->ref_edges( vertex_edges ); 02169 RefEdge* next_edge = 0; 02170 02171 if( !valence2_vertices || vertex_edges.size() < 3 ) 02172 { 02173 for( i = vertex_edges.size(); i > 0; i-- ) 02174 { 02175 RefEdge* edge2_ptr = vertex_edges.get_and_step(); 02176 if( edge2_ptr->marked() ) 02177 { 02178 next_edge = edge2_ptr; 02179 break; 02180 } 02181 } 02182 } 02183 02184 edge_ptr = next_edge; 02185 vtx_ptr = next_vtx; 02186 } while( edge_ptr ); 02187 } 02188 02189 assert( sorted_edge_list.size() == edge_list.size() ); 02190 02191 edge_list.clean_out(); 02192 edge_list = sorted_edge_list; 02193 return (passes == 1) ? CUBIT_SUCCESS : CUBIT_FAILURE; 02194 } 02195 02196 02197 CubitStatus CompositeTool::composite( DLIList<RefFace*>& faces_to_composite, 02198 DLIList<RefFace*>& new_composites, 02199 double max_angle ) 02200 { 02201 int i; 02202 DLIList<CoEdge*> coedges(2); 02203 double cos_max_angle = cos( max_angle ); 02204 CubitStatus result = CUBIT_SUCCESS; 02205 02206 DLIList<BasicTopologyEntity*> input, boundary, internal, other; 02207 CAST_LIST_TO_PARENT( faces_to_composite, input ); 02208 classify_children( input, boundary, internal, other ); 02209 DLIList<RefEdge*> internal_edges(internal.size()); 02210 CAST_LIST( internal, internal_edges, RefEdge ); 02211 if ( !internal_edges.size() ) 02212 return CUBIT_FAILURE; 02213 02214 // Group faces into sets to be composited 02215 02216 std::vector< DLIList<RefFace*> > face_sets; 02217 for ( i = faces_to_composite.size(); i--; ) 02218 faces_to_composite.get_and_step()->marked(0); 02219 02220 while ( internal_edges.size() ) 02221 { 02222 RefEdge* edge = internal_edges.pop(); 02223 coedges.clean_out(); 02224 edge->co_edges(coedges); 02225 if ( coedges.size() != 2 ) 02226 continue; 02227 02228 CoEdge* coedge1 = coedges.get_and_step(); 02229 CoEdge* coedge2 = coedges.get_and_step(); 02230 RefFace* face1 = coedge1->get_ref_face(); 02231 RefFace* face2 = coedge2->get_ref_face(); 02232 02233 if ( max_angle < 4.0 ) 02234 { 02235 CubitVector point, norm1, norm2; 02236 bool reversed = coedge1->get_sense() == coedge2->get_sense(); 02237 02238 edge->position_from_fraction( 0.33, point ); 02239 norm1 = face1->normal_at( point ); 02240 norm2 = face2->normal_at( point ); 02241 if ( reversed ) norm2 *= -1.0; 02242 double cos_angle = (norm1 % norm2)/(norm1.length()*norm2.length()); 02243 if ( cos_angle < cos_max_angle ) 02244 continue; 02245 02246 edge->position_from_fraction( 0.67, point ); 02247 norm1 = face1->normal_at( point ); 02248 norm2 = face2->normal_at( point ); 02249 if ( reversed ) norm2 *= -1.0; 02250 cos_angle = (norm1 % norm2)/(norm1.length()*norm2.length()); 02251 if ( cos_angle < cos_max_angle ) 02252 continue; 02253 } 02254 02255 if ( face1->marked() && face2->marked() ) 02256 { 02257 if ( face1->marked() != face2->marked() ) 02258 { 02259 DLIList<RefFace*>& merge_set = face_sets[face2->marked()-1]; 02260 face_sets[face1->marked()-1] += merge_set; 02261 while( merge_set.size() ) 02262 merge_set.pop()->marked( face1->marked() ); 02263 } 02264 } 02265 else if ( face2->marked() ) 02266 { 02267 face1->marked(face2->marked()); 02268 face_sets[face2->marked()-1].append(face1); 02269 } 02270 else 02271 { 02272 if ( !face1->marked() ) 02273 { 02274 face_sets.push_back(DLIList<RefFace*>()); 02275 face1->marked(face_sets.size()); 02276 face_sets[face1->marked()-1].append(face1); 02277 } 02278 face2->marked(face1->marked()); 02279 face_sets[face1->marked()-1].append(face2); 02280 } 02281 } 02282 02283 // clear all marks 02284 std::vector< DLIList<RefFace*> >::iterator s_itor; 02285 for ( s_itor = face_sets.begin(); s_itor != face_sets.end(); ++s_itor ) 02286 { 02287 for ( i = s_itor->size(); i--; ) 02288 s_itor->get_and_step()->marked(0); 02289 } 02290 02291 // composite faces 02292 for ( s_itor = face_sets.begin(); s_itor != face_sets.end(); ++s_itor ) 02293 { 02294 if ( s_itor->size() < 2 ) 02295 continue; 02296 02297 RefFace* comp = composite(*s_itor); 02298 if ( comp ) 02299 new_composites.append(comp); 02300 else 02301 result = CUBIT_FAILURE; 02302 } 02303 02304 return result; 02305 } 02306 02307 //------------------------------------------------------------------------- 02308 // Purpose : Composite surfaces and curves. 02309 // 02310 // Special Notes : 02311 // 02312 // Creator : Jason Kraftcheck 02313 // 02314 // Creation Date : 04/13/00 02315 //------------------------------------------------------------------------- 02316 RefFace* CompositeTool::composite( DLIList<RefFace*>& faces_to_composite, 02317 DLIList<RefEdge*>& result_edges, 02318 DLIList<RefVertex*>* vertices_to_keep, 02319 double max_vertex_angle ) 02320 { 02321 result_edges.clean_out(); 02322 RefFace* result = composite( faces_to_composite ); 02323 if( ! result ) return 0; 02324 02325 DLIList<RefEdge*> face_edges; 02326 result->ref_edges( face_edges ); 02327 composite( face_edges, result_edges, vertices_to_keep, max_vertex_angle ); 02328 02329 return result; 02330 } 02331 02332 //------------------------------------------------------------------------- 02333 // Purpose : Composite surfaces and curves. 02334 // 02335 // Special Notes : 02336 // 02337 // Creator : Jason Kraftcheck 02338 // 02339 // Creation Date : 04/13/00 02340 //------------------------------------------------------------------------- 02341 CubitStatus CompositeTool::composite( DLIList<RefFace*>& faces_to_composite, 02342 DLIList<RefFace*>& result_faces, 02343 DLIList<RefEdge*>& result_edges, 02344 double max_curve_angle, 02345 DLIList<RefVertex*>* vertices_to_keep, 02346 double max_vtx_angle ) 02347 { 02348 result_faces.clean_out(); 02349 result_edges.clean_out(); 02350 02351 CubitStatus status = 02352 composite( faces_to_composite, result_faces, max_curve_angle ); 02353 if( ! status ) return status; 02354 02355 DLIList<TopologyEntity*> query_input, query_output; 02356 CAST_LIST_TO_PARENT( result_faces, query_input ); 02357 ModelQueryEngine::instance()-> 02358 query_model( query_input, DagType::ref_edge_type(), query_output ); 02359 02360 DLIList<RefEdge*> edge_list; 02361 CAST_LIST( query_output, edge_list, RefEdge ); 02362 02363 return composite( edge_list, result_edges, vertices_to_keep, max_vtx_angle ); 02364 } 02365 02366 02367 02368 02369 CubitStatus CompositeTool::stitch_points( TBPoint* pt1, TBPoint* pt2 ) 02370 { 02371 if ( pt1->owner() && pt2->owner() && pt1->owner() != pt2->owner() ) 02372 return CUBIT_FAILURE; 02373 02374 CompositePoint* result = CompositeEngine::instance().stitch_points( pt1, pt2 ); 02375 return result ? CUBIT_SUCCESS : CUBIT_FAILURE; 02376 } 02377 02378 CubitStatus CompositeTool::stitch_curves( Curve* cv1, Curve* cv2 ) 02379 { 02380 if ( cv1->owner() && cv2->owner() && cv1->owner() != cv2->owner() ) 02381 return CUBIT_FAILURE; 02382 02383 DLIList<TopologyBridge*> points; 02384 TBPoint *start1, *end1, *start2, *end2; 02385 02386 points.clean_out(); 02387 cv1->get_children( points ); 02388 points.reset(); 02389 start1 = dynamic_cast<TBPoint*>(points.get_and_step()); 02390 end1 = dynamic_cast<TBPoint*>(points.get_and_step()); 02391 02392 points.clean_out(); 02393 cv2->get_children( points ); 02394 points.reset(); 02395 start2 = dynamic_cast<TBPoint*>(points.get_and_step()); 02396 end2 = dynamic_cast<TBPoint*>(points.get_and_step()); 02397 02398 assert( start1 && start2 && end1 && end2 ); 02399 02400 if ( (start1 == end1) != (start2 == end2) ) 02401 return CUBIT_FAILURE; 02402 02403 if ( start1 == end2 || start1->owner() == end2->owner() ) 02404 std::swap(start2, end2); 02405 02406 if ( (start1->owner() != start2->owner()) || (end1->owner() != end2->owner()) ) 02407 return CUBIT_FAILURE; 02408 02409 if ( start1 != start2 && !stitch_points( start1, start2 ) ) 02410 return CUBIT_FAILURE; 02411 02412 if ( start1 != end1 && end1 != end2 && !stitch_points( end1, end2 ) ) 02413 return CUBIT_FAILURE; 02414 02415 CompositeCurve* result = CompositeEngine::instance().stitch_curves( cv1, cv2 ); 02416 return result ? CUBIT_SUCCESS : CUBIT_FAILURE; 02417 } 02418 02419 02420 02421 02422 //------------------------------------------------------------------------- 02423 // Purpose : Functions overloaded by CompositeToolMesh 02424 // 02425 // Special Notes : 02426 // 02427 // Creator : Jason Kraftcheck 02428 // 02429 // Creation Date : 05/10/04 02430 //------------------------------------------------------------------------- 02431 CubitStatus CompositeTool::update_combined_vols( RefVolume*, RefVolume* ) 02432 {return CUBIT_SUCCESS;} 02433 CubitStatus CompositeTool::update_combined_faces( RefFace*, RefEdge*, RefFace* ) 02434 {return CUBIT_SUCCESS;} 02435 CubitStatus CompositeTool::update_combined_edges( RefEdge*, RefEdge* ,int keep_interval,double keep_size,FirmnessType interval_keep_type,SizeIntervalType size_keep_type) 02436 {return CUBIT_SUCCESS;} 02437 CubitStatus CompositeTool::determine_combined_edges_interval_or_size( RefEdge* edge_1, RefEdge* edge_2,int& result_interval,double& result_size,FirmnessType& interval_keep_type,SizeIntervalType& size_keep_type) 02438 {return CUBIT_SUCCESS;} 02439 02440 02441 02442