cgma
|
00001 00002 #include <assert.h> 00003 #include <stdlib.h> 00004 #include <math.h> 00005 00006 #include "CubitDefines.h" 00007 #include "AppUtil.hpp" 00008 #include "ProgressTool.hpp" 00009 #include "GeometryDefines.h" 00010 #include "GeometryEntity.hpp" 00011 #include "GeomMeasureTool.hpp" 00012 #include "GeometryQueryTool.hpp" 00013 #include "GeometryModifyTool.hpp" 00014 #include "AnalyticGeometryTool.hpp" 00015 #include "MergeTool.hpp" 00016 #include "GeometryQueryEngine.hpp" 00017 #include "GeometryModifyEngine.hpp" // for creation of temporary construction entities 00018 #include "DAG.hpp" 00019 #include "TBOwnerSet.hpp" 00020 00021 #include "RefEntity.hpp" 00022 #include "RefEntityFactory.hpp" 00023 #include "BasicTopologyEntity.hpp" 00024 #include "RefVertex.hpp" 00025 #include "RefEdge.hpp" 00026 #include "RefFace.hpp" 00027 #include "RefVolume.hpp" 00028 #include "RefGroup.hpp" 00029 00030 #include "CoVertex.hpp" 00031 #include "CoEdge.hpp" 00032 #include "CoFace.hpp" 00033 #include "CoVolume.hpp" 00034 00035 #include "Chain.hpp" 00036 #include "Loop.hpp" 00037 #include "Shell.hpp" 00038 #include "Body.hpp" 00039 00040 #include "Lump.hpp" 00041 #include "Surface.hpp" 00042 #include "Curve.hpp" 00043 #include "Point.hpp" 00044 #include "BodySM.hpp" 00045 #include "ShellSM.hpp" 00046 #include "LoopSM.hpp" 00047 #include "CoEdgeSM.hpp" 00048 00049 #include "CubitUtil.hpp" 00050 #include "CubitAttrib.hpp" 00051 #include "CubitVector.hpp" 00052 #include "CubitPlane.hpp" 00053 00054 #include "DLIList.hpp" 00055 #include "GSaveOpen.hpp" 00056 00057 #include "CubitMessage.hpp" 00058 00059 #include "CastTo.hpp" 00060 #include "CpuTimer.hpp" 00061 00062 #include "BridgeManager.hpp" 00063 #include "TDUniqueId.hpp" 00064 #include "CAMergePartner.hpp" 00065 #include "CAActuateSet.hpp" 00066 #include "CADeferredAttrib.hpp" 00067 #include "CAUniqueId.hpp" 00068 00069 #include "SettingHandler.hpp" 00070 #include "ModelQueryEngine.hpp" 00071 00072 #include "CubitTransformMatrix.hpp" 00073 #include "CubitUndo.hpp" 00074 #include "GMem.hpp" 00075 #include "IntersectionTool.hpp" 00076 00077 #include "GfxPreview.hpp" //DJQ 00078 #include "GfxDebug.hpp" //DJQ 00079 #include "RefEntityName.hpp" 00080 00081 double GeometryQueryTool::geometryToleranceFactor = DEFAULT_GEOM_FACTOR; 00082 GeometryQueryTool* GeometryQueryTool::instance_ = 0; 00083 CubitBoolean GeometryQueryTool::useFacetBBox = CUBIT_FALSE; 00084 CubitBoolean GeometryQueryTool::trackMergedAwayEnts = CUBIT_FALSE; 00085 CubitBoolean GeometryQueryTool::importingSolidModel = CUBIT_FALSE; 00086 CubitBoolean GeometryQueryTool::mergeGloballyOnImport = CUBIT_TRUE; 00087 CubitBoolean GeometryQueryTool::clearUidMapBeforeImport = CUBIT_TRUE; 00088 DLIList<int> GeometryQueryTool::uidsOfImportingEnts; 00089 int GeometryQueryTool::entitiesMergedAway = 0; 00090 00091 #ifndef CAT 00092 // Keep checking bounding box and use internal surf check for Sandia 00093 CubitBoolean GeometryQueryTool::bboxMergeTest = CUBIT_TRUE; 00094 int GeometryQueryTool::internalSurfaceMergeTest = 2; // 0=off, 1=all, 2=splines only 00095 #else 00096 //test 00097 // Cat prefers to avoid internal checks altogether as they cause problems with splines 00098 CubitBoolean GeometryQueryTool::bboxMergeTest = CUBIT_FALSE; 00099 int GeometryQueryTool::internalSurfaceMergeTest = 0; // 0=off, 1=all, 2=splines only 00100 #endif // ndef CAT 00101 00102 double GeometryQueryTool::curveSliverCleanUpTolerance = geometryToleranceFactor*GEOMETRY_RESABS ; 00103 double GeometryQueryTool::surfaceSliverCleanUpTolerance = -1.0; 00104 00105 // static CubitStatus import_actuate(DLIList<RefEntity*> &entity_list); 00106 00107 // ********** END STATIC DECLARATIONS ********** 00108 00109 #define PRINT(var) cout << #var << " = " << var << endl; 00110 00111 #define CUBIT_VERY_SMALL_NUMBER (CUBIT_RESABS * 1.0E-15) 00112 00113 // ********** BEGIN PUBLIC FUNCTIONS ********** 00114 //------------------------------------------------------------------------- 00115 // Purpose : Controls access and creation of the sole instance of this 00116 // class. 00117 // 00118 // Special Notes : 00119 // 00120 // Creator : Xuechen Liu 00121 // 00122 // Creation Date : 07/11/96 00123 //------------------------------------------------------------------------- 00124 00125 GeometryQueryTool* GeometryQueryTool::instance(GeometryQueryEngine *GQEPtr) 00126 { 00127 // Check to see if we have created an instance of the class 00128 // If proceed to create one. 00129 00130 if (instance_ == 0) 00131 { 00132 // When creating the instance, we should always have a valid 00133 // GQEPtr. If not, complain. 00134 00135 instance_ = new GeometryQueryTool (GQEPtr) ; 00136 00137 // check to make sure there's a ref entity factory extant 00138 //RefEntityFactory *factory = 00139 RefEntityFactory::instance(); 00140 } 00141 00142 // If there is an existing instance of the class, check if there 00143 // was a request to set default solid modeling engine. If so, be nice 00144 // to the calling routine :) :) and kindly set the default solid 00145 // modeling engine. 00146 00147 else if ( GQEPtr != NULL && !instance_->gqeList.move_to(GQEPtr)) { 00148 delete instance_->gqeList.remove(); 00149 instance_->gqeList.insert(GQEPtr); 00150 } 00151 00152 // Return the a pointer to the instance of the class. 00153 00154 return instance_ ; 00155 } 00156 00157 //------------------------------------------------------------------------- 00158 // Purpose : Destructor. 00159 // 00160 // Special Notes : 00161 // 00162 // Creator : Xuechen Liu 00163 // 00164 // Creation Date : 07/11/96 00165 //------------------------------------------------------------------------- 00166 GeometryQueryTool::~GeometryQueryTool () 00167 { 00168 00169 //Kill the geometry query engine(s). 00170 int i; 00171 for (i = gqeList.size(); i > 0; i--) 00172 { 00173 delete gqeList.get_and_step(); 00174 } 00175 gqeList.clean_out(); 00176 00177 instance_ = NULL; 00178 } 00179 00180 //------------------------------------------------------------------------- 00181 // Purpose : Function to delete instance variable 00182 // 00183 // Special Notes : 00184 // 00185 // Creator : Corey Ernst 00186 // 00187 // Creation Date : 12/31/07 00188 //------------------------------------------------------------------------- 00189 void GeometryQueryTool::delete_instance() 00190 { 00191 if( NULL != instance_ ) 00192 { 00193 delete instance_; 00194 instance_ = NULL; 00195 } 00196 } 00197 00198 //------------------------------------------------------------------------- 00199 // Purpose : Creates temporary geometry files for save/restore 00200 // 00201 // Special Notes : 00202 // 00203 // Creator : Corey Ernst 00204 // 00205 // Creation Date : 01/17/03 00206 //------------------------------------------------------------------------- 00207 00208 CubitStatus GeometryQueryTool::save_temp_geom_files(DLIList<RefEntity*> &ref_entity_list, 00209 const char *base_filename, 00210 const CubitString &cubit_version, 00211 std::list<CubitString> &files_written, 00212 std::list<CubitString> &types_written) 00213 { 00214 int i; 00215 // clear all attributes 00216 if (ref_entity_list.size() == 0) { 00217 00218 // All bodies are to be exported 00219 RefEntityFactory::instance()->ref_entity_list("Body", 00220 ref_entity_list); 00221 00222 // add free ref entities 00223 get_free_ref_entities(ref_entity_list); 00224 00225 } 00226 00227 // get all child entities 00228 DLIList<RefEntity*> child_list; 00229 RefEntity::get_all_child_ref_entities( ref_entity_list, child_list ); 00230 00231 // merge lists 00232 for(i = ref_entity_list.size(); i--; ) 00233 ref_entity_list.get_and_step()->marked(1); 00234 for(i = child_list.size(); i--; ) 00235 child_list.get_and_step()->marked(0); 00236 for(i = ref_entity_list.size(); i--; ) 00237 { 00238 RefEntity* ent = ref_entity_list.get_and_step(); 00239 if( ent->marked() ) 00240 { 00241 ent->marked(0); 00242 child_list.append(ent); 00243 } 00244 } 00245 00246 // now call auto update on this combined list; this will update both visible 00247 // and hidden entities; the combined list should be used here, but only the 00248 // export list should be exported (some of the hidden entities might be directly 00249 // related to other entities on the export list, and we want to avoid exporting 00250 // those entities twice) 00251 CubitAttribUser::auto_update_cubit_attrib(child_list); 00252 00253 // Get list of TopologyBridges to save 00254 DLIList<TopologyBridge*> geometry_list(ref_entity_list.size()), ref_ent_bridges; 00255 ref_entity_list.reset(); 00256 for ( i = ref_entity_list.size(); i--; ) 00257 { 00258 RefEntity* ref_ent = ref_entity_list.get_and_step(); 00259 TopologyEntity* topo_ent = dynamic_cast<TopologyEntity*>(ref_ent); 00260 if ( !topo_ent ) 00261 { 00262 PRINT_ERROR("Attempt to save %s (%s %d) as geometry.\n", 00263 ref_ent->entity_name().c_str(), ref_ent->class_name(), ref_ent->id()); 00264 continue; 00265 } 00266 00267 ref_ent_bridges.clean_out(); 00268 topo_ent->bridge_manager()->get_bridge_list(ref_ent_bridges); 00269 geometry_list += ref_ent_bridges; 00270 } 00271 00272 // Save virtual. 00273 for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 00274 (*itor)->export_geometry(geometry_list); 00275 00276 //we need this list around so that we can remove the CSAs off 00277 // the entities under the virtual entities 00278 DLIList<TopologyBridge*> geometry_list2 = geometry_list; 00279 00280 CubitStatus result = CUBIT_SUCCESS, temp_result; 00281 00282 GeometryQueryEngine* gqe = NULL; 00283 //we're just going to mess with MBG stuff right now 00284 gqeList.reset(); 00285 for( int k=0; k<gqeList.size(); k++) 00286 { 00287 gqe = gqeList.get_and_step(); 00288 00289 CubitString file_written; 00290 CubitString type_written; 00291 00292 temp_result = gqe->save_temp_geom_file(geometry_list, base_filename, 00293 cubit_version, file_written, 00294 type_written ); 00295 if( file_written.length() ) 00296 { 00297 files_written.push_back( file_written ); 00298 types_written.push_back( type_written ); 00299 } 00300 00301 if (CUBIT_SUCCESS == temp_result) result = temp_result; 00302 00303 } 00304 00305 00306 //if there is still geometry left over....could not be handled 00307 if( geometry_list.size() ) 00308 PRINT_ERROR("Not all geometry could be handled for save.\n"); 00309 CubitAttribUser::clear_all_simple_attrib(child_list); 00310 00311 //remove attributes off underlying entities of virtual geometry 00312 if( geometry_list2.size() ) 00313 GeometryQueryTool::instance()->ige_remove_attributes( geometry_list2 ); 00314 00315 gqeList.reset(); 00316 return result; 00317 } 00318 00319 //------------------------------------------------------------------------- 00320 // Purpose : Export a list of solid model entities to a file. 00321 // 00322 // Special Notes : 00323 // 00324 // Creator : Steve Storm 00325 // 00326 // Creation Date : 03/17/99 00327 //------------------------------------------------------------------------- 00328 00329 CubitStatus GeometryQueryTool::export_solid_model(DLIList<RefEntity*>& ref_entity_list, 00330 char const* filename, 00331 Model_File_Type filetype, 00332 int &num_ents_exported, 00333 const CubitString &cubit_version, 00334 ModelExportOptions &export_options ) 00335 { 00336 if (0 == gqeList.size()) 00337 { 00338 PRINT_WARNING("No active geometry engine.\n"); 00339 return CUBIT_FAILURE; 00340 } 00341 00342 int i; 00343 00344 if (ref_entity_list.size() == 0) { 00345 00346 // All bodies are to be exported 00347 RefEntityFactory::instance()->ref_entity_list("Body", 00348 ref_entity_list); 00349 00350 // add free ref entities 00351 get_free_ref_entities(ref_entity_list); 00352 00353 } 00354 00355 // Get TopologyBridges from RefEntities. 00356 DLIList<TopologyBridge*> bridge_list(ref_entity_list.size()), 00357 parent_bridges, ref_ent_bridges; 00358 ref_entity_list.reset(); 00359 for( i = ref_entity_list.size(); i--; ) 00360 { 00361 ref_ent_bridges.clean_out(); 00362 TopologyEntity* topo_ptr = dynamic_cast<TopologyEntity*>(ref_entity_list.get_and_step()); 00363 if( topo_ptr ) 00364 topo_ptr->bridge_manager()->get_bridge_list( ref_ent_bridges ); 00365 bridge_list += ref_ent_bridges; 00366 } 00367 00368 // Get all child RefEntities 00369 DLIList<RefEntity*> child_list; 00370 RefEntity::get_all_child_ref_entities( ref_entity_list, child_list ); 00371 00372 // Scan for free-but-merged entities in child list. 00373 child_list.reset(); 00374 for (i = child_list.size(); i--; ) 00375 { 00376 ref_ent_bridges.clean_out(); 00377 TopologyEntity* topo_ptr = dynamic_cast<TopologyEntity*>(child_list.get_and_step()); 00378 assert(!!topo_ptr); 00379 topo_ptr->bridge_manager()->get_bridge_list( ref_ent_bridges ); 00380 ref_ent_bridges.reset(); 00381 for (int j = ref_ent_bridges.size(); j--; ) 00382 { 00383 TopologyBridge* bridge = ref_ent_bridges.get_and_step(); 00384 parent_bridges.clean_out(); 00385 bridge->get_parents(parent_bridges); 00386 if (parent_bridges.size() == 0) 00387 bridge_list.append_unique(bridge); 00388 } 00389 } 00390 00391 // Merge lists so we have one big list of every 00392 // RefEntity to be saved. 00393 for(i = ref_entity_list.size(); i--; ) 00394 ref_entity_list.get_and_step()->marked(1); 00395 00396 for(i = child_list.size(); i--; ) 00397 child_list.get_and_step()->marked(0); 00398 for(i = ref_entity_list.size(); i--; ) 00399 { 00400 RefEntity* ent = ref_entity_list.get_and_step(); 00401 if( ent->marked() ) 00402 { 00403 ent->marked(0); 00404 child_list.append(ent); 00405 } 00406 } 00407 00408 // Make a copy of the bridge list to be used below in 00409 // removing the virtual geometry attributes. We can't 00410 // use the original bridge list because it gets emptied. 00411 DLIList<TopologyBridge*> copy_of_bridge_list = bridge_list; 00412 00413 int num_input_entities = bridge_list.size(); 00414 00415 // now call auto update on this combined list; this will update both visible 00416 // and hidden entities; the combined list should be used here, but only the 00417 // export list should be exported (some of the hidden entities might be directly 00418 // related to other entities on the export list, and we want to avoid exporting 00419 // those entities twice) 00420 CubitAttribUser::auto_update_cubit_attrib(child_list); 00421 00422 // Save virtual. 00423 IGESet::reverse_iterator itor; 00424 for (itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 00425 (*itor)->export_geometry(bridge_list); 00426 00427 CubitStatus result = CUBIT_SUCCESS, temp_result; 00428 00429 if( !bridge_list.size() ) 00430 { 00431 return CUBIT_SUCCESS; 00432 } 00433 // GeometryQueryEngine* gqe = NULL; 00434 //we're just going to mess with MBG stuff right now 00435 gqeList.reset(); 00436 00437 int num_ents_before = bridge_list.size(); 00438 temp_result = gqeList.get()->export_solid_model(bridge_list, filename, filetype, 00439 cubit_version, export_options ); 00440 if (temp_result == CUBIT_SUCCESS ) 00441 result = temp_result; 00442 00443 //if all geometry wasn't exported, warn user and print out 00444 //what wasn't 00445 if( bridge_list.size() != 0 ) 00446 { 00447 if( bridge_list.size() == num_ents_before ) 00448 PRINT_ERROR("No geometry exported. Must set geometry engine to another type.\n"); 00449 else 00450 PRINT_WARNING("Not all geometry could be handled for save.\n"); 00451 00452 PRINT_INFO("Set the geometry engine appropriately to export the following geometry:\n"); 00453 int k; 00454 for(k=bridge_list.size(); k--; ) 00455 { 00456 TopologyEntity *te = bridge_list.get()->topology_entity(); 00457 if( te ) 00458 { 00459 RefEntity *ref_ent = CAST_TO( te, RefEntity ); 00460 if( ref_ent ) 00461 { 00462 GeometryQueryEngine *gqe = bridge_list.get()->get_geometry_query_engine(); 00463 PRINT_INFO("%s is of Geometry Engine type %s\n", 00464 ref_ent->entity_name().c_str(), gqe->modeler_type() ); 00465 } 00466 } 00467 bridge_list.step(); 00468 } 00469 } 00470 00471 // clean off attributes off of underyling virtual geometry 00472 for (itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 00473 (*itor)->remove_attributes(copy_of_bridge_list); 00474 00475 CubitAttribUser::clear_all_simple_attrib(child_list); 00476 00477 num_ents_exported = num_input_entities - bridge_list.size(); 00478 gqeList.reset(); 00479 return result; 00480 } 00481 00482 // export entities to buffer 00483 CubitStatus GeometryQueryTool::export_solid_model(DLIList<RefEntity*>& ref_entity_list, 00484 char*& p_buffer, 00485 int& n_buffer_size, 00486 bool b_export_buffer) 00487 { 00488 if (0 == gqeList.size()) 00489 { 00490 PRINT_WARNING("No active geometry engine.\n"); 00491 return CUBIT_FAILURE; 00492 } 00493 00494 int i; 00495 00496 if (ref_entity_list.size() == 0) { 00497 // All bodies are to be exported 00498 RefEntityFactory::instance()->ref_entity_list("Body", 00499 ref_entity_list); 00500 00501 // add free ref entities 00502 get_free_ref_entities(ref_entity_list); 00503 } 00504 00505 // Get TopologyBridges from RefEntities. 00506 DLIList<TopologyBridge*> bridge_list(ref_entity_list.size()), 00507 parent_bridges, ref_ent_bridges; 00508 ref_entity_list.reset(); 00509 for( i = ref_entity_list.size(); i--; ) { 00510 ref_ent_bridges.clean_out(); 00511 TopologyEntity* topo_ptr = dynamic_cast<TopologyEntity*>(ref_entity_list.get_and_step()); 00512 if( topo_ptr ) 00513 topo_ptr->bridge_manager()->get_bridge_list( ref_ent_bridges ); 00514 bridge_list += ref_ent_bridges; 00515 } 00516 00517 // Get all child RefEntities 00518 DLIList<RefEntity*> child_list; 00519 RefEntity::get_all_child_ref_entities( ref_entity_list, child_list ); 00520 00521 // Scan for free-but-merged entities in child list. 00522 child_list.reset(); 00523 for (i = child_list.size(); i--; ) 00524 { 00525 ref_ent_bridges.clean_out(); 00526 TopologyEntity* topo_ptr = dynamic_cast<TopologyEntity*>(child_list.get_and_step()); 00527 assert(!!topo_ptr); 00528 topo_ptr->bridge_manager()->get_bridge_list( ref_ent_bridges ); 00529 ref_ent_bridges.reset(); 00530 for (int j = ref_ent_bridges.size(); j--; ) 00531 { 00532 TopologyBridge* bridge = ref_ent_bridges.get_and_step(); 00533 parent_bridges.clean_out(); 00534 bridge->get_parents(parent_bridges); 00535 if (parent_bridges.size() == 0) 00536 bridge_list.append_unique(bridge); 00537 } 00538 } 00539 00540 // Merge lists so we have one big list of every 00541 // RefEntity to be saved. 00542 for(i = ref_entity_list.size(); i--; ) 00543 ref_entity_list.get_and_step()->marked(1); 00544 00545 for(i = child_list.size(); i--; ) 00546 child_list.get_and_step()->marked(0); 00547 for(i = ref_entity_list.size(); i--; ) 00548 { 00549 RefEntity* ent = ref_entity_list.get_and_step(); 00550 if( ent->marked() ) 00551 { 00552 ent->marked(0); 00553 child_list.append(ent); 00554 } 00555 } 00556 00557 // Make a copy of the bridge list to be used below in 00558 // removing the virtual geometry attributes. We can't 00559 // use the original bridge list because it gets emptied. 00560 DLIList<TopologyBridge*> copy_of_bridge_list = bridge_list; 00561 00562 /*int num_input_entities =*/ bridge_list.size(); 00563 00564 // now call auto update on this combined list; this will update both visible 00565 // and hidden entities; the combined list should be used here, but only the 00566 // export list should be exported (some of the hidden entities might be directly 00567 // related to other entities on the export list, and we want to avoid exporting 00568 // those entities twice) 00569 CubitAttribUser::auto_update_cubit_attrib(child_list); 00570 00571 // Save virtual. 00572 IGESet::reverse_iterator itor; 00573 for (itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 00574 (*itor)->export_geometry(bridge_list); 00575 00576 CubitStatus result = CUBIT_SUCCESS, temp_result; 00577 00578 if( !bridge_list.size() ) 00579 { 00580 return CUBIT_SUCCESS; 00581 } 00582 // GeometryQueryEngine* gqe = NULL; 00583 //we're just going to mess with MBG stuff right now 00584 gqeList.reset(); 00585 00586 int num_ents_before = bridge_list.size(); 00587 temp_result = gqeList.get()->export_solid_model(bridge_list, p_buffer, 00588 n_buffer_size, b_export_buffer); 00589 if (temp_result == CUBIT_SUCCESS ) 00590 result = temp_result; 00591 00592 //if all geometry wasn't exported, warn user and print out 00593 //what wasn't 00594 if( bridge_list.size() != 0 ) 00595 { 00596 if( bridge_list.size() == num_ents_before ) 00597 PRINT_ERROR("No geometry exported. Must set geometry engine to another type.\n"); 00598 else 00599 PRINT_WARNING("Not all geometry could be handled for save.\n"); 00600 00601 PRINT_INFO("Set the geometry engine appropriately to export the following geometry:\n"); 00602 int k; 00603 for(k=bridge_list.size(); k--; ) 00604 { 00605 TopologyEntity *te = bridge_list.get()->topology_entity(); 00606 if( te ) 00607 { 00608 RefEntity *ref_ent = CAST_TO( te, RefEntity ); 00609 if( ref_ent ) 00610 { 00611 GeometryQueryEngine *gqe = bridge_list.get()->get_geometry_query_engine(); 00612 PRINT_INFO("%s is of Geometry Engine type %s\n", 00613 ref_ent->entity_name().c_str(), gqe->modeler_type() ); 00614 } 00615 } 00616 bridge_list.step(); 00617 } 00618 } 00619 00620 // clean off attributes off of underyling virtual geometry 00621 for (itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 00622 (*itor)->remove_attributes(copy_of_bridge_list); 00623 00624 CubitAttribUser::clear_all_simple_attrib(child_list); 00625 00626 //num_ents_exported = num_input_entities - bridge_list.size(); 00627 gqeList.reset(); 00628 return result; 00629 } 00630 00631 //------------------------------------------------------------------------- 00632 // Purpose : Fire a ray at a list of entities and return the 00633 // parameters along the ray (distance from origin of ray) 00634 // where it hits the entities; optionally find the 00635 // corresponding entities it hit. 00636 // 00637 // Special Notes : 00638 // 00639 // Creator : Steve Storm 00640 // 00641 // Creation Date : 3/29/2007 00642 //------------------------------------------------------------------------- 00643 CubitStatus GeometryQueryTool::fire_ray( CubitVector &origin, 00644 CubitVector &direction, 00645 DLIList<RefEntity*> &at_entity_list, 00646 DLIList<double> &ray_params, 00647 int max_hits, 00648 double ray_radius, 00649 DLIList<RefEntity*> *hit_entity_list_ptr ) 00650 { 00651 int i; 00652 00653 // Do this in a way to account for the case if they happen to be from 00654 // different geometry engines (could easily occur with virtual geometry) 00655 00656 DLIList<TopologyEntity*> te_fire_at_list; 00657 DLIList<TopologyEntity*> te_hit_entity_list; 00658 DLIList<TopologyEntity*> *te_hit_entity_list_ptr = 0; 00659 if( hit_entity_list_ptr ) 00660 te_hit_entity_list_ptr = &te_hit_entity_list; 00661 00662 GeometryQueryEngine *gqe = 0; 00663 GeometryQueryEngine *gqe_last = 0; 00664 RefEntity *ref_entity_ptr; 00665 TopologyEntity *topo_ptr; 00666 00667 int loc_max_hits = max_hits; 00668 CubitBoolean hits_limited = CUBIT_FALSE; 00669 if( max_hits > 0 ) 00670 hits_limited = CUBIT_TRUE; 00671 00672 // Note we care about order 00673 at_entity_list.reset(); 00674 for( i=at_entity_list.size(); i--; ) 00675 { 00676 ref_entity_ptr = at_entity_list.get_and_step(); 00677 00678 topo_ptr = CAST_TO( ref_entity_ptr, TopologyEntity ); 00679 if( !topo_ptr ) 00680 { 00681 PRINT_ERROR( "Couldnt get topo_ptr\n" ); 00682 continue; 00683 } 00684 00685 gqe = topo_ptr->get_geometry_query_engine(); 00686 if( !gqe ) 00687 { 00688 PRINT_ERROR( "Unable to find geometry engine associated with an entity!\n" ); 00689 return CUBIT_FAILURE; 00690 } 00691 00692 if( !gqe_last ) 00693 { 00694 gqe_last = gqe; 00695 } 00696 if( gqe != gqe_last ) 00697 { 00698 if( hits_limited == CUBIT_TRUE ) 00699 { 00700 loc_max_hits = max_hits - ray_params.size(); 00701 if( loc_max_hits <= 0 ) 00702 break; 00703 } 00704 00705 if( fire_ray( origin, direction, te_fire_at_list, ray_params, 00706 loc_max_hits, ray_radius, te_hit_entity_list_ptr ) == CUBIT_FAILURE ) 00707 return CUBIT_FAILURE; 00708 00709 // Reset 00710 gqe_last = gqe; 00711 te_fire_at_list.clean_out(); 00712 } 00713 00714 te_fire_at_list.append( topo_ptr ); 00715 } 00716 00717 // Do the last ray fire, if necessary 00718 if( hits_limited == CUBIT_TRUE ) 00719 loc_max_hits = max_hits - ray_params.size(); 00720 if( hits_limited==CUBIT_FALSE || loc_max_hits>0 ) 00721 if( fire_ray( origin, direction, te_fire_at_list, ray_params, 00722 loc_max_hits, ray_radius, te_hit_entity_list_ptr ) == CUBIT_FAILURE ) 00723 return CUBIT_FAILURE; 00724 00725 if( hit_entity_list_ptr ) 00726 { 00727 // Find RefEntities from TopologyEntities 00728 te_hit_entity_list.reset(); 00729 for( i=te_hit_entity_list.size(); i--; ) 00730 { 00731 topo_ptr = te_hit_entity_list.get_and_step(); 00732 if( !topo_ptr ) 00733 { 00734 hit_entity_list_ptr->append( 0 ); 00735 continue; 00736 } 00737 00738 ref_entity_ptr = CAST_TO( topo_ptr, RefEntity ); 00739 hit_entity_list_ptr->append( ref_entity_ptr ); 00740 } 00741 } 00742 00743 // Now, make sure we don't have more hits than asked for 00744 if( hits_limited == CUBIT_TRUE ) 00745 { 00746 if( ray_params.size() <= max_hits ) 00747 return CUBIT_SUCCESS; 00748 00749 for( i=ray_params.size()-max_hits; i--; ) 00750 { 00751 ray_params.last(); 00752 ray_params.remove(); 00753 if( hit_entity_list_ptr ) 00754 { 00755 hit_entity_list_ptr->last(); 00756 hit_entity_list_ptr->remove(); 00757 } 00758 } 00759 } 00760 00761 return CUBIT_SUCCESS; 00762 } 00763 00764 //------------------------------------------------------------------------- 00765 // Purpose : Fire a ray at a list of entities and return the 00766 // parameters along the ray (distance from origin of ray) 00767 // where it hits the entities; optionally find the 00768 // corresponding entities it hit. 00769 // 00770 // Special Notes : All entities must be from the same geometry engine. 00771 // 00772 // Creator : Steve Storm 00773 // 00774 // Creation Date : 5/19/2007 00775 //------------------------------------------------------------------------- 00776 CubitStatus GeometryQueryTool::fire_ray( CubitVector &origin, 00777 CubitVector &direction, 00778 DLIList<TopologyEntity*> &at_entity_list, 00779 DLIList<double> &ray_params, 00780 int max_hits, 00781 double ray_radius, 00782 DLIList<TopologyEntity*> *hit_entity_list_ptr ) 00783 { 00784 if( !at_entity_list.size() ) 00785 return CUBIT_SUCCESS; 00786 00787 00788 TopologyEntity *topo_ptr = at_entity_list.get(); 00789 00790 GeometryQueryEngine *gqe = topo_ptr->get_geometry_query_engine(); 00791 if( !gqe ) 00792 { 00793 PRINT_ERROR( "Unable to find geometry engine associated with an entity!\n" ); 00794 return CUBIT_FAILURE; 00795 } 00796 00797 00798 DLIList<TopologyBridge*> tb_list; 00799 int i; 00800 at_entity_list.reset(); 00801 for( i=at_entity_list.size(); i--; ) 00802 { 00803 topo_ptr = at_entity_list.get_and_step(); 00804 DLIList<TopologyBridge*> bridge_list; 00805 topo_ptr->bridge_manager()->get_bridge_list( bridge_list ); 00806 bridge_list.reset(); 00807 tb_list.append( bridge_list.get() ); 00808 } 00809 00810 // Setup temporary variables to pass 00811 DLIList<double> tmp_ray_params; 00812 00813 DLIList<TopologyBridge*> tb_hit_list; 00814 DLIList<TopologyBridge*> *tb_hit_list_ptr = NULL; 00815 if( hit_entity_list_ptr ) 00816 tb_hit_list_ptr = &tb_hit_list; 00817 00818 // Do the ray fire. Note we will sort the hits by distance and append to the output lists. 00819 if( gqe->fire_ray( origin, direction, tb_list, tmp_ray_params, 00820 max_hits, ray_radius, tb_hit_list_ptr ) == CUBIT_FAILURE ) 00821 return CUBIT_FAILURE; 00822 00823 tmp_ray_params.reset(); 00824 if( tb_hit_list_ptr) tb_hit_list_ptr->reset(); 00825 00826 // Append to output lists 00827 ray_params += tmp_ray_params; 00828 00829 // Get the TE's from the TopologyBridges 00830 if( hit_entity_list_ptr ) 00831 { 00832 // First need to make sure that the entities hit are visible...entities hit 00833 // may be hidden under virtual entities....we need to get the visible 00834 // entities. 00835 DLIList<TopologyBridge*> vis_tb_hit_list; 00836 DLIList<CubitVector*> cv_list; 00837 00838 CubitVector *loc_ptr; 00839 double param; 00840 tmp_ray_params.reset(); 00841 for( i=tmp_ray_params.size(); i--; ) 00842 { 00843 param = tmp_ray_params.get_and_step(); 00844 00845 loc_ptr = new CubitVector; 00846 origin.next_point( direction, param, *loc_ptr ); 00847 cv_list.append( loc_ptr ); 00848 } 00849 00850 00851 TopologyBridge *bridge_ptr; 00852 for( i=0; i<tb_hit_list_ptr->size(); i++ ) 00853 { 00854 bridge_ptr = tb_hit_list_ptr->get_and_step(); 00855 00856 TopologyBridge *visible_tb = NULL; 00857 TBOwner* o2 = bridge_ptr->owner(); 00858 00859 bool broke_early = false; 00860 BridgeManager* bridge_manager2; 00861 while (!(bridge_manager2 = dynamic_cast<BridgeManager*>(o2))) 00862 { 00863 if (TopologyBridge* bridge2 = dynamic_cast<TopologyBridge*>(o2)) 00864 { 00865 GeometryQueryEngine* gqe2 = bridge2->get_geometry_query_engine(); 00866 00867 //Let the VQE handle the work 00868 visible_tb = gqe2->get_visible_entity_at_point(bridge_ptr, cv_list[i]); 00869 if (visible_tb) 00870 o2 = visible_tb->owner(); 00871 else 00872 o2 = bridge2->owner(); 00873 } 00874 00875 else if(TBOwnerSet* set = dynamic_cast<TBOwnerSet*>(o2)) 00876 { 00877 DLIList<TopologyBridge*> list2; 00878 set->get_owners(list2); 00879 list2.reset(); 00880 00881 // This had better be the Virtual QE. 00882 GeometryQueryEngine* gqe2 = list2.get()->get_geometry_query_engine(); 00883 00884 //Let the VQE handle the work 00885 visible_tb = gqe2->get_visible_entity_at_point(bridge_ptr, cv_list[i]); 00886 if (visible_tb) 00887 o2 = visible_tb->owner(); 00888 else 00889 { 00890 broke_early = true; 00891 break; 00892 } 00893 } 00894 else 00895 { 00896 broke_early = true; 00897 break; 00898 } 00899 } 00900 00901 if (!broke_early) 00902 visible_tb = bridge_manager2->topology_bridge(); 00903 00904 00905 if( visible_tb ) 00906 { 00907 topo_ptr = visible_tb->topology_entity(); 00908 hit_entity_list_ptr->append( topo_ptr ); 00909 } 00910 else 00911 hit_entity_list_ptr->append( 0 ); 00912 } 00913 00914 00915 // Free memory 00916 while( cv_list.size() ) delete cv_list.pop(); 00917 } 00918 00919 // Sort ray_params (low to high) and sort hit_entity_list_ptr to match 00920 // This will ensure entities are in order of who got hit first 00921 // Do the sort by adding to a map (should auto-sort) 00922 std::map<double, TopologyEntity*> temp_map; 00923 for (i=0; i<ray_params.size(); i++) 00924 temp_map.insert(std::map<double, 00925 TopologyEntity*>::value_type( ray_params.get_and_step(), 00926 hit_entity_list_ptr ? hit_entity_list_ptr->get_and_step() : 0 ) ); 00927 00928 // The map should be sorted, so iterate through it and add to the official lists 00929 ray_params.clean_out(); 00930 if( hit_entity_list_ptr) hit_entity_list_ptr->clean_out(); 00931 00932 std::map<double, TopologyEntity*>::iterator iter; 00933 for (iter=temp_map.begin(); iter != temp_map.end(); iter++) 00934 { 00935 ray_params.append(iter->first); 00936 if( hit_entity_list_ptr) hit_entity_list_ptr->append(iter->second); 00937 } 00938 00939 return CUBIT_SUCCESS; 00940 } 00941 00942 //------------------------------------------------------------------------- 00943 // Purpose : Reads in geometry and creates the necessary Reference 00944 // entities associated with the input geometry. Has ability 00945 // to read selectively read in either bodies, free surfaces, 00946 // free curves or free vertices from the file. 00947 // 00948 // Valid file types are: 00949 // 00950 // "IGES" -- IGES file 00951 // "STEP" -- STEP file 00952 // "KCM" -- KCM file 00953 // 00954 // Special Notes : 00955 // 00956 // Creator : Steve Storm 00957 // 00958 // Creation Date : 03/17/99 00959 //------------------------------------------------------------------------- 00960 CubitStatus GeometryQueryTool::import_solid_model( const char* file_name, 00961 Model_File_Type file_type, 00962 ModelImportOptions &import_options, 00963 DLIList<RefEntity*> *imported_entities ) 00964 { 00965 if (0 == gqeList.size()) 00966 { 00967 PRINT_WARNING("No active geometry engine.\n"); 00968 return CUBIT_FAILURE; 00969 } 00970 00971 importingSolidModel = CUBIT_TRUE; 00972 uidsOfImportingEnts.clean_out(); 00973 mergeGloballyOnImport = import_options.merge_globally; 00974 00975 if( clearUidMapBeforeImport ) 00976 CAUniqueId::clear_out_old_to_new_map(); 00977 00978 if( GSaveOpen::performingUndo ) 00979 mergeGloballyOnImport = CUBIT_TRUE; 00980 00981 if( CubitUndo::get_undo_enabled() ) 00982 CubitUndo::save_state(); 00983 00984 // reset the attribImporteds flags to facilitate attribute reporting 00985 // CubitAttrib::clear_attrib_importeds(); 00986 00987 // Use the default MQE to import a list of ToplogyBridges from the file. 00988 gqeList.reset(); 00989 DLIList<TopologyBridge*> bridge_list; 00990 00991 import_options.print_results = CUBIT_TRUE; 00992 00993 // We will turn off the printing of name change warnings during import and just 00994 // keep track of how many happened. 00995 bool prev_print_warning_flag = RefEntityName::instance()->print_name_change_warnings(); 00996 RefEntityName::instance()->print_name_change_warnings(false); 00997 RefEntityName::instance()->num_name_change_warnings(0); 00998 00999 CubitStatus status = gqeList.get()->import_solid_model( file_name, 01000 file_type, bridge_list, import_options ); 01001 01002 if( bridge_list.size() == 0 ) 01003 { 01004 importingSolidModel = CUBIT_FALSE; 01005 mergeGloballyOnImport = CUBIT_FALSE; 01006 return status; 01007 } 01008 01009 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 01010 (*itor)->import_geometry(bridge_list); 01011 01012 bridge_list.reset(); 01013 DLIList<RefEntity*> tmp_ent_list; 01014 status = construct_refentities(bridge_list, &tmp_ent_list); 01015 01016 // Print out a summary warning message if names were changed. 01017 RefEntityName::instance()->print_name_change_warnings(prev_print_warning_flag); 01018 if(RefEntityName::instance()->num_name_change_warnings() > 0) 01019 { 01020 PRINT_WARNING("%d invalid names were found during import.\n\n", 01021 RefEntityName::instance()->num_name_change_warnings()); 01022 } 01023 01024 if( imported_entities ) 01025 (*imported_entities) += tmp_ent_list; 01026 01027 if( CubitUndo::get_undo_enabled() ) 01028 { 01029 if( tmp_ent_list.size() && status == CUBIT_SUCCESS ) 01030 CubitUndo::note_result_entities( tmp_ent_list ); 01031 else 01032 CubitUndo::remove_last_undo(); 01033 } 01034 01035 //clear out all attributes that were set to actuate 01036 DLIList<RefEntity*> all_ents; 01037 RefEntity::get_all_child_ref_entities( tmp_ent_list, all_ents ); 01038 all_ents += tmp_ent_list; 01039 CubitAttribUser::clear_all_simple_attrib_set_to_actuate( all_ents ); 01040 01041 // report attribs imported 01042 // CubitAttrib::report_attrib_importeds(); 01043 01044 importingSolidModel = CUBIT_FALSE; 01045 mergeGloballyOnImport = CUBIT_FALSE; 01046 // now return 01047 return status; 01048 } 01049 01050 // import entities to buffer 01051 CubitStatus GeometryQueryTool::import_solid_model(DLIList<RefEntity*> *imported_entities, 01052 const char* pBuffer, 01053 const int n_buffer_size) 01054 { 01055 if (0 == gqeList.size()) 01056 { 01057 PRINT_WARNING("No active geometry engine.\n"); 01058 return CUBIT_FAILURE; 01059 } 01060 01061 if( CubitUndo::get_undo_enabled() ) 01062 CubitUndo::save_state(); 01063 01064 // reset the attribImporteds flags to facilitate attribute reporting 01065 // CubitAttrib::clear_attrib_importeds(); 01066 01067 // Use the default MQE to import a list of ToplogyBridges from the file. 01068 gqeList.reset(); 01069 DLIList<TopologyBridge*> bridge_list; 01070 01071 CubitStatus status = CUBIT_SUCCESS; 01072 for(int i = 0; i < gqeList.size(); i++) 01073 { 01074 status = gqeList.get_and_step()->import_solid_model( bridge_list, pBuffer, n_buffer_size ); 01075 01076 if( bridge_list.size() > 0 ) 01077 break; 01078 } 01079 if(bridge_list.size() == 0) 01080 return status; 01081 01082 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 01083 (*itor)->import_geometry(bridge_list); 01084 01085 bridge_list.reset(); 01086 DLIList<RefEntity*> tmp_ent_list; 01087 status = construct_refentities(bridge_list, &tmp_ent_list); 01088 01089 if( imported_entities ) 01090 (*imported_entities) += tmp_ent_list; 01091 01092 if( CubitUndo::get_undo_enabled() ) 01093 { 01094 if( tmp_ent_list.size() && status == CUBIT_SUCCESS ) 01095 CubitUndo::note_result_entities( tmp_ent_list ); 01096 else 01097 CubitUndo::remove_last_undo(); 01098 } 01099 01100 //clear out all attributes that were set to actuate 01101 // DLIList<RefEntity*> all_ents; 01102 // RefEntity::get_all_child_ref_entities( tmp_ent_list, all_ents ); 01103 // all_ents += tmp_ent_list; 01104 // CubitAttribUser::clear_all_simple_attrib_set_to_actuate( all_ents ); 01105 01106 // report attribs imported 01107 // CubitAttrib::report_attrib_importeds(); 01108 01109 01110 // now return 01111 return status; 01112 } 01113 01114 CubitStatus GeometryQueryTool::construct_refentities(DLIList<TopologyBridge*> &bridge_list, 01115 DLIList<RefEntity*> *imported_entities) 01116 { 01117 01118 // Construct VGI Topology from the TopologyBridges. 01119 DLIList<Body*> body_list; 01120 DLIList<RefFace*> face_list; 01121 DLIList<RefEdge*> edge_list; 01122 DLIList<RefVertex*> vtx_list; 01123 // We are going to pop entities from bridge_list, 01124 // so reverse the list so that the entities get 01125 // created in the old order and the IDs remain 01126 // the same. 01127 bridge_list.reverse(); 01128 bridge_list.reset(); 01129 CubitStatus status = CUBIT_SUCCESS; 01130 01131 bool do_progress = bridge_list.size() > 2 ? true : false; 01132 01133 if(do_progress) 01134 { 01135 char message[128]; 01136 sprintf(message, "Building %d CUBIT Entities", bridge_list.size() ); 01137 AppUtil::instance()->progress_tool()->start(0, bridge_list.size(), "Progress", 01138 message, TRUE, TRUE); 01139 } 01140 01141 01142 while( bridge_list.size() && !AppUtil::instance()->interrupt() ) 01143 { 01144 BodySM* bodysm_ptr; 01145 Surface* surface_ptr; 01146 Curve* curve_ptr; 01147 TBPoint* point_ptr; 01148 TopologyBridge* bridge_ptr = bridge_list.pop(); 01149 if( (bodysm_ptr = dynamic_cast<BodySM*>(bridge_ptr) ) != NULL ) 01150 { 01151 Body* body_ptr = make_Body( bodysm_ptr ); 01152 if( body_ptr ) 01153 { 01154 body_list.append( body_ptr ); 01155 } 01156 else 01157 { 01158 PRINT_ERROR("\nError constructing VGI Body.\n"); 01159 status = CUBIT_FAILURE; 01160 } 01161 } 01162 else if( (surface_ptr = dynamic_cast<Surface*>(bridge_ptr) ) != NULL ) 01163 { 01164 bool is_free_face = true; 01165 RefFace* face_ptr = make_free_RefFace( surface_ptr, is_free_face ); 01166 if( face_ptr ) 01167 { 01168 face_list.append( face_ptr ); 01169 } 01170 else 01171 { 01172 PRINT_ERROR("\nError constructing free VGI Surface.\n"); 01173 status = CUBIT_FAILURE; 01174 } 01175 } 01176 else if( (curve_ptr = dynamic_cast<Curve*>(bridge_ptr) ) != NULL ) 01177 { 01178 RefEdge* edge_ptr = make_free_RefEdge( curve_ptr ); 01179 if( edge_ptr ) 01180 { 01181 edge_list.append( edge_ptr ); 01182 } 01183 else 01184 { 01185 PRINT_ERROR("\nError constructing free VGI Curve.\n"); 01186 status = CUBIT_FAILURE; 01187 } 01188 } 01189 else if( (point_ptr = dynamic_cast<TBPoint*>(bridge_ptr) ) != NULL ) 01190 { 01191 RefVertex* vtx_ptr = make_free_RefVertex( point_ptr ); 01192 if( vtx_ptr ) 01193 { 01194 vtx_list.append( vtx_ptr ); 01195 } 01196 else 01197 { 01198 PRINT_ERROR("\nError constructing free VGI Vertex.\n"); 01199 status = CUBIT_FAILURE; 01200 } 01201 } 01202 else 01203 { 01204 PRINT_ERROR("Unknown entity type imported by solid modeler. Ignored.\n"); 01205 status = CUBIT_FAILURE; 01206 } 01207 if(do_progress) 01208 AppUtil::instance()->progress_tool()->step(); 01209 } 01210 01211 if(do_progress) 01212 AppUtil::instance()->progress_tool()->end(); 01213 01214 PRINT_INFO("\n"); 01215 01216 // If the above loop was interrupted, bridge_list will not be 01217 // empty. Free any bridges we did not make topology for. 01218 if( AppUtil::instance()->interrupt() ) 01219 { 01220 PRINT_WARNING("Aborted construction of %d entities.\n", bridge_list.size()); 01221 } 01222 while( bridge_list.size() ) 01223 { 01224 TopologyBridge* bridge_ptr = bridge_list.pop(); 01225 GeometryQueryEngine* gqe = bridge_ptr->get_geometry_query_engine(); 01226 BodySM* body_ptr; 01227 Surface* surface_ptr; 01228 Curve* curve_ptr; 01229 TBPoint* point_ptr; 01230 if( (body_ptr = dynamic_cast<BodySM*>(bridge_ptr) ) != NULL ) 01231 gqe->delete_solid_model_entities( body_ptr ); 01232 else if( (surface_ptr = dynamic_cast<Surface*>(bridge_ptr) ) != NULL ) 01233 gqe->delete_solid_model_entities( surface_ptr ); 01234 else if( (curve_ptr = dynamic_cast<Curve*>(bridge_ptr) ) != NULL ) 01235 gqe->delete_solid_model_entities( curve_ptr ); 01236 else if( (point_ptr = dynamic_cast<TBPoint*>(bridge_ptr) ) != NULL ) 01237 gqe->delete_solid_model_entities( point_ptr ); 01238 } 01239 01240 /* 01241 // If any geometry was pre-merged during the 01242 // RefEntity construction, adjust the sense of 01243 // the entities to match what it was originally. 01244 DLIList<BasicTopologyEntity*> bte_list; 01245 DLIList<RefFace*> child_face_list; 01246 DLIList<RefEdge*> child_edge_list; 01247 for( int b = body_list.size(); b--; ) 01248 { 01249 body_list.get()->ref_faces( child_face_list ); 01250 CAST_LIST_TO_PARENT( child_face_list, bte_list ); 01251 adjust_merge_sense( bte_list ); 01252 body_list.get()->ref_edges( child_edge_list ); 01253 CAST_LIST_TO_PARENT( child_edge_list, bte_list ); 01254 adjust_merge_sense( bte_list ); 01255 body_list.step(); 01256 } 01257 CAST_LIST_TO_PARENT( face_list, bte_list ); 01258 adjust_merge_sense( bte_list ); 01259 for( int f = face_list.size(); f--; ) 01260 { 01261 face_list.get_and_step()->ref_edges( child_edge_list ); 01262 CAST_LIST_TO_PARENT( child_edge_list, bte_list ); 01263 adjust_merge_sense( bte_list ); 01264 } 01265 CAST_LIST_TO_PARENT( edge_list, bte_list ); 01266 adjust_merge_sense( bte_list ); 01267 */ 01268 01269 // Actuate Attributes 01270 DLIList<RefEntity*> ref_entity_list, temp_ref_list; 01271 01272 CAST_LIST_TO_PARENT( body_list, temp_ref_list ); 01273 ref_entity_list += temp_ref_list; 01274 CAST_LIST_TO_PARENT( face_list, temp_ref_list ); 01275 ref_entity_list += temp_ref_list; 01276 CAST_LIST_TO_PARENT( edge_list, temp_ref_list ); 01277 ref_entity_list += temp_ref_list; 01278 CAST_LIST_TO_PARENT( vtx_list, temp_ref_list ); 01279 ref_entity_list += temp_ref_list; 01280 01281 import_actuate( ref_entity_list ); 01282 01283 // Pass back imported entities 01284 if( imported_entities ) 01285 { 01286 *imported_entities = ref_entity_list; 01287 } 01288 01289 char pre[100]; 01290 if( body_list.size() ) 01291 { 01292 DLIList<RefVolume*> temp_vols; 01293 for( int nv = body_list.size(); nv > 0; nv-- ) 01294 { 01295 DLIList<RefVolume*> t2; 01296 body_list.get_and_step()->ref_volumes( t2 ); 01297 temp_vols += t2; 01298 } 01299 01300 DLIList<CubitEntity*> temp_list; 01301 if( DEBUG_FLAG( 153 ) ) 01302 { 01303 CAST_LIST_TO_PARENT(body_list, temp_list); 01304 if( temp_list.size() == 1 ) 01305 CubitUtil::list_entity_ids( "Constructed 1 Body: ", temp_list); 01306 else 01307 { 01308 sprintf( pre, "Constructed %d Bodies: ", temp_list.size() ); 01309 CubitUtil::list_entity_ids( pre, temp_list ); 01310 } 01311 } 01312 01313 temp_list.clean_out(); 01314 CAST_LIST_TO_PARENT( temp_vols, temp_list ); 01315 if( temp_list.size() == 1 ) 01316 CubitUtil::list_entity_ids( "Constructed 1 Volume: ", temp_list); 01317 else 01318 { 01319 sprintf( pre, "Constructed %d Volumes: ", temp_list.size() ); 01320 CubitUtil::list_entity_ids( pre, temp_list ); 01321 } 01322 } 01323 if( face_list.size() ) 01324 { 01325 DLIList<CubitEntity*> temp_list; 01326 CAST_LIST_TO_PARENT(face_list, temp_list); 01327 if( temp_list.size() == 1 ) 01328 CubitUtil::list_entity_ids( "Constructed 1 Free Surface: ", temp_list ); 01329 else 01330 { 01331 sprintf( pre, "Constructed %d Free Surfaces: ", temp_list.size() ); 01332 CubitUtil::list_entity_ids( pre, temp_list ); 01333 } 01334 } 01335 if( edge_list.size() ) 01336 { 01337 DLIList<CubitEntity*> temp_list; 01338 CAST_LIST_TO_PARENT(edge_list, temp_list); 01339 if( temp_list.size() == 1 ) 01340 CubitUtil::list_entity_ids( "Constructed 1 Free Curve: ", temp_list ); 01341 else 01342 { 01343 sprintf( pre, "Constructed %d Free Curves: ", temp_list.size() ); 01344 CubitUtil::list_entity_ids( pre, temp_list ); 01345 } 01346 } 01347 if( vtx_list.size() ) 01348 { 01349 DLIList<CubitEntity*> temp_list; 01350 CAST_LIST_TO_PARENT(vtx_list, temp_list); 01351 if( temp_list.size() == 1 ) 01352 CubitUtil::list_entity_ids( "Constructed 1 Free Vertex: ", temp_list ); 01353 else 01354 { 01355 sprintf( pre, "Constructed %d Free Vertices: ", temp_list.size() ); 01356 CubitUtil::list_entity_ids( pre, temp_list ); 01357 } 01358 } 01359 01360 return status; 01361 } 01362 01363 //------------------------------------------------------------------------- 01364 // Purpose : Build/update Body topology 01365 // 01366 // Special Notes : 01367 // 01368 // Creator : Jason Kraftcheck 01369 // 01370 // Creation Date : 08/21/02 01371 //------------------------------------------------------------------------- 01372 Body* GeometryQueryTool::make_Body(BodySM *bodysm_ptr) const 01373 { 01374 int i; 01375 CpuTimer timer; 01376 bool body_created = false; 01377 bool body_modified = false; 01378 bool vol_modified = false, tmp_vol_modified; 01379 01380 Body* body = CAST_TO( bodysm_ptr->topology_entity(), Body ); 01381 if( ! body ) 01382 { 01383 body = RefEntityFactory::instance()->construct_Body(bodysm_ptr); 01384 body_created = true; 01385 } 01386 if( ! body ) 01387 { 01388 PRINT_ERROR("Body creation failed in GeometryQueryTool::make_Body\n"); 01389 assert( !!body ); 01390 return 0; 01391 } 01392 01393 DLIList<Lump*> lumps; 01394 bodysm_ptr->lumps( lumps ); 01395 01396 DLIList<SenseEntity*> dead_covols, new_covols(lumps.size()); 01397 lumps.reset(); 01398 for( i = lumps.size(); i--; ) 01399 { 01400 RefVolume* vol = make_RefVolume( lumps.get_and_step(), tmp_vol_modified ); 01401 if( !vol ) 01402 { 01403 PRINT_ERROR("RefVolume creation failed in GeometryQueryTool::make_Body\n"); 01404 PRINT_ERROR("Aborting construction of Body %d\n", body->id() ); 01405 assert( !!vol ); 01406 } 01407 01408 if (tmp_vol_modified) 01409 vol_modified = true; 01410 01411 SenseEntity* covol = vol->find_sense_entity( body ); 01412 if (!covol) 01413 { 01414 covol = new CoVolume( vol ); 01415 body_modified = true; 01416 } 01417 01418 new_covols.append(covol); 01419 } 01420 01421 body->set_sense_entity_list( new_covols, dead_covols ); 01422 01423 while (dead_covols.size()) 01424 { 01425 destroy_dead_entity(dead_covols.pop()); 01426 body_modified = true; 01427 } 01428 01429 PRINT_DEBUG_3("Constructed Body %d from BodySM in %f seconds.\n", 01430 body->id(), timer.cpu_secs() ); 01431 01432 if( body_created ) 01433 { 01434 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, body)); 01435 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, body); 01436 const_cast<CGMHistory&>(mHistory).add_event(evt); 01437 } 01438 else if( body_modified ) 01439 { 01440 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, body)); 01441 CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, body); 01442 const_cast<CGMHistory&>(mHistory).add_event(evt); 01443 } 01444 else if( vol_modified ) 01445 { 01446 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, body)); 01447 CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, body); 01448 const_cast<CGMHistory&>(mHistory).add_event(evt); 01449 } 01450 01451 PRINT_DEBUG_3("Updated graphics for Body %d in %f seconds.\n", 01452 body->id(), timer.cpu_secs() ); 01453 01454 return body; 01455 } 01456 01457 //------------------------------------------------------------------------- 01458 // Purpose : Build/update RefVolume topology 01459 // 01460 // Special Notes : 01461 // 01462 // Creator : Jason Kraftcheck 01463 // 01464 // Creation Date : 08/21/02 01465 //------------------------------------------------------------------------- 01466 RefVolume* GeometryQueryTool::make_RefVolume( Lump* lump_ptr, 01467 bool& volume_modified ) const 01468 { 01469 int i; 01470 01471 DLIList<ShellSM*> shellsms; 01472 DLIList<GroupingEntity*> old_shells, new_shells; 01473 01474 bool volume_created = false; 01475 volume_modified = false; 01476 RefVolume* volume = CAST_TO( lump_ptr->topology_entity(), RefVolume ); 01477 if( ! volume ) 01478 { 01479 volume = RefEntityFactory::instance()->construct_RefVolume(lump_ptr); 01480 volume_created = true; 01481 } 01482 if( ! volume ) 01483 { 01484 PRINT_ERROR("Volume creation failed in GeometryQueryTool::make_RefVolume\n"); 01485 assert( !!volume ); 01486 return 0; 01487 } 01488 01489 lump_ptr->shellsms( shellsms ); 01490 shellsms.reset(); 01491 for( i = shellsms.size(); i--; ) 01492 { 01493 bool shell_modified; 01494 01495 // Don't use a shell if it is in a different RefVolume. 01496 // Can't move shells or other RefVolume may appear unmodified 01497 // in later call to make_RefVolume. 01498 // This breaks things -- live without it for now 01499 // ShellSM* shellsm = shellsms.get_and_step(); 01500 // Shell* shell = dynamic_cast<Shell*>(shellsm->topology_entity()); 01501 // if (shell && shell->get_basic_topology_entity_ptr() && 01502 // shell->get_basic_topology_entity_ptr() != volume) 01503 // shell->bridge_manager()->remove_bridge(shellsm); 01504 01505 // Build/update Shell 01506 Shell* shell = make_Shell( shellsms.get_and_step(), shell_modified ); 01507 01508 if( !shell ) 01509 { 01510 PRINT_ERROR("Shell creation failed in GeometryQueryTool::make_RefVolume\n"); 01511 PRINT_ERROR("Aborting construction of Volume %d\n", volume->id() ); 01512 assert( !!shell ); 01513 return 0; 01514 } 01515 if( shell_modified ) 01516 volume_modified = true; 01517 01518 // If the shell is new (not already part of RefVolume) then 01519 // we will be modifying the RefVolume when we add it later. 01520 BasicTopologyEntity* parent = shell->get_basic_topology_entity_ptr(); 01521 if (parent != volume) 01522 { 01523 if (parent) 01524 parent->remove_grouping_entity(shell); 01525 volume_modified = true; 01526 } 01527 01528 new_shells.append( shell ); 01529 } 01530 01531 volume->set_grouping_entity_list( new_shells, old_shells ); 01532 while( old_shells.size() ) 01533 { 01534 GroupingEntity* shell = old_shells.pop(); 01535 destroy_dead_entity( shell ); 01536 volume_modified = true; 01537 } 01538 01539 if (volume->deactivated()) 01540 volume_modified = false; 01541 else if(!volume_created && volume_modified ) 01542 { 01543 01544 #ifndef ALPHA_LAYTRACKS3D 01545 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, volume)); 01546 CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, volume); 01547 const_cast<CGMHistory&>(mHistory).add_event(evt); 01548 #endif 01549 } 01550 01551 return volume; 01552 } 01553 01554 //------------------------------------------------------------------------- 01555 // Purpose : Build/update Shell topology 01556 // 01557 // Special Notes : 01558 // 01559 // Creator : Jason Kraftcheck 01560 // 01561 // Creation Date : 08/21/02 01562 //------------------------------------------------------------------------- 01563 Shell* GeometryQueryTool::make_Shell(ShellSM *shellsm_ptr, bool& shell_modified ) const 01564 { 01565 Shell* shell = CAST_TO( shellsm_ptr->topology_entity(), Shell ); 01566 shell_modified = false; 01567 if( !shell ) 01568 shell = new Shell(shellsm_ptr); 01569 assert( shell != NULL ); 01570 01571 DLIList<CoFace*> face_cofaces(2); 01572 //shell->co_faces( old_cofaces ); 01573 DLIList<SenseEntity*> new_cofaces, old_cofaces; 01574 01575 DLIList<Surface*> surfaces; 01576 shellsm_ptr->surfaces( surfaces ); 01577 01578 int i; 01579 surfaces.reset(); 01580 for( i = surfaces.size(); i--; ) 01581 { 01582 Surface* surface = surfaces.get_and_step(); 01583 RefFace* face = make_RefFace(surface); 01584 if( !face ) 01585 { 01586 PRINT_ERROR("Surface creation failed in GeometryQueryTool::make_Shell\n"); 01587 assert( !!face ); 01588 return 0; 01589 } 01590 01591 CubitSense sense = surface->get_shell_sense( shellsm_ptr ); 01592 if( surface->bridge_sense() == CUBIT_REVERSED ) 01593 sense = CubitUtil::opposite_sense( sense ); 01594 01595 // If sense is CUBIT_UNKNOWN, we have a two-sided 01596 // face and need to make two CoFaces. 01597 int num_cofaces = 1; 01598 if( sense == CUBIT_UNKNOWN ) 01599 { 01600 DLIList<ShellSM*> surf_shells(2); 01601 surface->shellsms( surf_shells ); 01602 assert( surf_shells.is_in_list(shellsm_ptr) ); 01603 num_cofaces = 2; 01604 sense = CUBIT_FORWARD; 01605 } 01606 01607 // If two CoFaces, loop once for each 01608 face_cofaces.clean_out(); 01609 face->co_faces(face_cofaces); 01610 for( int k = 0; k < num_cofaces; k++ ) 01611 { 01612 01613 CoFace* coface = 0; 01614 for( int j = face_cofaces.size(); j--; ) 01615 { 01616 CoFace* tmp_coface = face_cofaces.get(); 01617 if( tmp_coface->get_sense() == sense && 01618 tmp_coface->get_shell_ptr() == shell ) 01619 { 01620 coface = tmp_coface; 01621 break; 01622 } 01623 } 01624 01625 if (!coface) 01626 { 01627 coface = new CoFace(); 01628 coface->attach_basic_topology_entity( face ); 01629 shell_modified = true; 01630 if( coface->get_sense() != sense ) 01631 coface->set_sense( sense ); 01632 } 01633 01634 new_cofaces.append(coface); 01635 01636 // If we loop to create a second CoFace between 01637 // the same Surface-Shell pair, create it with 01638 // the opposite sense. 01639 sense = CubitUtil::opposite_sense(sense); 01640 } 01641 } 01642 01643 shell->set_sense_entity_list( new_cofaces, old_cofaces ); 01644 01645 // Destroy any unwanted CoFaces (those remaining 01646 // in old_cofaces) 01647 while( old_cofaces.size() ) 01648 { 01649 CoFace* dead_coface = dynamic_cast<CoFace*>(old_cofaces.pop()); 01650 assert(!dead_coface->get_shell_ptr()); 01651 destroy_dead_entity(dead_coface); 01652 shell_modified = true; 01653 } 01654 01655 return shell; 01656 } 01657 01658 01659 //------------------------------------------------------------------------- 01660 // Purpose : Find the CoEdgeSM in the passed Surface that should 01661 // be merged with the passed CoEdgeSM. 01662 // 01663 // Special Notes : Should be O(1) in the average case. See comments below. 01664 // 01665 // Creator : Jason Kraftcheck 01666 // 01667 // Creation Date : 08/21/02 01668 //------------------------------------------------------------------------- 01669 CoEdgeSM* GeometryQueryTool::find_merged_coedgesm( Surface* on_this_surf, 01670 CoEdgeSM* merged_with_this ) const 01671 { 01672 // Get the relative sense of the merged surfaces 01673 DLIList<Surface*> coedge_surfaces(1); 01674 merged_with_this->surfaces( coedge_surfaces ); 01675 if( coedge_surfaces.size() != 1 ) 01676 return 0; 01677 bool surfaces_reversed = 01678 (coedge_surfaces.get()->bridge_sense() != on_this_surf->bridge_sense()); 01679 01680 // Get the Curve merge partner from the CoEdgeSM merge partner 01681 DLIList<Curve*> coedge_curves(1); 01682 merged_with_this->curves( coedge_curves ); 01683 if( coedge_curves.size() != 1 ) 01684 { 01685 assert(coedge_curves.size() == 1); 01686 return 0; 01687 } 01688 Curve* merged_curve = coedge_curves.get(); 01689 01690 // If the curve doesn't have a bridge manager, it is 01691 // not merged. 01692 if (!merged_curve->bridge_manager()) 01693 return 0; 01694 01695 // Get all curves merged with the merged_curve 01696 int num_bridges = merged_curve->bridge_manager()->number_of_bridges(); 01697 DLIList<TopologyBridge*> curve_bridges( num_bridges ); 01698 merged_curve->bridge_manager()->get_bridge_list( curve_bridges ); 01699 01700 // Loop through Curves, looking for the Curve with the 01701 // parent CoEdgeSM we want. This loop should be 01702 // roughly O(1) for manifold geometry (and most non- 01703 // manifold geometry), where n is the number of curves 01704 // merged together in the RefEdge. For manifold 01705 // geometry, there are never more than 2 CoEdgeSMs per 01706 // Curve. For most models, n is <= 4, so this entire 01707 // function can be considered O(1) for most models. 01708 DLIList<CoEdgeSM*> curve_coedges(2); 01709 curve_bridges.reset(); 01710 for( int i = curve_bridges.size(); i--; ) 01711 { 01712 TopologyBridge* curve = curve_bridges.get_and_step(); 01713 01714 curve_coedges.clean_out(); 01715 curve->coedgesms( curve_coedges ); 01716 curve_coedges.reset(); 01717 for( int j = curve_coedges.size(); j--; ) 01718 { 01719 CoEdgeSM* coedgesm = curve_coedges.get_and_step(); 01720 01721 // Get parent Surface of CoEdgeSM 01722 coedge_surfaces.clean_out(); 01723 coedgesm->surfaces( coedge_surfaces ); 01724 assert( coedge_surfaces.size() == 1 ); 01725 01726 // Is the parent Surface the one we are looking for? 01727 if( coedge_surfaces.get() == on_this_surf ) 01728 { 01729 // Curve may occur in surface twice for non-manifold 01730 // topology. We need to make sure we have the CoEdgeSM 01731 // with the correct sense. 01732 01733 // Are the curves reversed wrt to each other? 01734 bool curves_reversed = 01735 (merged_curve->bridge_sense() != curve->bridge_sense()); 01736 // Should this coedgesm be reversed wrt to the merge partner? 01737 bool should_be_reversed = (curves_reversed != surfaces_reversed); 01738 // Are the coedgesm actually reversed wrt to each other? 01739 bool are_reversed = (merged_with_this->sense() != coedgesm->sense()); 01740 01741 // Do the coedges have the appropriate senses 01742 if( should_be_reversed == are_reversed ) 01743 { 01744 return coedgesm; 01745 } 01746 } 01747 } // for(j = curve_coedgesms) 01748 } // for(i = curve_coedges) 01749 01750 return 0; 01751 } 01752 01753 //------------------------------------------------------------------------- 01754 // Purpose : Build/update RefFace topology 01755 // 01756 // Special Notes : 01757 // 01758 // Creator : Jason Kraftcheck 01759 // 01760 // Creation Date : 08/21/02 01761 //------------------------------------------------------------------------- 01762 RefFace* GeometryQueryTool::make_RefFace( Surface* surface_ptr ) const 01763 { 01764 int i; 01765 DLIList<LoopSM*> loopsms; 01766 DLIList<CoEdgeSM*> coedgesms; 01767 DLIList<Curve*> curves(1); 01768 01769 // Get/construct RefFace for surface. 01770 bool face_created = false; 01771 bool face_modified = false; 01772 bool face_modified2 = false; 01773 RefFace* face = CAST_TO( surface_ptr->topology_entity(), RefFace ); 01774 if( !face ) 01775 { 01776 face = dynamic_cast<RefFace*>(check_mergeable_refentity(surface_ptr)); 01777 01778 //Including this call in here in case the surface a composite and 01779 //hidden curves need to be removed in the graphics. 01780 if( face ) 01781 { 01782 face_modified2 = true; 01783 } 01784 } 01785 if( !face ) 01786 { 01787 face = RefEntityFactory::instance()->construct_RefFace(surface_ptr); 01788 face_created = true; 01789 } 01790 assert(!!face); 01791 bool merged = face->bridge_manager()->number_of_bridges() > 1; 01792 01793 // First construct all the RefEdges. If the Curves 01794 // were merged, the RefEdges will be constructed merged. 01795 // We need the merged RefEdges to determined which 01796 // CoEdges and Loops need to be merged. We could do this 01797 // with one loop by getting the curves directly from the 01798 // surface. However, that might result in different 01799 // RefEdge IDs, so do it with nested loops like the old code. 01800 loopsms.clean_out(); 01801 surface_ptr->loopsms( loopsms ); 01802 loopsms.reset(); 01803 for( i = loopsms.size(); i--; ) 01804 { 01805 LoopSM* loopsm = loopsms.get_and_step(); 01806 coedgesms.clean_out(); 01807 loopsm->coedgesms(coedgesms); 01808 coedgesms.reset(); 01809 for( int j = coedgesms.size(); j--; ) 01810 { 01811 CoEdgeSM* coedgesm = coedgesms.get_and_step(); 01812 curves.clean_out(); 01813 coedgesm->curves(curves); 01814 if( curves.size() != 1 ) 01815 { 01816 PRINT_ERROR("Invalid SolidModel topology encountered in " 01817 "GeometryQueryTool::make_RefFace. CoEdgeSM in " 01818 "Surface %d has %d curves.\n", face->id(), curves.size()); 01819 if( curves.size() == 0 ) 01820 continue; 01821 } 01822 01823 RefEdge* edge = make_RefEdge( curves.get() ); 01824 if( !edge ) 01825 { 01826 PRINT_ERROR("Failed to construct RefEdge in Surface %d\n",face->id()); 01827 } 01828 } 01829 } 01830 01831 // If the Surface was merged, make sure it can remain merged 01832 if (merged && !make_merged_RefFace(surface_ptr)) 01833 merged = false; 01834 01835 // If !merged, then if necessary unmerge the RefFace 01836 if( !merged && face->bridge_manager()->number_of_bridges() > 1 ) 01837 { 01838 PRINT_WARNING("Unmerging Surface %d.\n", face->id() ); 01839 01840 // unmerge 01841 face->bridge_manager()->remove_bridge(surface_ptr); 01842 01843 // reset bridge sense on unmerged surface 01844 if (surface_ptr->bridge_sense() == CUBIT_REVERSED) 01845 surface_ptr->reverse_bridge_sense(); 01846 01847 // if the first bridge in the old refface is now reversed, 01848 // flip the refface. 01849 if (face->get_surface_ptr()->bridge_sense() == CUBIT_REVERSED) 01850 { 01851 face->bridge_manager()->reverse_bridge_senses(); 01852 face->reverse_topology(); 01853 } 01854 01855 // construct new refface for unmerged surface. 01856 face = RefEntityFactory::instance()->construct_RefFace(surface_ptr); 01857 face_created = true; 01858 } 01859 01860 // If the sense of the Surface with respect to the RefFace is 01861 // reversed, need to construct Loops and CoEdges reversed. 01862 bool need_to_reverse = (surface_ptr->bridge_sense() == CUBIT_REVERSED); 01863 01864 // Construct LoopSMs and CoEdgeSMs, and attach 01865 loopsms.clean_out(); 01866 surface_ptr->loopsms( loopsms ); 01867 loopsms.reset(); 01868 DLIList<SenseEntity*> coedges, old_coedges; 01869 DLIList<GroupingEntity*> loops(loopsms.size()), dead_loops; 01870 for( i = loopsms.size(); i--; ) 01871 { 01872 // Get/construct Loop 01873 LoopSM* loopsm = loopsms.get_and_step(); 01874 Loop* loop = dynamic_cast<Loop*>(loopsm->topology_entity()); 01875 if( loop && !merged && loop->bridge_manager()->number_of_bridges() > 1 ) 01876 { 01877 loop->bridge_manager()->remove_bridge( loopsm ); 01878 loop = new Loop( loopsm ); 01879 face_modified = true; 01880 } 01881 else if( !loop ) 01882 { 01883 loop = new Loop( loopsm ); 01884 face_modified = true; 01885 } 01886 01887 // If loop is already attached to some other RefFace 01888 // we cannot use it. NOTE: Removing the Loop from 01889 // the other RefFace is NOT an option, even if the 01890 // loop has only our loopsm. If we were to remove it 01891 // we could potentially miss the fact that the other 01892 // RefFace was modified when doing make_RefFace for 01893 // RefFace. 01894 RefFace* loop_face = loop->get_ref_face_ptr(); 01895 if( loop_face && loop_face != face ) 01896 { 01897 loop->bridge_manager()->remove_bridge( loopsm ); 01898 loop = new Loop( loopsm ); 01899 face_modified = true; 01900 } 01901 loops.append(loop); 01902 01903 // Get CoEdges in the appropriate order 01904 coedgesms.clean_out(); 01905 loopsm->coedgesms( coedgesms ); 01906 if( coedgesms.size() == 0 ) 01907 { 01908 PRINT_ERROR("Encountered Loop with no CoEdges in Surface %d.\n", 01909 face->id() ); 01910 continue; 01911 } 01912 if( need_to_reverse ) 01913 coedgesms.reverse(); 01914 coedgesms.reset(); 01915 01916 // Consturct/update each CoEdge 01917 int j; 01918 coedges.clean_out(); 01919 for( j = coedgesms.size(); j--; ) 01920 { 01921 CoEdgeSM* coedgesm = coedgesms.get_and_step(); 01922 CoEdge* coedge = dynamic_cast<CoEdge*>(coedgesm->topology_entity()); 01923 01924 // If the CoEdge is merged but the surface isn't, unmerge 01925 // the CoEdge 01926 if( coedge && !merged && coedge->bridge_manager()->number_of_bridges() > 1 ) 01927 { 01928 coedge->bridge_manager()->remove_bridge( coedgesm ); 01929 coedge = 0; 01930 } 01931 01932 // If CoEdge belongs to a loop in some other face, don't 01933 // use it. 01934 if( coedge && coedge->get_loop_ptr() && coedge->get_loop_ptr() != loop ) 01935 { 01936 coedge->bridge_manager()->remove_bridge( coedgesm ); 01937 coedge = 0; 01938 } 01939 01940 // If the CoEdgeSM doesn't already have an owning CoEdge 01941 // (or we unmerged) create a new CoEdge 01942 if( !coedge ) 01943 { 01944 coedge = new CoEdge(); 01945 coedge->bridge_manager()->add_bridge( coedgesm ); 01946 face_modified = true; 01947 } 01948 coedges.append( coedge ); 01949 01950 // Find the RefEdge to attach to 01951 curves.clean_out(); 01952 coedgesm->curves( curves ); 01953 if( curves.size() == 0 ) 01954 continue; // error message should have been printed already 01955 01956 Curve* curve = curves.get(); 01957 RefEdge* edge = dynamic_cast<RefEdge*>(curve->topology_entity()); 01958 assert( edge != NULL ); 01959 01960 // Figure out what the CoEdge sense should be. 01961 // The CoEdge sense should be the product ("product" 01962 // as in multiply) of three 01963 // senses: 1) the sense of the surface wrt its RefFace, 01964 // 2) the sense of the curve wrt its RefEdge, and 3) 01965 // the sense of the CoEdgeSM. 01966 bool curve_reversed = (CUBIT_REVERSED == curve->bridge_sense()); 01967 bool reverse = (curve_reversed != need_to_reverse); 01968 CubitSense sense = coedgesm->sense(); 01969 if( reverse ) 01970 sense = CubitUtil::opposite_sense(sense); 01971 if( coedge->get_sense() != sense ) 01972 coedge->set_sense( sense ); 01973 01974 // Attach RefEdge to CoEdge (if it isn't already) 01975 RefEdge* coedge_edge = coedge->get_ref_edge_ptr(); 01976 if (coedge_edge != edge) 01977 { 01978 if (coedge_edge) 01979 { 01980 coedge_edge->remove_sense_entity(coedge); 01981 destroy_dead_entity(coedge_edge); 01982 face_modified = true; 01983 } 01984 coedge->attach_basic_topology_entity(edge); 01985 } 01986 } 01987 01988 // Attach CoEdges to Loop 01989 old_coedges.clean_out(); 01990 loop->set_sense_entity_list(coedges, old_coedges); 01991 01992 // Clean up dead coedges 01993 while (old_coedges.size()) 01994 { 01995 CoEdge* dead_coedge = dynamic_cast<CoEdge*>(old_coedges.pop()); 01996 assert(!dead_coedge->get_loop_ptr()); 01997 destroy_dead_entity(dead_coedge); 01998 face_modified = true; 01999 } 02000 } // end for( i == loopsms ) 02001 02002 // Attach loops 02003 face->set_grouping_entity_list( loops, dead_loops ); 02004 02005 // Remove any dead loops 02006 while (dead_loops.size()) 02007 { 02008 GroupingEntity* loop = dead_loops.pop(); 02009 destroy_dead_entity(loop); 02010 face_modified = true; 02011 } 02012 02013 if( !face_created && face_modified && !face->deactivated() ) 02014 { 02015 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_TOPOLOGY_MODIFIED, face)); 02016 CGMHistory::Event evt2(CGMHistory::TOPOLOGY_CHANGED, face); 02017 const_cast<CGMHistory&>(mHistory).add_event(evt2); 02018 CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, face); 02019 const_cast<CGMHistory&>(mHistory).add_event(evt); 02020 } 02021 else if(face_modified2) 02022 { 02023 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, face)); 02024 CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, face); 02025 const_cast<CGMHistory&>(mHistory).add_event(evt); 02026 } 02027 02028 return face; 02029 } 02030 02031 02032 //------------------------------------------------------------------------- 02033 // Purpose : Check if Surface can remain merged. 02034 // 02035 // Special Notes : 02036 // 02037 // Creator : Jason Kraftcheck 02038 // 02039 // Creation Date : 12/12/03 02040 //------------------------------------------------------------------------- 02041 CubitStatus GeometryQueryTool::make_merged_RefFace(Surface* surface_ptr) const 02042 { 02043 // Get the RefFace 02044 RefFace* face = dynamic_cast<RefFace*>(surface_ptr->topology_entity()); 02045 if (!face) // isn't merged 02046 return CUBIT_FAILURE; 02047 02048 // Get a Surface to compare to. 02049 int num_bridges = face->bridge_manager()->number_of_bridges(); 02050 if (num_bridges < 2) // isn't merged 02051 return CUBIT_FAILURE; 02052 02053 // Get some other Surface in merged RefFace to compare 02054 // topology with. 02055 DLIList<TopologyBridge*> bridge_list(num_bridges); 02056 face->bridge_manager()->get_bridge_list(bridge_list); 02057 bridge_list.reset(); 02058 if (bridge_list.get() == surface_ptr) 02059 bridge_list.step(); 02060 TopologyBridge* merged_bridge = bridge_list.get(); 02061 Surface* merged_surface = dynamic_cast<Surface*>(merged_bridge); 02062 assert(merged_surface && merged_surface != surface_ptr); 02063 02064 // Get the relative sense of the Surfaces 02065 bool surfaces_reversed = 02066 (surface_ptr->bridge_sense() != merged_surface->bridge_sense()); 02067 02068 // Get LoopSMs for both surfaces 02069 DLIList<LoopSM*> merged_loops, loopsms; 02070 surface_ptr->loopsms(loopsms); 02071 merged_surface->loopsms(merged_loops); 02072 if( merged_loops.size() != loopsms.size() ) 02073 return CUBIT_FAILURE; 02074 02075 // For each LoopSM on the merged Surface, find the 02076 // corresponding LoopSM on this Surface and merge. 02077 DLIList<CoEdgeSM*> merged_coedges, coedgesms; 02078 DLIList<LoopSM*> coedge_loops(1); 02079 DLIList<Curve*> curves(1); 02080 merged_loops.reset(); 02081 for( int i = merged_loops.size(); i--; ) 02082 { 02083 LoopSM* merged_loop = merged_loops.get_and_step(); 02084 02085 // Find the LoopSM by choosing a CoEdgeSM from the 02086 // merged LoopSM, and finding corresponding CoEdgeSM 02087 // on the Surface we are building. 02088 02089 merged_coedges.clean_out(); 02090 merged_loop->coedgesms( merged_coedges ); 02091 merged_coedges.reset(); 02092 CoEdgeSM* merged_coedge = merged_coedges.get(); 02093 02094 CoEdgeSM* coedgesm = find_merged_coedgesm( surface_ptr, merged_coedge ); 02095 if( !coedgesm ) 02096 return CUBIT_FAILURE; 02097 02098 // Get the LoopSM in surface_ptr from the CoEdgeSM 02099 coedge_loops.clean_out(); 02100 coedgesm->loopsms( coedge_loops ); 02101 assert( coedge_loops.size() == 1 ); 02102 LoopSM* loopsm = coedge_loops.get(); 02103 02104 // Get all the CoEdgeSMs on the LoopSM we are going to merge. 02105 coedgesms.clean_out(); 02106 loopsm->coedgesms( coedgesms ); 02107 if( coedgesms.size() != merged_coedges.size() ) 02108 return CUBIT_FAILURE; 02109 02110 // Get the CoEdge list in the appropriate order and position 02111 if( surfaces_reversed ) 02112 coedgesms.reverse(); 02113 coedgesms.move_to(coedgesm); 02114 assert( coedgesms.get() == coedgesm ); 02115 02116 // Now check and merge CoEdgeSM pairs 02117 for( int j = coedgesms.size(); j--; ) 02118 { 02119 coedgesm = coedgesms.get_and_step(); 02120 merged_coedge = merged_coedges.get_and_step(); 02121 02122 // Get Curve in surface_ptr 02123 curves.clean_out(); 02124 coedgesm->curves(curves); 02125 if( curves.size() != 1 ) 02126 { 02127 PRINT_ERROR("Invalid SolidModel topology encountered in " 02128 "GeometryQueryTool::make_RefFace. CoEdgeSM in " 02129 "has %d curves.\n", curves.size()); 02130 return CUBIT_FAILURE; 02131 } 02132 Curve* curve = curves.get(); 02133 02134 // Get Curve in merged_surface 02135 curves.clean_out(); 02136 merged_coedge->curves(curves); 02137 if( curves.size() != 1 ) 02138 { 02139 PRINT_ERROR("Invalid SolidModel topology encountered in " 02140 "GeometryQueryTool::make_RefFace. CoEdgeSM in " 02141 "has %d curves.\n", curves.size()); 02142 return CUBIT_FAILURE; 02143 } 02144 Curve* merged_curve = curves.get_and_step(); 02145 02146 // Check if curves are merged 02147 if( merged_curve->bridge_manager() != curve->bridge_manager() ) 02148 return CUBIT_FAILURE; 02149 02150 // Check that relative sense of CoEdgeSMs is correct 02151 bool curves_reversed = 02152 (merged_curve->bridge_sense() != curve->bridge_sense()); 02153 // Should this coedgesm be reversed wrt to the merge partner? 02154 bool should_be_reversed = (curves_reversed != surfaces_reversed); 02155 // Are the coedgesm actually reversed wrt to each other? 02156 bool are_reversed = (merged_coedge->sense() != coedgesm->sense()); 02157 if( should_be_reversed != are_reversed ) 02158 return CUBIT_FAILURE; 02159 02160 // Merge the CoEdgeSMs 02161 CoEdge* coedge = dynamic_cast<CoEdge*>(coedgesm->topology_entity()); 02162 CoEdge* merge = dynamic_cast<CoEdge*>(merged_coedge->topology_entity()); 02163 02164 // If this coedgesm is not the primary coedgesm in the 02165 // CoEdge, check to make sure the primary CoEdgeSM's curve 02166 // is merged with our curve. 02167 if (coedge && coedge->bridge_manager()->number_of_bridges() > 1 02168 && coedge->bridge_manager()->topology_bridge() != coedgesm 02169 && coedge->bridge_manager()->topology_bridge() != merged_coedge ) 02170 { 02171 curves.clean_out(); 02172 coedge->bridge_manager()->topology_bridge()->curves(curves); 02173 assert(curves.size() == 1); 02174 if (curves.get()->owner() != curve->owner()) 02175 { 02176 coedge->bridge_manager()->remove_bridge(coedgesm); 02177 assert(coedge->get_parents()); 02178 coedge = 0; 02179 } 02180 } 02181 if (merge && merge->bridge_manager()->number_of_bridges() > 1 02182 && merge->bridge_manager()->topology_bridge() != coedgesm 02183 && merge->bridge_manager()->topology_bridge() != merged_coedge ) 02184 { 02185 curves.clean_out(); 02186 merge->bridge_manager()->topology_bridge()->curves(curves); 02187 assert(curves.size() == 1); 02188 if (curves.get()->owner() != curve->owner()) 02189 { 02190 merge->bridge_manager()->remove_bridge(merged_coedge); 02191 assert(merge->get_parents()); 02192 merge = 0; 02193 } 02194 } 02195 02196 // If the two CoEdgeSM's aren't in the same CoEdge, 02197 // merge them. 02198 if (merge && merge != coedge) 02199 { 02200 if (coedge) 02201 { 02202 coedge->bridge_manager()->remove_bridge(coedgesm); 02203 destroy_dead_entity(coedge); 02204 } 02205 merge->bridge_manager()->add_bridge(coedgesm); 02206 } 02207 // If for some reason (Composite curve creatation does 02208 // this) neither CoEdgeSM has a CoEdge, create one and 02209 // re-merge them. 02210 else if (!coedge && !merge) 02211 { 02212 coedge = new CoEdge(coedgesm); 02213 coedge->bridge_manager()->add_bridge(merged_coedge); 02214 } 02215 else if(!coedge) 02216 { 02217 merge->bridge_manager()->add_bridge(coedgesm); 02218 } 02219 else if(!merge) 02220 { 02221 coedge->bridge_manager()->add_bridge(merged_coedge); 02222 } 02223 } // for( j = coedgesms ) 02224 02225 02226 Loop* loop = dynamic_cast<Loop*>(loopsm->topology_entity()); 02227 Loop* merged = dynamic_cast<Loop*>(merged_loop->topology_entity()); 02228 // If the two LoopSMs aren't in the same Loop, merge them 02229 if( merged != 0 && merged != loop ) 02230 { 02231 if( loop ) 02232 loop->bridge_manager()->remove_bridge(loopsm); 02233 merged->bridge_manager()->add_bridge(loopsm); 02234 } 02235 else if( !loop && !merged ) 02236 { 02237 loop = new Loop; 02238 loop->bridge_manager()->add_bridge(merged_loop); 02239 } 02240 else if( !loop ) 02241 { 02242 merged->bridge_manager()->add_bridge(loopsm); 02243 } 02244 else if( !merged ) 02245 { 02246 loop->bridge_manager()->add_bridge(merged_loop); 02247 } 02248 } // for( i = merged_loops ) 02249 02250 return CUBIT_SUCCESS; 02251 } 02252 02253 //------------------------------------------------------------------------- 02254 // Purpose : Get/construct/update a RefEdge from a Curve 02255 // 02256 // Special Notes : 02257 // 02258 // Creator : Jason Kraftcheck 02259 // 02260 // Creation Date : 08/22/02 02261 //------------------------------------------------------------------------- 02262 RefEdge* GeometryQueryTool::make_RefEdge( Curve* curve_ptr ) const 02263 { 02264 int i; 02265 02266 // Get/construct RefEdge 02267 bool edge_created = false; 02268 bool edge_modified = false; 02269 RefEdge* edge = dynamic_cast<RefEdge*>(curve_ptr->topology_entity()); 02270 if( !edge ) 02271 edge = dynamic_cast<RefEdge*>(check_mergeable_refentity(curve_ptr)); 02272 if( !edge ) 02273 { 02274 edge = RefEntityFactory::instance()->construct_RefEdge(curve_ptr); 02275 edge_created = true; 02276 } 02277 assert(edge != NULL); 02278 bool reversed = (CUBIT_REVERSED == curve_ptr->bridge_sense()); 02279 bool merged = edge->bridge_manager()->number_of_bridges() > 1; 02280 02281 // Construct RefVertices 02282 DLIList<TBPoint*> points(2); 02283 curve_ptr->points( points ); 02284 if( reversed ) 02285 points.reverse(); 02286 02287 if( points.size() > 2 || points.size() < 1 ) 02288 { 02289 PRINT_ERROR("Invalid SolidModel topology encountered in " 02290 "GeometryQueryTool::make_RefEdge. Curve %d " 02291 "has %d vertices.\n", edge->id(), points.size() ); 02292 assert( points.size() == 1 || points.size() == 2 ); 02293 if( points.size() == 0 ) 02294 return edge; 02295 } 02296 02297 points.reset(); 02298 RefVertex* start_vertex = make_RefVertex( points.get() ); 02299 points.last(); 02300 RefVertex* end_vertex = make_RefVertex( points.get() ); 02301 02302 // If curves are merged, make sure vertices are merged. 02303 if( merged ) 02304 { 02305 int num_bridges = edge->bridge_manager()->number_of_bridges(); 02306 DLIList<TopologyBridge*> bridge_list( num_bridges ); 02307 edge->bridge_manager()->get_bridge_list( bridge_list ); 02308 02309 bridge_list.reset(); 02310 for( i = bridge_list.size(); i--; ) 02311 if( bridge_list.get() != curve_ptr ) 02312 break; 02313 else 02314 bridge_list.step(); 02315 02316 // Get points on some other Curve that this curve is merged with. 02317 Curve* other_curve = dynamic_cast<Curve*>(bridge_list.get()); 02318 assert( other_curve != curve_ptr) ; 02319 points.clean_out(); 02320 other_curve->points(points); 02321 if( other_curve->bridge_sense() == CUBIT_REVERSED ) 02322 points.reverse(); 02323 02324 // Check that points merged. 02325 points.reset(); 02326 if( points.get()->topology_entity() != start_vertex ) 02327 merged = false; 02328 points.last(); 02329 if( points.get()->topology_entity() != end_vertex ) 02330 merged = false; 02331 02332 //perhaps the bridge sense just needs to be swapped 02333 if( merged == false ) 02334 { 02335 points.reverse(); 02336 points.reset(); 02337 TBPoint *point1 = points.get_and_step(); 02338 TBPoint *point2 = points.get_and_step(); 02339 if( point1->topology_entity() == start_vertex && 02340 point2->topology_entity() == end_vertex ) 02341 { 02342 merged = true; 02343 curve_ptr->reverse_bridge_sense(); 02344 } 02345 } 02346 } 02347 // Unmerge the curve, if necessary. 02348 if( !merged && edge->bridge_manager()->number_of_bridges() > 1 ) 02349 { 02350 PRINT_WARNING("Unmerging Curve %d\n", edge->id() ); 02351 02352 // unmerge 02353 edge->bridge_manager()->remove_bridge( curve_ptr ); 02354 02355 // reset bridge sense on un-merged curve 02356 if (curve_ptr->bridge_sense() == CUBIT_REVERSED) 02357 { 02358 curve_ptr->reverse_bridge_sense(); 02359 } 02360 02361 // if first curve in old edge now has reversed sense, 02362 // reverse the old edge also. 02363 //if (edge->get_curve_ptr()->bridge_sense() == CUBIT_REVERSED) 02364 //{ 02365 // edge->bridge_manager()->reverse_bridge_senses(); 02366 // edge->reverse_topology(); 02367 //} 02368 02369 // Create new RefEdge for un-merged curve 02370 edge = RefEntityFactory::instance()->construct_RefEdge( curve_ptr ); 02371 PRINT_WARNING("Creating edge %d that was supposed to be merged\n", edge->id() ); 02372 edge_created = true; 02373 02374 // If we had swapped the vertex order because the curve 02375 // was reversed, switch them back because we unmerged so 02376 // we're going to create the new curve with a forward sense. 02377 if( reversed ) 02378 std::swap(start_vertex,end_vertex); 02379 } 02380 02381 // Get/construct Chain 02382 Chain* chain = edge->get_chain_ptr(); 02383 if( !chain ) 02384 { 02385 chain = new Chain(); 02386 edge->add_grouping_entity( chain ); 02387 } 02388 02389 // Get any existing CoVertices 02390 DLIList<CoVertex*> co_vertices(2); 02391 chain->co_vertices( co_vertices ); 02392 if( co_vertices.size() > 2 ) 02393 { 02394 PRINT_ERROR("In GeometryQueryTool::make_RefEdge, encountered " 02395 "a Chain with %d CoVertices on Curve %d\n", 02396 co_vertices.size(), edge->id()); 02397 assert( co_vertices.size() <= 2 ); 02398 } 02399 02400 // Now construct CoVertices if necessary, and attach 02401 // RefVertices. 02402 DLIList<RefVertex*> vertices(1); 02403 CoVertex* prev = 0; 02404 // First iteration is for start RefVertex 02405 RefVertex* vertex = start_vertex; 02406 co_vertices.reset(); 02407 // Loop twice, once for each CoVertex. 02408 for( i = 0; i < 2; i++ ) 02409 { 02410 // Construct CoVertex if one does not already exist 02411 CoVertex* cvtx = 0; 02412 if( co_vertices.size() > i ) 02413 { 02414 cvtx = co_vertices.get_and_step(); 02415 } 02416 else 02417 { 02418 cvtx = new CoVertex(); 02419 chain->add_sense_entity( cvtx , prev ); 02420 } 02421 prev = cvtx; 02422 02423 // Get existing RefVertex from CoVertex, if it has one. 02424 vertices.clean_out(); 02425 cvtx->ref_vertices( vertices ); 02426 if( vertices.size() > 1 ) 02427 { 02428 PRINT_ERROR("In GeometryQueryTool::make_RefEdge, encountered " 02429 "a CoVertex with %d Vertices on Curve %d\n", 02430 vertices.size(), edge->id()); 02431 assert( vertices.size() <= 1 ); 02432 vertices.reset(); 02433 } 02434 RefVertex* cvtx_vertex = vertices.size() ? vertices.get() : 0; 02435 02436 // Attach RefVertex to CoVertex if necessary 02437 if( cvtx_vertex != vertex ) 02438 { 02439 // Wrong RefVertex. Unhook from that one. 02440 if( cvtx_vertex ) 02441 { 02442 cvtx_vertex->remove_sense_entity(cvtx); 02443 if (NULL == cvtx_vertex->get_point_ptr()) 02444 destroy_dead_entity( cvtx_vertex ); 02445 } 02446 02447 cvtx->attach_basic_topology_entity( vertex ); 02448 edge_modified = true; 02449 } 02450 02451 // Second iteration is for end RefVertex 02452 vertex = end_vertex; 02453 } 02454 02455 if( !edge_created && edge_modified && !edge->deactivated() ) 02456 { 02457 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_TOPOLOGY_MODIFIED, edge)); 02458 CGMHistory::Event evt2(CGMHistory::TOPOLOGY_CHANGED, edge); 02459 const_cast<CGMHistory&>(mHistory).add_event(evt2); 02460 CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, edge); 02461 const_cast<CGMHistory&>(mHistory).add_event(evt); 02462 } 02463 02464 return edge; 02465 } 02466 02467 02468 RefEntity *GeometryQueryTool::check_mergeable_refentity(GeometryEntity *bridge) const 02469 { 02470 // Disable for surfaces until we can correctly handle 02471 // surfaces that have virtual curves. 02472 // J.Kraftcheck Apr.29,2002 02473 // if( dynamic_cast<Surface*>(bridge) ) 02474 // return 0; 02475 02476 if (CUBIT_FALSE == CGMApp::instance()->attrib_manager()->auto_actuate_flag(CA_MERGE_PARTNER)) 02477 return NULL; 02478 02479 // checks the topology bridge for a merge attribute, which might lead to another 02480 // refentity 02481 DLIList<CubitSimpleAttrib> csa_list; 02482 const char* name = CGMApp::instance()->attrib_manager()->att_internal_name(CA_MERGE_PARTNER); 02483 bridge->get_simple_attribute(name, csa_list); 02484 02485 RefEntity *re_ptr = NULL; 02486 02487 if(csa_list.size() > 0) 02488 { 02489 const CubitSimpleAttrib &csa_ptr = csa_list.size() ? csa_list.get() : CubitSimpleAttrib(); 02490 02491 // from the csa, call CAMP to get the partner, if one exists 02492 // (and return it) 02493 int merge_id = csa_ptr.int_data_list()[0]; 02494 02495 if( importingSolidModel && CUBIT_FALSE == GSaveOpen::performingUndo && 02496 !mergeGloballyOnImport ) 02497 { 02498 //if the merge id isn't already on some other entity already imported, 02499 //this entity doesn't have anybody to merge with...return NULL 02500 if( !uidsOfImportingEnts.is_in_list( merge_id) ) 02501 { 02502 GeometryQueryTool::uidsOfImportingEnts.append( merge_id ); 02503 return NULL; 02504 } 02505 } 02506 02507 bool unique_append = false; 02508 if( GeometryQueryTool::trackMergedAwayEnts ) 02509 unique_append = GeometryQueryTool::uidsOfImportingEnts.append_unique( merge_id ); 02510 02511 ToolDataUser *tdu = TDUniqueId::find_td_unique_id(merge_id); 02512 TopologyEntity *te = dynamic_cast<TopologyEntity*>(tdu); 02513 02514 CubitSense sense = CAMergePartner::get_bridge_sense( csa_ptr ); 02515 02516 //We found the merge partner..... 02517 if (te != NULL) 02518 { 02519 //it's the first time you found this uid and you found an entity 02520 // 02521 if(GeometryQueryTool::trackMergedAwayEnts && unique_append ) 02522 GeometryQueryTool::entitiesMergedAway++; 02523 02524 // assume this merge attrib will be actuated, so remove the csa 02525 bridge->remove_simple_attribute_virt(csa_ptr); 02526 02527 // now do the actual merge 02528 re_ptr = dynamic_cast<RefEntity*> (te); 02529 02530 //compare relative sense.....reverse bridges as necessary 02531 Surface *surface = CAST_TO( bridge, Surface ); 02532 Curve *curve= CAST_TO( bridge, Curve ); 02533 CubitSense rel_sense = CUBIT_FORWARD; 02534 02535 CubitBoolean is_survivor = CAMergePartner::is_survivor( csa_ptr ); 02536 if( surface ) 02537 { 02538 TopologyBridge *other_bridge = te->bridge_manager()->topology_bridge(); 02539 Surface *other_surface = CAST_TO( other_bridge, Surface ); 02540 rel_sense = relative_sense( surface, other_surface ); 02541 } 02542 else if( curve ) 02543 { 02544 TopologyBridge *other_bridge = te->bridge_manager()->topology_bridge(); 02545 Curve *other_curve = CAST_TO( other_bridge, Curve ); 02546 rel_sense = curve->relative_sense( other_curve ); 02547 } 02548 02549 //non-surviving merged entity is here....reverse 02550 //its bridge sense so that it will merge 02551 if( !is_survivor && sense != CUBIT_UNKNOWN && rel_sense == CUBIT_REVERSED ) 02552 bridge->reverse_bridge_sense(); 02553 //surviving merged entity is now being restored.... 02554 //reverse the ref entity and make this entity the primary one 02555 if( is_survivor ) 02556 { 02557 //If the passed in new bridge is the real survivor of the merge, 02558 //it should be the first bridge in the bridge manager. The first 02559 //bridge in the bridge manager is always FORWARD wrt the TE. 02560 // If this new bridge is reversed wrt the current first bridge, 02561 // reverse all the other bridges so that they will all merge 02562 //successfully with this new first bridge. Also add this new bridge 02563 //as the first bridge, since it was the original survivor. 02564 if( rel_sense == CUBIT_REVERSED ) 02565 { 02566 te->reverse_topology(); 02567 02568 //reverse the sense of the bridges of this refentity 02569 DLIList<TopologyBridge*> bridge_list; 02570 te->bridge_manager()->get_bridge_list( bridge_list ); 02571 02572 int kk; 02573 for( kk=bridge_list.size(); kk--; ) 02574 { 02575 TopologyBridge *tmp_bridge = bridge_list.get_and_step(); 02576 tmp_bridge->reverse_bridge_sense(); 02577 } 02578 } 02579 02580 //add this bridge as the primary bridge 02581 te->bridge_manager()->add_bridge_as_representation(bridge); 02582 } 02583 else 02584 te->bridge_manager()->add_bridge(bridge); 02585 } 02586 02587 // Set the merge sense of the bridge, if it is saved in the 02588 // attribute. 02589 if( re_ptr && sense == CUBIT_UNKNOWN ) 02590 { 02591 TopologyBridge* first = te->bridge_manager()->topology_bridge(); 02592 Curve* curve; 02593 Surface* surface; 02594 if( (curve = dynamic_cast<Curve*>(bridge) ) != NULL ) 02595 { 02596 Curve* first_curve = dynamic_cast<Curve*>(first); 02597 assert(first_curve != NULL); 02598 sense = first_curve->bridge_sense(); 02599 if( first_curve->relative_sense(curve) == CUBIT_REVERSED ) 02600 sense = CubitUtil::opposite_sense(sense); 02601 } 02602 else if( (surface = dynamic_cast<Surface*>(bridge) ) != NULL ) 02603 { 02604 Surface* first_surf = dynamic_cast<Surface*>(first); 02605 assert(first_surf != NULL); 02606 sense = first_surf->bridge_sense(); 02607 if( relative_sense( first_surf, surface ) == CUBIT_REVERSED ) 02608 sense = CubitUtil::opposite_sense(sense); 02609 } 02610 } 02611 02612 int id = CAMergePartner::get_saved_id( csa_ptr ); 02613 if (id) 02614 bridge->set_saved_id( id ); 02615 } 02616 02617 return re_ptr; 02618 } 02619 02620 //------------------------------------------------------------------------- 02621 // Purpose : Find relative senes of two Surfaces 02622 // 02623 // Special Notes : Used when CAMergePartner attrib is too old to 02624 // contain sense information. 02625 // 02626 // Creator : Jason Kraftcheck 02627 // 02628 // Creation Date : 08/22/02 02629 //------------------------------------------------------------------------- 02630 CubitSense GeometryQueryTool::relative_sense( Surface* surf1, Surface* surf2 ) 02631 { 02632 CubitVector point1 = surf1->bounding_box().center(); 02633 CubitVector point2 = surf2->bounding_box().center(); 02634 CubitVector point = 0.5 * (point1 + point2); 02635 02636 CubitVector closest1, closest2, normal1, normal2; 02637 surf1->closest_point_trimmed( point, closest1 ); 02638 surf2->closest_point( closest1, &closest2, &normal2 ); 02639 surf1->closest_point( closest2, &closest1, &normal1 ); 02640 02641 return normal1 % normal2 < 0 ? CUBIT_REVERSED : CUBIT_FORWARD; 02642 } 02643 02644 RefVertex* GeometryQueryTool::make_RefVertex(TBPoint* point) const 02645 { 02646 // first, handle making the new RefVertex's; check for 02647 // existing chain afterwards 02648 RefVertex* vertex = 0; 02649 02650 // First check to make sure we haven't already created a RefVertex 02651 // from this point 02652 TopologyEntity* topo = point->topology_entity(); 02653 vertex = CAST_TO(topo, RefVertex); 02654 02655 if ( vertex == NULL) 02656 { 02657 assert( topo == NULL ); 02658 RefEntity *re_ptr = check_mergeable_refentity(point); 02659 if (re_ptr != NULL) 02660 { 02661 vertex = dynamic_cast<RefVertex*>(re_ptr); 02662 } 02663 } 02664 02665 if (vertex == NULL) 02666 { 02667 // Create a RefVertex from this TBPoint. 02668 vertex = RefEntityFactory::instance()->construct_RefVertex(point); 02669 } 02670 assert(vertex != NULL); 02671 02672 return vertex; 02673 } 02674 02675 02676 02677 //------------------------------------------------------------------------- 02678 // Purpose : Build a free RefFace given a SurfaceSM. 02679 // 02680 // Special Notes : Purpose is to build a free surface. Entities are 02681 // added to the graphics. 02682 // 02683 // Creator : Steve Storm 02684 // 02685 // Creation Date : 3/27/99 02686 //------------------------------------------------------------------------- 02687 RefFace* GeometryQueryTool::make_free_RefFace(Surface *surface_ptr, 02688 bool is_free_face ) const 02689 { 02690 RefFace* ref_face_ptr = make_RefFace( surface_ptr ); 02691 if( !ref_face_ptr ) 02692 { 02693 PRINT_ERROR("Failed to construct free RefFace.\n"); 02694 assert(!!ref_face_ptr); 02695 return 0; 02696 } 02697 02698 // Add the new ref_face to the graphics 02699 if( is_free_face ) 02700 { 02701 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, ref_face_ptr)); 02702 02703 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, ref_face_ptr); 02704 const_cast<CGMHistory&>(mHistory).add_event(evt); 02705 } 02706 02707 return ref_face_ptr; 02708 } 02709 02710 //------------------------------------------------------------------------- 02711 // Purpose : Build a free RefEdge given a CurveSM. 02712 // 02713 // Special Notes : Purpose is to build a free curve. Entities are 02714 // added to the graphics. 02715 // 02716 // Creator : Steve Storm 02717 // 02718 // Creation Date : 3/27/99 02719 //------------------------------------------------------------------------- 02720 RefEdge* GeometryQueryTool::make_free_RefEdge(Curve *curve_ptr ) const 02721 { 02722 RefEdge* ref_edge_ptr = make_RefEdge(curve_ptr); 02723 if( !ref_edge_ptr ) 02724 { 02725 PRINT_ERROR("Failed to construct free RefEdge.\n"); 02726 assert(!!ref_edge_ptr); 02727 return 0; 02728 } 02729 02730 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, ref_edge_ptr)); 02731 02732 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, ref_edge_ptr); 02733 const_cast<CGMHistory&>(mHistory).add_event(evt); 02734 02735 return ref_edge_ptr; 02736 } 02737 02738 //------------------------------------------------------------------------- 02739 // Purpose : Build a free RefVertex given a PointSM. 02740 // 02741 // Special Notes : Purpose is to build a free vertex. Vertex 02742 // is added to the graphics. 02743 // 02744 // Creator : Steve Storm 02745 // 02746 // Creation Date : 3/27/99 02747 //------------------------------------------------------------------------- 02748 RefVertex* GeometryQueryTool::make_free_RefVertex(TBPoint *point_ptr ) const 02749 { 02750 RefVertex* ref_vertex_ptr = make_RefVertex( point_ptr ); 02751 if( !ref_vertex_ptr ) 02752 { 02753 PRINT_ERROR("Failed to construct free RefVertex.\n"); 02754 assert(!!ref_vertex_ptr); 02755 return 0; 02756 } 02757 02758 // Add the new ref_vertex to the graphics 02759 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, ref_vertex_ptr)); 02760 02761 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, ref_vertex_ptr); 02762 const_cast<CGMHistory&>(mHistory).add_event(evt); 02763 02764 return ref_vertex_ptr; 02765 } 02766 02767 void GeometryQueryTool::delete_Body(DLIList<Body*>& body_list) 02768 { 02769 body_list.reset(); 02770 for (int i = body_list.size(); i--; ) 02771 delete_Body(body_list.get_and_step()); 02772 } 02773 02774 //------------------------------------------------------------------------- 02775 // Purpose : Delete a Body 02776 // 02777 // Special Notes : 02778 // 02779 // Creator : Jason Kraftcheck 02780 // 02781 // Creation Date : 09/24/03 02782 //------------------------------------------------------------------------- 02783 CubitStatus GeometryQueryTool::delete_Body( Body* body_ptr ) 02784 { 02785 BodySM* bodysm = body_ptr->get_body_sm_ptr(); 02786 if (!bodysm) 02787 { 02788 PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n",body_ptr->id()); 02789 } 02790 else 02791 { 02792 // Ask owning model engine to delete the TopologyBridges 02793 GeometryQueryEngine* gqe = bodysm->get_geometry_query_engine(); 02794 gqe->delete_solid_model_entities(bodysm); 02795 02796 // Clean up any virtual geometry that was on the body 02797 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 02798 (*itor)->clean_out_deactivated_geometry(); 02799 } 02800 02801 // Check if body actually got deleted. 02802 return destroy_dead_entity( body_ptr ); 02803 } 02804 02805 //------------------------------------------------------------------------- 02806 // Purpose : Delete a Body 02807 // 02808 // Special Notes : Checks if child entities are merged and regenerates 02809 // graphics for them. This is necessary when 2 merged 02810 // entities have been "force-merged", usually meaning they 02811 // are not spatially equal. 02812 // 02813 // Creator : Corey Ernst 02814 // 02815 // Creation Date : 08/25/04 02816 //------------------------------------------------------------------------- 02817 CubitStatus GeometryQueryTool::delete_single_Body( Body* body_ptr ) 02818 { 02819 BodySM* bodysm = body_ptr->get_body_sm_ptr(); 02820 DLIList<RefEntity*> merged_children; 02821 DLIList<RefFace*> faces_to_reverse; 02822 DLIList<RefEdge*> edges_to_reverse; 02823 if (!bodysm) 02824 { 02825 PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n",body_ptr->id()); 02826 } 02827 else 02828 { 02829 //get all the child entities that have been merged 02830 DLIList<RefEntity*> tmp_merged_children; 02831 MergeTool::instance()->contains_merged_children( body_ptr, tmp_merged_children ); 02832 02833 //get the owning bodies for each entity 02834 int i; 02835 for(i=tmp_merged_children.size(); i--;) 02836 { 02837 RefEntity *ref_ent = tmp_merged_children.get_and_step(); 02838 TopologyEntity *tmp_entity = CAST_TO( ref_ent, TopologyEntity); 02839 DLIList<Body*> body_list; 02840 tmp_entity->bodies( body_list ); 02841 //if 2 bodies own it, get body that is not "body_ptr" 02842 //for later graphics regeneration 02843 if( body_list.size() > 1 ) 02844 { 02845 if( body_list.get() != body_ptr ) 02846 merged_children.append( ref_ent ); 02847 else if( body_list.step_and_get() != body_ptr ) 02848 merged_children.append( ref_ent ); 02849 } 02850 } 02851 02852 // if( tmp_merged_children.size() ) 02853 // MergeTool::instance()->unmerge( body_ptr ); 02854 02855 //fix up merged children -- some might need to be reversed 02856 for(i=merged_children.size(); i--; ) 02857 { 02858 RefEntity *merged_child = merged_children.get_and_step(); 02859 BasicTopologyEntity *bte = static_cast<BasicTopologyEntity*>(merged_child); 02860 02861 //get the first bridge of the entity 02862 DLIList<TopologyBridge*> child_bridge_list; 02863 bte->bridge_manager()->get_bridge_list( child_bridge_list ); 02864 child_bridge_list.reset(); 02865 TopologyBridge *first_bridge = child_bridge_list.get_and_step(); 02866 02867 //if it is not the body we're deleting just continue 02868 BodySM *owning_body = first_bridge->bodysm(); 02869 if( owning_body != bodysm ) 02870 continue; 02871 02872 RefFace *ref_face = CAST_TO( merged_child, RefFace ); 02873 if( ref_face ) 02874 { 02875 TopologyBridge *second_bridge = child_bridge_list.get_and_step(); 02876 02877 if( first_bridge->bridge_sense() != second_bridge->bridge_sense() ) 02878 faces_to_reverse.append( ref_face ); 02879 continue; 02880 } 02881 RefEdge *ref_edge = CAST_TO( merged_child, RefEdge ); 02882 if( ref_edge ) 02883 { 02884 //get merged_child's first topology bridge 02885 TopologyBridge *second_bridge = child_bridge_list.get_and_step(); 02886 02887 Curve *first_curve = CAST_TO( first_bridge, Curve ); 02888 Curve *second_curve = CAST_TO( second_bridge, Curve ); 02889 02890 CubitSense relative_sense = first_curve->relative_sense( second_curve ); 02891 02892 if( relative_sense == CUBIT_REVERSED ) 02893 edges_to_reverse.append( ref_edge ); 02894 continue; 02895 } 02896 } 02897 02898 // Ask owning model engine to delete the TopologyBridges 02899 GeometryQueryEngine* gqe = bodysm->get_geometry_query_engine(); 02900 gqe->delete_solid_model_entities(bodysm); 02901 02902 02903 // Clean up any virtual geometry that was on the body 02904 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 02905 (*itor)->clean_out_deactivated_geometry(); 02906 } 02907 02908 int i; 02909 for( i=faces_to_reverse.size(); i--; ) 02910 faces_to_reverse.get_and_step()->reverse_normal(); 02911 for( i=edges_to_reverse.size(); i--; ) 02912 edges_to_reverse.get_and_step()->reverse_tangent(); 02913 02914 //regenerate graphics of merged entities 02915 for( i=merged_children.size(); i--; ) 02916 { 02917 RefEntity* child = merged_children.get_and_step(); 02918 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_TOPOLOGY_MODIFIED, child)); 02919 CGMHistory::Event evt2(CGMHistory::TOPOLOGY_CHANGED, child); 02920 const_cast<CGMHistory&>(mHistory).add_event(evt2); 02921 CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, child); 02922 const_cast<CGMHistory&>(mHistory).add_event(evt); 02923 } 02924 02925 // Check if body actually got deleted. 02926 CubitStatus ret = destroy_dead_entity( body_ptr ); 02927 02928 // Send an unmerge event out for surfaces that were a part 02929 // of the body that was deleted. Do this after the above 02930 // call to destroy_dead_entity() so that the Body 02931 // pointer associated with the deleted volume will no 02932 // longer be referenced by the merged surface. This code 02933 // was added so that sidesets which are watching surface 02934 // modifications will know to update their data when 02935 // the body is deleted. 02936 for( i=merged_children.size(); i--; ) 02937 { 02938 RefFace* child = CAST_TO(merged_children.get_and_step(), RefFace); 02939 if(child) 02940 { 02941 UnMergeEvent unmerge_event( child, child ); 02942 AppUtil::instance()->send_event(unmerge_event ); 02943 } 02944 } 02945 02946 return ret; 02947 } 02948 02949 //------------------------------------------------------------------------- 02950 // Purpose : Delete a RefEntity 02951 // 02952 // Special Notes : 02953 // 02954 // Creator : Jason Kraftcheck 02955 // 02956 // Creation Date : 09/24/03 02957 //------------------------------------------------------------------------- 02958 CubitStatus GeometryQueryTool::delete_RefEntity( RefEntity* ref_entity_ptr ) 02959 { 02960 if (Body* body = dynamic_cast<Body*>(ref_entity_ptr)) 02961 return delete_Body(body); 02962 02963 if(RefFace* face = dynamic_cast<RefFace*>(ref_entity_ptr)) 02964 return delete_RefFace(face); 02965 02966 if(RefEdge* edge = dynamic_cast<RefEdge*>(ref_entity_ptr)) 02967 return delete_RefEdge(edge); 02968 02969 if(RefVertex* vtx = dynamic_cast<RefVertex*>(ref_entity_ptr)) 02970 return delete_RefVertex(vtx); 02971 PRINT_ERROR("Cannot delete entity of type '%s'\n", ref_entity_ptr->class_name()); 02972 return CUBIT_FAILURE; 02973 } 02974 02975 //------------------------------------------------------------------------- 02976 // Purpose : Delete a RefFace 02977 // 02978 // Special Notes : 02979 // 02980 // Creator : Jason Kraftcheck 02981 // 02982 // Creation Date : 09/24/03 02983 //------------------------------------------------------------------------- 02984 CubitStatus GeometryQueryTool::delete_RefFace( RefFace* ref_face ) 02985 { 02986 // Get the list of Surfaces owned by the RefFace 02987 BridgeManager* manager = ref_face->bridge_manager(); 02988 DLIList<TopologyBridge*> bridge_list(manager->number_of_bridges()); 02989 manager->get_bridge_list(bridge_list); 02990 02991 // Ask each Surface's owning engine to destroy the surface. 02992 while( bridge_list.size() ) 02993 { 02994 TopologyBridge* bridge = bridge_list.pop(); 02995 Surface* surface = dynamic_cast<Surface*>(bridge); 02996 if (!surface) 02997 { 02998 PRINT_ERROR("RefFace %d is invalid -- attached TopologyBridge " 02999 "is not a Surface.\n", ref_face->id()); 03000 continue; 03001 } 03002 03003 surface->get_geometry_query_engine()-> 03004 delete_solid_model_entities( surface ); 03005 } 03006 03007 // Clean up any virtual geometry that was on the surface 03008 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 03009 (*itor)->clean_out_deactivated_geometry(); 03010 03011 // Check if all the Surfaces got deleted. 03012 return destroy_dead_entity( ref_face ); 03013 } 03014 03015 //------------------------------------------------------------------------- 03016 // Purpose : Delete a RefEdge 03017 // 03018 // Special Notes : 03019 // 03020 // Creator : Jason Kraftcheck 03021 // 03022 // Creation Date : 09/24/03 03023 //------------------------------------------------------------------------- 03024 CubitStatus GeometryQueryTool::delete_RefEdge( RefEdge* ref_edge ) 03025 { 03026 // Get the list of Curves owned by the RefEdge 03027 BridgeManager* manager = ref_edge->bridge_manager(); 03028 DLIList<TopologyBridge*> bridge_list(manager->number_of_bridges()); 03029 manager->get_bridge_list(bridge_list); 03030 03031 // Ask each Curve's owning engine to destroy the surface. 03032 while( bridge_list.size() ) 03033 { 03034 TopologyBridge* bridge = bridge_list.pop(); 03035 Curve* curve = dynamic_cast<Curve*>(bridge); 03036 if (!curve) 03037 { 03038 PRINT_ERROR("RefEdge %d is invalid -- attached TopologyBridge " 03039 "is not a Curve.\n", ref_edge->id()); 03040 continue; 03041 } 03042 03043 curve->get_geometry_query_engine()-> 03044 delete_solid_model_entities( curve ); 03045 } 03046 03047 // Clean up any virtual geometry that was on the curve 03048 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 03049 (*itor)->clean_out_deactivated_geometry(); 03050 03051 // Check if all the curves got deleted. 03052 return destroy_dead_entity( ref_edge ); 03053 } 03054 03055 //------------------------------------------------------------------------- 03056 // Purpose : Delete a RefVertex 03057 // 03058 // Special Notes : 03059 // 03060 // Creator : Jason Kraftcheck 03061 // 03062 // Creation Date : 09/24/03 03063 //------------------------------------------------------------------------- 03064 CubitStatus GeometryQueryTool::delete_RefVertex( RefVertex* ref_vertex ) 03065 { 03066 // Get the list of Points owned by the RefVertex 03067 BridgeManager* manager = ref_vertex->bridge_manager(); 03068 DLIList<TopologyBridge*> bridge_list(manager->number_of_bridges()); 03069 manager->get_bridge_list(bridge_list); 03070 03071 // Ask each Curve's owning engine to destroy the surface. 03072 while( bridge_list.size() ) 03073 { 03074 TopologyBridge* bridge = bridge_list.pop(); 03075 TBPoint* point = dynamic_cast<TBPoint*>(bridge); 03076 if (!point) 03077 { 03078 PRINT_ERROR("RefVertex %d is invalid -- attached TopologyBridge " 03079 "is not a Point.\n", ref_vertex->id()); 03080 continue; 03081 } 03082 03083 point->get_geometry_query_engine()-> 03084 delete_solid_model_entities( point ); 03085 } 03086 03087 // Clean up any virtual geometry that was on the Point 03088 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 03089 (*itor)->clean_out_deactivated_geometry(); 03090 03091 // Check if all the Points got deleted. 03092 return destroy_dead_entity( ref_vertex ); 03093 } 03094 03095 //Initialize all settings in this class 03096 void GeometryQueryTool::initialize_settings() 03097 { 03098 03099 SettingHandler::instance()->add_setting("Merge Tolerance", 03100 GeometryQueryTool::set_geometry_factor, 03101 GeometryQueryTool::get_geometry_factor); 03102 03103 SettingHandler::instance()->add_setting("Merge Test BBox", 03104 GeometryQueryTool::set_merge_test_bbox, 03105 GeometryQueryTool::get_merge_test_bbox); 03106 03107 SettingHandler::instance()->add_setting("Merge Test InternalSurf", 03108 GeometryQueryTool::set_merge_test_internal, 03109 GeometryQueryTool::get_merge_test_internal); 03110 03111 SettingHandler::instance()->add_setting("Facet BBox", 03112 GeometryQueryTool::set_facet_bbox, 03113 GeometryQueryTool::get_facet_bbox); 03114 } 03115 03116 //------------------------------------------------------------------------- 03117 // Purpose : Constructor of the GeometryQueryTool class. 03118 // 03119 // Special Notes : 03120 // 03121 // Creator : Xuechen Liu 03122 // 03123 // Creation Date : 07/11/96 03124 //------------------------------------------------------------------------- 03125 GeometryQueryTool::GeometryQueryTool(GeometryQueryEngine*gqe_ptr) 03126 { 03127 if (gqe_ptr != NULL) add_gqe(gqe_ptr); 03128 } 03129 03130 // ********** END PROTECTED FUNCTIONS ********** 03131 03132 // ********** BEGIN PRIVATE FUNCTIONS ********** 03133 03134 03135 void GeometryQueryTool::geom_debug( DLIList<TopologyEntity*> topo_list ) 03136 { 03137 //This function was created March 1998 to assist in debugging 03138 //the unmerge command. When sufficient time has passed and 03139 //it is no longer needed, this function can be deleted. 03140 //SR Jankovich 03141 for( int i = topo_list.size(); i > 0; i-- ) 03142 { 03143 TopologyEntity *topo_entity = topo_list.get_and_step(); 03144 if( !topo_entity ) 03145 return; 03146 RefEntity *ref_entity = CAST_TO( topo_entity, RefEntity ); 03147 if( !ref_entity ) 03148 return; 03149 03150 PRINT_INFO( "%s\n", ref_entity->entity_name().c_str() ); 03151 DLIList<TopologyEntity*> next_topo_list; 03152 next_topo_list.clean_out(); 03153 03154 if( CAST_TO( ref_entity, Body ) ) 03155 { 03156 03157 DLIList<CoVolume*> co_vol_list; 03158 if( !topo_entity->co_volumes( co_vol_list ) ) 03159 return; 03160 for( int j = co_vol_list.size(); j > 0; j-- ) 03161 { 03162 CoVolume *co_vol = co_vol_list.get_and_step(); 03163 PRINT_INFO( " CoVolume %d (not id)\n", 03164 co_vol_list.size() - j ); 03165 TopologyEntity *temp_topo = CAST_TO( co_vol, TopologyEntity ); 03166 if( !temp_topo ) 03167 return; 03168 DLIList<RefVolume*> vol_list; 03169 if( !temp_topo->ref_volumes( vol_list ) ) 03170 return; 03171 for( int k = vol_list.size(); k > 0; k-- ) 03172 { 03173 RefVolume *vol = vol_list.get_and_step(); 03174 PRINT_INFO( " %s\n", vol->entity_name().c_str() ); 03175 TopologyEntity *next_topo = CAST_TO( vol, TopologyEntity ); 03176 next_topo_list.append( next_topo ); 03177 } 03178 } 03179 GeometryQueryTool::geom_debug( next_topo_list ); 03180 } 03181 else if( CAST_TO( ref_entity, RefVolume ) ) 03182 { 03183 DLIList<Shell*> shell_list; 03184 if( !topo_entity->shells( shell_list ) ) 03185 return; 03186 for( int m = shell_list.size(); m > 0; m-- ) 03187 { 03188 Shell *shell = shell_list.get_and_step(); 03189 PRINT_INFO( " Shell %d (not id)\n", shell_list.size() - m ); 03190 TopologyEntity *group_topo = CAST_TO( shell, TopologyEntity ); 03191 if( !group_topo ) 03192 return; 03193 DLIList<CoFace*> co_face_list; 03194 if( !group_topo->co_faces( co_face_list ) ) 03195 return; 03196 for( int j = co_face_list.size(); j > 0; j-- ) 03197 { 03198 CoFace *co_face = co_face_list.get_and_step(); 03199 PRINT_INFO( " CoFace %d (not id)\n", 03200 co_face_list.size() - j ); 03201 TopologyEntity *temp_topo = CAST_TO( co_face, TopologyEntity ); 03202 if( !temp_topo ) 03203 return; 03204 DLIList<RefFace*> face_list; 03205 if( !temp_topo->ref_faces( face_list ) ) 03206 return; 03207 for( int k = face_list.size(); k > 0; k-- ) 03208 { 03209 RefFace *face = face_list.get_and_step(); 03210 PRINT_INFO( " %s\n", face->entity_name().c_str() ); 03211 TopologyEntity *next_topo = CAST_TO( face, TopologyEntity ); 03212 next_topo_list.append( next_topo ); 03213 } 03214 } 03215 } 03216 GeometryQueryTool::geom_debug( next_topo_list ); 03217 } 03218 else if( CAST_TO( ref_entity, RefFace ) ) 03219 { 03220 DLIList<Loop*> loop_list; 03221 if( !topo_entity->loops( loop_list ) ) 03222 return; 03223 for( int m = loop_list.size(); m > 0; m-- ) 03224 { 03225 Loop *loop = loop_list.get_and_step(); 03226 PRINT_INFO( " Loop %d (not id)\n", loop_list.size() - m ); 03227 TopologyEntity *group_topo = CAST_TO( loop, TopologyEntity ); 03228 if( !group_topo ) 03229 return; 03230 DLIList<CoEdge*> co_edge_list; 03231 if( !group_topo->co_edges( co_edge_list ) ) 03232 return; 03233 for( int j = co_edge_list.size(); j > 0; j-- ) 03234 { 03235 CoEdge *co_edge = co_edge_list.get_and_step(); 03236 PRINT_INFO( " CoEdge %d (not id)\n", 03237 co_edge_list.size() - j ); 03238 TopologyEntity *temp_topo = CAST_TO( co_edge, TopologyEntity ); 03239 if( !temp_topo ) 03240 return; 03241 DLIList<RefEdge*> edge_list; 03242 if( !temp_topo->ref_edges( edge_list ) ) 03243 return; 03244 for( int k = edge_list.size(); k > 0; k-- ) 03245 { 03246 RefEdge *edge = edge_list.get_and_step(); 03247 PRINT_INFO( " %s\n", edge->entity_name().c_str() ); 03248 TopologyEntity *next_topo = CAST_TO( edge, TopologyEntity ); 03249 next_topo_list.append( next_topo ); 03250 } 03251 } 03252 } 03253 GeometryQueryTool::geom_debug( next_topo_list ); 03254 } 03255 else if( CAST_TO( ref_entity, RefEdge ) ) 03256 { 03257 DLIList<Chain*> chain_list; 03258 if( !topo_entity->chains( chain_list ) ) 03259 return; 03260 for( int m = chain_list.size(); m > 0; m-- ) 03261 { 03262 Chain *chain = chain_list.get_and_step(); 03263 PRINT_INFO( " Chain %d (not id)\n", chain_list.size() - m ); 03264 TopologyEntity *group_topo = CAST_TO( chain, TopologyEntity ); 03265 if( !group_topo ) 03266 return; 03267 DLIList<CoVertex*> co_vertex_list; 03268 if( !group_topo->co_vertices( co_vertex_list ) ) 03269 return; 03270 for( int j = co_vertex_list.size(); j > 0; j-- ) 03271 { 03272 CoVertex *co_vertex = co_vertex_list.get_and_step(); 03273 PRINT_INFO( " CoVertex %d (not id)\n", 03274 co_vertex_list.size() - j ); 03275 TopologyEntity *temp_topo = CAST_TO( co_vertex, TopologyEntity ); 03276 if( !temp_topo ) 03277 return; 03278 DLIList<RefVertex*> vertex_list; 03279 if( !temp_topo->ref_vertices( vertex_list ) ) 03280 return; 03281 for( int k = vertex_list.size(); k > 0; k-- ) 03282 { 03283 RefVertex *vertex = vertex_list.get_and_step(); 03284 PRINT_INFO( " %s\n", 03285 vertex->entity_name().c_str() ); 03286 TopologyEntity *next_topo = CAST_TO( vertex, TopologyEntity ); 03287 next_topo_list.append( next_topo ); 03288 } 03289 } 03290 } 03291 GeometryQueryTool::geom_debug( next_topo_list ); 03292 } 03293 else if( CAST_TO( ref_entity, RefVertex ) ) 03294 ;//Do nothing 03295 else 03296 PRINT_INFO( "UNKNOWN ENTITY TYPE!!!\n" ); 03297 } 03298 } 03299 03300 CubitBoolean GeometryQueryTool::about_spatially_equal (RefVertex* refVertex1, 03301 RefVertex* refVertex2, 03302 double tolerance_factor) 03303 { 03304 return ( refVertex1->about_spatially_equal( refVertex2, tolerance_factor)); 03305 } 03306 03307 CubitBoolean GeometryQueryTool::about_spatially_equal (const CubitVector &vector1, 03308 const CubitVector &vector2, 03309 double tolerance_factor) 03310 { 03311 double tol = GEOMETRY_RESABS * tolerance_factor; 03312 tol *= tol; 03313 double dist_sq = vector1.distance_between_squared(vector2); 03314 return !(dist_sq > tol); 03315 // within_tolerance() just checks coordinate aligned distances, not the actual distance. 03316 // return (vector1.within_tolerance( vector2, GEOMETRY_RESABS * tolerance_factor )); 03317 } 03318 03319 double GeometryQueryTool::geometric_angle(RefEdge* ref_edge_1, 03320 RefEdge* ref_edge_2, 03321 RefFace* ref_face ) 03322 { 03323 // calculates internal surface angles given 2 refedges on the surface 03324 CoEdge *co_edge_1, *co_edge_2; 03325 //First get the two coedges that corrispond to the edges sent into 03326 //this function. The two coedges are found from the ref_face's loop 03327 //where co_edge_1 is followed by co_edge_2 in the loop and co_edge_1 is 03328 //associated with ref_edge_1 while co_edge_2 is associated with 03329 //ref_edge_2. 03330 ref_edge_1->get_two_co_edges( ref_edge_2, ref_face, co_edge_1, 03331 co_edge_2 ); 03332 03333 return geometric_angle( co_edge_1, co_edge_2 ); 03334 } 03335 03336 double GeometryQueryTool::geometric_angle(CoEdge* co_edge_1, 03337 CoEdge* co_edge_2 ) 03338 { 03339 03340 RefEdge *ref_edge_1 = co_edge_1->get_ref_edge_ptr(); 03341 RefEdge *ref_edge_2 = co_edge_2->get_ref_edge_ptr(); 03342 03343 // return 2 pi for the tip of a hard line. 03344 if ( co_edge_1 != co_edge_2 && ref_edge_1 == ref_edge_2 ) 03345 return 2.0 * CUBIT_PI; 03346 03347 RefVertex *ref_vertex = 03348 co_edge_1->get_sense() == CUBIT_FORWARD ? 03349 ref_edge_1->end_vertex() : 03350 ref_edge_1->start_vertex(); 03351 03352 //RefVertex *junk_vertex1 = ref_edge_2->start_vertex(); 03353 //RefVertex *junk_vertex2 = ref_edge_2->end_vertex(); 03354 //CubitSense junk_sense = co_edge_2->get_sense(); 03355 03356 assert( ref_vertex == 03357 ( co_edge_2->get_sense() == CUBIT_FORWARD ? 03358 ref_edge_2->start_vertex() : 03359 ref_edge_2->end_vertex() ) ); 03360 03361 // coordinates of common point 03362 CubitVector vertex_point = ref_vertex->coordinates(); 03363 03364 // Find normal to the the face at the common vertex of 03365 // the refedges. Use loop sense to artificially switch inner loops. 03366 // Use intrinsic normal. 03367 RefFace *ref_face = co_edge_1->get_ref_face(); 03368 CubitVector normal = ref_face->normal_at(vertex_point, NULL); 03369 03370 // Find directed tangents to determine interior angle 03371 // Use sense of edge with respect to this face's loop. 03372 CubitVector tangent_1, tangent_2; 03373 ref_edge_1->tangent( vertex_point, tangent_1 ); 03374 ref_edge_2->tangent( vertex_point, tangent_2 ); 03375 03376 if ( co_edge_1->get_sense() == CUBIT_REVERSED ) 03377 tangent_1 = -tangent_1; 03378 if ( co_edge_2->get_sense() == CUBIT_REVERSED ) 03379 tangent_2 = -tangent_2; 03380 03381 // At this point we have the tangents going in the correct loop 03382 // sense. 03383 // Now get tangent pointing away from the center for the correct 03384 // angle 03385 tangent_1 = -tangent_1; 03386 // Return angle from given tangents and normal to face 03387 double angle = normal.vector_angle( tangent_2, tangent_1 ); 03388 if ( angle*180.0/CUBIT_PI > 360.0 - GEOMETRY_RESABS ) 03389 { 03390 //try other points to make sure this is going the right way. 03391 CubitVector new_loc_1, new_loc_2; 03392 if ( ref_edge_1->start_vertex() == ref_vertex ) 03393 ref_edge_1->position_from_fraction(0.01, 03394 new_loc_1); 03395 else 03396 ref_edge_1->position_from_fraction(0.99, 03397 new_loc_1); 03398 if ( ref_edge_2->start_vertex() == ref_vertex ) 03399 ref_edge_2->position_from_fraction(0.01, 03400 new_loc_2); 03401 else 03402 ref_edge_2->position_from_fraction(0.99, 03403 new_loc_2); 03404 //Now just do the exact same thing as above but 03405 //use these new points... 03406 ref_edge_1->tangent( new_loc_1, tangent_1 ); 03407 ref_edge_2->tangent( new_loc_2, tangent_2 ); 03408 03409 if ( co_edge_1->get_sense() == CUBIT_REVERSED ) 03410 tangent_1 = -tangent_1; 03411 if ( co_edge_2->get_sense() == CUBIT_REVERSED ) 03412 tangent_2 = -tangent_2; 03413 tangent_1 = -tangent_1; 03414 // Return angle from given tangents and normal to face 03415 angle = normal.vector_angle( tangent_2, tangent_1 ); 03416 if ( angle < CUBIT_PI ) 03417 angle = 0.0; 03418 else 03419 angle = 2.0*CUBIT_PI; 03420 } 03421 return angle; 03422 } 03423 03424 CubitString GeometryQueryTool::get_engine_version_string() 03425 { 03426 if (gqeList.size()) 03427 { 03428 gqeList.reset(); 03429 return gqeList.get()->get_engine_version_string(); 03430 } 03431 else 03432 { 03433 return CubitString("No Active GeometryEngine"); 03434 } 03435 } 03436 03437 CubitBoolean 03438 GeometryQueryTool::does_geom_contain_query_engine(DLIList<TopologyEntity*> &topo_list, 03439 GeometryQueryEngine *engine) const 03440 { 03441 GeometryQueryEngine *ge_ptr; 03442 for( int i=topo_list.size(); i--; ) 03443 { 03444 ge_ptr = topo_list.get_and_step()->get_geometry_query_engine(); 03445 if( ge_ptr == engine ) 03446 { 03447 return CUBIT_TRUE; 03448 } 03449 } 03450 03451 return CUBIT_FALSE; 03452 } 03453 03454 CubitBoolean 03455 GeometryQueryTool::does_geom_contain_query_engine(DLIList<RefEntity*> &ref_entity_list, 03456 GeometryQueryEngine *engine, 03457 CubitBoolean children_too) const 03458 { 03459 DLIList<RefEntity*> complete_entity_list; 03460 03461 // Check the check_children option and check all the children if necessary 03462 if (children_too) 03463 { 03464 //Make a complete list of all the RefEntitys and their children 03465 DLIList<RefEntity*> temp = ref_entity_list; 03466 RefEntity* ref_entity_ptr; 03467 int i; 03468 for( i=ref_entity_list.size(); i--; ) 03469 { 03470 ref_entity_ptr = ref_entity_list.get_and_step(); 03471 complete_entity_list.clean_out(); 03472 ref_entity_ptr->get_all_child_ref_entities(complete_entity_list); 03473 temp += complete_entity_list; 03474 } 03475 complete_entity_list.clean_out(); 03476 complete_entity_list.merge_unique(temp); 03477 } 03478 03479 // Now check the RefEntities for the given geometry engine 03480 DLIList<TopologyEntity*> te_list; 03481 CAST_LIST(complete_entity_list, te_list, TopologyEntity); 03482 return does_geom_contain_query_engine(te_list, engine); 03483 } 03484 03485 TopologyEntity* GeometryQueryTool::entity_from_bridge( TopologyBridge* bridge_ptr ) const 03486 { 03487 if( !bridge_ptr ) 03488 return NULL; 03489 TBOwner* owner = bridge_ptr->owner(); 03490 BridgeManager* bridge_manager; 03491 while (!(bridge_manager = dynamic_cast<BridgeManager*>(owner))) 03492 { 03493 if (TopologyBridge* bridge = dynamic_cast<TopologyBridge*>(owner)) 03494 owner = bridge->owner(); 03495 else if(TBOwnerSet* set = dynamic_cast<TBOwnerSet*>(owner)) 03496 { 03497 DLIList<TopologyBridge*> list; 03498 set->get_owners(list); 03499 list.reset(); 03500 owner = list.get()->owner(); 03501 } 03502 else 03503 break; 03504 } 03505 03506 return bridge_manager ? bridge_manager->topology_entity() : 0; 03507 } 03508 03509 03510 CubitStatus GeometryQueryTool::set_default_gqe(GeometryQueryEngine* gqe) 03511 { 03512 int i; 03513 for (i = 0; i < gqeList.size(); i++) 03514 { 03515 if(gqe == gqeList.get()) 03516 break; 03517 03518 gqeList.step(); 03519 } 03520 03521 if(i == gqeList.size()) return CUBIT_FAILURE; 03522 03523 GeometryQueryEngine* temp_ptr = gqeList.get(); 03524 gqeList.remove(); 03525 gqeList.insert_first(temp_ptr); 03526 PRINT_INFO("Geometry engine set to: %s\n", gqe->get_engine_version_string().c_str() ); 03527 return CUBIT_SUCCESS; 03528 } 03529 03530 CubitStatus GeometryQueryTool::set_export_allint_version(int version) 03531 { 03532 if (gqeList.size()) 03533 { 03534 gqeList.reset(); 03535 return gqeList.get()->set_export_allint_version(version); 03536 } 03537 else 03538 { 03539 PRINT_WARNING("No active geometry engine."); 03540 return CUBIT_FAILURE; 03541 } 03542 } 03543 03544 int GeometryQueryTool::get_allint_version() 03545 { 03546 if (gqeList.size()) 03547 { 03548 gqeList.reset(); 03549 return gqeList.get()->get_allint_version(); 03550 } 03551 else 03552 { 03553 PRINT_WARNING("No active geometry engine."); 03554 return 0; 03555 } 03556 } 03557 03558 CubitStatus GeometryQueryTool::list_engine_versions(CubitString &versions) 03559 { 03560 if (gqeList.size()) 03561 { 03562 gqeList.reset(); 03563 return gqeList.get()->list_engine_versions(versions); 03564 } 03565 else 03566 { 03567 PRINT_WARNING("No active geometry engine."); 03568 return CUBIT_FAILURE; 03569 } 03570 } 03571 03572 double GeometryQueryTool::get_sme_resabs_tolerance() 03573 { 03574 if (gqeList.size()) 03575 { 03576 gqeList.reset(); 03577 return gqeList.get()->get_sme_resabs_tolerance(); 03578 } 03579 else 03580 { 03581 PRINT_WARNING("No active geometry engine."); 03582 return 0.0; 03583 } 03584 } 03585 03586 double GeometryQueryTool::set_sme_resabs_tolerance( double new_resabs ) 03587 { 03588 if (gqeList.size()) 03589 { 03590 gqeList.reset(); 03591 return gqeList.get()->set_sme_resabs_tolerance( new_resabs ); 03592 } 03593 else 03594 { 03595 PRINT_WARNING("No active geometry engine."); 03596 return 0.0; 03597 } 03598 } 03599 03600 CubitStatus GeometryQueryTool::set_sme_int_option( const char* opt_name, int val ) 03601 { 03602 if (gqeList.size()) 03603 { 03604 gqeList.reset(); 03605 return gqeList.get()->set_int_option( opt_name, val ); 03606 } 03607 else 03608 { 03609 PRINT_WARNING("No active geometry engine."); 03610 return CUBIT_FAILURE; 03611 } 03612 } 03613 03614 CubitStatus GeometryQueryTool::set_sme_dbl_option( const char* opt_name, double val ) 03615 { 03616 if (gqeList.size()) 03617 { 03618 gqeList.reset(); 03619 return gqeList.get()->set_dbl_option( opt_name, val ); 03620 } 03621 else 03622 { 03623 PRINT_WARNING("No active geometry engine."); 03624 return CUBIT_FAILURE; 03625 } 03626 } 03627 03628 CubitStatus GeometryQueryTool::set_sme_str_option( const char* opt_name, const char* val ) 03629 { 03630 if (gqeList.size()) 03631 { 03632 gqeList.reset(); 03633 return gqeList.get()->set_str_option( opt_name, val ); 03634 } 03635 else 03636 { 03637 PRINT_WARNING("No active geometry engine."); 03638 return CUBIT_FAILURE; 03639 } 03640 } 03641 03642 CubitStatus GeometryQueryTool::get_intersections( RefEdge* ref_edge1, 03643 CubitVector& point1, 03644 CubitVector& point2, 03645 DLIList<CubitVector>& intersection_list, 03646 CubitBoolean bounded, 03647 CubitBoolean closest) 03648 { 03649 Curve* curve_ptr1 = ref_edge1->get_curve_ptr(); 03650 if( curve_ptr1 == NULL ) 03651 { 03652 if( curve_ptr1 == NULL ) 03653 PRINT_ERROR("Unable to retrieve underlying geometric entity of Curve %d\n" " This is a bug - please report it\n", ref_edge1->id() ); 03654 return CUBIT_FAILURE; 03655 } 03656 03657 if ( curve_ptr1->geometry_type() == STRAIGHT_CURVE_TYPE ) 03658 { 03659 CubitVector dir = point2 - point1; 03660 return straightline_intersections(ref_edge1, point1, dir, 03661 intersection_list, bounded, closest); 03662 } 03663 03664 GeometryQueryEngine* GQE_ptr = 03665 curve_ptr1->get_geometry_query_engine(); 03666 return GQE_ptr->get_intersections( curve_ptr1, point1, point2, 03667 intersection_list, bounded, closest); 03668 } 03669 03670 CubitStatus GeometryQueryTool::straightline_intersections(RefEdge* ref_edge1, 03671 CubitVector & origin2, 03672 CubitVector & dir, 03673 DLIList<CubitVector> &intersection_list, 03674 CubitBoolean bounded , 03675 CubitBoolean closest) 03676 { 03677 Curve* curve_ptr1 = ref_edge1->get_curve_ptr(); 03678 03679 if( curve_ptr1 == NULL ) 03680 { 03681 if( curve_ptr1 == NULL ) 03682 PRINT_ERROR("Unable to retrieve underlying geometric entity of Curve %d\n" " This is a bug - please report it\n", ref_edge1->id() ); 03683 return CUBIT_FAILURE; 03684 } 03685 03686 CubitVector dir2 = dir; 03687 dir2.normalize(); 03688 assert( curve_ptr1->geometry_type() == STRAIGHT_CURVE_TYPE ); 03689 // Proceed with the intersection calculation 03690 CubitVector origin1, dir1; 03691 double origin_pnt1[3], dir_vec1[3], origin_pnt2[3], dir_vec2[3]; 03692 03693 if( ref_edge1->get_point_direction( origin1, dir1 ) == CUBIT_FAILURE ) 03694 { 03695 PRINT_ERROR( "Unable to get straight line information for Curve %d; aborting\n", 03696 ref_edge1->id() ); 03697 return CUBIT_FAILURE; 03698 } 03699 03700 origin1.get_xyz( origin_pnt1 ); origin2.get_xyz( origin_pnt2 ); 03701 dir1.get_xyz( dir_vec1 ); dir2.get_xyz( dir_vec2 ); 03702 03703 AnalyticGeometryTool* agt = AnalyticGeometryTool::instance(); 03704 03705 int num_int; 03706 double int_pnt1[3], int_pnt2[3]; 03707 num_int = agt->int_ln_ln( origin_pnt1, dir_vec1, origin_pnt2, dir_vec2, 03708 int_pnt1, int_pnt2 ); 03709 if( num_int == 0 || (closest == CUBIT_FALSE && num_int == 2) ) 03710 { 03711 if( num_int == 0 ) 03712 PRINT_ERROR( "Curves %d and the straight line defined by position %g, %g, %g, and direction %g, %g, %g are parallel - no intersection exists\n", 03713 ref_edge1->id(), origin2.x(), origin2.y(), origin2.z(), dir2.x(), dir2.y(), dir2.z()); 03714 03715 else 03716 PRINT_ERROR( "Curves %d and the straight line defined by position %g, %g, %g, and direction %g, %g, %g do not intersect\n", ref_edge1->id(), 03717 origin2.x(), origin2.y(), origin2.z(), dir2.x(), dir2.y(), dir2.z()); 03718 return CUBIT_FAILURE; 03719 } 03720 03721 if( bounded == CUBIT_TRUE ) 03722 { 03723 CubitVector start1 = ref_edge1->start_vertex()->coordinates(); 03724 CubitVector end1 = ref_edge1->end_vertex()->coordinates(); 03725 CubitVector start2 = origin2; 03726 CubitVector end2 = origin2 + dir; 03727 03728 double start_pnt1[3], end_pnt1[3], start_pnt2[3], end_pnt2[3]; 03729 start1.get_xyz( start_pnt1 ); start2.get_xyz( start_pnt2 ); 03730 end1.get_xyz( end_pnt1 ); end2.get_xyz( end_pnt2 ); 03731 03732 if( num_int == 1 ) 03733 { 03734 // Vertex must be on both curves 03735 if( agt->is_pnt_on_ln_seg( int_pnt1, start_pnt1, end_pnt1 ) && 03736 agt->is_pnt_on_ln_seg( int_pnt2, start_pnt2, end_pnt2 ) ) 03737 { 03738 intersection_list.append( CubitVector(int_pnt1) ); 03739 } 03740 else 03741 { 03742 PRINT_WARNING( "intersection point of Curves was not within bounds of both curves\n"); 03743 } 03744 } 03745 else 03746 { 03747 // Only keep the vertices that are on the curve bounds 03748 if( agt->is_pnt_on_ln_seg( int_pnt1, start_pnt1, end_pnt1 ) ) 03749 { 03750 intersection_list.append( CubitVector(int_pnt1) ); 03751 } 03752 else 03753 { 03754 PRINT_WARNING( "intersection point on Curve %d was not within it's bounds\n", 03755 ref_edge1->id() ); 03756 } 03757 if( agt->is_pnt_on_ln_seg( int_pnt2, start_pnt2, end_pnt2 ) ) 03758 { 03759 intersection_list.append( CubitVector(int_pnt2) ); 03760 } 03761 else 03762 { 03763 PRINT_WARNING( "intersection point on the straight line defined by position %g, %g, %g, and direction %g, %g, %g was not within it's bounds\n", 03764 origin2.x(), origin2.y(), origin2.z(), dir2.x(), dir2.y(), dir2.z() ); 03765 } 03766 } 03767 if( intersection_list.size() == 0 ) 03768 return CUBIT_FAILURE; 03769 03770 return CUBIT_SUCCESS; 03771 } 03772 else // Not bounded 03773 { 03774 intersection_list.append( CubitVector(int_pnt1) ); 03775 if( num_int == 2 ) 03776 { 03777 intersection_list.append( CubitVector(int_pnt2) ); 03778 } 03779 return CUBIT_SUCCESS; 03780 } 03781 } 03782 03783 CubitStatus GeometryQueryTool::get_intersections( RefEdge* ref_edge1, 03784 RefEdge* ref_edge2, 03785 DLIList<CubitVector>& intersection_list, 03786 CubitBoolean bounded, 03787 CubitBoolean closest) 03788 { 03789 // If both curves are straight, compute their intersection; otherwise 03790 // use the geometry engine to do it. 03791 CubitStatus status = CUBIT_FAILURE; 03792 Curve* curve_ptr1 = ref_edge1->get_curve_ptr(); 03793 Curve* curve_ptr2 = ref_edge2->get_curve_ptr(); 03794 03795 if( curve_ptr1 == NULL || curve_ptr2 == NULL ) 03796 { 03797 if( curve_ptr1 == NULL ) 03798 PRINT_ERROR("Unable to retrieve underlying geometric entity of Curve %d\n" 03799 " This is a bug - please report it\n", ref_edge1->id() ); 03800 if( curve_ptr2 == NULL ) 03801 PRINT_ERROR("Unable to retrieve underlying geometry entity of Curve %d\n" 03802 " This is a bug - please report it\n", ref_edge2->id() ); 03803 return CUBIT_FAILURE; 03804 } 03805 03806 if( curve_ptr1->geometry_type() == STRAIGHT_CURVE_TYPE && 03807 curve_ptr2->geometry_type() == STRAIGHT_CURVE_TYPE ) 03808 { 03809 // Proceed with the intersection calculation 03810 CubitVector origin2, dir2; 03811 03812 if( ref_edge2->get_point_direction( origin2, dir2 ) == CUBIT_FAILURE ) 03813 { 03814 PRINT_ERROR( "Unable to get straight line information for Curve %d; aborting\n", 03815 ref_edge2->id() ); 03816 return CUBIT_FAILURE; 03817 } 03818 03819 if (bounded) 03820 { 03821 origin2 = ref_edge2->start_vertex()->coordinates(); 03822 dir2 = ref_edge2->end_vertex()->coordinates() - origin2; 03823 } 03824 return straightline_intersections(ref_edge1, origin2, dir2, 03825 intersection_list, bounded, closest); 03826 } 03827 03828 if( closest == CUBIT_TRUE ) 03829 { 03830 PRINT_ERROR( "'Near' option only works for straight lines\n" ); 03831 return CUBIT_FAILURE; 03832 } 03833 03834 // Use geometry engine to find intersections 03835 DLIList<TopologyEntity*> entity_list(2); 03836 DLIList<TopologyBridge*> bridge_list(2); 03837 DLIList<TopologyBridge*> curve_list1, curve_list2; 03838 entity_list.append(ref_edge1); 03839 entity_list.append(ref_edge2); 03840 03841 //if there's virtual edge, find the underlying real curve. 03842 if (ref_edge1->get_geometry_query_engine()) 03843 ref_edge1->get_geometry_query_engine()->get_underlying_curves(curve_ptr1, curve_list1); 03844 if (ref_edge2->get_geometry_query_engine()) 03845 ref_edge2->get_geometry_query_engine()->get_underlying_curves(curve_ptr2, curve_list2); 03846 03847 GeometryQueryEngine* gqe = common_query_engine( entity_list, bridge_list ); 03848 03849 //if they are both virtual...set gqe to NULL 03850 if( is_intermediate_geometry(curve_ptr1) && is_intermediate_geometry( curve_ptr2 ) ) 03851 gqe = NULL; 03852 03853 if( gqe == NULL && (curve_list1.size() > 0 || curve_list2.size() > 0) ) 03854 { 03855 if (curve_list1.size() == 0) 03856 curve_list1.append (CAST_TO(curve_ptr1, TopologyBridge)); 03857 if (curve_list2.size() == 0) 03858 curve_list2.append (CAST_TO(curve_ptr2, TopologyBridge)); 03859 int i, j; 03860 for (i = 0; i <curve_list1.size(); i++) 03861 { 03862 TopologyBridge * tb1 = curve_list1.get_and_step(); 03863 GeometryQueryEngine *gqe_ptr1 = tb1->get_geometry_query_engine(); 03864 curve_ptr1 = CAST_TO(tb1, Curve); 03865 03866 for(j = 0; j< curve_list2.size(); j++) 03867 { 03868 TopologyBridge * tb2 = curve_list2.get_and_step(); 03869 GeometryQueryEngine *gqe_ptr2 = tb2->get_geometry_query_engine(); 03870 if (gqe_ptr1 && gqe_ptr1 == gqe_ptr2 ) 03871 { 03872 curve_ptr2 = CAST_TO(tb2, Curve); 03873 status = gqe_ptr1->get_intersections(curve_ptr1, curve_ptr2, 03874 intersection_list, bounded, closest ); 03875 } 03876 } 03877 } 03878 03879 //remove duplicate intersections 03880 for( int k=0; k<intersection_list.size(); k++ ) 03881 { 03882 intersection_list.reset(); 03883 intersection_list.step(k+1); 03884 for( int s=k+1; s<intersection_list.size();) 03885 { 03886 if( intersection_list[k].distance_between( intersection_list[s] ) < GEOMETRY_RESABS ) 03887 { 03888 intersection_list.remove(); 03889 } 03890 else 03891 { 03892 s++; 03893 intersection_list.step(); 03894 } 03895 } 03896 } 03897 03898 return status; 03899 } 03900 03901 else if (gqe == NULL) 03902 { 03903 PRINT_ERROR( "Curves %d and %d do not have the same underlying geometry modeling engine\n" 03904 " For intersection calculations, they must be the same\n", 03905 ref_edge1->id(), ref_edge2->id() ); 03906 return CUBIT_FAILURE; 03907 } 03908 03909 bridge_list.reset(); 03910 curve_ptr1 = dynamic_cast<Curve*>(bridge_list.next(0)); 03911 curve_ptr2 = dynamic_cast<Curve*>(bridge_list.next(1)); 03912 return gqe->get_intersections( curve_ptr1, curve_ptr2, 03913 intersection_list, bounded, closest ); 03914 } 03915 03916 CubitStatus 03917 GeometryQueryTool::get_intersections( RefEdge* ref_edge, RefFace* ref_face, 03918 DLIList<CubitVector>& intersection_list, 03919 CubitBoolean bounded ) 03920 { 03921 // Use geometry engine to find intersections 03922 DLIList<TopologyEntity*> entity_list(2); 03923 DLIList<TopologyBridge*> bridge_list(2); 03924 entity_list.append(ref_edge); 03925 entity_list.append(ref_face); 03926 GeometryQueryEngine* gqe = common_query_engine( entity_list, bridge_list ); 03927 03928 if( gqe == NULL ) 03929 { 03930 PRINT_ERROR( "Curve %d and Surface %d do not have the same underlying geometry query engine\n" 03931 " For intersection calculations, they must be the same\n", 03932 ref_edge->id(), ref_face->id() ); 03933 return CUBIT_FAILURE; 03934 } 03935 03936 bridge_list.reset(); 03937 Curve* curve = dynamic_cast<Curve*>(bridge_list.next(0)); 03938 Surface* surf = dynamic_cast<Surface*>(bridge_list.next(1)); 03939 return gqe->get_intersections( curve, surf, intersection_list, bounded ); 03940 } 03941 03942 CubitStatus 03943 GeometryQueryTool::get_intersections(RefEdge* ref_edge, CubitPlane plane, 03944 DLIList<CubitVector> &intersection_list, 03945 CubitBoolean bounded, double extended_percent ) 03946 { 03947 CubitBox box = ref_edge->bounding_box(); 03948 03949 // create a Surface from the plane 03950 CubitVector p1, p2, p3, p4; 03951 AnalyticGeometryTool::instance()->min_pln_box_int_corners(plane, box, 1, extended_percent, p1, p2, p3, p4, true ); 03952 03953 TopologyBridge* bridge = 0; 03954 GeometryModifyEngine* gme = GeometryModifyTool::instance()->get_engine( ref_edge, &bridge ); 03955 BodySM* sheet = gme->planar_sheet(p1, p2, p3, p4); 03956 if (!sheet) 03957 { 03958 PRINT_INFO("%s", "Unable to test for planar intersections\n"); 03959 return CUBIT_FAILURE; 03960 } 03961 03962 DLIList<Surface*> surfaces; 03963 sheet->surfaces( surfaces ); 03964 03965 Curve* curve = ref_edge->get_curve_ptr(); 03966 GeometryQueryEngine* gqe = ref_edge->get_geometry_query_engine(); 03967 CubitStatus status = gqe->get_intersections( curve, surfaces[0], intersection_list, bounded ); 03968 03969 gqe->delete_solid_model_entities(sheet); 03970 03971 return status; 03972 } 03973 03974 //=============================================================================== 03975 // Function : entity_extrema 03976 // Member Type: PUBLIC 03977 // Description: Find extrema location on entity 03978 // Author : Steve Storm 03979 // Date : 11/02 03980 //=============================================================================== 03981 CubitStatus 03982 GeometryQueryTool::entity_extrema( RefEntity *ref_entity_ptr, 03983 const CubitVector *dir1, 03984 const CubitVector *dir2, 03985 const CubitVector *dir3, 03986 CubitVector &extrema, 03987 RefEntity *&extrema_entity_ptr ) 03988 { 03989 DLIList<RefEntity*> ref_entity_list; 03990 ref_entity_list.append( ref_entity_ptr ); 03991 03992 return entity_extrema( ref_entity_list, dir1, dir2, dir3, extrema, 03993 extrema_entity_ptr ); 03994 } 03995 03996 //=============================================================================== 03997 // Function : entity_extrema 03998 // Member Type: PUBLIC 03999 // Description: Find extrema location on a list of entities 04000 // Author : Steve Storm 04001 // Date : 11/02 04002 //=============================================================================== 04003 CubitStatus 04004 GeometryQueryTool::entity_extrema( DLIList<RefEntity*> &ref_entity_list, 04005 const CubitVector *dir1, 04006 const CubitVector *dir2, 04007 const CubitVector *dir3, 04008 CubitVector &extrema, 04009 RefEntity *&extrema_entity_ptr ) 04010 { 04011 if( ref_entity_list.size() == 0 ) 04012 { 04013 PRINT_ERROR( "No entities found for extrema calculation.\n" ); 04014 return CUBIT_FAILURE; 04015 } 04016 04017 DLIList<TopologyEntity*> entity_list(ref_entity_list.size()); 04018 DLIList<TopologyBridge*> bridge_list(ref_entity_list.size()); 04019 DLIList<RefVolume*> ref_vols; 04020 // Can only do BasicTopologyEntitys. Relace Bodys with RefVolumes. 04021 ref_entity_list.reset(); 04022 for (int i = ref_entity_list.size(); i--; ) 04023 { 04024 RefEntity* entity = ref_entity_list.get_and_step(); 04025 if (BasicTopologyEntity* bte = dynamic_cast<BasicTopologyEntity*>(entity)) 04026 { 04027 entity_list.append(bte); 04028 continue; 04029 } 04030 04031 if (Body* body = dynamic_cast<Body*>(entity)) 04032 { 04033 ref_vols.clean_out(); 04034 body->ref_volumes(ref_vols); 04035 ref_vols.reset(); 04036 for (int j = ref_vols.size(); j--;) 04037 entity_list.append(ref_vols.get_and_step()); 04038 continue; 04039 } 04040 04041 PRINT_ERROR("Don't know how to handle entity of type '%s' in " 04042 "GQT::entity_extrema.\n", entity->class_name()); 04043 return CUBIT_FAILURE; 04044 } 04045 04046 04047 GeometryQueryEngine* gqe = common_query_engine(entity_list, bridge_list); 04048 if( gqe == NULL ) 04049 { 04050 PRINT_ERROR( "Entities specified for extrema do not have the same\n" 04051 " underlying geometry query engine.\n" 04052 " For extrema calculations, they must be the same.\n" ); 04053 return CUBIT_FAILURE; 04054 } 04055 04056 // Need GeometryEntities. 04057 DLIList<GeometryEntity*> geom_list(bridge_list.size()); 04058 CAST_LIST(bridge_list, geom_list, GeometryEntity); 04059 04060 // Check direction inputs 04061 if( dir1 == NULL ) 04062 { 04063 PRINT_ERROR( "Direction not found for extrema calculation - it is required.\n" ); 04064 return CUBIT_FAILURE; 04065 } 04066 if( dir2 == NULL && dir3 ) 04067 { 04068 PRINT_ERROR( "Second direction not specified but last direction\n" 04069 " was - this is not allowed for extrema calculation.\n" ); 04070 return CUBIT_FAILURE; 04071 } 04072 04073 GeometryEntity* extrema_geom = 0; 04074 CubitStatus status = gqe->entity_extrema( geom_list, dir1, dir2, dir3, 04075 extrema, extrema_geom ); 04076 extrema_entity_ptr = dynamic_cast<RefEntity*>(entity_from_bridge(extrema_geom)); 04077 return status; 04078 } 04079 04080 CubitStatus 04081 GeometryQueryTool::entity_entity_distance( RefEntity *ref_entity_ptr1, 04082 RefEntity *ref_entity_ptr2, 04083 CubitVector &pos1, CubitVector &pos2, 04084 double &distance ) 04085 { 04086 DLIList<TopologyEntity*> entity_list(2); 04087 DLIList<TopologyBridge*> bridge_list(2); 04088 04089 BasicTopologyEntity* bte1 = dynamic_cast<BasicTopologyEntity*>(ref_entity_ptr1); 04090 BasicTopologyEntity* bte2 = dynamic_cast<BasicTopologyEntity*>(ref_entity_ptr2); 04091 if (!bte1 || !bte2) 04092 { 04093 const char* name = bte2 ? ref_entity_ptr1->class_name() : ref_entity_ptr2->class_name(); 04094 PRINT_ERROR("Cannot calculate entity distance for entity of type '%s'\n", name); 04095 return CUBIT_FAILURE; 04096 } 04097 04098 entity_list.append(bte1); 04099 entity_list.append(bte2); 04100 GeometryQueryEngine* gqe = common_query_engine(entity_list, bridge_list); 04101 if( gqe == NULL ) 04102 { 04103 PRINT_ERROR( "%s and %s do not have the same underlying geometry query engine.\n" 04104 " For distance calculations, they must be the same.\n", 04105 ref_entity_ptr1->entity_name().c_str(), ref_entity_ptr2->entity_name().c_str() ); 04106 return CUBIT_FAILURE; 04107 } 04108 04109 bridge_list.reset(); 04110 GeometryEntity* geom1 = dynamic_cast<GeometryEntity*>(bridge_list.next(0)); 04111 GeometryEntity* geom2 = dynamic_cast<GeometryEntity*>(bridge_list.next(1)); 04112 return gqe->entity_entity_distance( geom1, geom2, pos1, pos2, distance ); 04113 } 04114 04115 CubitStatus 04116 GeometryQueryTool::entity_entity_distance( GeometryEntity *ge1, 04117 GeometryEntity *ge2, 04118 CubitVector &pos1, CubitVector &pos2, 04119 double &distance ) 04120 { 04121 GeometryQueryEngine *gqe1 = ge1->get_geometry_query_engine(); 04122 GeometryQueryEngine *gqe2 = ge2->get_geometry_query_engine(); 04123 04124 if(gqe1 != gqe2) 04125 { 04126 if(gqe1->is_intermediate_engine()) 04127 return gqe1->entity_entity_distance(ge1, ge2, pos1, pos2, distance); 04128 else if(gqe2->is_intermediate_engine()) 04129 return gqe2->entity_entity_distance(ge1, ge2, pos1, pos2, distance); 04130 else 04131 { 04132 PRINT_ERROR( "Entities do not have the same underlying geometry query engine.\n" 04133 " For distance calculations, they must be the same.\n" ); 04134 return CUBIT_FAILURE; 04135 } 04136 } 04137 else 04138 { 04139 return gqe1->entity_entity_distance(ge1, ge2, pos1, pos2, distance); 04140 } 04141 } 04142 04143 CubitBox GeometryQueryTool::bounding_box_of_bodies() 04144 { 04145 CubitBox total_bound; 04146 int i; 04147 04148 if(GeometryQueryTool::instance()->num_bodies() > 0) 04149 { 04150 GeometryQueryTool::instance()->get_last_body(); 04151 // Assign the first body's bounding box to total_bound 04152 total_bound = GeometryQueryTool::instance()->get_last_body()->bounding_box(); 04153 04154 // Create union of all remaining bounding boxes 04155 for (i = GeometryQueryTool::instance()->num_bodies(); --i; ) 04156 total_bound |= GeometryQueryTool::instance()->get_next_body()->bounding_box(); 04157 } 04158 else 04159 { 04160 // Set the box to [(0,0,0)(0,0,0)] 04161 CubitVector temp(0,0,0); 04162 total_bound.reset(temp); 04163 } 04164 // Return the box 04165 return total_bound; 04166 } 04167 04168 void GeometryQueryTool::cleanout_deactivated_geometry () 04169 { 04170 04171 04172 // This routine removes from the model all RefEntities that have been 04173 // deactivated 04174 PRINT_DEBUG_17("\n\n...Cleaning out deactivated RefEntities " 04175 "and asociated Mesh Entities from the model\n"); 04176 04177 // First delete the meshes associated with the deactivated RefEntities 04178 // delete_meshes_of_deactivated_refEntities(); 04179 04180 // Now delete the deactivated RefEntities and remove all traces 04181 // of them from the DAG 04182 DAG::instance()->cleanout_deactivated_DAG_nodes(); 04183 04184 // Leave gracefully :-) 04185 PRINT_DEBUG_17( 04186 "Successfully cleaned out all deactivated RefEntities " 04187 "and associated Mesh Entities from the model.\n"); 04188 04189 return; 04190 } 04191 04192 void GeometryQueryTool::delete_geometry () 04193 { 04194 04195 CubitStatus status = CUBIT_FAILURE; 04196 04197 // Delete all RefGroups 04198 RefGroup::delete_all_groups(); 04199 Body* bodyPtr = NULL; 04200 //DLIList<Body*> bodyList; 04201 //GeometryQueryTool::instance()->bodies(bodyList); 04202 //bodyList.reset(); 04203 //for ( i = bodyList.size(); i > 0; i--) 04204 //{ 04205 // bodyPtr = bodyList.get_and_step(); 04206 04207 while( (bodyPtr = GeometryQueryTool::instance()->get_last_body() ) != NULL ) 04208 { 04209 // Now delete this Body and its underlying solid model entities 04210 status = GeometryQueryTool::instance()->delete_Body( bodyPtr ); 04211 if (status == CUBIT_FAILURE) 04212 { 04213 PRINT_ERROR("In GeometryQueryTool::delete_geometry\n" 04214 " Could not delete Body %d.\n" 04215 " The Model database is likely corrupted due" 04216 " to\n this unsuccessful deletion.\n", 04217 bodyPtr->id() ); 04218 assert( status != CUBIT_FAILURE) ; 04219 break; 04220 } 04221 } 04222 04223 // Remove free-floating RefFaces 04224 RefFace* refFacePtr = NULL; 04225 //DLIList<RefFace*> refFaceList; 04226 //GeometryQueryTool::instance()->ref_faces(refFaceList); 04227 //refFaceList.reset(); 04228 //for ( i = refFaceList.size(); i > 0; i--) 04229 //{ 04230 // refFacePtr = refFaceList.get_and_step(); 04231 04232 while( (refFacePtr = GeometryQueryTool::instance()->get_last_ref_face() ) != NULL ) 04233 { 04234 // NOTE- 04235 // The following GeometryQueryTool call results in a call to 04236 // the RefFace destructor which notifies the Model of 04237 // the destruction event. Model, in turn, removes the RefFace 04238 // pointer from refFaceList. Hence, the size of this list 04239 // changes inside this "while" loop. 04240 status = GeometryQueryTool::instance()->delete_RefFace( refFacePtr ); 04241 if (status == CUBIT_FAILURE) 04242 { 04243 PRINT_ERROR("In GeometryQueryTool::delete_geometry\n" 04244 " Could not delete RefFace %d.\n" 04245 " The Model database is likely corrupted " 04246 "due to\n this unsuccessful deletion.\n", 04247 refFacePtr->id()); 04248 assert( status != CUBIT_FAILURE) ; 04249 break; 04250 } 04251 } 04252 04253 // Remove free-floating RefEdges 04254 RefEdge* refEdgePtr = NULL; 04255 //DLIList<RefEdge*> refEdgeList; 04256 //GeometryQueryTool::instance()->ref_edges(refEdgeList); 04257 //refEdgeList.reset(); 04258 //for ( i = refEdgeList.size(); i > 0; i--) 04259 //{ 04260 // refEdgePtr = refEdgeList.get_and_step(); 04261 04262 while( (refEdgePtr = GeometryQueryTool::instance()->get_last_ref_edge() ) != NULL ) 04263 { 04264 // NOTE- 04265 // The following GeometryQueryTool call results in a call to 04266 // the RefEdge destructor which notifies the Model of 04267 // the destruction event. Model, in turn, removes the RefEdge 04268 // pointer from refEdgeList. Hence, the size of this list 04269 // changes inside this "while" loop. 04270 status = GeometryQueryTool::instance()->delete_RefEdge( refEdgePtr ); 04271 if (status == CUBIT_FAILURE) 04272 { 04273 PRINT_ERROR("In GeometryQueryTool::delete_geometry\n" 04274 " Could not delete RefEdge %d.\n" 04275 " The Model database is likely corrupted " 04276 "due to\n this unsuccessful deletion.\n", 04277 refEdgePtr->id()); 04278 assert( status != CUBIT_FAILURE) ; 04279 break; 04280 } 04281 } 04282 04283 // Remove free-floating RefVertex'es 04284 RefVertex* refVertexPtr = NULL; 04285 //DLIList<RefVertex*> refVertexList; 04286 //GeometryQueryTool::instance()->ref_vertices(refVertexList); 04287 //refVertexList.reset(); 04288 //for ( i = refVertexList.size(); i > 0; i--) 04289 //{ 04290 // refVertexPtr = refVertexList.get_and_step(); 04291 04292 while( (refVertexPtr = GeometryQueryTool::instance()->get_last_ref_vertex() ) != NULL ) 04293 { 04294 // NOTE- 04295 // The following GeometryQueryTool call results in a call to 04296 // the RefVertex destructor which notifies the Model of 04297 // the destruction event. Model, in turn, removes the RefVertex 04298 // pointer from refVertexList. Hence, the size of this list 04299 // changes inside this "while" loop. 04300 status = GeometryQueryTool::instance()->delete_RefVertex( refVertexPtr ); 04301 if (status == CUBIT_FAILURE) 04302 { 04303 PRINT_ERROR("In GeometryQueryTool::delete_geometry\n" 04304 " Could not delete RefVertex %d.\n" 04305 " The Model database is likely corrupted " 04306 "due to\n this unsuccessful deletion.\n", 04307 refVertexPtr->id()); 04308 assert( status != CUBIT_FAILURE) ; 04309 break; 04310 } 04311 } 04312 04313 04314 // reset counters 04315 RefEntityFactory::instance()->reset_ids(); 04316 04317 } 04318 04319 CubitStatus GeometryQueryTool::ref_entity_list(char const* keyword, 04320 DLIList<RefEntity*> &entity_list, 04321 const CubitBoolean print_errors) 04322 { 04323 return RefEntityFactory::instance()->ref_entity_list(keyword, entity_list, 04324 print_errors); 04325 } 04326 04327 CubitBox GeometryQueryTool::model_bounding_box() 04328 { 04329 int i; 04330 CubitBox result; 04331 DLIList<Body*> bodies; 04332 this->bodies(bodies); 04333 04334 DLIList<RefEntity*> free_entity_list; 04335 this->get_free_ref_entities(free_entity_list); 04336 04337 if (!(bodies.size() + free_entity_list.size())) 04338 return result; 04339 04340 bodies.reset(); 04341 free_entity_list.reset(); 04342 04343 if( bodies.size() ) 04344 { 04345 result = bodies.get_and_step()->bounding_box(); 04346 for ( i = bodies.size()-1; i--; ) 04347 result |= bodies.get_and_step()->bounding_box(); 04348 i = free_entity_list.size(); 04349 } 04350 else 04351 { 04352 result = free_entity_list.get_and_step()->bounding_box(); 04353 i = free_entity_list.size()-1; 04354 } 04355 04356 for ( ; i>0 ; i-- ) 04357 result |= free_entity_list.get_and_step()->bounding_box(); 04358 04359 return result; 04360 } 04361 04362 void GeometryQueryTool::bodies(DLIList<Body*> &bodies) 04363 { 04364 RefEntityFactory::instance()->bodies(bodies); 04365 } 04366 04367 void GeometryQueryTool::ref_volumes(DLIList<RefVolume*> &ref_volumes) 04368 { 04369 RefEntityFactory::instance()->ref_volumes(ref_volumes); 04370 } 04371 04372 void GeometryQueryTool::ref_groups(DLIList<RefGroup*> &ref_groups) 04373 { 04374 RefEntityFactory::instance()->ref_groups(ref_groups); 04375 } 04376 04377 void GeometryQueryTool::ref_faces(DLIList<RefFace*> &ref_faces) 04378 { 04379 RefEntityFactory::instance()->ref_faces(ref_faces); 04380 } 04381 04382 void GeometryQueryTool::ref_edges(DLIList<RefEdge*> &ref_edges) 04383 { 04384 RefEntityFactory::instance()->ref_edges(ref_edges); 04385 } 04386 04387 void GeometryQueryTool::ref_vertices(DLIList<RefVertex*> &ref_vertices) 04388 { 04389 RefEntityFactory::instance()->ref_vertices(ref_vertices); 04390 } 04391 04392 void GeometryQueryTool::get_ordered_loops(RefFace* face, DLIList<Loop*> &loop_list) 04393 { 04394 GeometryQueryEngine *gqe = face->get_geometry_query_engine(); 04395 gqe->get_ordered_loops(face, loop_list); 04396 } 04397 04398 #ifdef PROE 04399 void GeometryQueryTool::ref_parts (DLIList<RefPart*> &ref_parts) 04400 { 04401 RefEntityFactory::instance()->ref_parts(ref_parts); 04402 } 04403 04404 void GeometryQueryTool::ref_assemblies (DLIList<RefAssembly*> &ref_assemblies) 04405 { 04406 RefEntityFactory::instance()->ref_assemblies(ref_assemblies); 04407 } 04408 #endif 04409 04410 int GeometryQueryTool::num_bodies() const 04411 { 04412 return RefEntityFactory::instance()->num_bodies(); 04413 } 04414 04415 int GeometryQueryTool::num_ref_volumes() const 04416 { 04417 return RefEntityFactory::instance()->num_ref_volumes(); 04418 } 04419 04420 int GeometryQueryTool::num_ref_groups() const 04421 { 04422 return RefEntityFactory::instance()->num_ref_groups(); 04423 } 04424 04425 int GeometryQueryTool::num_ref_faces() const 04426 { 04427 return RefEntityFactory::instance()->num_ref_faces(); 04428 } 04429 04430 int GeometryQueryTool::num_ref_edges() const 04431 { 04432 return RefEntityFactory::instance()->num_ref_edges(); 04433 } 04434 04435 int GeometryQueryTool::num_ref_vertices() const 04436 { 04437 return RefEntityFactory::instance()->num_ref_vertices(); 04438 } 04439 04440 RefEntity *GeometryQueryTool::get_ref_entity(const char *type, int id) 04441 { 04442 return RefEntityFactory::instance()->get_ref_entity(type, id); 04443 } 04444 04445 RefEntity *GeometryQueryTool::get_ref_entity(const std::type_info& type, int id) 04446 { 04447 return RefEntityFactory::instance()->get_ref_entity(type, id); 04448 } 04449 04450 Body *GeometryQueryTool::get_body( int id) 04451 { 04452 return RefEntityFactory::instance()->get_body(id); 04453 } 04454 04455 RefVolume *GeometryQueryTool::get_ref_volume( int id) 04456 { 04457 return RefEntityFactory::instance()->get_ref_volume(id); 04458 } 04459 04460 RefGroup *GeometryQueryTool::get_ref_group( int id) 04461 { 04462 return RefEntityFactory::instance()->get_ref_group(id); 04463 } 04464 04465 RefFace *GeometryQueryTool::get_ref_face( int id) 04466 { 04467 return RefEntityFactory::instance()->get_ref_face(id); 04468 } 04469 04470 RefEdge *GeometryQueryTool::get_ref_edge( int id) 04471 { 04472 return RefEntityFactory::instance()->get_ref_edge(id); 04473 } 04474 04475 RefVertex *GeometryQueryTool::get_ref_vertex( int id) 04476 { 04477 return RefEntityFactory::instance()->get_ref_vertex(id); 04478 } 04479 04480 Body *GeometryQueryTool::get_first_body() 04481 { 04482 return RefEntityFactory::instance()->get_first_body(); 04483 } 04484 04485 RefVolume *GeometryQueryTool::get_first_ref_volume() 04486 { 04487 return RefEntityFactory::instance()->get_first_ref_volume(); 04488 } 04489 04490 RefGroup *GeometryQueryTool::get_first_ref_group() 04491 { 04492 return RefEntityFactory::instance()->get_first_ref_group(); 04493 } 04494 04495 RefFace *GeometryQueryTool::get_first_ref_face() 04496 { 04497 return RefEntityFactory::instance()->get_first_ref_face(); 04498 } 04499 04500 RefEdge *GeometryQueryTool::get_first_ref_edge() 04501 { 04502 return RefEntityFactory::instance()->get_first_ref_edge(); 04503 } 04504 04505 RefVertex *GeometryQueryTool::get_first_ref_vertex() 04506 { 04507 return RefEntityFactory::instance()->get_first_ref_vertex(); 04508 } 04509 04510 Body *GeometryQueryTool::get_next_body() 04511 { 04512 return RefEntityFactory::instance()->get_next_body(); 04513 } 04514 04515 RefVolume *GeometryQueryTool::get_next_ref_volume() 04516 { 04517 return RefEntityFactory::instance()->get_next_ref_volume(); 04518 } 04519 04520 RefGroup *GeometryQueryTool::get_next_ref_group() 04521 { 04522 return RefEntityFactory::instance()->get_next_ref_group(); 04523 } 04524 04525 RefFace *GeometryQueryTool::get_next_ref_face() 04526 { 04527 return RefEntityFactory::instance()->get_next_ref_face(); 04528 } 04529 04530 RefEdge *GeometryQueryTool::get_next_ref_edge() 04531 { 04532 return RefEntityFactory::instance()->get_next_ref_edge(); 04533 } 04534 04535 RefVertex *GeometryQueryTool::get_next_ref_vertex() 04536 { 04537 return RefEntityFactory::instance()->get_next_ref_vertex(); 04538 } 04539 04540 04541 Body *GeometryQueryTool::get_last_body() 04542 { 04543 return RefEntityFactory::instance()->get_last_body(); 04544 } 04545 04546 RefVolume *GeometryQueryTool::get_last_ref_volume() 04547 { 04548 return RefEntityFactory::instance()->get_last_ref_volume(); 04549 } 04550 04551 RefGroup *GeometryQueryTool::get_last_ref_group() 04552 { 04553 return RefEntityFactory::instance()->get_last_ref_group(); 04554 } 04555 04556 RefFace *GeometryQueryTool::get_last_ref_face() 04557 { 04558 return RefEntityFactory::instance()->get_last_ref_face(); 04559 } 04560 04561 RefEdge *GeometryQueryTool::get_last_ref_edge() 04562 { 04563 return RefEntityFactory::instance()->get_last_ref_edge(); 04564 } 04565 04566 RefVertex *GeometryQueryTool::get_last_ref_vertex() 04567 { 04568 return RefEntityFactory::instance()->get_last_ref_vertex(); 04569 } 04570 04571 CubitStatus GeometryQueryTool::get_free_ref_entities(DLIList<RefEntity*> &free_entities) 04572 { 04573 // go through the global entity lists looking for free entities 04574 04575 // this algorithm works as follows: start by marking all entities in the model; 04576 // - bodies that don't have virtual children are NOT free, along with their children; 04577 // unmark them all 04578 // - for all remaining entities: 04579 // . entities that are unmarked are not free since they were unmarked during the 04580 // body check 04581 // . entities that are virtual are not free, but their underlying entities may be; 04582 // check this, and unmark the underlying non-free entities, but not their children 04583 // . entities that don't have a TopologyBridge connected to a bodysm are free 04584 // 04585 // - Removed virtual stuff - no longer required - J.Kraftcheck 10-8-2003 04586 04587 int i, j; 04588 RefEntityFactory *REF = RefEntityFactory::instance(); 04589 04590 // define a macro to mark all the children 04591 #define MARK_CHILDREN(entity, index) \ 04592 {ref_list.clean_out(); entity->get_all_child_ref_entities(ref_list); \ 04593 for (index=ref_list.size(); index>0; index--) ref_list.get_and_step()->marked(0);} 04594 04595 // mark all entities first 04596 for (i = REF->num_ref_volumes(); i > 0; i--) 04597 REF->get_next_ref_volume()->marked(1); 04598 for (i = REF->num_ref_faces(); i > 0; i--) 04599 REF->get_next_ref_face()->marked(1); 04600 for (i = REF->num_ref_edges(); i > 0; i--) 04601 REF->get_next_ref_edge()->marked(1); 04602 for (i = REF->num_ref_vertices(); i > 0; i--) 04603 REF->get_next_ref_vertex()->marked(1); 04604 04605 DLIList<RefEntity*> ref_list; 04606 04607 // first, mark all the children of bodies 04608 Body *body; 04609 for (i = REF->num_bodies(); i > 0; i--) { 04610 body = REF->get_next_body(); 04611 MARK_CHILDREN(body, j); 04612 } 04613 04614 // now go through them, checking for VG and free entities 04615 RefVolume *volume; 04616 for (i = REF->num_ref_volumes(); i > 0; i--) { 04617 volume = REF->get_next_ref_volume(); 04618 if (volume->marked()) { 04619 // go through volume's children & unmark 04620 MARK_CHILDREN(volume, j); 04621 free_entities.append(volume); 04622 volume->marked(0); 04623 } 04624 } 04625 04626 RefFace *face; 04627 for (i = REF->num_ref_faces(); i > 0; i--) { 04628 face = REF->get_next_ref_face(); 04629 if (face->marked()) { 04630 MARK_CHILDREN(face, j); 04631 free_entities.append(face); 04632 face->marked(0); 04633 } 04634 } 04635 04636 RefEdge *edge; 04637 for (i = REF->num_ref_edges(); i > 0; i--) { 04638 edge = REF->get_next_ref_edge(); 04639 if (edge->marked()) { 04640 MARK_CHILDREN(edge, j); 04641 free_entities.append(edge); 04642 edge->marked(0); 04643 } 04644 } 04645 04646 RefVertex *vertex; 04647 for (i = REF->num_ref_vertices(); i > 0; i--) { 04648 vertex = REF->get_next_ref_vertex(); 04649 if (vertex->marked()) { 04650 free_entities.append(vertex); 04651 vertex->marked(0); 04652 } 04653 } 04654 04655 return CUBIT_SUCCESS; 04656 } 04657 04658 04659 double GeometryQueryTool::surface_angle(RefFace *ref_face_1, RefFace *ref_face_2, 04660 RefEdge *ref_edge, 04661 RefVolume *ref_volume, 04662 double frac) 04663 { 04664 04665 // check for and supply missing ref edge if necessary 04666 if (ref_edge == NULL) { 04667 ref_edge = ref_face_1->common_ref_edge(ref_face_2); 04668 assert (ref_edge != NULL); 04669 } 04670 04671 if (ref_volume == NULL) { 04672 ref_volume = ref_face_1->common_ref_volume(ref_face_2); 04673 assert(ref_volume != NULL); 04674 } 04675 04676 //Find the dihedral angle for the ref_edge 04677 CubitVector mid_point; 04678 if ( frac != .5 ) 04679 ref_edge->position_from_fraction(frac, mid_point); 04680 else 04681 mid_point = ref_edge->center_point(); 04682 04683 04684 //Now find the normals of the surfaces at this point, wrt volume 04685 CubitVector surf_1_norm = ref_face_1->normal_at( mid_point, ref_volume ); 04686 CubitVector surf_2_norm = ref_face_2->normal_at( mid_point, ref_volume ); 04687 04688 //Now we need to get the correct normal 04689 CubitVector tangent_vector; 04690 04691 //This gets the correct tangent with respect for to the 04692 //ref_face_ptr. Do the following check for non-manifold volumes. 04693 //This function will assert if the ref_edge has more than 04694 //one co_edge for the two_faces. But this should be okay 04695 //since up above this function, that should be traped for... 04696 04697 //Weed-out case where one edge is shared between more 04698 //than 2 surfaces of the same volume 04699 DLIList<RefFace*> tmp_faces; 04700 ref_edge->ref_faces( tmp_faces ); 04701 04702 if( tmp_faces.size() > 2 ) 04703 { 04704 int kk; 04705 for(kk=tmp_faces.size(); kk--;) 04706 { 04707 if( !tmp_faces.get()->is_child( ref_volume ) ) 04708 tmp_faces.change_to(NULL); 04709 tmp_faces.step(); 04710 } 04711 tmp_faces.remove_all_with_value( NULL ); 04712 if( tmp_faces.size() > 2 ) 04713 //this isn't the type of surface we are looking for... 04714 return 0.0; 04715 } 04716 04717 04718 ref_edge->tangent( mid_point, tangent_vector, ref_face_1 ); 04719 CubitSense face_1_sense = ref_face_1->sense( ref_volume ); 04720 04721 if( CUBIT_REVERSED != face_1_sense && CUBIT_FORWARD != face_1_sense ) 04722 if(!(ref_volume->is_sheet())) 04723 return 0.0; 04724 04725 if ( face_1_sense == CUBIT_REVERSED ) 04726 tangent_vector = -tangent_vector; 04727 04728 double angle = CUBIT_PI + 04729 tangent_vector.vector_angle(surf_2_norm, surf_1_norm ); 04730 // note 1 and 2 switched. 04731 // tangent is cw, opposite of rhr 04732 04733 // Range of above is pi/2 to 5pi/2, shift to 0 to 2pi. 04734 if ( angle >= 2.0* CUBIT_PI ) 04735 angle -= 2.0 * CUBIT_PI; 04736 04737 // if the angle is close to 0 or 2pi, use a center point check 04738 // to figure out if the interior angle is zero or 2pi 04739 const double min_tol = 0.1; // CUBIT_RESABS*100. too small 04740 // We could have a real overlap in some models, so keep 04741 // min_tol fairly big. 04742 const double max_tol = 2.0*CUBIT_PI - min_tol; 04743 04744 // angle near zero - 2pi, make some checks at nearby locations 04745 if (angle <= min_tol || angle >= max_tol ) 04746 { 04747 // try to get the inside-outness where the surfaces have a gap 04748 // between them 04749 04750 // get a non-shared edge with a shared vertex between the surfaces 04751 04752 int i; 04753 04754 // get the next edge in the loop 04755 DLIList<DLIList<RefEdge*> > loops_1; 04756 DLIList<RefEdge*> *loop_1 = NULL; 04757 ref_face_1->ref_edge_loops( loops_1 ); 04758 for ( i = loops_1.size(); i--; ) 04759 { 04760 loop_1 = &loops_1.get_and_step(); 04761 if ( loop_1->move_to( ref_edge ) ) 04762 break; 04763 } 04764 assert( loop_1->get() == ref_edge ); 04765 04766 DLIList<DLIList<RefEdge*> > loops_2; 04767 DLIList<RefEdge*> *loop_2 = NULL; 04768 ref_face_2->ref_edge_loops( loops_2 ); 04769 for ( i = loops_2.size(); i--; ) 04770 { 04771 loop_2 = &loops_2.get_and_step(); 04772 if ( loop_2->move_to( ref_edge ) ) 04773 break; 04774 } 04775 assert( loop_2->get() == ref_edge ); 04776 04777 RefEdge *common_edge = ref_edge, *next_edge, 04778 *uncommon_edge_1 = NULL, *uncommon_edge_2 = NULL; 04779 RefVertex *common_vertex = NULL; 04780 04781 for ( i = loop_1->size(); !common_vertex && i--; ) 04782 { 04783 next_edge = loop_1->step_and_get(); 04784 if ( loop_2->prev() == next_edge ) 04785 { 04786 loop_2->back(); 04787 common_edge = next_edge; 04788 } 04789 else if ( loop_2->next() == next_edge ) 04790 { 04791 loop_2->step(); 04792 common_edge = next_edge; 04793 } 04794 else 04795 { 04796 uncommon_edge_1 = next_edge; 04797 04798 // if both vertices are shared, it doesn't matter which we chose. 04799 common_vertex = common_edge->common_ref_vertex( uncommon_edge_1 ); 04800 04801 if ( loop_2->next()->is_parent( common_vertex ) ) 04802 uncommon_edge_2 = loop_2->next(); 04803 else 04804 { 04805 assert( loop_2->prev()->is_parent( common_vertex ) ); 04806 uncommon_edge_2 = loop_2->prev(); 04807 } 04808 } 04809 } 04810 04811 int too_far; 04812 04813 CubitVector center_1, center_2, center_norm_1, center_norm_2; 04814 04815 // we've found non-common edges with a common vertex 04816 int bad_angle = CUBIT_TRUE; 04817 if ( common_vertex ) 04818 { 04819 04820 // These two curves are only good geometrically if they 04821 // have a small angle between them: If the angle is too big, 04822 // then the closest pt will be the vertex, and we'll have to 04823 // start over with the surfaces or something. 04824 04825 // reset midpoint and normals to common vertex... 04826 CubitVector vertex_coord = common_vertex->coordinates(); 04827 04828 // get a pair of close points on each surface 04829 center_1 = uncommon_edge_1->center_point(); 04830 center_2 = uncommon_edge_2->center_point(); 04831 04832 double d_1 = (center_1 - vertex_coord).length_squared(); 04833 double d_2 = (center_2 - vertex_coord).length_squared(); 04834 int give_up = 0; 04835 i = 0; 04836 if ( d_1 <= d_2 ) 04837 { 04838 do 04839 { 04840 center_2 = center_1; 04841 uncommon_edge_2->move_to_curve( center_2 ); 04842 d_2 = (center_2 - vertex_coord).length_squared(); 04843 bad_angle = d_2 < d_1 * 0.2; 04844 give_up = ( d_1 < GEOMETRY_RESABS*10 || i++ > 10 ); 04845 if ( give_up ) 04846 break; 04847 if ( bad_angle ) 04848 { 04849 center_1 += vertex_coord; 04850 center_1 /= 2.0; 04851 uncommon_edge_1->move_to_curve( center_1 ); 04852 d_1 = (center_1 - vertex_coord).length_squared(); 04853 } 04854 } while ( bad_angle ); 04855 } 04856 else 04857 { 04858 do 04859 { 04860 center_1 = center_2; 04861 uncommon_edge_1->move_to_curve( center_1 ); 04862 d_1 = (center_1 - vertex_coord).length_squared(); 04863 bad_angle = d_1 < d_2 * 0.2; 04864 give_up = ( d_2 < GEOMETRY_RESABS*10 || i++ > 10 ); 04865 if ( give_up ) 04866 break; 04867 if ( bad_angle ) 04868 { 04869 center_2 += vertex_coord; 04870 center_2 /= 2.0; 04871 uncommon_edge_2->move_to_curve( center_2 ); 04872 d_2 = (center_2 - vertex_coord).length_squared(); 04873 } 04874 } while ( bad_angle ); 04875 } 04876 if ( !bad_angle ) 04877 { 04878 mid_point = vertex_coord; 04879 surf_1_norm = ref_face_1->normal_at( mid_point, ref_volume ); 04880 surf_2_norm = ref_face_2->normal_at( mid_point, ref_volume ); 04881 04882 04883 double best_d_1 = CUBIT_DBL_MAX; 04884 04885 CubitVector test_center_1 = center_1; 04886 CubitVector test_center_norm_1; 04887 04888 // may be too far away - make sure normal is roughly the same 04889 // as at the midpoint 04890 04891 too_far = CUBIT_TRUE; 04892 for ( i = 12; i-- && too_far; ) 04893 { 04894 test_center_norm_1 = 04895 ref_face_1->normal_at( test_center_1, ref_volume ); 04896 d_1 = test_center_norm_1 % surf_1_norm; 04897 if ( d_1 < best_d_1 ) 04898 { 04899 center_1 = test_center_1; 04900 center_norm_1 = test_center_norm_1; 04901 } 04902 too_far = d_1 < 0.2; 04903 if ( too_far && i ) // skip last time 04904 { 04905 test_center_1 += mid_point; 04906 test_center_1 /= 2.0; 04907 uncommon_edge_1->move_to_curve( test_center_1 ); 04908 } 04909 } 04910 04911 double best_d_2 = CUBIT_DBL_MAX; 04912 04913 CubitVector test_center_2 = center_2; 04914 CubitVector test_center_norm_2; 04915 04916 // may be too far away - make sure normal is roughly the same 04917 // as at the surface midpoint 04918 too_far = CUBIT_TRUE; 04919 for ( i = 12; i-- && too_far; ) 04920 { 04921 test_center_norm_2 = 04922 ref_face_2->normal_at( test_center_2, ref_volume ); 04923 d_2 = test_center_norm_2 % surf_2_norm; 04924 if ( d_2 < best_d_2 ) 04925 { 04926 center_2 = test_center_2; 04927 center_norm_2 = test_center_norm_2; 04928 } 04929 too_far = d_2 < 0.2; 04930 if ( too_far && i ) // skip last time 04931 { 04932 test_center_2 += mid_point; 04933 test_center_2 /= 2.0; 04934 uncommon_edge_2->move_to_curve( test_center_2 ); 04935 } 04936 } 04937 } 04938 } 04939 // surfaces share all edges! try the face center point 04940 if ( !common_vertex || bad_angle ) 04941 { 04942 04943 // get a pair of close points on each surface 04944 center_1 = ref_face_1->center_point(); 04945 center_2 = ref_face_2->center_point(); 04946 double d_1 = (center_1 - mid_point).length_squared(); 04947 double d_2 = (center_2 - mid_point).length_squared(); 04948 if ( d_1 <= d_2 ) 04949 { 04950 center_2 = center_1; 04951 ref_face_2->move_to_surface( center_2 ); 04952 } 04953 else 04954 { 04955 center_1 = center_2; 04956 ref_face_1->move_to_surface( center_1 ); 04957 } 04958 04959 double best_d_1 = CUBIT_DBL_MAX; 04960 04961 CubitVector test_center_1 = center_1; 04962 CubitVector test_center_norm_1; 04963 04964 // may be too far away - make sure normal is roughly the same 04965 // as at the curve midpoint 04966 too_far = CUBIT_TRUE; 04967 for ( i = 12; i-- && too_far; ) 04968 { 04969 test_center_norm_1 = 04970 ref_face_1->normal_at( test_center_1, ref_volume ); 04971 d_1 = test_center_norm_1 % surf_1_norm; 04972 if ( d_1 < best_d_1 ) 04973 { 04974 center_1 = test_center_1; 04975 center_norm_1 = test_center_norm_1; 04976 } 04977 too_far = d_1 < 0.2; 04978 if ( too_far && i ) // skip last time 04979 { 04980 test_center_1 += mid_point; 04981 test_center_1 /= 2.0; 04982 ref_face_1->move_to_surface( test_center_1 ); 04983 } 04984 } 04985 04986 // surfaces share all edge! try the center point 04987 double best_d_2 = CUBIT_DBL_MAX; 04988 04989 CubitVector test_center_2 = center_2; 04990 CubitVector test_center_norm_2; 04991 04992 // may be too far away - make sure normal is roughly the same 04993 // as at the curve midpoint 04994 too_far = CUBIT_TRUE; 04995 for ( i = 12; i-- && too_far; ) 04996 { 04997 test_center_norm_2 = 04998 ref_face_2->normal_at( test_center_2, ref_volume ); 04999 d_2 = test_center_norm_2 % surf_2_norm; 05000 if ( d_2 < best_d_2 ) 05001 { 05002 center_2 = test_center_2; 05003 center_norm_2 = test_center_norm_2; 05004 } 05005 too_far = d_2 < 0.2; 05006 if ( too_far && i ) // skip last time 05007 { 05008 test_center_2 += mid_point; 05009 test_center_2 /= 2.0; 05010 ref_face_2->move_to_surface( test_center_2 ); 05011 } 05012 } 05013 } 05014 05015 // gap vector from center_1 to center_2 05016 CubitVector gap_vector = center_2; 05017 gap_vector -= center_1; 05018 05019 double gap_d = gap_vector % center_norm_1; 05020 gap_d += -gap_vector % center_norm_2; 05021 05022 if ( gap_d >= 0 ) 05023 { 05024 if ( angle < max_tol ) 05025 angle = 2*CUBIT_PI; 05026 // else leave at its current nearly-2pi value 05027 } 05028 else 05029 if ( angle > min_tol ) 05030 angle = 0.; 05031 // else leave at its current nearly-zero value 05032 05033 } // if angle near zero - 2pi 05034 05035 return angle; 05036 } 05037 05038 //------------------------------------------------------------------------- 05039 // Purpose : Find a common geometry query engine 05040 // 05041 // Special Notes : 05042 // 05043 // Creator : Jason Kraftcheck 05044 // 05045 // Creation Date : 02/28/00 05046 //------------------------------------------------------------------------- 05047 GeometryQueryEngine* GeometryQueryTool::common_query_engine( 05048 DLIList<TopologyEntity*>& topology_list, 05049 DLIList<TopologyBridge*>& engine_bridges, 05050 CubitBoolean allow_default_engine ) const 05051 { 05052 topology_list.reset(); 05053 05054 TopologyEntity* topo_ptr = topology_list.get_and_step(); 05055 DLIList<TopologyBridge*> first_bridge_list; 05056 topo_ptr->bridge_manager()->get_bridge_list( first_bridge_list ); 05057 05058 first_bridge_list.reset(); 05059 GeometryQueryEngine* gqe_ptr = 0; 05060 for( int i = first_bridge_list.size(); i > 0; i-- ) 05061 { 05062 TopologyBridge* bridge_ptr = first_bridge_list.get_and_step(); 05063 engine_bridges.clean_out(); 05064 engine_bridges.append( bridge_ptr ); 05065 gqe_ptr = bridge_ptr->get_geometry_query_engine(); 05066 05067 topology_list.reset(); 05068 topology_list.step(); //skip first entry 05069 for( int j = topology_list.size(); j > 1; j-- ) 05070 { 05071 topo_ptr = topology_list.get_and_step(); 05072 bridge_ptr = topo_ptr->bridge_manager()->topology_bridge(gqe_ptr); 05073 if( bridge_ptr ) engine_bridges.append( bridge_ptr ); 05074 else break; 05075 } 05076 05077 if( engine_bridges.size() == topology_list.size() ) 05078 break; 05079 05080 gqe_ptr = 0; 05081 } 05082 05083 if( !gqe_ptr ) 05084 { 05085 engine_bridges.clean_out(); 05086 05087 if( allow_default_engine ) 05088 { 05089 PRINT_WARNING("Entities do not belong to the same geometry " 05090 "engine. Using the default geometry engine.\n"); 05091 gqe_ptr = default_gqe; 05092 topology_list.reset(); 05093 for( int j = topology_list.size(); j > 0; j-- ) 05094 { 05095 topo_ptr = topology_list.get_and_step(); 05096 TopologyBridge* bridge_ptr = 05097 topo_ptr->bridge_manager()->topology_bridge( gqe_ptr ); 05098 if( ! bridge_ptr ) 05099 bridge_ptr = topo_ptr->bridge_manager()->topology_bridge(); 05100 engine_bridges.append( bridge_ptr ); 05101 } 05102 } 05103 } 05104 05105 return gqe_ptr; 05106 } 05107 05108 05109 void GeometryQueryTool::get_connected_free_ref_entities( 05110 RefEntity *entity, 05111 const int merge_option, 05112 DLIList<Body*> &body_list, 05113 DLIList<RefFace*> &ref_face_list, 05114 DLIList<RefEdge*> &ref_edge_list, 05115 DLIList<RefVertex*> &ref_vertex_list ) 05116 { 05117 05118 body_list.clean_out(); 05119 ref_face_list.clean_out(); 05120 ref_edge_list.clean_out(); 05121 ref_vertex_list.clean_out(); 05122 05123 if ( !entity ) 05124 return; 05125 05126 // cases are different enough, just do something totally different 05127 if ( !merge_option ) 05128 { 05129 // get top level entities 05130 TopologyEntity *source_entity = CAST_TO(entity, TopologyEntity); 05131 05132 Body *body = CAST_TO( source_entity, Body ); 05133 if( body ) 05134 body_list.append( body ); 05135 else 05136 // get attached bodies, if any 05137 source_entity->bodies( body_list ); 05138 05139 if(body_list.size() == 0) 05140 { 05141 RefEdge* ref_edge = CAST_TO(source_entity, RefEdge); 05142 if ( ref_edge ) 05143 ref_edge_list.append( ref_edge ); 05144 else 05145 { 05146 source_entity->ref_edges( ref_edge_list ); 05147 } 05148 if ( ref_edge_list.size() == 0 ) 05149 { 05150 RefVertex *vert = CAST_TO( source_entity, RefVertex ); 05151 if ( vert ) 05152 ref_vertex_list.append( vert ); 05153 } 05154 } 05155 // this is the easy case, we're all done 05156 return; 05157 } 05158 05159 05160 // merge_option == 1 05161 DLIList <TopologyEntity*> source_list; 05162 DLIList <RefEntity*> source_entity_list; 05163 05164 int i; 05165 05166 DLIList <RefEntity*> free_list; 05167 05168 DLIList<TopologyBridge*> bridge_list; 05169 05170 TopologyEntity *topo_entity = CAST_TO( entity, TopologyEntity ); 05171 source_list.append( topo_entity ); 05172 DLIList<RefEntity*> entity_list; 05173 do 05174 { 05175 // get vertices (bottom level ref entities) 05176 source_entity_list.clean_out(); 05177 05178 for (i = source_list.size(); i--; ) 05179 { 05180 TopologyEntity *source_entity = source_list.get_and_step(); 05181 DLIList<RefVertex*> local_vert_list; 05182 DLIList<RefEntity*> tmp_source_entity_list; 05183 source_entity->ref_vertices( local_vert_list ); 05184 if(local_vert_list.size() == 0) 05185 { 05186 DLIList<RefEdge*> local_edge_list; 05187 source_entity->ref_edges(local_edge_list); 05188 if(local_edge_list.size() == 0) 05189 { 05190 DLIList<RefFace*> local_face_list; 05191 source_entity->ref_faces(local_face_list); 05192 if(local_face_list.size() > 0) 05193 { 05194 CAST_LIST( local_face_list, tmp_source_entity_list, RefEntity); 05195 source_entity_list += tmp_source_entity_list; 05196 } 05197 } 05198 else 05199 { 05200 CAST_LIST( local_edge_list, tmp_source_entity_list, RefEntity); 05201 source_entity_list += tmp_source_entity_list; 05202 } 05203 } 05204 else 05205 { 05206 CAST_LIST( local_vert_list, tmp_source_entity_list, RefEntity); 05207 source_entity_list += tmp_source_entity_list; 05208 } 05209 } 05210 source_list.clean_out(); 05211 05212 // get top level entities 05213 for ( i = source_entity_list.size(); i--; ) 05214 { 05215 RefEntity *source_entity = source_entity_list.get_and_step(); 05216 // get all upwards related ref entities 05217 entity_list.clean_out(); 05218 // get the bodies, too! 05219 source_entity->get_all_parent_ref_entities( entity_list, CUBIT_TRUE ); 05220 entity_list.append( source_entity ); 05221 05222 // check each one to see if it is a new top level in the solid 05223 // modeller 05224 int j; 05225 for ( j = entity_list.size(); j--; ) 05226 { 05227 // entity is top level if it has a topology bridge that has a bodysm 05228 RefEntity *ref_entity = entity_list.get_and_step(); 05229 05230 if ( !ref_entity->marked() ) 05231 { 05232 bridge_list.clean_out(); 05233 topo_entity = CAST_TO( ref_entity, TopologyEntity ); 05234 topo_entity->bridge_manager()->get_bridge_list(bridge_list); 05235 int k; 05236 bool no_parents = true; 05237 for ( k = bridge_list.size(); k--; ) 05238 { 05239 TopologyBridge* bridge = bridge_list.get_and_step(); 05240 DLIList<TopologyBridge*> parents; 05241 bridge->get_parents( parents ); 05242 if( parents.size() ) 05243 { 05244 no_parents = false; 05245 break; 05246 } 05247 } 05248 if( no_parents ) 05249 { 05250 ref_entity->marked( 1 ); 05251 topo_entity = CAST_TO( ref_entity, TopologyEntity ); 05252 source_list.append( topo_entity ); 05253 free_list.append( ref_entity ); 05254 continue; 05255 } 05256 } 05257 } 05258 } 05259 05260 } while( source_list.size() ); 05261 05262 // xfer data, clean up marks 05263 for ( i = free_list.size(); i--; ) 05264 { 05265 RefEntity *ref_entity = free_list.get_and_step(); 05266 ref_entity->marked(0); 05267 } 05268 CAST_LIST( free_list, body_list, Body ); 05269 CAST_LIST( free_list, ref_face_list, RefFace); 05270 CAST_LIST( free_list, ref_edge_list, RefEdge); 05271 CAST_LIST( free_list, ref_vertex_list, RefVertex); 05272 } 05273 05274 05275 CubitStatus GeometryQueryTool::register_intermediate_engine( 05276 IntermediateGeomEngine* engine_ptr ) 05277 { 05278 return (CubitStatus)igeSet.insert(engine_ptr).second; 05279 } 05280 05281 void GeometryQueryTool::unregister_intermediate_engine( 05282 IntermediateGeomEngine* engine_ptr ) 05283 { 05284 igeSet.erase(engine_ptr); 05285 } 05286 05287 void GeometryQueryTool::ige_export_geom( DLIList<TopologyBridge*> &geom_list ) 05288 { 05289 for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 05290 (*itor)->export_geometry(geom_list); 05291 } 05292 05293 void GeometryQueryTool::ige_push_imprint_attributes_before_modify 05294 ( DLIList<BodySM*> &geom_list ) 05295 { 05296 for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 05297 (*itor)->push_imprint_attributes_before_modify(geom_list); 05298 } 05299 05300 void GeometryQueryTool::ige_push_named_attributes_to_curves_and_points 05301 ( DLIList<TopologyBridge*> &tb_list, const char *name_in ) 05302 { 05303 for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 05304 (*itor)->push_named_attributes_to_curves_and_points(tb_list, name_in); 05305 } 05306 05307 void GeometryQueryTool::ige_remove_imprint_attributes_after_modify 05308 ( DLIList<BodySM*> &old_sms, 05309 DLIList<BodySM*> &new_sms ) 05310 { 05311 for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 05312 (*itor)->remove_imprint_attributes_after_modify(old_sms, new_sms); 05313 } 05314 05315 bool GeometryQueryTool::ige_is_composite(TBOwner *bridge_owner) 05316 { 05317 bool ret = false; 05318 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end() && ret != true; ++itor) 05319 { 05320 if((*itor)->is_composite(bridge_owner)) 05321 { 05322 ret = true; 05323 } 05324 } 05325 return ret; 05326 } 05327 05328 bool GeometryQueryTool::ige_is_composite(TopologyBridge *bridge) 05329 { 05330 bool ret = false; 05331 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end() && ret != true; ++itor) 05332 { 05333 if((*itor)->is_composite(bridge)) 05334 { 05335 ret = true; 05336 } 05337 } 05338 return ret; 05339 } 05340 05341 05342 bool GeometryQueryTool::ige_is_partition(TBOwner *bridge_owner) 05343 { 05344 bool ret = false; 05345 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end() && ret != true; ++itor) 05346 { 05347 if((*itor)->is_partition(bridge_owner)) 05348 { 05349 ret = true; 05350 } 05351 } 05352 return ret; 05353 } 05354 05355 void GeometryQueryTool::ige_import_geom( DLIList<TopologyBridge*> &geom_list ) 05356 { 05357 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 05358 (*itor)->import_geometry(geom_list); 05359 } 05360 05361 void GeometryQueryTool::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge, 05362 DLIList<TopologyBridge*> &tbs ) 05363 { 05364 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 05365 (*itor)->get_tbs_with_bridge_manager_as_owner( source_bridge, tbs ); 05366 } 05367 05368 void GeometryQueryTool::ige_attribute_after_imprinting(DLIList<TopologyBridge*> &tb_list, 05369 DLIList<Body*> &old_bodies) 05370 { 05371 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 05372 (*itor)->attribute_after_imprinting(tb_list, old_bodies); 05373 } 05374 05375 void GeometryQueryTool::ige_remove_attributes( DLIList<TopologyBridge*> &geom_list ) 05376 { 05377 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 05378 (*itor)->remove_attributes(geom_list); 05379 } 05380 05381 void GeometryQueryTool::ige_remove_attributes_from_unmodifed_virtual(DLIList<TopologyBridge*> &bridges) 05382 { 05383 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 05384 (*itor)->remove_attributes_from_unmodifed_virtual(bridges); 05385 } 05386 05387 bool GeometryQueryTool::contains_intermediate_geometry(DLIList<RefEntity*>& ref_entity_list) const 05388 { 05389 // Unfortunately, the current implementation of partition creates virtual 05390 // bodies as well as virtual subentities. Thus, we have to go up the tree 05391 // as well as down it. 05392 // TODO: Partitioning HAS got to change. KGM 2/9/06 05393 //get the owning bodies 05394 DLIList<Body*> body_list; 05395 int j; 05396 for(j=ref_entity_list.size(); j--;) 05397 { 05398 TopologyEntity* te = dynamic_cast<TopologyEntity*>( ref_entity_list.get_and_step()); 05399 te->bodies( body_list ); 05400 } 05401 int i; 05402 for ( i = 0; i < body_list.size(); i++) 05403 if (GeometryQueryTool::instance()-> 05404 is_intermediate_geometry(body_list.next(i))) 05405 return true; 05406 05407 for ( i = 0; i < ref_entity_list.size(); i++) 05408 if (GeometryQueryTool::instance()-> 05409 contains_intermediate_geometry(ref_entity_list.next(i))) 05410 return true; 05411 05412 return false; 05413 } 05414 05415 bool GeometryQueryTool::contains_intermediate_geometry(RefEntity* entity_ptr) const 05416 { 05417 if (igeSet.empty()) 05418 return false; 05419 05420 DLIList<RefEntity*> children; 05421 entity_ptr->get_all_child_ref_entities(children); 05422 children.append(entity_ptr); 05423 05424 while(children.size()) 05425 if (is_intermediate_geometry(children.pop())) 05426 return true; 05427 05428 return false; 05429 } 05430 05431 bool GeometryQueryTool::is_intermediate_geometry(RefEntity* entity_ptr) const 05432 { 05433 TopologyEntity* topo_ptr = CAST_TO(entity_ptr, TopologyEntity); 05434 if (!topo_ptr) 05435 return false; 05436 05437 DLIList<TopologyBridge*> bridge_list; 05438 topo_ptr->bridge_manager()->get_bridge_list(bridge_list); 05439 while(bridge_list.size()) 05440 if (is_intermediate_geometry(bridge_list.pop())) 05441 return true; 05442 05443 return false; 05444 } 05445 05446 bool GeometryQueryTool::is_intermediate_geometry( TopologyBridge* bridge ) const 05447 { 05448 if (bridge->get_geometry_query_engine() == NULL ) 05449 return true; 05450 else 05451 return bridge->get_geometry_query_engine()->is_intermediate_engine(); 05452 } 05453 05454 05455 //------------------------------------------------------------------------- 05456 // Purpose : Destroy dead entity and dead children 05457 // 05458 // Special Notes : 05459 // 05460 // Creator : Jason Kraftcheck 05461 // 05462 // Creation Date : 12/08/03 05463 //------------------------------------------------------------------------- 05464 CubitStatus GeometryQueryTool::destroy_dead_entity( 05465 TopologyEntity* topo_ent, 05466 bool top ) const 05467 { 05468 if (topo_ent->get_parents() || topo_ent->bridge_manager()->topology_bridge()) 05469 return CUBIT_FAILURE; 05470 05471 topo_ent->deactivated(CUBIT_TRUE); 05472 05473 CubitObservable* ob = dynamic_cast<CubitObservable*>(topo_ent); 05474 if (ob) 05475 { 05476 if (dynamic_cast<RefEntity*>(topo_ent)) 05477 { 05478 // "top" indicates if this call is the topmost call to this 05479 // recursive function. It should be the case that if it is 05480 // the topmost call and the passed entity is a RefEntity, then 05481 // the entity was top-level (had no parent entities in the 05482 // topology graph.) For cases where dead topology is cleaned 05483 // out and a dead RefEntity is not-top-most, it will have some 05484 // parent sense entity which this function will be called on and 05485 // that call will be the top-most one. 05486 if (top) 05487 { 05488 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOP_LEVEL_ENTITY_DESTRUCTED, static_cast<RefEntity*>(ob))); 05489 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, static_cast<RefEntity*>(ob)); 05490 const_cast<CGMHistory&>(mHistory).add_event(evt); 05491 } 05492 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_ENTITY_DESTRUCTED, static_cast<RefEntity*>(ob))); 05493 } 05494 else 05495 AppUtil::instance()->send_event(TopologyEvent(TopologyEvent::TOPOLOGY_ENTITY_DESTRUCTED, topo_ent)); 05496 } 05497 05498 DLIList<TopologyEntity*> child_list; 05499 topo_ent->disconnect_all_children(&child_list); 05500 child_list.reset(); 05501 for (int i = child_list.size(); i--; ) 05502 { 05503 TopologyEntity* child = child_list.get_and_step(); 05504 TopologyEntity* child_topo_ent = dynamic_cast<TopologyEntity*>(child); 05505 if (child_topo_ent) 05506 { 05507 destroy_dead_entity(child_topo_ent, false); 05508 if (!child_topo_ent->deactivated() && 05509 child_topo_ent->bridge_manager()->number_of_bridges() > 0 && 05510 child_topo_ent->get_parents() == 0 && 05511 NULL != (ob = dynamic_cast<CubitObservable*>(child_topo_ent))) 05512 { 05513 DLIList<TopologyBridge*> list1, list2; 05514 bool has_parents = false; 05515 child_topo_ent->bridge_manager()->get_bridge_list(list1); 05516 while (list1.size()) 05517 { 05518 list2.clean_out(); 05519 list1.pop()->get_parents(list2); 05520 if (list2.size()) 05521 has_parents = true; 05522 } 05523 if (!has_parents) 05524 { 05525 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, static_cast<RefEntity*>(ob))); 05526 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, static_cast<RefEntity*>(ob)); 05527 const_cast<CGMHistory&>(mHistory).add_event(evt); 05528 } 05529 } 05530 } 05531 } 05532 05533 if (top) 05534 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 05535 05536 return CUBIT_SUCCESS; 05537 } 05538 05539 // TODO - find out where this functionality belongs 05540 CubitStatus GeometryQueryTool::import_actuate(DLIList<RefEntity*> &entity_list) 05541 { 05542 int i; 05543 05544 // given a Body list, actuates first the merge partner attribute 05545 // on all entities in the list, then actuates all other types of 05546 // attributes 05547 05548 DLIList<TopologyEntity*> temp_list; 05549 DLIList<RefEntity*> refent_list; 05550 05551 CubitBoolean auto_actuate_merge; 05552 auto_actuate_merge = CGMApp::instance()->attrib_manager()->auto_actuate_flag(CA_MERGE_PARTNER); 05553 05554 05555 if (auto_actuate_merge) { 05556 05557 // Prevent MergeTool from destroying dead entities 05558 // after merging. Otherwise we get stale pointers 05559 // in our lists. 05560 // Don't forget to turn this back on later! 05561 MergeTool::destroy_dead_geometry( false ); 05562 05563 DLIList<TopologyEntity*> me_list; 05564 CAST_LIST(entity_list, me_list, TopologyEntity); 05565 05566 ModelQueryEngine *const mqe = ModelQueryEngine::instance(); 05567 05568 // vertices 05569 mqe->query_model(me_list, DagType::ref_vertex_type(), temp_list); 05570 CAST_LIST(temp_list, refent_list, RefEntity); 05571 // actuate merge attribute for vertices 05572 if (refent_list.size() > 0) 05573 refent_list.get()->actuate_cubit_attrib(refent_list, CA_MERGE_PARTNER); 05574 05575 // edges 05576 temp_list.clean_out(); 05577 refent_list.clean_out(); 05578 mqe->query_model(me_list, DagType::ref_edge_type(), temp_list); 05579 CAST_LIST(temp_list, refent_list, RefEntity); 05580 // actuate merge attribute for edges 05581 if (refent_list.size() > 0) 05582 refent_list.get()->actuate_cubit_attrib(refent_list, CA_MERGE_PARTNER); 05583 05584 // faces 05585 temp_list.clean_out(); 05586 refent_list.clean_out(); 05587 mqe->query_model(me_list, DagType::ref_face_type(), temp_list); 05588 CAST_LIST(temp_list, refent_list, RefEntity); 05589 // actuate merge attribute for faces 05590 if (refent_list.size() > 0) 05591 refent_list.get()->actuate_cubit_attrib(refent_list, CA_MERGE_PARTNER); 05592 05593 // clean out entities destroyed during merge 05594 entity_list.reset(); 05595 for( i = entity_list.size(); i--; ) 05596 { 05597 TopologyEntity* me_ptr = dynamic_cast<TopologyEntity*>(entity_list.get()); 05598 if( me_ptr && me_ptr->deactivated() ) 05599 entity_list.extract(); 05600 else 05601 entity_list.step(); 05602 } 05603 05604 // Restore merge tool setting, and clean up dead geometry 05605 MergeTool::destroy_dead_geometry( true ); 05606 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 05607 } 05608 05609 // now actuate other attributes 05610 RefEntity* entity_ptr; 05611 CAActuateSet actuate_set( entity_list ); 05612 05613 // actuate in increasing dimension 05614 // (vtx = 0, ..., volume = 3, body = 4) 05615 for( i = 0; i < 5; i++ ) 05616 { 05617 actuate_set.set_current_dimension( i ); 05618 while( (entity_ptr = actuate_set.remove_next() ) != NULL ) 05619 entity_ptr->auto_actuate_cubit_attrib(CUBIT_FALSE); 05620 } 05621 05622 // actuate deferred attribs 05623 CADeferredAttrib::cleanup_cadas(CUBIT_TRUE, CUBIT_TRUE); 05624 05625 // finally, actuate the attributes that go after all other geometry changes 05626 for( i = 0; i < 4; i++ ) 05627 { 05628 actuate_set.set_current_dimension( i ); 05629 while( (entity_ptr = actuate_set.remove_next() ) != NULL ) 05630 entity_ptr->auto_actuate_cubit_attrib(CUBIT_FALSE, CUBIT_TRUE); 05631 } 05632 05633 return CUBIT_SUCCESS; 05634 } 05635 05636 CubitBoolean GeometryQueryTool::okay_to_transform( Body* body ) const 05637 { 05638 MergeTool* mt = MergeTool::instance(); 05639 int i; 05640 05641 // Check for merged vertices 05642 DLIList<RefVertex*> vertices; 05643 body->ref_vertices( vertices ); 05644 for (i = vertices.size(); i--; ) 05645 if ( mt->entity_merged( vertices.get_and_step() ) ) 05646 { 05647 PRINT_ERROR("Cannot transform %s (Body %d) with merged geomtery.\n", 05648 body->entity_name().c_str(), body->id() ); 05649 return CUBIT_FALSE; 05650 } 05651 05652 // Need to check for merged surfaces because can have surfaces 05653 // w/out vertices. 05654 DLIList<RefFace*> surfaces; 05655 body->ref_faces( surfaces ); 05656 for (i = surfaces.size(); i--; ) 05657 if ( mt->entity_merged( surfaces.get_and_step() ) ) 05658 { 05659 PRINT_ERROR("Cannot transform %s (Body %d) with merged geomtery.\n", 05660 body->entity_name().c_str(), body->id() ); 05661 return CUBIT_FALSE; 05662 } 05663 05664 return CUBIT_TRUE; 05665 } 05666 05667 void GeometryQueryTool::translate( DLIList<RefEntity*> &entities_to_transform, 05668 double x, double y, double z, bool check_before_transforming, 05669 DLIList<RefEntity*> &entities_transformed, 05670 bool preview /*= false*/) 05671 { 05672 CubitVector delta(x,y,z); 05673 05674 //translate free, merged-away entities first 05675 DLIList<TopologyBridge*> free_ents; 05676 get_merged_away_free_entities( entities_to_transform, free_ents ); 05677 05678 int i; 05679 if (!preview) 05680 { 05681 for( i=free_ents.size(); i--; ) 05682 { 05683 TopologyBridge *bridge = free_ents.get_and_step(); 05684 Curve *curve= CAST_TO( bridge, Curve ); 05685 TBPoint *point = CAST_TO( bridge, TBPoint ); 05686 05687 if( curve || point ) 05688 { 05689 GeometryEntity *geom = CAST_TO( bridge, GeometryEntity ); 05690 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 05691 CubitStatus result = engine->translate( geom, delta ); 05692 if (CUBIT_SUCCESS != result) { 05693 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 05694 return; 05695 } 05696 } 05697 } 05698 } 05699 05700 RefFace *tmp_face; 05701 RefEdge *tmp_curve; 05702 RefVertex *tmp_vertex; 05703 CubitStatus result = CUBIT_SUCCESS; 05704 05705 DLIList<Body*> bodies_to_translate; 05706 DLIList<BasicTopologyEntity*> ents_to_translate; 05707 CAST_LIST( entities_to_transform, bodies_to_translate, Body); 05708 05709 if( bodies_to_translate.size() != entities_to_transform.size() ) 05710 { 05711 for( int k=0; k<entities_to_transform.size(); k++ ) 05712 { 05713 RefEntity *ent = entities_to_transform[k]; 05714 05715 if( ( tmp_face = CAST_TO( ent, RefFace ) ) != NULL ) 05716 ents_to_translate.append( tmp_face ); 05717 else if( (tmp_curve = CAST_TO( ent, RefEdge ) ) != NULL ) 05718 ents_to_translate.append( tmp_curve ); 05719 else if( (tmp_vertex = CAST_TO( ent, RefVertex ) ) != NULL ) 05720 ents_to_translate.append( tmp_vertex ); 05721 } 05722 } 05723 05724 05725 if( bodies_to_translate.size() ) 05726 { 05727 DLIList<Body*> bodies_translated; 05728 result = translate( bodies_to_translate, 05729 CubitVector(x,y,z), 05730 &bodies_translated, 05731 check_before_transforming, 05732 preview ); 05733 05734 if( result ) 05735 { 05736 for( int k=0; k<bodies_translated.size(); k++ ) 05737 entities_transformed.append( bodies_translated[k] ); 05738 } 05739 } 05740 05741 if( ents_to_translate.size() ) 05742 { 05743 DLIList<BasicTopologyEntity*> btes_translated; 05744 result = translate( ents_to_translate, 05745 CubitVector(x,y,z), 05746 &btes_translated, 05747 check_before_transforming, 05748 preview ); 05749 05750 if( result ) 05751 { 05752 for( int k=0; k<btes_translated.size(); k++ ) 05753 entities_transformed.append( btes_translated[k] ); 05754 } 05755 } 05756 } 05757 05758 05759 CubitStatus GeometryQueryTool::translate( DLIList<Body*> &bodies, 05760 const CubitVector& delta, 05761 DLIList<Body*> *bodies_translated, 05762 bool check_to_transform, 05763 bool preview ) 05764 { 05765 CubitTransformMatrix xform; 05766 xform.translate( delta ); 05767 05768 DLIList<RefEntity*> ents_transformed; 05769 05770 for( int k=0; k<bodies.size(); k++ ) 05771 { 05772 Body *body = bodies[k]; 05773 05774 if( check_to_transform ) 05775 if (!okay_to_transform( body )) 05776 continue; 05777 05778 if (preview) 05779 { 05780 DLIList<RefEdge*> edges; 05781 body->ref_edges(edges); 05782 if( edges.size() ) 05783 { 05784 for (int i = 0; i < edges.size(); i++) 05785 { 05786 GMem poly; 05787 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 05788 { 05789 poly.transform(xform); 05790 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 05791 } 05792 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 05793 { 05794 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 05795 tmp_pt = xform*tmp_pt; 05796 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 05797 } 05798 } 05799 } 05800 else 05801 { 05802 //just draw the surfaces 05803 DLIList<RefFace*> faces; 05804 body->ref_faces( faces ); 05805 for( int i=0; i<faces.size(); i-- ) 05806 { 05807 GMem poly; 05808 faces.get_and_step()->get_graphics( poly ); 05809 poly.transform(xform); 05810 05811 int* facet_list = poly.facet_list(); 05812 GPoint* plist = poly.point_list(); 05813 05814 GPoint p[3]; 05815 for (i = 0; i < poly.fListCount; ) 05816 { 05817 int sides = facet_list[i++]; 05818 if (sides != 3) 05819 { 05820 i += sides; 05821 continue; 05822 } 05823 else 05824 { 05825 p[0] = plist[facet_list[i++]]; 05826 p[1] = plist[facet_list[i++]]; 05827 p[2] = plist[facet_list[i++]]; 05828 GfxPreview::draw_polygon(p, 3, CUBIT_BLUE_INDEX, CUBIT_BLUE_INDEX, false); 05829 } 05830 } 05831 } 05832 } 05833 GfxPreview::flush(); 05834 continue; 05835 } 05836 05837 BodySM* bodysm = body->get_body_sm_ptr(); 05838 GeometryQueryEngine* engine = bodysm->get_geometry_query_engine(); 05839 CubitStatus result = engine->translate( bodysm, delta ); 05840 if (result) 05841 { 05842 notify_intermediate_of_transform( body, xform ); 05843 05844 if( bodies_translated ) 05845 bodies_translated->append( body ); 05846 ents_transformed.append( body ); 05847 } 05848 else 05849 PRINT_ERROR("Translate of %s (%s %d) failed.\n", 05850 body->entity_name().c_str(), body->class_name(), body->id() ); 05851 } 05852 05853 if( ents_transformed.size() ) 05854 { 05855 notify_observers_of_transform( ents_transformed, &xform ); 05856 return CUBIT_SUCCESS; 05857 } 05858 else if( preview ) 05859 return CUBIT_SUCCESS; 05860 else 05861 return CUBIT_FAILURE; 05862 } 05863 05864 CubitStatus GeometryQueryTool::rotate( DLIList<RefEntity*> &entities_to_transform, 05865 const CubitVector& point, 05866 const CubitVector& direction, 05867 double angle, 05868 bool check_before_transforming, 05869 DLIList<RefEntity*> &entities_transformed, 05870 bool preview /*= false*/) 05871 { 05872 //rotate free, merged-away entities first 05873 DLIList<TopologyBridge*> free_ents; 05874 get_merged_away_free_entities( entities_to_transform, free_ents ); 05875 05876 int i; 05877 if (!preview) 05878 { 05879 for( i=free_ents.size(); i--; ) 05880 { 05881 TopologyBridge *bridge = free_ents.get_and_step(); 05882 Curve *curve= CAST_TO( bridge, Curve ); 05883 TBPoint *tmp_point = CAST_TO( bridge, TBPoint ); 05884 05885 if( curve || tmp_point ) 05886 { 05887 GeometryEntity *geom = CAST_TO( bridge, GeometryEntity ); 05888 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 05889 CubitStatus result = engine->translate( geom, -point ); 05890 if (CUBIT_SUCCESS != result) { 05891 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 05892 return result; 05893 } 05894 result = engine->rotate( geom, direction, angle ); 05895 if (CUBIT_SUCCESS != result) { 05896 PRINT_ERROR("GeometryQueryEngine::rotate failed.\n"); 05897 return result; 05898 } 05899 result = engine->translate( geom, point ); 05900 if (CUBIT_SUCCESS != result) { 05901 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 05902 return result; 05903 } 05904 } 05905 } 05906 } 05907 05908 RefFace *tmp_face; 05909 RefEdge *tmp_curve; 05910 RefVertex *tmp_vertex; 05911 CubitStatus result = CUBIT_SUCCESS; 05912 05913 DLIList<Body*> bodies_to_rotate; 05914 DLIList<BasicTopologyEntity*> ents_to_rotate; 05915 CAST_LIST( entities_to_transform, bodies_to_rotate, Body); 05916 05917 if( bodies_to_rotate.size() != entities_to_transform.size() ) 05918 { 05919 for( int k=0; k<entities_to_transform.size(); k++ ) 05920 { 05921 RefEntity *ent = entities_to_transform[k]; 05922 05923 if( ( tmp_face = CAST_TO( ent, RefFace ) ) != NULL ) 05924 ents_to_rotate.append( tmp_face ); 05925 else if( (tmp_curve = CAST_TO( ent, RefEdge ) ) != NULL ) 05926 ents_to_rotate.append( tmp_curve ); 05927 else if( (tmp_vertex = CAST_TO( ent, RefVertex ) ) != NULL ) 05928 ents_to_rotate.append( tmp_vertex ); 05929 } 05930 } 05931 05932 05933 if( bodies_to_rotate.size() ) 05934 { 05935 DLIList<Body*> bodies_rotated; 05936 05937 result = rotate( bodies_to_rotate, 05938 point, direction, angle, 05939 &bodies_rotated, 05940 check_before_transforming, preview); 05941 05942 if( result ) 05943 { 05944 for( int k=0; k<bodies_rotated.size(); k++ ) 05945 entities_transformed.append( bodies_rotated[k] ); 05946 } 05947 } 05948 05949 if( ents_to_rotate.size() ) 05950 { 05951 DLIList<BasicTopologyEntity*> btes_rotated; 05952 05953 result = rotate( ents_to_rotate, 05954 point, 05955 direction, 05956 angle, 05957 &btes_rotated, 05958 check_before_transforming, 05959 preview ); 05960 05961 if( result ) 05962 { 05963 for( int k=0; k<btes_rotated.size(); k++ ) 05964 entities_transformed.append( btes_rotated[k] ); 05965 } 05966 } 05967 05968 if( entities_transformed.size() ) 05969 return CUBIT_SUCCESS; 05970 else 05971 return CUBIT_FAILURE; 05972 } 05973 05974 CubitStatus GeometryQueryTool::rotate( DLIList<Body*> &bodies, 05975 const CubitVector& axis, 05976 double angle, 05977 DLIList<Body*> *bodies_rotated, 05978 bool check_to_transform, 05979 bool preview ) 05980 { 05981 CubitTransformMatrix xform; 05982 xform.rotate( angle, axis ); 05983 05984 DLIList<RefEntity*> ents_transformed; 05985 05986 for( int k=0; k<bodies.size(); k++ ) 05987 { 05988 Body *body = bodies[k]; 05989 05990 if( check_to_transform ) 05991 if (!okay_to_transform( body )) 05992 continue; 05993 05994 if (preview) 05995 { 05996 DLIList<RefEdge*> edges; 05997 body->ref_edges(edges); 05998 if( edges.size() ) 05999 { 06000 for (int i = 0; i < edges.size(); i++) 06001 { 06002 GMem poly; 06003 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 06004 { 06005 poly.transform(xform); 06006 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06007 } 06008 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 06009 { 06010 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 06011 tmp_pt = xform*tmp_pt; 06012 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 06013 } 06014 } 06015 } 06016 else 06017 { 06018 //just draw the surfaces 06019 DLIList<RefFace*> faces; 06020 body->ref_faces( faces ); 06021 for( int i=0; i<faces.size(); i-- ) 06022 { 06023 GMem poly; 06024 faces.get_and_step()->get_graphics( poly ); 06025 poly.transform(xform); 06026 06027 int* facet_list = poly.facet_list(); 06028 GPoint* plist = poly.point_list(); 06029 06030 GPoint p[3]; 06031 for (i = 0; i < poly.fListCount; ) 06032 { 06033 int sides = facet_list[i++]; 06034 if (sides != 3) 06035 { 06036 i += sides; 06037 continue; 06038 } 06039 else 06040 { 06041 p[0] = plist[facet_list[i++]]; 06042 p[1] = plist[facet_list[i++]]; 06043 p[2] = plist[facet_list[i++]]; 06044 GfxPreview::draw_polygon(p, 3, CUBIT_BLUE_INDEX, CUBIT_BLUE_INDEX, false); 06045 } 06046 } 06047 } 06048 } 06049 GfxPreview::flush(); 06050 continue; 06051 } 06052 06053 BodySM* bodysm = body->get_body_sm_ptr(); 06054 GeometryQueryEngine* engine = bodysm->get_geometry_query_engine(); 06055 CubitStatus result = engine->rotate( bodysm, axis, angle ); 06056 06057 if (result) 06058 { 06059 notify_intermediate_of_transform( body, xform ); 06060 06061 if( bodies_rotated ) 06062 bodies_rotated->append( body ); 06063 ents_transformed.append( body ); 06064 } 06065 else 06066 PRINT_ERROR("Rotate of %s (%s %d) failed.\n", 06067 body->entity_name().c_str(), body->class_name(), body->id() ); 06068 } 06069 06070 if( ents_transformed.size() ) 06071 { 06072 notify_observers_of_transform( ents_transformed, &xform ); 06073 return CUBIT_SUCCESS; 06074 } 06075 else if( preview ) 06076 return CUBIT_SUCCESS; 06077 else 06078 return CUBIT_FAILURE; 06079 } 06080 06081 CubitStatus GeometryQueryTool::rotate( DLIList<Body*> &bodies, 06082 const CubitVector& point, 06083 const CubitVector& direction, 06084 double degrees, 06085 DLIList<Body*> *bodies_rotated, 06086 bool check_to_transform, 06087 bool preview /*=false*/) 06088 { 06089 CubitTransformMatrix prev_xform; 06090 prev_xform.translate(-point); 06091 06092 CubitTransformMatrix rot_mat; 06093 rot_mat.rotate( degrees, direction ); 06094 06095 CubitTransformMatrix mov_mat; 06096 mov_mat.translate( point ); 06097 06098 CubitTransformMatrix total_transform; 06099 total_transform = mov_mat*rot_mat*prev_xform; 06100 06101 DLIList<RefEntity*> ents_transformed; 06102 06103 for( int k=0; k<bodies.size(); k++ ) 06104 { 06105 Body *body = bodies[k]; 06106 06107 if( check_to_transform ) 06108 if (!okay_to_transform( body )) 06109 continue; 06110 06111 if (preview) 06112 { 06113 DLIList<RefEdge*> edges; 06114 body->ref_edges(edges); 06115 if( edges.size() ) 06116 { 06117 for (int i = 0; i < edges.size(); i++) 06118 { 06119 GMem poly; 06120 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 06121 { 06122 poly.transform( total_transform ); 06123 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06124 } 06125 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 06126 { 06127 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 06128 tmp_pt = total_transform*tmp_pt; 06129 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 06130 } 06131 } 06132 } 06133 else 06134 { 06135 //just draw the surfaces 06136 DLIList<RefFace*> faces; 06137 body->ref_faces( faces ); 06138 for( int i=0; i<faces.size(); i-- ) 06139 { 06140 GMem poly; 06141 faces.get_and_step()->get_graphics( poly ); 06142 poly.transform( total_transform ); 06143 06144 int* facet_list = poly.facet_list(); 06145 GPoint* plist = poly.point_list(); 06146 06147 GPoint p[3]; 06148 for (i = 0; i < poly.fListCount; ) 06149 { 06150 int sides = facet_list[i++]; 06151 if (sides != 3) 06152 { 06153 i += sides; 06154 continue; 06155 } 06156 else 06157 { 06158 p[0] = plist[facet_list[i++]]; 06159 p[1] = plist[facet_list[i++]]; 06160 p[2] = plist[facet_list[i++]]; 06161 GfxPreview::draw_polygon(p, 3, CUBIT_BLUE_INDEX, CUBIT_BLUE_INDEX, false); 06162 } 06163 } 06164 } 06165 } 06166 GfxPreview::flush(); 06167 continue; 06168 } 06169 06170 BodySM* bodysm = body->get_body_sm_ptr(); 06171 GeometryQueryEngine* engine = bodysm->get_geometry_query_engine(); 06172 CubitStatus result = CUBIT_FAILURE; 06173 06174 // Move to origin 06175 result = engine->translate( bodysm, -point ); 06176 06177 if (result) 06178 { 06179 CubitTransformMatrix xform; 06180 xform.translate( -point ); 06181 notify_intermediate_of_transform( body, xform ); 06182 } 06183 else 06184 { 06185 continue; 06186 } 06187 06188 // Rotate about direction vector 06189 result = engine->rotate( bodysm, direction, degrees ); 06190 if (result) 06191 { 06192 CubitTransformMatrix rot_mat; 06193 rot_mat.rotate( degrees, direction ); 06194 notify_intermediate_of_transform( body, rot_mat ); 06195 } 06196 else 06197 { 06198 continue; 06199 } 06200 06201 result= engine->translate( bodysm, point ); 06202 if (result) 06203 { 06204 CubitTransformMatrix xform; 06205 xform.translate( point ); 06206 notify_intermediate_of_transform( body, xform ); 06207 06208 if( bodies_rotated ) 06209 bodies_rotated->append( body ); 06210 ents_transformed.append( body ); 06211 } 06212 else 06213 { 06214 continue; 06215 } 06216 } 06217 06218 if( ents_transformed.size() ) 06219 { 06220 notify_observers_of_transform( ents_transformed, &total_transform ); 06221 return CUBIT_SUCCESS; 06222 } 06223 else if( preview ) 06224 return CUBIT_SUCCESS; 06225 else 06226 return CUBIT_FAILURE; 06227 } 06228 06229 void GeometryQueryTool::scale( DLIList<RefEntity*> &entities_to_transform, 06230 const CubitVector& point, 06231 double scale_x, double scale_y, double scale_z, 06232 bool check_before_transforming, 06233 DLIList<RefEntity*> &entities_scaled, 06234 bool preview /*= false*/) 06235 { 06236 CubitVector factors(scale_x, scale_y, scale_z); 06237 06238 //scale free, merged-away entities first 06239 DLIList<TopologyBridge*> free_ents; 06240 get_merged_away_free_entities( entities_to_transform, free_ents ); 06241 int i; 06242 if (!preview) 06243 { 06244 for( i=free_ents.size(); i--; ) 06245 { 06246 TopologyBridge *bridge = free_ents.get_and_step(); 06247 Curve *curve= CAST_TO( bridge, Curve ); 06248 TBPoint *tbpoint = CAST_TO( bridge, TBPoint ); 06249 06250 if( curve || tbpoint ) 06251 { 06252 GeometryEntity *geom = CAST_TO( bridge, GeometryEntity ); 06253 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 06254 CubitStatus result = engine->translate( geom, -point ); 06255 if (CUBIT_SUCCESS != result) { 06256 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 06257 return; 06258 } 06259 result = engine->scale( geom, factors ); 06260 if (CUBIT_SUCCESS != result) { 06261 PRINT_ERROR("GeometryQueryEngine::scale failed.\n"); 06262 return; 06263 } 06264 result = engine->translate( geom, point ); 06265 if (CUBIT_SUCCESS != result) { 06266 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 06267 return; 06268 } 06269 } 06270 } 06271 } 06272 06273 06274 CubitStatus result = CUBIT_SUCCESS; 06275 for(i=entities_to_transform.size(); i--; ) 06276 { 06277 RefEntity *tmp_ent = entities_to_transform.get_and_step(); 06278 Body *tmp_body; 06279 RefFace* tmp_face; 06280 RefEdge *tmp_curve; 06281 RefVertex *tmp_vertex; 06282 if( ( tmp_body = CAST_TO( tmp_ent, Body ) ) != NULL ) 06283 { 06284 //non-uniform scaling 06285 if( scale_x != scale_y || 06286 scale_x != scale_z || 06287 scale_y != scale_z ) 06288 { 06289 // use GMT version for non-uniform scaling b/c it updates topology if it changes 06290 06291 result = GeometryModifyTool::instance()->scale(tmp_body,point, factors, 06292 check_before_transforming, preview,false); 06293 tmp_ent = tmp_body; 06294 } 06295 else 06296 result = scale( tmp_body,point, CubitVector(scale_x, scale_y, scale_z), 06297 check_before_transforming, preview); 06298 } 06299 else if( ( tmp_face = CAST_TO( tmp_ent, RefFace ) ) != NULL ) 06300 { 06301 // only allow scaling of RefFaces if preview is on 06302 if (!preview) 06303 continue; 06304 result = scale( tmp_face,point, CubitVector(scale_x, scale_y, scale_z), 06305 check_before_transforming, preview); 06306 } 06307 else if( ( tmp_curve = CAST_TO( tmp_ent, RefEdge ) ) != NULL ) 06308 { 06309 result = scale( tmp_curve,point, CubitVector(scale_x, scale_y, scale_z), 06310 check_before_transforming, preview); 06311 } 06312 else if( ( tmp_vertex = CAST_TO( tmp_ent, RefVertex ) ) != NULL ) 06313 { 06314 result = scale( tmp_vertex,point, CubitVector(scale_x, scale_y, scale_z), 06315 check_before_transforming, preview); 06316 } 06317 if(result) 06318 entities_scaled.append( tmp_ent ); 06319 } 06320 06321 } 06322 06323 06324 CubitStatus GeometryQueryTool::scale( Body* body,const CubitVector& point, double factor, bool check_to_transform, bool preview ) 06325 { 06326 if( check_to_transform ) 06327 if (!okay_to_transform( body )) 06328 return CUBIT_FAILURE; 06329 06330 CubitTransformMatrix pre_form; 06331 pre_form.translate( -point ); 06332 06333 CubitTransformMatrix xform; 06334 xform.scale_about_origin( factor ); 06335 06336 CubitTransformMatrix post_form; 06337 post_form.translate( point ); 06338 06339 if (preview) 06340 { 06341 DLIList<RefEdge*> edges; 06342 body->ref_edges(edges); 06343 if( edges.size() ) 06344 { 06345 for (int i = 0; i < edges.size(); i++) 06346 { 06347 GMem poly; 06348 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 06349 { 06350 poly.transform(pre_form); 06351 poly.transform(xform); 06352 poly.transform(post_form); 06353 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06354 } 06355 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 06356 { 06357 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 06358 tmp_pt = pre_form*tmp_pt; 06359 tmp_pt = xform*tmp_pt; 06360 tmp_pt = post_form*tmp_pt; 06361 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 06362 } 06363 } 06364 } 06365 else 06366 { 06367 //just draw the surfaces 06368 DLIList<RefFace*> faces; 06369 body->ref_faces( faces ); 06370 for( int i=0; i<faces.size(); i-- ) 06371 { 06372 GMem poly; 06373 faces.get_and_step()->get_graphics( poly ); 06374 poly.transform(pre_form); 06375 poly.transform(xform); 06376 poly.transform(post_form); 06377 06378 int* facet_list = poly.facet_list(); 06379 GPoint* plist = poly.point_list(); 06380 06381 GPoint p[3]; 06382 for (i = 0; i < poly.fListCount; ) 06383 { 06384 int sides = facet_list[i++]; 06385 if (sides != 3) 06386 { 06387 i += sides; 06388 continue; 06389 } 06390 else 06391 { 06392 p[0] = plist[facet_list[i++]]; 06393 p[1] = plist[facet_list[i++]]; 06394 p[2] = plist[facet_list[i++]]; 06395 GfxPreview::draw_polygon(p, 3, CUBIT_BLUE_INDEX, CUBIT_BLUE_INDEX, false); 06396 } 06397 } 06398 } 06399 } 06400 GfxPreview::flush(); 06401 return CUBIT_SUCCESS; 06402 } 06403 06404 06405 06406 //if (preview) 06407 //{ 06408 // DLIList<RefEdge*> edges; 06409 // body->ref_edges(edges); 06410 // for (int i = 0; i < edges.size(); i++) 06411 // { 06412 // GMem poly; 06413 // edges[i]->get_graphics(poly); 06414 // poly.transform(pre_form); 06415 // poly.transform(xform); 06416 // poly.transform(post_form); 06417 // GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06418 // } 06419 // GfxPreview::flush(); 06420 // return CUBIT_SUCCESS; 06421 //} 06422 06423 BodySM* bodysm = body->get_body_sm_ptr(); 06424 GeometryQueryEngine* engine = bodysm->get_geometry_query_engine(); 06425 CubitStatus result = engine->translate( bodysm, -point ); 06426 if (result) 06427 { 06428 notify_intermediate_of_transform( body, pre_form ); 06429 } 06430 else 06431 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 06432 body->entity_name().c_str(), body->class_name(), body->id() ); 06433 06434 06435 result = engine->scale( bodysm, factor ); 06436 if (result) 06437 { 06438 notify_intermediate_of_transform( body, xform ); 06439 } 06440 else 06441 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 06442 body->entity_name().c_str(), body->class_name(), body->id() ); 06443 06444 result = engine->translate( bodysm, point ); 06445 if (result) 06446 { 06447 notify_intermediate_of_transform( body, post_form ); 06448 } 06449 else 06450 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 06451 body->entity_name().c_str(), body->class_name(), body->id() ); 06452 06453 notify_observers_of_transform( body ); 06454 06455 return result; 06456 } 06457 06458 CubitStatus GeometryQueryTool::scale( Body *body, 06459 const CubitVector& point, 06460 const CubitVector& factors, 06461 bool check_to_transform, 06462 bool preview ) 06463 { 06464 if( check_to_transform ) 06465 if (!okay_to_transform( body )) 06466 return CUBIT_FAILURE; 06467 06468 CubitTransformMatrix pre_form; 06469 pre_form.translate( -point ); 06470 06471 CubitTransformMatrix xform; 06472 xform.scale_about_origin( factors ); 06473 06474 CubitTransformMatrix post_form; 06475 post_form.translate( point ); 06476 06477 if (preview) 06478 { 06479 DLIList<RefEdge*> edges; 06480 body->ref_edges(edges); 06481 if( edges.size() ) 06482 { 06483 for (int i = 0; i < edges.size(); i++) 06484 { 06485 GMem poly; 06486 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 06487 { 06488 poly.transform(pre_form); 06489 poly.transform(xform); 06490 poly.transform(post_form); 06491 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06492 } 06493 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 06494 { 06495 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 06496 tmp_pt = pre_form*tmp_pt; 06497 tmp_pt = xform*tmp_pt; 06498 tmp_pt = post_form*tmp_pt; 06499 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 06500 } 06501 } 06502 } 06503 else 06504 { 06505 //just draw the surfaces 06506 DLIList<RefFace*> faces; 06507 body->ref_faces( faces ); 06508 for( int i=0; i<faces.size(); i-- ) 06509 { 06510 GMem poly; 06511 faces.get_and_step()->get_graphics( poly ); 06512 poly.transform(pre_form); 06513 poly.transform(xform); 06514 poly.transform(post_form); 06515 06516 int* facet_list = poly.facet_list(); 06517 GPoint* plist = poly.point_list(); 06518 06519 GPoint p[3]; 06520 for (i = 0; i < poly.fListCount; ) 06521 { 06522 int sides = facet_list[i++]; 06523 if (sides != 3) 06524 { 06525 i += sides; 06526 continue; 06527 } 06528 else 06529 { 06530 p[0] = plist[facet_list[i++]]; 06531 p[1] = plist[facet_list[i++]]; 06532 p[2] = plist[facet_list[i++]]; 06533 GfxPreview::draw_polygon(p, 3, CUBIT_BLUE_INDEX, CUBIT_BLUE_INDEX, false); 06534 } 06535 } 06536 } 06537 } 06538 06539 GfxPreview::flush(); 06540 return CUBIT_SUCCESS; 06541 } 06542 06543 BodySM* bodysm = body->get_body_sm_ptr(); 06544 GeometryQueryEngine* engine = bodysm->get_geometry_query_engine(); 06545 06546 CubitStatus result = engine->translate( bodysm, -point ); 06547 if (result) 06548 { 06549 notify_intermediate_of_transform( body, pre_form ); 06550 } 06551 else 06552 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 06553 body->entity_name().c_str(), body->class_name(), body->id() ); 06554 06555 06556 result = engine->scale( bodysm, factors ); 06557 if (result) 06558 { 06559 notify_intermediate_of_transform( body, xform ); 06560 } 06561 else 06562 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 06563 body->entity_name().c_str(), body->class_name(), body->id() ); 06564 06565 result = engine->translate( bodysm, point ); 06566 if (result) 06567 { 06568 notify_intermediate_of_transform( body, post_form ); 06569 } 06570 else 06571 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 06572 body->entity_name().c_str(), body->class_name(), body->id() ); 06573 06574 notify_observers_of_transform( body ); 06575 06576 return result; 06577 } 06578 06579 void GeometryQueryTool::reflect( DLIList<RefEntity*> &entities_to_reflect, 06580 const CubitVector& point, 06581 const CubitVector& normal, 06582 bool check_before_transforming, 06583 DLIList<RefEntity*> &entities_transformed, 06584 bool preview /*= false*/) 06585 { 06586 //reflect free, merged-away entities 06587 DLIList<TopologyBridge*> free_ents; 06588 get_merged_away_free_entities( entities_to_reflect, free_ents ); 06589 06590 int i; 06591 if (!preview) 06592 { 06593 for( i=free_ents.size(); i--; ) 06594 { 06595 TopologyBridge *bridge = free_ents.get_and_step(); 06596 Curve *curve= CAST_TO( bridge, Curve ); 06597 TBPoint *tmp_point = CAST_TO( bridge, TBPoint ); 06598 06599 if( curve || tmp_point ) 06600 { 06601 GeometryEntity *geom = CAST_TO( bridge, GeometryEntity ); 06602 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 06603 CubitStatus result = engine->translate( geom, -point ); 06604 if (CUBIT_SUCCESS != result) { 06605 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 06606 return; 06607 } 06608 result = engine->reflect( geom, normal ); 06609 if (CUBIT_SUCCESS != result) { 06610 PRINT_ERROR("GeometryQueryEngine::reflect failed.\n"); 06611 return; 06612 } 06613 result = engine->translate( geom, point ); 06614 if (CUBIT_SUCCESS != result) { 06615 PRINT_ERROR("GeometryQueryEngine::translate failed.\n"); 06616 return; 06617 } 06618 } 06619 } 06620 } 06621 06622 RefFace *tmp_face; 06623 RefEdge *tmp_curve; 06624 RefVertex *tmp_vertex; 06625 CubitStatus result; 06626 06627 DLIList<Body*> bodies_to_reflect; 06628 DLIList<BasicTopologyEntity*> ents_to_reflect; 06629 CAST_LIST( entities_to_reflect, bodies_to_reflect, Body); 06630 06631 if( bodies_to_reflect.size() != entities_to_reflect.size() ) 06632 { 06633 for( int k=0; k<entities_to_reflect.size(); k++ ) 06634 { 06635 RefEntity *ent = entities_to_reflect[k]; 06636 06637 if( ( tmp_face = CAST_TO( ent, RefFace ) ) != NULL ) 06638 ents_to_reflect.append( tmp_face ); 06639 else if( (tmp_curve = CAST_TO( ent, RefEdge ) ) != NULL ) 06640 ents_to_reflect.append( tmp_curve ); 06641 else if( (tmp_vertex = CAST_TO( ent, RefVertex ) ) != NULL ) 06642 ents_to_reflect.append( tmp_vertex ); 06643 } 06644 } 06645 06646 if( bodies_to_reflect.size() ) 06647 { 06648 DLIList<Body*> bodies_reflected; 06649 result = reflect( bodies_to_reflect, 06650 point, normal, 06651 &bodies_reflected, 06652 preview ); 06653 06654 if( result ) 06655 { 06656 for( int k=0; k<bodies_reflected.size(); k++ ) 06657 entities_transformed.append( bodies_reflected[k] ); 06658 } 06659 } 06660 06661 if( ents_to_reflect.size() ) 06662 { 06663 DLIList<BasicTopologyEntity*> btes_reflected; 06664 result = reflect( ents_to_reflect, 06665 point, 06666 normal, 06667 &btes_reflected, 06668 check_before_transforming, 06669 preview ); 06670 06671 if( result ) 06672 { 06673 for( int k=0; k<btes_reflected.size(); k++ ) 06674 entities_transformed.append( btes_reflected[k] ); 06675 } 06676 } 06677 } 06678 06679 CubitStatus GeometryQueryTool::reflect( DLIList<Body*> &bodies, 06680 const CubitVector& point, 06681 const CubitVector& normal, 06682 DLIList<Body*> *bodies_reflected, 06683 bool preview) 06684 { 06685 Body *tmp_body; 06686 CubitStatus result = CUBIT_FAILURE; 06687 06688 CubitTransformMatrix prev_xform; 06689 prev_xform.translate(-point); 06690 06691 CubitTransformMatrix ref_mat; 06692 ref_mat.reflect(normal ); 06693 06694 CubitTransformMatrix mov_mat; 06695 mov_mat.translate( point ); 06696 06697 CubitTransformMatrix total_transform; 06698 total_transform = mov_mat*ref_mat*prev_xform; 06699 06700 DLIList<RefEntity*> ents_transformed; 06701 06702 if (preview) 06703 { 06704 for (int i = 0; i < bodies.size(); i++) 06705 { 06706 DLIList<RefEdge*> edges; 06707 bodies[i]->ref_edges(edges); 06708 if( edges.size() ) 06709 { 06710 for (int i = 0; i < edges.size(); i++) 06711 { 06712 GMem poly; 06713 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 06714 { 06715 poly.transform( total_transform ); 06716 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06717 } 06718 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 06719 { 06720 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 06721 tmp_pt = total_transform*tmp_pt; 06722 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 06723 } 06724 } 06725 } 06726 else 06727 { 06728 //just draw the surfaces 06729 DLIList<RefFace*> faces; 06730 bodies[i]->ref_faces( faces ); 06731 for( int i=0; i<faces.size(); i-- ) 06732 { 06733 GMem poly; 06734 faces.get_and_step()->get_graphics( poly ); 06735 poly.transform( total_transform ); 06736 06737 int* facet_list = poly.facet_list(); 06738 GPoint* plist = poly.point_list(); 06739 06740 GPoint p[3]; 06741 for (i = 0; i < poly.fListCount; ) 06742 { 06743 int sides = facet_list[i++]; 06744 if (sides != 3) 06745 { 06746 i += sides; 06747 continue; 06748 } 06749 else 06750 { 06751 p[0] = plist[facet_list[i++]]; 06752 p[1] = plist[facet_list[i++]]; 06753 p[2] = plist[facet_list[i++]]; 06754 GfxPreview::draw_polygon(p, 3, CUBIT_BLUE_INDEX, CUBIT_BLUE_INDEX, false); 06755 } 06756 } 06757 } 06758 } 06759 GfxPreview::flush(); 06760 } 06761 return CUBIT_SUCCESS; 06762 } 06763 //first, reflect the underlying geometry 06764 int i; 06765 for( i=bodies.size(); i--;) 06766 { 06767 tmp_body = bodies.get_and_step(); 06768 BodySM* bodysm = tmp_body->get_body_sm_ptr(); 06769 GeometryQueryEngine* engine = bodysm->get_geometry_query_engine(); 06770 06771 // Move to origin 06772 result = engine->translate( bodysm, -point ); 06773 if (result) 06774 { 06775 CubitTransformMatrix xform; 06776 xform.translate( -point ); 06777 notify_intermediate_of_transform( tmp_body, xform ); 06778 } 06779 else 06780 { 06781 PRINT_ERROR("Reflect of %s (%s %d) failed.\n", 06782 tmp_body->entity_name().c_str(), tmp_body->class_name(), tmp_body->id() ); 06783 return result; 06784 } 06785 06786 result = engine->reflect( bodysm, normal ); 06787 if (result) 06788 { 06789 CubitTransformMatrix xform; 06790 xform.reflect( normal); 06791 notify_intermediate_of_transform( tmp_body, xform ); 06792 } 06793 else 06794 { 06795 PRINT_ERROR("Reflect of %s (%s %d) failed.\n", 06796 tmp_body->entity_name().c_str(), tmp_body->class_name(), tmp_body->id() ); 06797 return result; 06798 } 06799 06800 result = engine->translate( bodysm, point ); 06801 if (result) 06802 { 06803 CubitTransformMatrix xform; 06804 xform.translate( point ); 06805 notify_intermediate_of_transform( tmp_body, xform ); 06806 06807 if( bodies_reflected ) 06808 bodies_reflected->append( tmp_body ); 06809 ents_transformed.append( tmp_body ); 06810 } 06811 else 06812 { 06813 PRINT_ERROR("Reflect of %s (%s %d) failed.\n", 06814 tmp_body->entity_name().c_str(), tmp_body->class_name(), tmp_body->id() ); 06815 return result; 06816 } 06817 } 06818 06819 for( i=0; i<ents_transformed.size(); i++) 06820 { 06821 tmp_body = (Body*)ents_transformed[i]; 06822 tmp_body = make_Body( tmp_body->get_body_sm_ptr() ); 06823 if( tmp_body != ents_transformed[i] ) 06824 ents_transformed[i] = tmp_body; 06825 } 06826 06827 if( ents_transformed.size() ) 06828 { 06829 notify_observers_of_transform( ents_transformed, &total_transform ); 06830 return CUBIT_SUCCESS; 06831 } 06832 else if( preview ) 06833 return CUBIT_SUCCESS; 06834 else 06835 return CUBIT_FAILURE; 06836 } 06837 06838 CubitStatus GeometryQueryTool::notify_intermediate_of_transform( 06839 TopologyEntity* entity, 06840 const CubitTransformMatrix& xform ) const 06841 { 06842 for (IGESet::const_iterator iter = igeSet.begin(); iter != igeSet.end(); ++iter) 06843 (*iter)->notify_transform( entity->bridge_manager()->topology_bridge(), xform ); 06844 return CUBIT_SUCCESS; 06845 } 06846 06847 void GeometryQueryTool::notify_observers_of_transform( 06848 DLIList<RefEntity*> &ref_ents, 06849 const CubitTransformMatrix *xform ) const 06850 { 06851 if( xform ) 06852 { 06853 //gather all the children 06854 DLIList<RefEntity*> all_ref_ents; 06855 RefEntity::get_all_child_ref_entities( ref_ents, all_ref_ents ); 06856 all_ref_ents.uniquify_ordered(); 06857 06858 all_ref_ents += ref_ents; 06859 06860 for(int i=0; i<all_ref_ents.size(); i++) 06861 { 06862 GeometryEvent evt(GeometryEvent::GEOMETRY_TRANSFORMED, all_ref_ents[i]); 06863 all_ref_ents[i]->notify_observers(&evt); 06864 } 06865 06866 AppUtil::instance()->send_event(TransformEvent(*xform, all_ref_ents.as_vector() )); 06867 } 06868 else 06869 { 06870 for( int i=0; i<ref_ents.size(); i++ ) 06871 { 06872 RefEntity *ent = ref_ents[i]; 06873 ent->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 06874 } 06875 } 06876 } 06877 06878 void GeometryQueryTool::notify_observers_of_transform( 06879 RefEntity* ref_entity, 06880 const CubitTransformMatrix *xform ) const 06881 { 06882 ref_entity->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 06883 06884 //CGMHistory::Event evt(CGMHistory::GEOMETRY_TRANSFORMED, ref_entity); 06885 //const_cast<CGMHistory&>(mHistory).add_event(evt); 06886 } 06887 06888 CubitBoolean GeometryQueryTool::okay_to_transform( BasicTopologyEntity* bte ) const 06889 { 06890 if (bte->get_parents() > 0) 06891 { 06892 PRINT_ERROR("Cannot transform %s (%s %d) : not a free %s\n", 06893 bte->entity_name().c_str(), bte->class_name(), bte->id(), bte->class_name() ); 06894 return CUBIT_FALSE; 06895 } 06896 06897 DLIList<RefEntity*> list(1); 06898 list.append( bte ); 06899 if (MergeTool::instance()->contains_merged_entities( list )) 06900 { 06901 PRINT_ERROR("Cannot tranmform %s (%s %d) : " 06902 "%s is merged or contains merged geomtry.\n", 06903 bte->entity_name().c_str(), bte->class_name(), bte->id(), bte->class_name() ); 06904 return CUBIT_FALSE; 06905 } 06906 06907 return CUBIT_TRUE; 06908 } 06909 06910 CubitStatus GeometryQueryTool::translate( DLIList<BasicTopologyEntity*> &btes, 06911 const CubitVector& delta, 06912 DLIList<BasicTopologyEntity*> *btes_translated, 06913 bool check_to_transform, 06914 bool preview ) 06915 { 06916 CubitTransformMatrix xform; 06917 xform.translate(delta); 06918 06919 DLIList<RefEntity*> transformed_ents; 06920 06921 for( int k=0; k<btes.size(); k++ ) 06922 { 06923 BasicTopologyEntity *bte = btes[k]; 06924 06925 if( check_to_transform ) 06926 if (!okay_to_transform( bte )) 06927 continue; 06928 06929 if (preview) 06930 { 06931 if(bte->dimension()==0) 06932 { 06933 DLIList<RefVertex*> points; 06934 bte->ref_vertices(points); 06935 for (int i = 0; i < points.size(); i++) 06936 { 06937 CubitVector temp(points[i]->center_point()); 06938 temp = xform*temp; 06939 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 06940 } 06941 } 06942 else 06943 { 06944 DLIList<RefEdge*> edges; 06945 bte->ref_edges(edges); 06946 for (int i = 0; i < edges.size(); i++) 06947 { 06948 GMem poly; 06949 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 06950 { 06951 poly.transform(xform); 06952 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 06953 } 06954 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 06955 { 06956 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 06957 tmp_pt = xform*tmp_pt; 06958 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 06959 } 06960 } 06961 if (edges.size() == 0) 06962 { 06963 DLIList<RefVertex*> points; 06964 bte->ref_vertices(points); 06965 for (int i = 0; i < points.size(); i++) 06966 { 06967 CubitVector temp(points[i]->center_point()); 06968 temp=xform*temp; 06969 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 06970 } 06971 } 06972 } 06973 GfxPreview::flush(); 06974 continue; 06975 } 06976 06977 GeometryEntity* geom = bte->get_geometry_entity_ptr(); 06978 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 06979 CubitStatus result = engine->translate( geom, delta ); 06980 if (result) 06981 { 06982 notify_intermediate_of_transform( bte, xform ); 06983 06984 if( btes_translated ) 06985 btes_translated->append( bte ); 06986 transformed_ents.append( bte ); 06987 } 06988 else 06989 PRINT_ERROR("Translate of %s (%s %d) failed.\n", 06990 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 06991 } 06992 06993 if( transformed_ents.size() ) 06994 { 06995 notify_observers_of_transform( transformed_ents, &xform ); 06996 return CUBIT_SUCCESS; 06997 } 06998 else if( preview ) 06999 return CUBIT_SUCCESS; 07000 else 07001 return CUBIT_FAILURE; 07002 } 07003 07004 CubitStatus GeometryQueryTool::rotate( DLIList<BasicTopologyEntity*> &btes, 07005 const CubitVector& point, 07006 const CubitVector& direction, 07007 double angle, 07008 DLIList<BasicTopologyEntity*> *btes_rotated, 07009 bool check_to_transform, 07010 bool preview ) 07011 { 07012 CubitTransformMatrix prev_xform; 07013 prev_xform.translate(-point); 07014 07015 CubitTransformMatrix rot_mat; 07016 rot_mat.rotate( angle, direction ); 07017 07018 CubitTransformMatrix mov_mat; 07019 mov_mat.translate( point ); 07020 07021 CubitTransformMatrix total_transform; 07022 total_transform = mov_mat*rot_mat*prev_xform; 07023 07024 DLIList<RefEntity*> ents_transformed; 07025 07026 for( int k=0; k<btes.size(); k++ ) 07027 { 07028 BasicTopologyEntity *bte = btes[k]; 07029 07030 if( check_to_transform ) 07031 if (!okay_to_transform( bte )) 07032 continue; 07033 07034 if (preview) 07035 { 07036 if(bte->dimension()==0) 07037 { 07038 DLIList<RefVertex*> points; 07039 bte->ref_vertices(points); 07040 for (int i = 0; i < points.size(); i++) 07041 { 07042 CubitVector temp(points[i]->center_point()); 07043 temp = total_transform*temp; 07044 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 07045 } 07046 } 07047 else 07048 { 07049 07050 DLIList<RefEdge*> edges; 07051 bte->ref_edges(edges); 07052 07053 for (int j = 0; j < edges.size(); j++) 07054 { 07055 GMem poly; 07056 if( CUBIT_SUCCESS == edges[j]->get_graphics(poly) ) 07057 { 07058 poly.transform(total_transform); 07059 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 07060 } 07061 else if( edges[j]->start_vertex() == edges[j]->end_vertex() ) 07062 { 07063 CubitVector tmp_pt = edges[j]->start_vertex()->coordinates(); 07064 tmp_pt = total_transform*tmp_pt; 07065 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 07066 } 07067 } 07068 if (edges.size() == 0) 07069 { 07070 DLIList<RefVertex*> points; 07071 bte->ref_vertices(points); 07072 for (int i = 0; i < points.size(); i++) 07073 { 07074 CubitVector p(points[i]->center_point()); 07075 p = total_transform*p; 07076 GfxPreview::draw_point(p, CUBIT_BLUE_INDEX); 07077 } 07078 } 07079 } 07080 07081 GfxPreview::flush(); 07082 continue; 07083 } 07084 07085 GeometryEntity* geom = bte->get_geometry_entity_ptr(); 07086 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 07087 CubitStatus result; 07088 // Move to origin 07089 result = engine->translate( geom, -point ); 07090 if (result) 07091 { 07092 CubitTransformMatrix xform; 07093 xform.translate( -point ); 07094 notify_intermediate_of_transform( bte, xform ); 07095 } 07096 else 07097 { 07098 PRINT_ERROR("Rotate of %s (%s %d) failed.\n", 07099 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07100 continue; 07101 } 07102 07103 result = engine->rotate( geom, direction, angle ); 07104 if (result) 07105 { 07106 CubitTransformMatrix rot_mat; 07107 rot_mat.rotate( angle, direction ); 07108 notify_intermediate_of_transform( bte, rot_mat ); 07109 } 07110 else 07111 { 07112 PRINT_ERROR("Rotate of %s (%s %d) failed.\n", 07113 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07114 continue; 07115 } 07116 result=engine->translate( geom, point ); 07117 07118 if (result) 07119 { 07120 CubitTransformMatrix mov_mat; 07121 mov_mat.translate( point ); 07122 notify_intermediate_of_transform( bte, mov_mat ); 07123 07124 if( btes_rotated ) 07125 btes_rotated->append( bte ); 07126 ents_transformed.append( bte ); 07127 } 07128 else 07129 { 07130 PRINT_ERROR("Rotate of %s (%s %d) failed.\n", 07131 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07132 continue; 07133 } 07134 } 07135 07136 if( ents_transformed.size() ) 07137 { 07138 notify_observers_of_transform( ents_transformed, &total_transform ); 07139 return CUBIT_SUCCESS; 07140 } 07141 else if( preview ) 07142 return CUBIT_SUCCESS; 07143 else 07144 return CUBIT_FAILURE; 07145 } 07146 07147 CubitStatus GeometryQueryTool::rotate( DLIList<BasicTopologyEntity*> &btes, 07148 const CubitVector& axis, 07149 double angle, 07150 DLIList<BasicTopologyEntity*> *btes_rotated, 07151 bool check_to_transform, 07152 bool preview ) 07153 { 07154 CubitTransformMatrix xform; 07155 xform.rotate( angle, axis ); 07156 07157 DLIList<RefEntity*> ents_transformed; 07158 07159 for( int k=0; k<btes.size(); k++ ) 07160 { 07161 BasicTopologyEntity *bte = btes[k]; 07162 07163 if( check_to_transform ) 07164 if (!okay_to_transform( bte )) 07165 continue; 07166 07167 if (preview) 07168 { 07169 if(bte->dimension()==0) 07170 { 07171 DLIList<RefVertex*> points; 07172 bte->ref_vertices(points); 07173 for (int i = 0; i < points.size(); i++) 07174 { 07175 CubitVector temp(points[i]->center_point()); 07176 temp = xform*temp; 07177 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 07178 } 07179 } 07180 else 07181 { 07182 DLIList<RefEdge*> edges; 07183 bte->ref_edges(edges); 07184 07185 for (int j = 0; j < edges.size(); j++) 07186 { 07187 GMem poly; 07188 if( CUBIT_SUCCESS == edges[j]->get_graphics(poly) ) 07189 { 07190 poly.transform(xform); 07191 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 07192 } 07193 else if( edges[j]->start_vertex() == edges[j]->end_vertex() ) 07194 { 07195 CubitVector tmp_pt = edges[j]->start_vertex()->coordinates(); 07196 tmp_pt = xform*tmp_pt; 07197 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 07198 } 07199 } 07200 if (edges.size() == 0) 07201 { 07202 DLIList<RefVertex*> points; 07203 bte->ref_vertices(points); 07204 for (int i = 0; i < points.size(); i++) 07205 { 07206 CubitVector p(points[i]->center_point()); 07207 CubitVector q =xform*p; 07208 GfxPreview::draw_point(q, CUBIT_BLUE_INDEX); 07209 } 07210 } 07211 } 07212 07213 GfxPreview::flush(); 07214 continue; 07215 } 07216 07217 GeometryEntity* geom = bte->get_geometry_entity_ptr(); 07218 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 07219 CubitStatus result = engine->rotate( geom, axis, angle ); 07220 if (result) 07221 { 07222 notify_intermediate_of_transform( bte, xform ); 07223 07224 if( btes_rotated ) 07225 btes_rotated->append( bte ); 07226 ents_transformed.append( bte ); 07227 } 07228 else 07229 PRINT_ERROR("Rotate of %s (%s %d) failed.\n", 07230 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07231 } 07232 07233 if( ents_transformed.size() ) 07234 { 07235 notify_observers_of_transform( ents_transformed, &xform ); 07236 return CUBIT_SUCCESS; 07237 } 07238 else if( preview ) 07239 return CUBIT_SUCCESS; 07240 else 07241 return CUBIT_FAILURE; 07242 } 07243 07244 CubitStatus GeometryQueryTool::scale( BasicTopologyEntity* bte,const CubitVector& point, double factor, 07245 bool check_to_transform, bool preview ) 07246 { 07247 if( check_to_transform ) 07248 if (!okay_to_transform( bte )) 07249 return CUBIT_FAILURE; 07250 07251 CubitTransformMatrix prev_xform; 07252 prev_xform.translate(-point); 07253 07254 CubitTransformMatrix xform; 07255 xform.scale_about_origin( factor ); 07256 07257 CubitTransformMatrix mov_mat; 07258 mov_mat.translate( point ); 07259 07260 07261 if (preview) 07262 { 07263 07264 if(bte->dimension()==0) 07265 { 07266 DLIList<RefVertex*> points; 07267 bte->ref_vertices(points); 07268 for (int i = 0; i < points.size(); i++) 07269 { 07270 CubitVector temp(points[i]->center_point()); 07271 temp = prev_xform*temp; 07272 temp = xform*temp; 07273 temp = mov_mat*temp; 07274 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 07275 } 07276 } 07277 else 07278 { 07279 07280 DLIList<RefEdge*> edges; 07281 bte->ref_edges(edges); 07282 for (int i = 0; i < edges.size(); i++) 07283 { 07284 GMem poly; 07285 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 07286 { 07287 poly.transform(prev_xform); 07288 poly.transform(xform); 07289 poly.transform(mov_mat); 07290 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 07291 } 07292 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 07293 { 07294 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 07295 tmp_pt = prev_xform*tmp_pt; 07296 tmp_pt = xform*tmp_pt; 07297 tmp_pt = mov_mat*tmp_pt; 07298 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 07299 } 07300 } 07301 } 07302 GfxPreview::flush(); 07303 return CUBIT_SUCCESS; 07304 } 07305 07306 GeometryEntity* geom = bte->get_geometry_entity_ptr(); 07307 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 07308 CubitStatus result = engine->translate( geom, -point ); 07309 if (result) 07310 { 07311 CubitTransformMatrix prev_xform; 07312 prev_xform.translate(-point); 07313 notify_intermediate_of_transform( bte, prev_xform ); 07314 } 07315 else 07316 { 07317 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 07318 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07319 return result; 07320 } 07321 07322 result = engine->scale( geom, factor ); 07323 if (result) 07324 { 07325 CubitTransformMatrix xform; 07326 xform.scale_about_origin( factor ); 07327 notify_intermediate_of_transform( bte, xform ); 07328 } 07329 else 07330 { 07331 PRINT_ERROR("Scvale of %s (%s %d) failed.\n", 07332 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07333 return result; 07334 } 07335 result = engine->translate( geom, point ); 07336 if (result) 07337 { 07338 CubitTransformMatrix mov_mat; 07339 mov_mat.translate( point ); 07340 07341 notify_intermediate_of_transform( bte, prev_xform ); 07342 notify_observers_of_transform( bte ); 07343 } 07344 else 07345 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 07346 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07347 return result; 07348 } 07349 07350 07351 CubitStatus GeometryQueryTool::scale( BasicTopologyEntity* bte, 07352 const CubitVector& point, 07353 const CubitVector& factors, 07354 bool check_to_transform, 07355 bool preview ) 07356 { 07357 if( check_to_transform ) 07358 if (!okay_to_transform( bte )) 07359 return CUBIT_FAILURE; 07360 07361 CubitTransformMatrix prev_xform; 07362 prev_xform.translate(-point); 07363 07364 CubitTransformMatrix xform; 07365 xform.scale_about_origin( factors ); 07366 07367 CubitTransformMatrix mov_mat; 07368 mov_mat.translate( point ); 07369 07370 07371 if (preview) 07372 { 07373 if(bte->dimension()==0) 07374 { 07375 DLIList<RefVertex*> points; 07376 bte->ref_vertices(points); 07377 for (int i = 0; i < points.size(); i++) 07378 { 07379 CubitVector temp(points[i]->center_point()); 07380 temp = prev_xform*temp; 07381 temp = xform*temp; 07382 temp = mov_mat*temp; 07383 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 07384 } 07385 } 07386 else 07387 { 07388 07389 DLIList<RefEdge*> edges; 07390 bte->ref_edges(edges); 07391 for (int i = 0; i < edges.size(); i++) 07392 { 07393 GMem poly; 07394 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 07395 { 07396 poly.transform(prev_xform); 07397 poly.transform(xform); 07398 poly.transform(mov_mat); 07399 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 07400 } 07401 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 07402 { 07403 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 07404 tmp_pt = prev_xform*tmp_pt; 07405 tmp_pt = xform*tmp_pt; 07406 tmp_pt = mov_mat*tmp_pt; 07407 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 07408 } 07409 } 07410 } 07411 GfxPreview::flush(); 07412 return CUBIT_SUCCESS; 07413 } 07414 07415 GeometryEntity* geom = bte->get_geometry_entity_ptr(); 07416 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 07417 CubitStatus result = engine->translate( geom, -point ); 07418 if (result) 07419 { 07420 notify_intermediate_of_transform( bte, prev_xform ); 07421 } 07422 else 07423 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 07424 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07425 07426 result = engine->scale( geom, factors ); 07427 if (result) 07428 { 07429 notify_intermediate_of_transform( bte, xform ); 07430 } 07431 else 07432 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 07433 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07434 07435 07436 result = engine->translate( geom, point ); 07437 if (result) 07438 { 07439 notify_intermediate_of_transform( bte, mov_mat ); 07440 notify_observers_of_transform( bte ); 07441 } 07442 else 07443 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 07444 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07445 07446 07447 07448 return result; 07449 } 07450 07451 CubitStatus GeometryQueryTool::reflect( DLIList<BasicTopologyEntity*> &btes, 07452 const CubitVector& point, 07453 const CubitVector& normal, 07454 DLIList<BasicTopologyEntity*> *btes_reflected, 07455 bool check_to_transform, 07456 bool preview ) 07457 { 07458 CubitTransformMatrix prev_xform; 07459 prev_xform.translate(-point); 07460 07461 CubitTransformMatrix ref_mat; 07462 ref_mat.reflect(normal ); 07463 07464 CubitTransformMatrix mov_mat; 07465 mov_mat.translate( point ); 07466 07467 CubitTransformMatrix total_transform; 07468 total_transform = mov_mat*ref_mat*prev_xform; 07469 07470 DLIList<RefEntity*> transformed_ents; 07471 07472 for( int k=0; k<btes.size(); k++ ) 07473 { 07474 BasicTopologyEntity *bte = btes[k]; 07475 07476 if( check_to_transform ) 07477 if (!okay_to_transform( bte )) 07478 return CUBIT_FAILURE; 07479 07480 if (preview) 07481 { 07482 if(bte->dimension()==0) 07483 { 07484 DLIList<RefVertex*> points; 07485 bte->ref_vertices(points); 07486 for (int i = 0; i < points.size(); i++) 07487 { 07488 CubitVector temp(points[i]->center_point()); 07489 temp = total_transform*temp; 07490 GfxPreview::draw_point(temp, CUBIT_BLUE_INDEX); 07491 } 07492 } 07493 else 07494 { 07495 07496 DLIList<RefEdge*> edges; 07497 bte->ref_edges(edges); 07498 for (int j = 0; j < edges.size(); j++) 07499 { 07500 GMem poly; 07501 if( CUBIT_SUCCESS == edges[j]->get_graphics(poly) ) 07502 { 07503 poly.transform( total_transform ); 07504 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 07505 } 07506 else if( edges[j]->start_vertex() == edges[j]->end_vertex() ) 07507 { 07508 CubitVector tmp_pt = edges[j]->start_vertex()->coordinates(); 07509 tmp_pt = total_transform*tmp_pt; 07510 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 07511 } 07512 } 07513 } 07514 GfxPreview::flush(); 07515 continue; 07516 } 07517 07518 GeometryEntity* geom = bte->get_geometry_entity_ptr(); 07519 GeometryQueryEngine* engine = geom->get_geometry_query_engine(); 07520 CubitStatus result; 07521 07522 // Move to origin 07523 result = engine->translate( geom, -point ); 07524 if (result) 07525 { 07526 CubitTransformMatrix xform; 07527 xform.translate( -point ); 07528 notify_intermediate_of_transform( bte, xform ); 07529 } 07530 else 07531 { 07532 PRINT_ERROR("Reflect of %s (%s %d) failed.\n", 07533 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07534 return result; 07535 } 07536 07537 result = engine->reflect( geom, normal ); 07538 if (result) 07539 { 07540 CubitTransformMatrix xform; 07541 xform.reflect( normal); 07542 notify_intermediate_of_transform( bte, xform ); 07543 } 07544 else 07545 { 07546 PRINT_ERROR("Reflect of %s (%s %d) failed.\n", 07547 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07548 return result; 07549 } 07550 07551 result = engine->translate( geom, point ); 07552 if (result) 07553 { 07554 CubitTransformMatrix xform; 07555 xform.translate( point ); 07556 notify_intermediate_of_transform( bte, xform ); 07557 07558 if( btes_reflected ) 07559 btes_reflected->append( bte ); 07560 transformed_ents.append( bte ); 07561 } 07562 else 07563 { 07564 PRINT_ERROR("Reflect of %s (%s %d) failed.\n", 07565 bte->entity_name().c_str(), bte->class_name(), bte->id() ); 07566 return result; 07567 } 07568 } 07569 07570 if( transformed_ents.size() ) 07571 { 07572 notify_observers_of_transform( transformed_ents, &total_transform ); 07573 return CUBIT_SUCCESS; 07574 } 07575 else if( preview ) 07576 return CUBIT_SUCCESS; 07577 else 07578 return CUBIT_FAILURE; 07579 } 07580 07581 void GeometryQueryTool::ige_remove_modified(DLIList<Surface*> &all_surfs, 07582 DLIList<Curve*> &all_curves, 07583 DLIList<TBPoint*> &all_points) 07584 { 07585 IGESet::iterator itor; 07586 07587 for (itor = igeSet.begin(); itor != igeSet.end(); ++itor) 07588 (*itor)->remove_modified(all_surfs, all_curves, all_points); 07589 07590 for (itor = igeSet.begin(); itor != igeSet.end(); ++itor) 07591 (*itor)->clean_out_deactivated_geometry(); 07592 } 07593 07594 CubitBoolean GeometryQueryTool::bodies_overlap( Body *body_ptr_1, 07595 Body *body_ptr_2 ) 07596 { 07597 BodySM *body1 = body_ptr_1->get_body_sm_ptr(); 07598 BodySM *body2 = body_ptr_2->get_body_sm_ptr(); 07599 07600 if( is_intermediate_geometry( body_ptr_1 ) ) 07601 return body_ptr_1->get_geometry_query_engine()->bodies_overlap( body1, body2 ); 07602 else if( is_intermediate_geometry( body_ptr_2 ) ) 07603 return body_ptr_2->get_geometry_query_engine()->bodies_overlap( body2, body1 ); 07604 else if( body_ptr_1->get_geometry_query_engine() != 07605 body_ptr_2->get_geometry_query_engine() ) 07606 { 07607 PRINT_ERROR("Volumes must be of the same type ( SolidWorks, etc) to\n" 07608 "find if they overlap.\n"); 07609 return CUBIT_FALSE; 07610 } 07611 else 07612 return body_ptr_1->get_geometry_query_engine()->bodies_overlap( body1, body2 ); 07613 } 07614 07615 CubitBoolean GeometryQueryTool::volumes_overlap( RefVolume *volume_1, 07616 RefVolume *volume_2 ) 07617 { 07618 Lump *lump1 = volume_1->get_lump_ptr(); 07619 Lump *lump2 = volume_2->get_lump_ptr(); 07620 07621 if( is_intermediate_geometry( volume_1 ) ) 07622 return volume_1->get_geometry_query_engine()->volumes_overlap( lump1, lump2 ); 07623 else if( is_intermediate_geometry( volume_2 ) ) 07624 return volume_2->get_geometry_query_engine()->volumes_overlap( lump2, lump1 ); 07625 else if( volume_1->get_geometry_query_engine() != 07626 volume_2->get_geometry_query_engine() ) 07627 { 07628 PRINT_ERROR("Volumes must be of the same type (SolidWorks, etc) to\n" 07629 "find if they overlap.\n"); 07630 return CUBIT_FALSE; 07631 } 07632 else 07633 return volume_1->get_geometry_query_engine()->volumes_overlap( lump1, lump2 ); 07634 } 07635 07636 void GeometryQueryTool::find_nonmanifold_curves(DLIList<RefVolume*> &vol_list, 07637 DLIList<RefEdge*> &curve_list) 07638 { 07639 int i; 07640 for(i=vol_list.size(); i>0; i--) 07641 { 07642 RefVolume *vol = vol_list.get_and_step(); 07643 DLIList<RefEdge*> vol_curves; 07644 vol->ref_edges(vol_curves); 07645 int j; 07646 for(j=vol_curves.size(); j>0; j--) 07647 { 07648 RefEdge *cur_curve = vol_curves.get_and_step(); 07649 if(cur_curve->is_merged()) 07650 { 07651 DLIList<RefFace*> curve_faces; 07652 cur_curve->ref_faces(curve_faces); 07653 bool merged_face_exists = false; 07654 while(curve_faces.size() && !merged_face_exists) 07655 { 07656 RefFace *cur_face = curve_faces.pop(); 07657 if(cur_face->is_merged()) 07658 merged_face_exists = true; 07659 } 07660 if(!merged_face_exists) 07661 curve_list.append(cur_curve); 07662 } 07663 } 07664 } 07665 curve_list.uniquify_ordered(); 07666 } 07667 07668 double GeometryQueryTool::estimate_merge_tolerance(DLIList<RefVolume*> &vol_list, 07669 bool accurate_in, 07670 bool report_in, 07671 double lo_val_in, 07672 double hi_val_in, 07673 int num_calculations_in, 07674 bool return_calculations_in, 07675 DLIList<double> *merge_tols, 07676 DLIList<int> *num_proximities) 07677 { 07678 double return_merge_tol = -1.0; // return value of < 0.0 will mean failure 07679 // to find a merge tolerance 07680 07681 DLIList<double> local_merge_tols; 07682 DLIList<int> local_num_proximities; 07683 bool report = report_in; 07684 double lo_val = 0.0; 07685 double hi_val = get_geometry_factor()*GEOMETRY_RESABS*10.0; // 10 * merge tol -- arbitrary 07686 int num_calculations = num_calculations_in; 07687 07688 if(lo_val_in != -1.0) 07689 lo_val = lo_val_in; 07690 if(hi_val_in != -1.0) 07691 hi_val = hi_val_in; 07692 07693 if(hi_val > lo_val) 07694 { 07695 double cur_val = lo_val; 07696 double step = (hi_val - lo_val)/(double)num_calculations; 07697 int i; 07698 if(report) 07699 { 07700 PRINT_INFO("\n\nLooking for merge toleance...\n\n"); 07701 PRINT_INFO(" Possible range: %f, %f\n", lo_val, hi_val); 07702 PRINT_INFO(" Number of steps: %d\n\n", num_calculations+1); 07703 } 07704 07705 std::map <RefVertex*, DLIList<dist_vert_struct*>*> vert_dist_map; 07706 GeomMeasureTool::find_near_coincident_vertices_unique(vol_list, hi_val, vert_dist_map); 07707 07708 int total_num_proximities = 0; 07709 for(i=0; i<=num_calculations; i++) 07710 { 07711 int cur_num_proximities = 0; 07712 local_merge_tols.append(cur_val); 07713 07714 std::map <RefVertex*, DLIList<dist_vert_struct*>*>::iterator iter; 07715 for(iter=vert_dist_map.begin(); iter != vert_dist_map.end(); iter++ ) 07716 { 07717 //RefVertex *vert = iter->first; 07718 DLIList<dist_vert_struct*> *struct_list = iter->second; 07719 int m; 07720 for(m=struct_list->size(); m>0; m--) 07721 { 07722 dist_vert_struct *dvs = struct_list->get(); 07723 if(dvs->dist <= cur_val) 07724 { 07725 // PRINT_INFO("Vertices %d and %d, distance: %.10lf\n", vert->id(), dvs->v2->id(), dvs->dist); 07726 struct_list->change_to(NULL); 07727 delete dvs; 07728 cur_num_proximities++; 07729 } 07730 struct_list->step(); 07731 } 07732 struct_list->remove_all_with_value(NULL); 07733 } 07734 07735 total_num_proximities += cur_num_proximities; 07736 local_num_proximities.append(total_num_proximities); 07737 07738 if(report) 07739 { 07740 PRINT_INFO(" At merge tolerance = %f number of proximities = %d.\n", cur_val, total_num_proximities); 07741 } 07742 07743 cur_val += step; 07744 } 07745 07746 std::map <RefVertex*, DLIList<dist_vert_struct*>*>::iterator iter; 07747 for(iter=vert_dist_map.begin(); iter != vert_dist_map.end(); iter++ ) 07748 { 07749 DLIList<dist_vert_struct*> *struct_list = iter->second; 07750 // I think all of the items in the lists should be gone 07751 // by now but just in case... 07752 while(struct_list->size()) 07753 delete struct_list->pop(); 07754 delete struct_list; 07755 } 07756 07757 local_num_proximities.reset(); 07758 local_merge_tols.reset(); 07759 int num_total = local_merge_tols.size(); 07760 if(num_total > 2) 07761 { 07762 int num_triplets = num_total - 2; 07763 int h, min_index, min_diff; 07764 DLIList<int> diffs; 07765 for(h=0; h<num_triplets; h++) 07766 { 07767 int num_begin = local_num_proximities.get(); 07768 local_num_proximities.step(2); 07769 int num_end = local_num_proximities.get(); 07770 local_num_proximities.back(); 07771 int cur_diff = num_end - num_begin; 07772 if(h==0) 07773 { 07774 min_index = h; 07775 min_diff = cur_diff; 07776 } 07777 else 07778 { 07779 if(cur_diff < min_diff) 07780 { 07781 min_diff = cur_diff; 07782 min_index = h; 07783 } 07784 } 07785 } 07786 local_merge_tols.step(min_index+1); 07787 return_merge_tol = local_merge_tols.get(); 07788 } 07789 else 07790 PRINT_ERROR("Unable to estimate merge tolerance.\n"); 07791 07792 /* 07793 // Pick off a merge tolerance. 07794 local_num_proximities.reset(); 07795 local_merge_tols.reset(); 07796 DLIList<int> unique_num_proximities; 07797 DLIList<int> unique_counts; 07798 DLIList<double> tmp_merge_tol_list; 07799 int tmp_num_proximities; 07800 double tmp_merge_tol; 07801 07802 double cur_merge_tol = local_merge_tols.get_and_step(); 07803 int cur_num_prox = local_num_proximities.get_and_step(); 07804 int cur_unique_counts = 1; 07805 // Loop over the whole size even though we have processed the 07806 // first entry because we need to record the results after the 07807 // last entry. 07808 for(i=local_num_proximities.size(); i>0; i--) 07809 { 07810 if(i>1) 07811 { 07812 tmp_num_proximities = local_num_proximities.get_and_step(); 07813 tmp_merge_tol = local_merge_tols.get_and_step(); 07814 } 07815 else 07816 { 07817 // On the last time in just give it a dummy value so we 07818 // can record the results from the last real entry. 07819 tmp_num_proximities = -1; 07820 } 07821 if(cur_num_prox == tmp_num_proximities) 07822 { 07823 cur_unique_counts++; 07824 } 07825 else 07826 { 07827 tmp_merge_tol_list.append(cur_merge_tol); 07828 unique_counts.append(cur_unique_counts); 07829 unique_num_proximities.append(cur_num_prox); 07830 cur_unique_counts = 1; 07831 cur_num_prox = tmp_num_proximities; 07832 cur_merge_tol = tmp_merge_tol; 07833 } 07834 } 07835 07836 int max_index = -1; 07837 int cur_max_num_counts = 0; 07838 unique_counts.reset(); 07839 unique_num_proximities.reset(); 07840 tmp_merge_tol_list.reset(); 07841 for(i=unique_counts.size(); i>0; i--) 07842 { 07843 int cur_num_counts = unique_counts.get(); 07844 if(cur_num_counts > cur_max_num_counts) 07845 { 07846 cur_max_num_counts = cur_num_counts; 07847 max_index = unique_counts.get_index(); 07848 } 07849 unique_counts.step(); 07850 } 07851 07852 if(max_index > -1) 07853 { 07854 tmp_merge_tol_list.step(max_index); 07855 return_merge_tol = tmp_merge_tol_list.get(); 07856 } 07857 else 07858 { 07859 PRINT_ERROR("Unable to estimate merge tolerance.\n"); 07860 } 07861 */ 07862 07863 if(report) 07864 PRINT_INFO("\nEstimated merge tolerance: %f\n", return_merge_tol); 07865 } 07866 else 07867 PRINT_ERROR("Range low value is larger than range high value.\n"); 07868 07869 return return_merge_tol; 07870 } 07871 07872 void GeometryQueryTool::find_floating_volumes(DLIList<RefVolume*> &vol_list, 07873 DLIList<RefVolume*> &floating_list) 07874 { 07875 int i; 07876 for(i=vol_list.size(); i>0; i--) 07877 { 07878 bool floating = true; 07879 RefVolume *vol = vol_list.get_and_step(); 07880 DLIList<RefEdge*> vol_curves; 07881 DLIList<RefVertex*> vol_verts; 07882 DLIList<RefFace*> vol_surfs; 07883 vol->ref_edges(vol_curves); 07884 vol->ref_faces(vol_surfs); 07885 vol->ref_vertices(vol_verts); 07886 int j; 07887 for(j=vol_surfs.size(); j>0 && floating; j--) 07888 { 07889 RefFace *cur_surf = vol_surfs.get_and_step(); 07890 if(cur_surf->is_merged()) 07891 floating = false; 07892 } 07893 for(j=vol_curves.size(); j>0 && floating; j--) 07894 { 07895 RefEdge *cur_curve = vol_curves.get_and_step(); 07896 if(cur_curve->is_merged()) 07897 floating = false; 07898 } 07899 for(j=vol_verts.size(); j>0 && floating; j--) 07900 { 07901 RefVertex *cur_vert = vol_verts.get_and_step(); 07902 if(cur_vert->is_merged()) 07903 floating = false; 07904 } 07905 if(floating) 07906 floating_list.append(vol); 07907 } 07908 floating_list.uniquify_ordered(); 07909 } 07910 07911 void GeometryQueryTool::find_nonmanifold_vertices(DLIList<RefVolume*> &vol_list, 07912 DLIList<RefVertex*> &vertex_list) 07913 { 07914 int i; 07915 for(i=vol_list.size(); i>0; i--) 07916 { 07917 RefVolume *vol = vol_list.get_and_step(); 07918 DLIList<RefVertex*> vol_verts; 07919 vol->ref_vertices(vol_verts); 07920 int j; 07921 for(j=vol_verts.size(); j>0; j--) 07922 { 07923 RefVertex *cur_vert = vol_verts.get_and_step(); 07924 if(cur_vert->is_merged()) 07925 { 07926 DLIList<RefEdge*> vert_edges; 07927 cur_vert->ref_edges(vert_edges); 07928 bool merged_edge_exists = false; 07929 while(vert_edges.size() && !merged_edge_exists) 07930 { 07931 RefEdge *cur_edge = vert_edges.pop(); 07932 if(cur_edge->is_merged()) 07933 merged_edge_exists = true; 07934 } 07935 if(!merged_edge_exists) 07936 vertex_list.append(cur_vert); 07937 } 07938 } 07939 } 07940 vertex_list.uniquify_ordered(); 07941 } 07942 07943 CGMHistory& GeometryQueryTool::history() 07944 { 07945 return mHistory; 07946 } 07947 07948 void GeometryQueryTool::get_merged_away_free_entities( DLIList<RefEntity*> &ref_ents, 07949 DLIList<TopologyBridge*> &free_ents ) 07950 { 07951 //determine if you have any free entities that were merged away 07952 DLIList<RefEntity*> merged_ref_ents; 07953 MergeTool::instance()->contains_merged_entities( ref_ents, &merged_ref_ents ); 07954 int i; 07955 for( i=merged_ref_ents.size(); i--; ) 07956 { 07957 RefEntity *tmp_ent = merged_ref_ents.get_and_step(); 07958 DLIList<TopologyBridge*> bridge_list; 07959 TopologyEntity *te = CAST_TO(tmp_ent, TopologyEntity ); 07960 te->bridge_manager()->get_bridge_list( bridge_list ); 07961 //bridge_list.reset(); 07962 //bridge_list.step(); //don't want to first bridge...that's the real thing 07963 07964 //check for free entities... 07965 int j; 07966 for( j=0; j<bridge_list.size(); j++ ) 07967 { 07968 TopologyBridge *tmp_bridge = bridge_list.get_and_step(); 07969 07970 //ignore the representation bridge if it's a free vertex 07971 if( j==0 ) 07972 if( tmp_ent->num_parent_ref_entities() == 0 ) 07973 continue; 07974 07975 DLIList<TopologyBridge*> parents; 07976 tmp_bridge->get_parents( parents ); 07977 if( parents.size() == 0 ) 07978 free_ents.append( tmp_bridge ); 07979 } 07980 } 07981 } 07982 07983 07984 CubitStatus GeometryQueryTool::get_graphics( RefFace *ref_face, 07985 GMem *gmem, 07986 std::vector<RefEntity*> &facet_point_ownership_vector, 07987 std::vector<std::pair< RefEntity*, std::pair<int,int> > > &facetedges_on_refedges, 07988 unsigned short normal_tolerance, 07989 double distance_tolerance, 07990 double max_edge_length ) 07991 { 07992 Surface* surf_ptr = ref_face->get_surface_ptr(); 07993 if (!surf_ptr) 07994 { 07995 PRINT_ERROR("RefFace %d is invalid -- no attached Surface.\n",ref_face->id()); 07996 return CUBIT_FAILURE; 07997 } 07998 07999 std::vector<TopologyBridge*> vertex_edge_to_point_vector; 08000 std::vector<std::pair<TopologyBridge*, std::pair<int,int> > > facetedges_on_curve; 08001 08002 CubitStatus rv = surf_ptr->get_geometry_query_engine()-> 08003 get_graphics(surf_ptr, gmem, vertex_edge_to_point_vector, facetedges_on_curve, 08004 normal_tolerance, distance_tolerance, max_edge_length ); 08005 if (CUBIT_SUCCESS != rv) { 08006 PRINT_ERROR("GeometryQueryEngine::get_graphics failed.\n"); 08007 return rv; 08008 } 08009 08010 facet_point_ownership_vector.resize( vertex_edge_to_point_vector.size(), NULL ); 08011 RefEntity *ref_ent = NULL; 08012 for( unsigned int i = 0; i < vertex_edge_to_point_vector.size(); i++ ) 08013 { 08014 TopologyBridge *tb = vertex_edge_to_point_vector[i]; 08015 if( NULL == tb ) 08016 continue; 08017 08018 if( tb->topology_entity() ) 08019 { 08020 ref_ent = CAST_TO( tb->topology_entity(), RefEntity ); 08021 facet_point_ownership_vector[i] = ref_ent; 08022 } 08023 else 08024 assert(0); 08025 } 08026 08027 for( unsigned int i = 0; i < facetedges_on_curve.size(); i++ ) 08028 { 08029 std::pair<TopologyBridge*, std::pair<int,int> > tmp_pair = facetedges_on_curve[i]; 08030 TopologyBridge *tb = tmp_pair.first; 08031 08032 if( tb->topology_entity() ) 08033 { 08034 ref_ent = CAST_TO( tb->topology_entity(), RefEntity ); 08035 facetedges_on_refedges.push_back( std::make_pair( ref_ent, tmp_pair.second ) ); 08036 } 08037 else 08038 { 08039 assert(0); 08040 } 08041 } 08042 08043 08044 bool debug = false; 08045 08046 if( debug ) 08047 { 08048 //GfxDebug::clear(); 08049 //GPoint *pt_list = gmem->point_list(); 08050 for( unsigned int i = 0; i < facet_point_ownership_vector.size(); i++ ) 08051 { 08052 //RefEntity *ref_ent = facet_point_ownership_vector[i]; 08053 08054 //int color = 3; 08055 //if( ref_ent->dimension() == 1 ) 08056 //color = 4; 08057 //else if( ref_ent->dimension() == 2 ) 08058 //color = 5; 08059 } 08060 08061 GfxDebug::flush(); 08062 GfxDebug::mouse_xforms(); 08063 08064 08065 GfxDebug::clear(); 08066 //draw the curves 08067 for( unsigned int i=0; i<facetedges_on_refedges.size(); i++ ) 08068 { 08069 std::pair<RefEntity*, std::pair<int,int> > tmp_pair; 08070 tmp_pair = facetedges_on_refedges[i]; 08071 08072 RefEntity* ref_ent = tmp_pair.first; 08073 std::pair<int,int> int_pair = tmp_pair.second; 08074 08075 CubitVector pt0( gmem->point_list()[int_pair.first].x, 08076 gmem->point_list()[int_pair.first].y, 08077 gmem->point_list()[int_pair.first].z ); 08078 08079 CubitVector pt1( gmem->point_list()[int_pair.second].x, 08080 gmem->point_list()[int_pair.second].y, 08081 gmem->point_list()[int_pair.second].z ); 08082 08083 GfxDebug::draw_point(pt0, (ref_ent->id()%10) + 3 ); 08084 GfxDebug::draw_point(pt1, (ref_ent->id()%10) + 3 ); 08085 GfxDebug::draw_line( pt0, pt1, (ref_ent->id()%10) + 3 ); 08086 } 08087 GfxDebug::flush(); 08088 GfxDebug::mouse_xforms(); 08089 08090 int index = 0; 08091 GfxDebug::clear(); 08092 for( int i=0; i<gmem->fListCount; i++ ) 08093 { 08094 int step = gmem->facet_list()[index++]; 08095 //create pts 08096 CubitVector pt0( gmem->point_list()[ gmem->facet_list()[index] ].x, 08097 gmem->point_list()[ gmem->facet_list()[index] ].y, 08098 gmem->point_list()[ gmem->facet_list()[index] ].z ); 08099 index++; 08100 08101 CubitVector pt1( gmem->point_list()[ gmem->facet_list()[index] ].x, 08102 gmem->point_list()[ gmem->facet_list()[index] ].y, 08103 gmem->point_list()[ gmem->facet_list()[index] ].z ); 08104 index++; 08105 08106 CubitVector pt2( gmem->point_list()[ gmem->facet_list()[index] ].x, 08107 gmem->point_list()[ gmem->facet_list()[index] ].y, 08108 gmem->point_list()[ gmem->facet_list()[index] ].z ); 08109 index++; 08110 08111 //draw lines 08112 GPoint three_pts[3]; 08113 three_pts[0].x = pt0.x(); 08114 three_pts[0].y = pt0.y(); 08115 three_pts[0].z = pt0.z(); 08116 08117 three_pts[1].x = pt1.x(); 08118 three_pts[1].y = pt1.y(); 08119 three_pts[1].z = pt1.z(); 08120 08121 three_pts[2].x = pt2.x(); 08122 three_pts[2].y = pt2.y(); 08123 three_pts[2].z = pt2.z(); 08124 08125 GfxDebug::draw_polygon( three_pts, 3, i%20, i%20, true ); 08126 GfxDebug::draw_line( pt0, pt1, i%20 ); 08127 GfxDebug::draw_line( pt1, pt2, i%20 ); 08128 GfxDebug::draw_line( pt0, pt2, i%20 ); 08129 i+=step; 08130 } 08131 GfxDebug::flush(); 08132 GfxDebug::mouse_xforms(); 08133 } 08134 08135 08136 08137 08138 return CUBIT_SUCCESS; 08139 } 08140 08141 08142 CubitStatus GeometryQueryTool::get_graphics( Body *body, 08143 GMem *g_mem, 08144 std::vector<RefFace*> &ref_face_to_facet_vector, 08145 std::vector<RefEntity*> &facet_point_ownership_vector, 08146 std::vector<std::pair< RefEntity*, std::pair<int,int> > > &facetedges_on_refedges, 08147 unsigned short normal_tolerance, 08148 double distance_tolerance, 08149 double max_edge_length ) 08150 { 08151 //get all the RefFaces from 08152 DLIList<RefFace*> all_ref_faces; 08153 body->ref_faces( all_ref_faces ); 08154 08155 BodySM *body_sm = NULL; 08156 08157 //get the underlying body in partition bodies 08158 if( GeometryQueryTool::instance()->is_intermediate_geometry( body ) ) 08159 { 08160 DLIList<TopologyBridge*> partition_body(1); 08161 body->get_body_sm_ptr()->get_geometry_query_engine()->get_underlying_bridges( body->get_body_sm_ptr(), partition_body ); 08162 if( partition_body.size() == 1 ) 08163 body_sm = static_cast<BodySM*>(partition_body.get()); 08164 } 08165 else 08166 body_sm = body->get_body_sm_ptr(); 08167 08168 //make sure everything belongs to the same GQE 08169 GeometryQueryEngine* gqe = body_sm->get_geometry_query_engine(); 08170 08171 //get the graphics 08172 std::vector<Surface*> surfaces_to_facet_vector; 08173 std::vector<TopologyBridge*> tmp_facet_point_ownership_vector; 08174 std::vector<std::pair<TopologyBridge*, std::pair<int,int> > > facetedges_on_curve; 08175 CubitStatus stat = gqe->get_graphics( body_sm, g_mem, surfaces_to_facet_vector, tmp_facet_point_ownership_vector, 08176 facetedges_on_curve, normal_tolerance, distance_tolerance, max_edge_length ); 08177 08178 if( CUBIT_FAILURE == stat ) 08179 return CUBIT_FAILURE; 08180 08181 //map Surfaces to MRefFaces 08182 Surface *current_surf = NULL; 08183 RefFace *current_ref_face = NULL; 08184 bool ignore_facets = false; 08185 08186 unsigned int i; 08187 for( i=0; i<surfaces_to_facet_vector.size(); i++ ) 08188 { 08189 Surface *tmp_surf = surfaces_to_facet_vector[i]; 08190 08191 if( tmp_surf != current_surf ) 08192 { 08193 ignore_facets = false; 08194 current_surf = tmp_surf; 08195 08196 if( tmp_surf->topology_entity() ) 08197 { 08198 current_ref_face = CAST_TO( tmp_surf->topology_entity(), RefFace ); 08199 if( current_ref_face ) 08200 ref_face_to_facet_vector.push_back( current_ref_face ); 08201 } 08202 else 08203 { 08204 int times_through = 0; 08205 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 08206 { 08207 times_through++; 08208 DLIList<TopologyBridge*> bridge_list; 08209 (*itor)->get_tbs_with_bridge_manager_as_owner(tmp_surf, bridge_list); 08210 if( bridge_list.size() == 0 ) 08211 { 08212 if( times_through == 2 ) 08213 assert(0); 08214 continue; 08215 } 08216 08217 if( bridge_list.size() == 1 ) 08218 { 08219 current_ref_face = CAST_TO( bridge_list.get()->topology_entity(), RefFace ); 08220 if( current_ref_face ) 08221 ref_face_to_facet_vector.push_back( current_ref_face ); 08222 else 08223 { 08224 PRINT_INFO("Having trouble finding the top-level RefFace\n"); 08225 assert(0); 08226 } 08227 break; 08228 } 08229 else if( bridge_list.size() > 1 ) // it is a partition...we'll ignore the facets 08230 { 08231 ref_face_to_facet_vector.push_back( NULL ); 08232 ignore_facets = true; 08233 break; 08234 } 08235 } 08236 } 08237 } 08238 else 08239 { 08240 if( ignore_facets ) 08241 ref_face_to_facet_vector.push_back( NULL ); 08242 else 08243 ref_face_to_facet_vector.push_back( current_ref_face ); 08244 } 08245 } 08246 08247 facet_point_ownership_vector.resize( tmp_facet_point_ownership_vector.size(), NULL ); 08248 RefEntity *ref_ent = NULL; 08249 for( i=0; i<tmp_facet_point_ownership_vector.size(); i++ ) 08250 { 08251 TopologyBridge *tb = tmp_facet_point_ownership_vector[i]; 08252 if( NULL == tb ) 08253 continue; 08254 08255 if( tb->topology_entity() ) 08256 { 08257 ref_ent = CAST_TO( tb->topology_entity(), RefEntity ); 08258 facet_point_ownership_vector[i] = ref_ent; 08259 } 08260 else 08261 { 08262 int times_through = 0; 08263 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 08264 { 08265 times_through++; 08266 DLIList<TopologyBridge*> bridge_list; 08267 (*itor)->get_tbs_with_bridge_manager_as_owner(tb, bridge_list); 08268 if( bridge_list.size() == 0 ) 08269 { 08270 if( times_through == 2 ) 08271 assert(0); 08272 continue; 08273 } 08274 08275 //composites 08276 if( bridge_list.size() == 1 ) 08277 { 08278 ref_ent = CAST_TO( bridge_list.get()->topology_entity(), RefEntity ); 08279 if( ref_ent ) 08280 facet_point_ownership_vector[i] = ref_ent; 08281 else 08282 { 08283 PRINT_INFO("Having trouble finding the top-level RefEdge or RefVertex\n"); 08284 assert(0); 08285 } 08286 break; 08287 } 08288 else if( bridge_list.size() > 1 ) // it is a partition...we'll ignore the facets 08289 { 08290 facet_point_ownership_vector[i] = NULL; 08291 ignore_facets = true; 08292 break; 08293 } 08294 } 08295 } 08296 } 08297 08298 for( i=0; i<facetedges_on_curve.size(); i++ ) 08299 { 08300 std::pair<TopologyBridge*, std::pair<int,int> > tmp_pair = facetedges_on_curve[i]; 08301 TopologyBridge *tb = tmp_pair.first; 08302 08303 if( tb->topology_entity() ) 08304 { 08305 ref_ent = CAST_TO( tb->topology_entity(), RefEntity ); 08306 facetedges_on_refedges.push_back( std::make_pair( ref_ent, tmp_pair.second ) ); 08307 } 08308 else 08309 { 08310 int times_through = 0; 08311 for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor) 08312 { 08313 times_through++; 08314 DLIList<TopologyBridge*> bridge_list; 08315 (*itor)->get_tbs_with_bridge_manager_as_owner(tb, bridge_list); 08316 if( bridge_list.size() == 0 ) 08317 { 08318 //if( times_through == 2 ) 08319 // assert(0); 08320 continue; 08321 } 08322 08323 //composites 08324 if( bridge_list.size() == 1 ) 08325 { 08326 ref_ent = CAST_TO( bridge_list.get()->topology_entity(), RefEntity ); 08327 if( ref_ent ) 08328 facetedges_on_refedges.push_back( std::make_pair( ref_ent, tmp_pair.second ) ); 08329 else 08330 { 08331 PRINT_INFO("Having trouble finding the top-level RefEdge or RefVertex\n"); 08332 assert(0); 08333 } 08334 break; 08335 } 08336 else if( bridge_list.size() > 1 ) // it is a partition...we'll ignore the facets 08337 { 08338 break; 08339 } 08340 } 08341 } 08342 } 08343 08344 08345 bool debug = false; 08346 08347 if( debug ) 08348 { 08349 //GfxDebug::clear(); 08350 GPoint *pt_list = g_mem->point_list(); 08351 for( unsigned int i = 0; i < facet_point_ownership_vector.size(); i++ ) 08352 { 08353 RefEntity *ref_ent = facet_point_ownership_vector[i]; 08354 08355 int color = 3; 08356 if( ref_ent->dimension() == 1 ) 08357 color = 4; 08358 else if( ref_ent->dimension() == 2 ) 08359 color = 5; 08360 08361 GfxDebug::draw_point( pt_list[i].x, pt_list[i].y, pt_list[i].z, color ); 08362 } 08363 08364 GfxDebug::flush(); 08365 GfxDebug::mouse_xforms(); 08366 /* 08367 GfxDebug::clear(); 08368 //draw the curves 08369 for( int i=0; i<facetedges_on_refedges.size(); i++ ) 08370 { 08371 std::pair<RefEntity*, std::pair<int,int> > tmp_pair; 08372 tmp_pair = facetedges_on_refedges[i]; 08373 08374 RefEntity* ref_ent = tmp_pair.first; 08375 std::pair<int,int> int_pair = tmp_pair.second; 08376 08377 CubitVector pt0( g_mem->point_list()[int_pair.first].x, 08378 g_mem->point_list()[int_pair.first].y, 08379 g_mem->point_list()[int_pair.first].z ); 08380 08381 CubitVector pt1( g_mem->point_list()[int_pair.second].x, 08382 g_mem->point_list()[int_pair.second].y, 08383 g_mem->point_list()[int_pair.second].z ); 08384 08385 GfxDebug::draw_point(pt0, (ref_ent->id()%10) + 3 ); 08386 GfxDebug::draw_point(pt1, (ref_ent->id()%10) + 3 ); 08387 GfxDebug::draw_line( pt0, pt1, (ref_ent->id()%10) + 3 ); 08388 } 08389 GfxDebug::flush(); 08390 GfxDebug::mouse_xforms(); 08391 08392 int index = 0; 08393 int color; 08394 08395 index = 0; 08396 GfxDebug::clear(); 08397 for( int i=0; i<g_mem->fListCount; i++ ) 08398 { 08399 int step = g_mem->facet_list()[index++]; 08400 //create pts 08401 RefEntity *ref_ent = facet_point_ownership_vector[ g_mem->facet_list()[index] ]; 08402 if( ref_ent->dimension() == 2 ) 08403 color = ref_ent->id() + 3 ; 08404 CubitVector pt0( g_mem->point_list()[ g_mem->facet_list()[index] ].x, 08405 g_mem->point_list()[ g_mem->facet_list()[index] ].y, 08406 g_mem->point_list()[ g_mem->facet_list()[index] ].z ); 08407 index++; 08408 08409 ref_ent = facet_point_ownership_vector[ g_mem->facet_list()[index] ]; 08410 if( ref_ent->dimension() == 2 ) 08411 color = ref_ent->id() + 3 ; 08412 CubitVector pt1( g_mem->point_list()[ g_mem->facet_list()[index] ].x, 08413 g_mem->point_list()[ g_mem->facet_list()[index] ].y, 08414 g_mem->point_list()[ g_mem->facet_list()[index] ].z ); 08415 index++; 08416 08417 ref_ent = facet_point_ownership_vector[ g_mem->facet_list()[index] ]; 08418 if( ref_ent->dimension() == 2 ) 08419 color = ref_ent->id() + 3 ; 08420 CubitVector pt2( g_mem->point_list()[ g_mem->facet_list()[index] ].x, 08421 g_mem->point_list()[ g_mem->facet_list()[index] ].y, 08422 g_mem->point_list()[ g_mem->facet_list()[index] ].z ); 08423 index++; 08424 08425 //draw lines 08426 08427 GPoint three_pts[3]; 08428 three_pts[0].x = pt0.x(); 08429 three_pts[0].y = pt0.y(); 08430 three_pts[0].z = pt0.z(); 08431 08432 three_pts[1].x = pt1.x(); 08433 three_pts[1].y = pt1.y(); 08434 three_pts[1].z = pt1.z(); 08435 08436 three_pts[2].x = pt2.x(); 08437 three_pts[2].y = pt2.y(); 08438 three_pts[2].z = pt2.z(); 08439 08440 GfxDebug::draw_polygon( three_pts, 3, i%20, i%20, true ); 08441 GfxDebug::draw_line( pt0, pt1, color ); 08442 GfxDebug::draw_line( pt1, pt2, color ); 08443 GfxDebug::draw_line( pt0, pt2, color ); 08444 i+=step; 08445 } 08446 GfxDebug::flush(); 08447 GfxDebug::mouse_xforms(); 08448 */ 08449 } 08450 08451 return CUBIT_SUCCESS; 08452 } 08453 08454 08455 CubitStatus GeometryQueryTool::get_point_containment( DLIList<Body*> &body_list, 08456 DLIList<CubitVector> &point_list, 08457 double tolerance, 08458 bool allow_pts_in_multiple_bodies, 08459 std::vector< std::pair<Body*, std::vector<int> > > &body_to_pt_indices ) 08460 { 08461 DLIList<TopologyEntity*> entity_list( body_list.size() ); 08462 for( int i=body_list.size(); i--; ) 08463 entity_list.append( body_list.get_and_step() ); 08464 08465 DLIList<TopologyBridge*> bridge_list; 08466 GeometryQueryEngine* gqe = common_query_engine( entity_list, bridge_list ); 08467 08468 //map for associating PartitionBody back to Body 08469 std::map<BodySM*, Body*> partition_body_map; 08470 08471 //there is a slim chance that all bodies are ParititonBodies. If so, 08472 //the gqe will be non-NULL...let's check if the first one is 08473 if( gqe && GeometryModifyTool::instance()->contains_partitions( body_list ) ) 08474 gqe = NULL; 08475 08476 //if the engine is still NULL, we could just have a partition body in there... 08477 if( gqe == NULL ) 08478 { 08479 bridge_list.clean_out(); 08480 08481 for( int k=0; k<body_list.size(); k++ ) 08482 { 08483 DLIList<TopologyBridge*> underlying_body; 08484 08485 //if it is virtual 08486 if( body_list[k]->get_geometry_query_engine()->is_intermediate_engine() ) 08487 { 08488 //get the underlying Body...in PartitionBody case, it should be a Body 08489 underlying_body.append( body_list[k]->bridge_manager()->topology_bridge() ); 08490 IGESet::reverse_iterator itor; 08491 for (itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor) 08492 (*itor)->export_geometry(underlying_body); 08493 08494 //if it is different than the original Body TopologyBridge, we found it 08495 if( underlying_body.size() && body_list[k]->bridge_manager()->topology_bridge() != underlying_body.get() ) 08496 { 08497 partition_body_map.insert( std::make_pair( (BodySM*)underlying_body.get(), body_list[k] ) ); 08498 bridge_list.append( underlying_body.get() ); 08499 } 08500 } 08501 else 08502 bridge_list.append( body_list[k]->bridge_manager()->topology_bridge() ); 08503 } 08504 08505 bridge_list.reset(); 08506 gqe = bridge_list.get_and_step()->get_geometry_query_engine(); 08507 08508 for( int i=1; i<bridge_list.size(); i++ ) 08509 { 08510 TopologyBridge *tmp_bridge = bridge_list.get_and_step(); 08511 if( gqe != tmp_bridge->get_geometry_query_engine() ) 08512 { 08513 gqe = NULL; 08514 break; 08515 } 08516 } 08517 } 08518 08519 if( gqe == NULL ) 08520 { 08521 PRINT_ERROR("Input geometry does not have the same geometry engine.\n"); 08522 return CUBIT_FAILURE; 08523 } 08524 08525 DLIList<BodySM*> body_sm_list; 08526 CAST_LIST(bridge_list, body_sm_list, BodySM); 08527 08528 std::vector< std::pair<BodySM*, std::vector<int> > > bodysm_to_pt_indices; 08529 gqe->get_point_containment( body_sm_list, point_list, tolerance, allow_pts_in_multiple_bodies, bodysm_to_pt_indices ); 08530 08531 //convert the BodySMs back to BODYs 08532 for( unsigned int i=0; i<bodysm_to_pt_indices.size(); i++ ) 08533 { 08534 std::pair<BodySM*, std::vector<int> > tmp_pair = bodysm_to_pt_indices[i]; 08535 BodySM *body_sm = tmp_pair.first; 08536 Body *tmp_body = dynamic_cast<Body*>( body_sm->topology_entity() ); 08537 if( !tmp_body ) 08538 { 08539 //PartitionBody case...look it up in the map 08540 std::map<BodySM*, Body*>::iterator tmp_iter = partition_body_map.find( body_sm ); 08541 if( partition_body_map.end() != tmp_iter ) 08542 { 08543 body_to_pt_indices.push_back( std::make_pair( tmp_iter->second, tmp_pair.second) ); 08544 } 08545 } 08546 else 08547 body_to_pt_indices.push_back( std::make_pair( tmp_body, tmp_pair.second) ); 08548 } 08549 08550 return CUBIT_SUCCESS; 08551 } 08552 08553 void GeometryQueryTool::validate_geometry_database() 08554 { 08555 DLIList<GeometryQueryEngine*> gqe_list; 08556 this->get_gqe_list(gqe_list); 08557 for(int i=0; i<gqe_list.size(); i++) 08558 { 08559 GeometryQueryEngine *gqe = gqe_list[i]; 08560 gqe->validate_geometry_database(); 08561 } 08562 } 08563 08564