cgma
|
00001 //- Class: SurfaceOverlapTool 00002 //- Description: Utilities to debug imprinting/merging problems 00003 //- Owner: Steve Storm 00004 //- Created: 22 October 1999 00005 //- Overhauled: January 2003 00006 00007 #include "RefEntityFactory.hpp" 00008 #include "SurfaceOverlapTool.hpp" 00009 #include "RefVertex.hpp" 00010 #include "RefEdge.hpp" 00011 #include "RefFace.hpp" 00012 #include "Body.hpp" 00013 #include "CoEdge.hpp" 00014 #include "BodySM.hpp" 00015 #include "RefGroup.hpp" 00016 #include "GeometryModifyTool.hpp" 00017 #include "GeometryQueryTool.hpp" 00018 #include "TopologyEntity.hpp" 00019 #include "Surface.hpp" 00020 #include "Curve.hpp" 00021 00022 #include "CubitBox.hpp" 00023 #include "CubitUtil.hpp" 00024 00025 #include "DLIList.hpp" 00026 #include "ProgressTool.hpp" 00027 #include "AppUtil.hpp" 00028 #include "SurfaceOverlapFacet.hpp" 00029 #include "CurveOverlapFacet.hpp" 00030 #include "TDSurfaceOverlap.hpp" 00031 #include "RTree.hpp" 00032 #include "AbstractTree.hpp" 00033 00034 #include "GMem.hpp" 00035 #include "SettingHandler.hpp" 00036 00037 #include "GfxPreview.hpp" 00038 #include "GfxDebug.hpp" 00039 #include "CpuTimer.hpp" 00040 00041 #define NO_FACETS_FOR_ABSTRACTTREE 10 00042 00043 SurfaceOverlapTool* SurfaceOverlapTool::instance_ = 0; 00044 double SurfaceOverlapTool::gapMin = 0.0; 00045 double SurfaceOverlapTool::gapMax = 0.01; 00046 double SurfaceOverlapTool::angleMin = 0.0; 00047 double SurfaceOverlapTool::angleMax = 5.0; 00048 int SurfaceOverlapTool::normalType = 1; // 1=any, 2=opposite, 3=same 00049 double SurfaceOverlapTool::overlapTolerance = .001; 00050 CubitBoolean SurfaceOverlapTool::groupResults = CUBIT_TRUE; 00051 CubitBoolean SurfaceOverlapTool::listPairs = CUBIT_TRUE; 00052 CubitBoolean SurfaceOverlapTool::displayPairs = CUBIT_TRUE; 00053 CubitBoolean SurfaceOverlapTool::imprintResults = CUBIT_FALSE; 00054 double SurfaceOverlapTool::facetAbsTol = 0.0; // Use default 00055 unsigned short SurfaceOverlapTool::facetAngTol = 15; // Seems to work pretty good 00056 CubitBoolean SurfaceOverlapTool::checkWithinBodies = CUBIT_FALSE; 00057 CubitBoolean SurfaceOverlapTool::checkAcrossBodies = CUBIT_TRUE; 00058 bool SurfaceOverlapTool::skipFacingSurfaces = CUBIT_FALSE; // skip the pair if the normals pass through eachother (normalType must == 2) 00059 00060 // Constructor 00061 SurfaceOverlapTool* SurfaceOverlapTool::instance() 00062 { 00063 if( instance_ == NULL ) 00064 instance_ = new SurfaceOverlapTool; 00065 return instance_; 00066 } 00067 00068 SurfaceOverlapTool::SurfaceOverlapTool() 00069 { 00070 facetAbsTol = 0.0; // Use default 00071 facetAngTol = 10; // Seems to work pretty good 00072 gapMin = 0.0; 00073 gapMax = 0.01; 00074 angleMin = 0.0; 00075 angleMax = 5.0; 00076 normalType = 1; // 1=any, 2=opposite, 3=same 00077 groupResults = CUBIT_TRUE; 00078 listPairs = CUBIT_TRUE; 00079 displayPairs = CUBIT_TRUE; 00080 overlapTolerance = .001; 00081 imprintResults = CUBIT_FALSE; 00082 checkWithinBodies = CUBIT_FALSE; 00083 checkAcrossBodies = CUBIT_TRUE; 00084 skipFacingSurfaces = CUBIT_FALSE; 00085 } 00086 00087 // Destructor 00088 SurfaceOverlapTool::~SurfaceOverlapTool() 00089 { 00090 } 00091 00092 CubitBoolean SurfaceOverlapTool::draw_overlapping_surface_pair( RefFace *ref_face_1, 00093 RefFace *ref_face_2) 00094 { 00095 CubitBoolean abort = CUBIT_FALSE; 00096 CubitBoolean draw_overlap = CUBIT_TRUE; 00097 CubitBoolean overlap = check_overlap( ref_face_1, ref_face_2, 00098 abort, draw_overlap ); 00099 00100 return overlap; 00101 } 00102 00103 CubitStatus 00104 SurfaceOverlapTool::find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list, 00105 DLIList<RefEntity*> &faces_to_draw, 00106 bool filter_slivers) 00107 { 00108 DLIList<RefFace*> list1, list2; 00109 return find_overlapping_surfaces( ref_face_list, list1, list2, faces_to_draw, CUBIT_TRUE, 00110 filter_slivers); 00111 } 00112 00113 CubitStatus 00114 SurfaceOverlapTool::find_overlapping_surfaces( DLIList<Body*> &body_list, 00115 DLIList<RefEntity*> &faces_to_draw, 00116 bool filter_slivers) 00117 { 00118 DLIList<RefFace*> list1, list2; 00119 return find_overlapping_surfaces( body_list, list1, list2, faces_to_draw, CUBIT_TRUE, 00120 filter_slivers); 00121 } 00122 00123 00124 CubitStatus 00125 SurfaceOverlapTool::find_candidate_surfaces_for_imprinting( DLIList<BodySM*> &body_list, 00126 DLIList<Surface*> &surface_list1, 00127 DLIList<Surface*> &surface_list2, 00128 double overlap_tol, 00129 bool filter_slivers) 00130 { 00131 //collect all the surfaces 00132 DLIList<Surface*> surface_list; 00133 int i; 00134 for( i=body_list.size(); i--; ) 00135 { 00136 BodySM *body_sm = body_list.get_and_step(); 00137 DLIList<Surface*> surfs; 00138 body_sm->surfaces_ignore_virtual( surfs, false ); 00139 // body_sm->surfaces( surfs ); 00140 surface_list.merge_unique( surfs ); 00141 } 00142 00143 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 00144 if(overlap_tol > 0.0) 00145 tolerance = overlap_tol; 00146 00147 // Populate the Surface AbstractTree 00148 AbstractTree<Surface*> *a_tree = new RTree<Surface*>( tolerance ); 00149 surface_list.reset(); 00150 for( i=surface_list.size(); i--; ) 00151 { 00152 Surface *surface = surface_list.get_and_step(); 00153 a_tree->add( surface ); 00154 } 00155 00156 std::map<Surface*, DLIList<SurfaceOverlapFacet*>* > surface_facet_map; 00157 std::map<Surface*, double > surface_to_area_map; 00158 std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* > a_tree_map; 00159 00160 surface_list.reset(); 00161 for( i=surface_list.size(); i--; ) 00162 { 00163 Surface *surf1 = surface_list.get_and_step(); 00164 00165 BodySM *surf1_body = surf1->bodysm(); 00166 00167 // Remove this surface from AbstractTree so it is not found and never 00168 // found again 00169 a_tree->remove( surf1 ); 00170 00171 // Find RefFaces from AbstractTree that are within range of this surface 00172 CubitBox surf1_box = surf1->bounding_box(); 00173 DLIList<Surface*> close_surfaces; 00174 a_tree->find( surf1_box, close_surfaces ); 00175 00176 int j; 00177 for( j=close_surfaces.size(); j--; ) 00178 { 00179 Surface *surf2 = close_surfaces.get_and_step(); 00180 BodySM *surf2_body = surf2->bodysm(); 00181 00182 //don't check for overlapping surfaces within bodies 00183 if( surf1_body == surf2_body ) 00184 continue; 00185 00186 // check for overlap, boundary contact, int contact, penetration, etc. 00187 if( check_surfs_for_imprinting( surf1, surf2, 00188 &surface_facet_map, 00189 &surface_to_area_map, 00190 &a_tree_map, 00191 overlap_tol ) == CUBIT_TRUE ) 00192 { 00193 surface_list1.append( surf1 ); 00194 surface_list2.append( surf2 ); 00195 } 00196 00197 } 00198 } 00199 00200 //clean up maps; 00201 std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* >::iterator tree_iter; 00202 tree_iter = a_tree_map.begin(); 00203 for(; tree_iter != a_tree_map.end(); tree_iter++ ) 00204 delete tree_iter->second; 00205 00206 std::map<Surface*, DLIList<SurfaceOverlapFacet*>* >::iterator sof_iter; 00207 sof_iter = surface_facet_map.begin(); 00208 for(; sof_iter != surface_facet_map.end(); sof_iter++) 00209 { 00210 DLIList<SurfaceOverlapFacet*> *tmp_list = sof_iter->second; 00211 00212 //delete contents of list 00213 for( i=tmp_list->size(); i--; ) 00214 delete tmp_list->get_and_step(); 00215 00216 //delete the list 00217 delete tmp_list; 00218 } 00219 00220 delete a_tree; 00221 00222 return CUBIT_SUCCESS; 00223 } 00224 00225 CubitStatus 00226 SurfaceOverlapTool::find_overlapping_surfaces( DLIList<Body*> &body_list, 00227 DLIList<RefFace*> &ref_face_list1, 00228 DLIList<RefFace*> &ref_face_list2, 00229 DLIList<RefEntity*> &faces_to_draw, 00230 CubitBoolean show_messages, 00231 bool filter_slivers) 00232 { 00233 CubitStatus status = CUBIT_SUCCESS; 00234 00235 CubitBoolean group_results = CUBIT_FALSE; 00236 CubitBoolean list_pairs = CUBIT_FALSE; 00237 CubitBoolean imprint_results = CUBIT_FALSE; 00238 00239 if( show_messages == CUBIT_TRUE ) 00240 { 00241 group_results = groupResults; 00242 list_pairs = listPairs; 00243 imprint_results = imprintResults; 00244 } 00245 00246 // Handle the special case of finding overlapping surfaces within a given 00247 // body - we can do this MUCH faster than the general case (this is a 00248 // rare case in general but at Cat we have an application for this!). 00249 00250 // The usual case 00251 if( checkWithinBodies == CUBIT_FALSE || 00252 (checkWithinBodies == CUBIT_TRUE && checkAcrossBodies == CUBIT_TRUE) ) 00253 { 00254 // Utilize a straight surface list 00255 DLIList<RefFace*> ref_face_list; 00256 body_list.reset(); 00257 int i; 00258 for( i=body_list.size(); i--; ) 00259 { 00260 Body* body_ptr = body_list.get_and_step(); 00261 DLIList<RefFace*> body_face_list; 00262 body_ptr->ref_faces( body_face_list ); 00263 ref_face_list.merge_unique( body_face_list ); 00264 } 00265 00266 int prog_step = 0; 00267 if( show_messages ) 00268 { 00269 prog_step = 10; 00270 PRINT_INFO( "Finding surface overlap...\n" ); 00271 if( ref_face_list.size() > prog_step ) 00272 { 00273 char message[128]; 00274 sprintf(message, "Finding Surface Overlap On %d Surfaces", ref_face_list.size() ); 00275 AppUtil::instance()->progress_tool()->start(0, ref_face_list.size(), 00276 "Progress", message, TRUE, TRUE ); 00277 } 00278 } 00279 00280 status = find_overlapping_surfaces( ref_face_list, ref_face_list1, 00281 ref_face_list2, faces_to_draw, list_pairs, prog_step, filter_slivers ); 00282 00283 if( show_messages && ref_face_list.size() > prog_step ) 00284 AppUtil::instance()->progress_tool()->end(); 00285 } 00286 00287 // Special case - checking within bodies 00288 else 00289 { 00290 int prog_step = 5; 00291 if( show_messages ) 00292 { 00293 PRINT_INFO( "Finding surface overlap...\n" ); 00294 if( body_list.size() > prog_step ) 00295 { 00296 char message[128]; 00297 sprintf(message, "Finding Surface Overlap On %d Bodies", body_list.size() ); 00298 AppUtil::instance()->progress_tool()->start(0, body_list.size(), 00299 "Progress", message, TRUE, TRUE ); 00300 } 00301 } 00302 00303 int i; 00304 body_list.reset(); 00305 for( i=body_list.size(); i--; ) 00306 { 00307 Body* body_ptr = body_list.get_and_step(); 00308 DLIList<RefFace*> body_face_list; 00309 body_ptr->ref_faces( body_face_list ); 00310 00311 status = find_overlapping_surfaces( body_face_list, ref_face_list1, 00312 ref_face_list2, faces_to_draw, list_pairs, -1, filter_slivers ); 00313 00314 if( show_messages && body_list.size() > prog_step ) 00315 AppUtil::instance()->progress_tool()->step(); 00316 00317 if( status == CUBIT_FAILURE ) 00318 break; 00319 } 00320 00321 if( show_messages && body_list.size() > prog_step ) 00322 AppUtil::instance()->progress_tool()->end(); 00323 } 00324 00325 if( faces_to_draw.size() ) 00326 { 00327 if( group_results == CUBIT_TRUE ) 00328 { 00329 RefGroup *new_group = RefEntityFactory::instance()->construct_RefGroup( "surf_overlap" ); 00330 new_group->add_ref_entity( faces_to_draw ); 00331 CubitString name = new_group->entity_name(); 00332 PRINT_INFO( "Found %d overlapping surface pairs (added to group '%s')\n", 00333 ref_face_list1.size(), name.c_str() ); 00334 } 00335 else if( show_messages ) 00336 PRINT_INFO( "Found %d overlapping surface pairs\n", ref_face_list1.size() ); 00337 00338 if ( imprint_results ) 00339 { 00340 CubitStatus stat = imprint(ref_face_list1, ref_face_list2); 00341 if ( stat != CUBIT_SUCCESS ) 00342 { 00343 PRINT_WARNING("Imprinting overlaps was unsuccessful\n"); 00344 } 00345 } 00346 } 00347 else if (show_messages ) 00348 PRINT_INFO( "Found 0 overlapping surface pairs\n" ); 00349 00350 return status; 00351 } 00352 00353 CubitStatus 00354 SurfaceOverlapTool::find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list, 00355 DLIList<RefFace*> &ref_face_list1, 00356 DLIList<RefFace*> &ref_face_list2, 00357 DLIList<RefEntity*> &faces_to_draw, 00358 CubitBoolean show_messages, 00359 bool filter_slivers) 00360 { 00361 CubitStatus status = CUBIT_SUCCESS; 00362 00363 CubitBoolean group_results = CUBIT_FALSE; 00364 CubitBoolean list_pairs = CUBIT_FALSE; 00365 CubitBoolean imprint_results = CUBIT_FALSE; 00366 00367 if( show_messages == CUBIT_TRUE ) 00368 { 00369 group_results = groupResults; 00370 list_pairs = listPairs; 00371 imprint_results = imprintResults; 00372 } 00373 00374 int prog_step = 10; 00375 00376 if( show_messages ) 00377 { 00378 PRINT_INFO( "Finding surface overlap...\n" ); 00379 if( ref_face_list.size() > prog_step ) 00380 { 00381 char message[128]; 00382 sprintf(message, "Finding Surface Overlap On %d Surfaces", ref_face_list.size() ); 00383 AppUtil::instance()->progress_tool()->start(0, ref_face_list.size(), 00384 "Progress", message, TRUE, TRUE ); 00385 } 00386 } 00387 else 00388 prog_step = -1; 00389 00390 status = find_overlapping_surfaces( ref_face_list, ref_face_list1, 00391 ref_face_list2, faces_to_draw, list_pairs, prog_step, filter_slivers ); 00392 00393 if( show_messages && ref_face_list.size() > prog_step ) 00394 AppUtil::instance()->progress_tool()->end(); 00395 00396 if( faces_to_draw.size() ) 00397 { 00398 if( group_results == CUBIT_TRUE ) 00399 { 00400 RefGroup *new_group = RefEntityFactory::instance()->construct_RefGroup( "surf_overlap" ); 00401 new_group->add_ref_entity( faces_to_draw ); 00402 CubitString name = new_group->entity_name(); 00403 PRINT_INFO( "Found %d overlapping surface pairs (added to group '%s')\n", 00404 ref_face_list1.size(), name.c_str() ); 00405 } 00406 else if( show_messages ) 00407 PRINT_INFO( "Found %d overlapping surface pairs\n", ref_face_list1.size() ); 00408 00409 if ( imprint_results ) 00410 { 00411 CubitStatus stat = imprint(ref_face_list1, ref_face_list2); 00412 if ( stat != CUBIT_SUCCESS ) 00413 { 00414 PRINT_WARNING("Imprinting overlaps was unsuccessful\n"); 00415 } 00416 } 00417 } 00418 else if (show_messages ) 00419 PRINT_INFO( "Found 0 overlapping surface pairs\n" ); 00420 00421 return status; 00422 } 00423 00424 CubitStatus 00425 SurfaceOverlapTool::find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list, 00426 DLIList<RefFace*> &ref_face_list1, 00427 DLIList<RefFace*> &ref_face_list2, 00428 DLIList<RefEntity*> &pair_list, 00429 CubitBoolean list_pairs, 00430 int prog_step, 00431 bool filter_slivers) 00432 { 00433 int number_pairs = 0; 00434 CubitBoolean abort = CUBIT_FALSE; 00435 RefEntity* ref_entity; 00436 00437 // Check each surface with each one later in the list 00438 RefFace *ref_face_ptr1, *ref_face_ptr2; 00439 00440 // Populate the RefFace AbstractTree 00441 AbstractTree<RefFace*> *a_tree = new RTree<RefFace*>( gapMax ); 00442 int i; 00443 ref_face_list.reset(); 00444 for( i=ref_face_list.size(); i--; ) 00445 { 00446 RefFace *ref_face_ptr = ref_face_list.get_and_step(); 00447 a_tree->add( ref_face_ptr ); 00448 } 00449 00450 // Main loop for finding overlapping surfaces 00451 ref_face_list.reset(); 00452 for( i=ref_face_list.size(); i--; ) 00453 { 00454 // Cancel button pushed or cntrl-C 00455 if (AppUtil::instance()->interrupt()) 00456 { 00457 PRINT_INFO("Find overlap operation aborted.\n"); 00458 goto done; 00459 } 00460 00461 ref_face_ptr1 = ref_face_list.get_and_step(); 00462 00463 // Remove this surface from AbstractTree so it is not found and never 00464 // found again 00465 a_tree->remove( ref_face_ptr1 ); 00466 00467 // Find RefFaces from AbstractTree that are within range of this surface 00468 CubitBox ref_face1_box = ref_face_ptr1->bounding_box(); 00469 DLIList<RefFace*> close_ref_faces; 00470 a_tree->find( ref_face1_box, close_ref_faces ); 00471 00472 int j; 00473 for( j=close_ref_faces.size(); j--; ) 00474 { 00475 // Cancel button pushed or cntrl-C 00476 if (AppUtil::instance()->interrupt()) 00477 { 00478 PRINT_INFO("Find overlap operation aborted.\n"); 00479 goto done; 00480 } 00481 00482 ref_face_ptr2 = close_ref_faces.get_and_step(); 00483 00484 bool overlap = check_overlap( ref_face_ptr1, ref_face_ptr2, abort ); 00485 if(overlap == CUBIT_TRUE && filter_slivers) 00486 { 00487 RefFace *f1, *f2; 00488 DLIList<RefEdge*> f1_edges, f2_edges, *f1_edge_list/* , *f2_edge_list */; 00489 ref_face_ptr1->ref_edges(f1_edges); 00490 ref_face_ptr2->ref_edges(f2_edges); 00491 if(f1_edges.size() > f2_edges.size()) 00492 { 00493 f1 = ref_face_ptr2; 00494 f2 = ref_face_ptr1; 00495 f1_edge_list = &f2_edges; 00496 } 00497 else 00498 { 00499 f1 = ref_face_ptr1; 00500 f2 = ref_face_ptr2; 00501 f1_edge_list = &f1_edges; 00502 } 00503 int b; 00504 for(b=f1_edge_list->size(); b>0 && overlap; b--) 00505 { 00506 RefEdge *cur_edge = f1_edge_list->get_and_step(); 00507 if(cur_edge->is_merged()) 00508 { 00509 DLIList<RefFace*> face_list; 00510 cur_edge->ref_faces(face_list); 00511 if(face_list.is_in_list(f2)) 00512 { 00513 CubitVector mid_pt; 00514 cur_edge->mid_point(mid_pt); 00515 CubitVector f1_norm = f1->normal_at(mid_pt); 00516 CubitVector f2_norm = f2->normal_at(mid_pt); 00517 DLIList<CoEdge*> f1_coedges, f2_coedges; 00518 cur_edge->get_co_edges(f1_coedges, f1); 00519 cur_edge->get_co_edges(f2_coedges, f2); 00520 if(f1_coedges.size() == 1 && f2_coedges.size() == 1) 00521 { 00522 CoEdge *ce1 = f1_coedges.get(); 00523 CoEdge *ce2 = f2_coedges.get(); 00524 CubitVector curve_dir; 00525 00526 if( cur_edge->get_curve_ptr()->geometry_type() == STRAIGHT_CURVE_TYPE ) 00527 cur_edge->get_point_direction(mid_pt, curve_dir); 00528 else 00529 cur_edge->tangent( mid_pt, curve_dir ); 00530 00531 CubitVector ce1_dir, ce2_dir; 00532 if(ce1->get_sense() == CUBIT_REVERSED) 00533 ce1_dir = -curve_dir; 00534 else 00535 ce1_dir = curve_dir; 00536 if(ce2->get_sense() == CUBIT_REVERSED) 00537 ce2_dir = -curve_dir; 00538 else 00539 ce2_dir = curve_dir; 00540 CubitVector in_dir1 = f1_norm * ce1_dir; 00541 CubitVector in_dir2 = f2_norm * ce2_dir; 00542 if(in_dir1 % in_dir2 < 0.0) 00543 overlap = false; 00544 } 00545 } 00546 } 00547 } 00548 } 00549 if(overlap) 00550 { 00551 if( abort == CUBIT_TRUE ) 00552 goto done; 00553 00554 if( list_pairs == CUBIT_TRUE ) 00555 PRINT_INFO( " Surface %d and %d overlap\n", ref_face_ptr1->id(), 00556 ref_face_ptr2->id() ); 00557 00558 number_pairs++; 00559 00560 ref_entity = CAST_TO(ref_face_ptr1,RefEntity); 00561 pair_list.append_unique( ref_entity ); 00562 00563 ref_entity = CAST_TO(ref_face_ptr2,RefEntity); 00564 pair_list.append_unique( ref_entity ); 00565 00566 ref_face_list1.append( ref_face_ptr1 ); 00567 ref_face_list2.append( ref_face_ptr2 ); 00568 } 00569 00570 if( abort == CUBIT_TRUE ) 00571 goto done; 00572 } 00573 00574 // Free memory, since this surface will never be accessed again. This 00575 // helps to reduce memory required. 00576 ref_face_ptr1->delete_TD( &TDSurfaceOverlap::is_surface_overlap ); 00577 00578 if( prog_step>0 && ref_face_list.size() > prog_step ) 00579 AppUtil::instance()->progress_tool()->step(); 00580 } 00581 00582 done: 00583 00584 // Make sure all tool datas are deleted 00585 for( i=ref_face_list.size(); i--; ) 00586 ref_face_list.get_and_step()->delete_TD( &TDSurfaceOverlap::is_surface_overlap ); 00587 00588 delete a_tree; 00589 00590 return CUBIT_SUCCESS; 00591 } 00592 00593 00594 double SurfaceOverlapTool::find_area_overlap( SurfaceOverlapFacet *facet1, SurfaceOverlapFacet *facet2, const double facet_compare_tol ) 00595 { 00596 double local_overlap_area = 0.0; 00597 double opp_low = 180.0 - angleMax; 00598 double opp_high = 180.0 - angleMin; 00599 00600 // Check angle between triangles, must be within criteria 00601 double ang = facet1->angle( *facet2 ); 00602 00603 // Allow overlap for angles close to 180 and 0 degrees 00604 00605 // normalType - 1=any, 2=opposite, 3=same 00606 //ang>=180.0-angt || ang<angt 00607 if( ((normalType==1 && ang>=opp_low && ang<=opp_high) || 00608 (normalType==1 && ang>=angleMin && ang<=angleMax) || 00609 (normalType==2 && ang>=opp_low && ang<=opp_high) || 00610 (normalType==3 && ang>=angleMin && ang<=angleMax)) && 00611 (normalType != 2 || !skipFacingSurfaces || !facet1->facing( *facet2 )))// check to make sure the surfaces are not facing 00612 { 00613 // If triangle bounding boxes don't intersect - no overlap 00614 if( facet1->bbox_overlap( facet_compare_tol, *facet2 ) ) 00615 { 00616 // Check distance between triangles, must be within criteria 00617 double dist = facet1->distance( *facet2 ); 00618 if( dist >= gapMin && dist <= facet_compare_tol ) 00619 { 00620 // Check for projected overlap 00621 // We want sum of area of ALL overlapping facets 00622 local_overlap_area = facet1->projected_overlap( *facet2 ); 00623 return local_overlap_area; 00624 } 00625 } 00626 } 00627 return local_overlap_area; 00628 } 00629 00630 CubitBoolean SurfaceOverlapTool::extract_surf_facets( 00631 Surface *surface1, 00632 Surface *surface2, 00633 std::map<Surface*, DLIList<SurfaceOverlapFacet*>* > *facet_map, 00634 const double tolerance, 00635 const double facet_tol, 00636 DLIList<SurfaceOverlapFacet*> *&facet_list1, 00637 DLIList<SurfaceOverlapFacet*> *&facet_list2 00638 ) 00639 { 00640 int i; 00641 AnalyticGeometryTool::instance(); 00642 00643 00644 std::map<Surface*, DLIList<SurfaceOverlapFacet*>* >::iterator facet_iterator; 00645 00646 00647 //see if surface is in map...if not we have to create faceting for it. 00648 if( facet_map ) 00649 facet_iterator = facet_map->find( surface1 ); 00650 00651 if( facet_map == NULL || facet_iterator == facet_map->end() ) 00652 { 00653 //for non-planar surfaces, facet wrt the smallest curve of the surface 00654 double min_edge_length = 0.0; 00655 00656 if( surface1->geometry_type() != PLANE_SURFACE_TYPE ) 00657 { 00658 DLIList<Curve*> tmp_curves; 00659 surface1->curves( tmp_curves ); 00660 CubitBox surface_box = surface1->bounding_box(); 00661 00662 //ignore curves that are really small 00663 double min_length_threshold = (surface_box.diagonal().length())*0.01; 00664 if( tmp_curves.size() ) 00665 { 00666 min_edge_length = CUBIT_DBL_MAX; 00667 double tmp_length; 00668 for( i=tmp_curves.size(); i--; ) 00669 { 00670 tmp_length = tmp_curves.get_and_step()->measure(); 00671 if( tmp_length > min_length_threshold && tmp_length < min_edge_length ) 00672 min_edge_length = tmp_length; 00673 } 00674 } 00675 if( min_edge_length == CUBIT_DBL_MAX ) 00676 min_edge_length = 0.0; 00677 else 00678 min_edge_length *= 2; 00679 } 00680 00681 facet_list1 = new DLIList<SurfaceOverlapFacet*>; 00682 GMem surface_graphics; 00683 surface1->get_geometry_query_engine()->get_graphics( surface1, &surface_graphics, 00684 0, facet_tol, 0 ); 00685 00686 GPoint* plist = surface_graphics.point_list(); 00687 int* facet_list = surface_graphics.facet_list(); 00688 00689 GPoint p[3]; 00690 for (i = 0; i < surface_graphics.fListCount; ) 00691 { 00692 int sides = facet_list[i++]; 00693 if (sides != 3) 00694 { 00695 PRINT_WARNING("Skipping n-sided polygone in triangle list" 00696 " in TDSurfaceOverlap.\n"); 00697 i += sides; 00698 } 00699 else 00700 { 00701 p[0] = plist[facet_list[i++]]; 00702 p[1] = plist[facet_list[i++]]; 00703 p[2] = plist[facet_list[i++]]; 00704 00705 SurfaceOverlapFacet *facet = new SurfaceOverlapFacet( p ); 00706 facet_list1->append( facet ); 00707 } 00708 } 00709 00710 if( facet_map ) 00711 facet_map->insert( std::map<Surface*, 00712 DLIList<SurfaceOverlapFacet*>*>::value_type( surface1, facet_list1 )); 00713 } 00714 else 00715 facet_list1 = facet_iterator->second; 00716 00717 //see if surface is in map...if not we have to create faceting for it. 00718 if( facet_map ) 00719 facet_iterator = facet_map->find( surface2 ); 00720 00721 if( facet_map == NULL || facet_iterator == facet_map->end() ) 00722 { 00723 //for non-planar surfaces, facet wrt the smallest curve of the surface 00724 double min_edge_length = 0.0; 00725 00726 if( surface2->geometry_type() != PLANE_SURFACE_TYPE ) 00727 { 00728 DLIList<Curve*> tmp_curves; 00729 surface2->curves( tmp_curves ); 00730 CubitBox surface_box = surface2->bounding_box(); 00731 00732 //ignore curves that are really small 00733 double min_length_threshold = (surface_box.diagonal().length())*0.01; 00734 if( tmp_curves.size() ) 00735 { 00736 min_edge_length = CUBIT_DBL_MAX; 00737 double tmp_length; 00738 for( i=tmp_curves.size(); i--; ) 00739 { 00740 tmp_length = tmp_curves.get_and_step()->measure(); 00741 if( tmp_length > min_length_threshold && tmp_length < min_edge_length ) 00742 min_edge_length = tmp_length; 00743 } 00744 } 00745 if( min_edge_length == CUBIT_DBL_MAX ) 00746 min_edge_length = 0.0; 00747 else 00748 min_edge_length *= 2; 00749 } 00750 00751 facet_list2 = new DLIList<SurfaceOverlapFacet*>; 00752 GMem surface_graphics; 00753 surface2->get_geometry_query_engine()->get_graphics( surface2, &surface_graphics, 00754 0, facet_tol, 0 ); 00755 00756 GPoint* plist = surface_graphics.point_list(); 00757 int* facet_list = surface_graphics.facet_list(); 00758 00759 GPoint p[3]; 00760 for (i = 0; i < surface_graphics.fListCount; ) 00761 { 00762 int sides = facet_list[i++]; 00763 if (sides != 3) 00764 { 00765 PRINT_WARNING("Skipping n-sided polygone in triangle list" 00766 " in TDSurfaceOverlap.\n"); 00767 i += sides; 00768 } 00769 else 00770 { 00771 p[0] = plist[facet_list[i++]]; 00772 p[1] = plist[facet_list[i++]]; 00773 p[2] = plist[facet_list[i++]]; 00774 00775 SurfaceOverlapFacet *facet = new SurfaceOverlapFacet( p ); 00776 facet_list2->append( facet ); 00777 } 00778 } 00779 00780 if( facet_map ) 00781 facet_map->insert( std::map<Surface*, 00782 DLIList<SurfaceOverlapFacet*>*>::value_type( surface2, facet_list2 )); 00783 } 00784 else 00785 facet_list2 = facet_iterator->second; 00786 00787 return CUBIT_TRUE; 00788 } 00789 00790 CubitBoolean SurfaceOverlapTool::check_size_and_swap_surfs( 00791 Surface *&tmp_surf1, 00792 Surface *&tmp_surf2, 00793 const double tolerance, 00794 const double facet_tol, 00795 DLIList<SurfaceOverlapFacet*> *&facet_list1, 00796 DLIList<SurfaceOverlapFacet*> *&facet_list2, 00797 std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* > *&a_tree_map, 00798 AbstractTree<SurfaceOverlapFacet*> *&a_tree2 ) 00799 { 00800 00801 // Compare facets 00802 int num_tri1 = facet_list1->size(); 00803 if( !num_tri1 ) 00804 { 00805 PRINT_WARNING( "Unable to facet surface\n" ); 00806 return CUBIT_FALSE; 00807 } 00808 00809 int num_tri2 = facet_list2->size(); 00810 if( !num_tri2 ) 00811 { 00812 PRINT_WARNING( "Unable to facet surface\n" ); 00813 return CUBIT_FALSE; 00814 } 00815 00816 // Compare least to most - possibly switch the lists 00817 Surface *temp_surf; 00818 if( facet_list1->size() > facet_list2->size() ) 00819 { 00820 DLIList<SurfaceOverlapFacet*> *temp_list = facet_list1; 00821 facet_list1 = facet_list2; 00822 facet_list2 = temp_list; 00823 temp_surf = tmp_surf1; 00824 tmp_surf1 = tmp_surf2; 00825 tmp_surf2 = temp_surf; 00826 } 00827 00828 // Possibly use an AbstractTree for facet_list2 00829 int i; 00830 if( facet_list2->size() > NO_FACETS_FOR_ABSTRACTTREE ) 00831 { 00832 std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* >::iterator iter1, iter2; 00833 // If the same size, use the existing AbstractTree if one has 00834 // one and the other doesn't. This probably won't 00835 // save time, but there is a miniscule chance it might. 00836 if( facet_list1->size() == facet_list2->size() ) 00837 { 00838 //see if both are in the a_tree_map 00839 iter1 = a_tree_map->find( tmp_surf1 ); 00840 iter2 = a_tree_map->find( tmp_surf2 ); 00841 00842 if( !(iter2 != a_tree_map->end()) && (iter1 != a_tree_map->end()) ) 00843 { 00844 // Switch them, just to use the existing AbstractTree 00845 DLIList<SurfaceOverlapFacet*> *temp_list = facet_list1; 00846 facet_list1 = facet_list2; 00847 facet_list2 = temp_list; 00848 Surface *tmp_surf = tmp_surf1; 00849 tmp_surf1 = tmp_surf2; 00850 tmp_surf2 = tmp_surf; 00851 std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* >::iterator tmp_iter; 00852 tmp_iter = iter1; 00853 iter1 = iter2; 00854 iter2 = tmp_iter; 00855 } 00856 } 00857 00858 //populate tree if necessary 00859 iter2 = a_tree_map->find( tmp_surf2 ); 00860 if( iter2 == a_tree_map->end() ) 00861 { 00862 //a_tree = new RTree<SurfaceOverlapFacet*>( gapMax ); 00863 a_tree2 = new RTree<SurfaceOverlapFacet*>( tolerance+facet_tol ); 00864 00865 for( i=facet_list2->size(); i--; ) 00866 a_tree2->add( facet_list2->get_and_step() ); 00867 00868 a_tree_map->insert( std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>*>::value_type( tmp_surf2, a_tree2 )); 00869 } 00870 else 00871 a_tree2 = iter2->second; 00872 } 00873 return CUBIT_TRUE; 00874 } 00875 00876 //Currently this function is only called when using tolerant imprinting. 00877 //It does not use the settings controlled by the user for this tool 00878 00879 CubitBoolean SurfaceOverlapTool::check_surfs_for_imprinting( Surface *surface1, Surface *surface2, 00880 std::map<Surface*, DLIList<SurfaceOverlapFacet*>* > *facet_map, 00881 std::map<Surface*, double > *area_map, 00882 std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* > *a_tree_map, 00883 double overlap_tol) 00884 { 00885 if( surface1 == surface2 ) 00886 return CUBIT_FALSE; 00887 00888 // Initialize toelrances 00889 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 00890 if(overlap_tol > 0.0) 00891 tolerance = overlap_tol; 00892 double facet_tol = tolerance*10; 00893 //double facet_tol = 0.00025; 00894 00895 // Extract graphics facets if not available in map 00896 DLIList<SurfaceOverlapFacet*> *facet_list1 = NULL; 00897 DLIList<SurfaceOverlapFacet*> *facet_list2 = NULL; 00898 extract_surf_facets( surface1, surface2, facet_map, tolerance, facet_tol, facet_list1, facet_list2 ); 00899 00900 // Swap first and second surfaces/facets to set smaller surface as first 00901 Surface *tmp_surf1 = surface1; 00902 Surface *tmp_surf2 = surface2; 00903 AbstractTree<SurfaceOverlapFacet*> *a_tree2 = NULL; 00904 if( CUBIT_FALSE == check_size_and_swap_surfs( tmp_surf1, tmp_surf2, tolerance, facet_tol, facet_list1, facet_list2, a_tree_map, a_tree2 ) ) 00905 { 00906 return CUBIT_FALSE; 00907 } 00908 00909 // Calculate the tolerances for dist and area overlap comparision 00910 double facet_compare_tol = facet_tol+tolerance; // tolerance used in evaluating dist betwen facets 00911 double overlap_tolerance = tolerance * tolerance; // tolerance used in overlaping facets 00912 //calculate_tolerances_for_surf_intersection( tmp_surf1, tmp_surf2, facet_list1, facet_list2, area_map, facet_compare_tol, overlap_tolerance ); 00913 00914 // Check 1: check for boundary contact (boundary entities (curves & verts) of one surface touches other surface ) 00915 if( check_boundary_contact( facet_list1, facet_list2, a_tree2, facet_compare_tol, overlap_tolerance ) ) 00916 { 00917 return CUBIT_TRUE; 00918 } 00919 00920 //if surfaces are not splines and are not of the same type, they won't overlap 00921 if( (surface1->geometry_type() != SPLINE_SURFACE_TYPE && 00922 surface2->geometry_type() != SPLINE_SURFACE_TYPE) && 00923 (surface1->geometry_type() != surface2->geometry_type() )) 00924 return CUBIT_FALSE; 00925 00926 // Check 2: check for overlap between surfaces 00927 if( check_overlap( facet_list1, facet_list2, a_tree2, facet_compare_tol, overlap_tolerance ) ) 00928 { 00929 return CUBIT_TRUE; 00930 } 00931 00932 00933 00934 00935 // Check 3: check for interior contact (interior of surface touches interior of other surface ) 00936 00937 // Check 4: check for peneration ( one surface penetrates other surface ) 00938 00939 return CUBIT_FALSE; 00940 } 00941 00942 CubitBoolean SurfaceOverlapTool::calculate_tolerances_for_surf_intersection( 00943 Surface *tmp_surf1, 00944 Surface *tmp_surf2, 00945 DLIList<SurfaceOverlapFacet*> *facet_list1, 00946 DLIList<SurfaceOverlapFacet*> *facet_list2, 00947 std::map<Surface*, double > *area_map, 00948 double &facet_compare_tol, 00949 double &overlap_tolerance ) 00950 { 00951 00952 00953 //set ovelap tolerance to one thousandth of the smaller area. 00954 double face1_area, face2_area; 00955 if( area_map ) 00956 { 00957 std::map<Surface*, double>::iterator area_iter; 00958 area_iter = area_map->find( tmp_surf1); 00959 if( area_iter == area_map->end() ) 00960 { 00961 face1_area = tmp_surf1->measure(); 00962 area_map->insert( std::map<Surface*, double>::value_type( tmp_surf1, face1_area ) ); 00963 } 00964 else 00965 face1_area = area_iter->second; 00966 00967 area_iter = area_map->find( tmp_surf2); 00968 if( area_iter == area_map->end() ) 00969 { 00970 face2_area = tmp_surf2->measure(); 00971 area_map->insert( std::map<Surface*, double>::value_type( tmp_surf2, face2_area )); 00972 } 00973 else 00974 face2_area = area_iter->second; 00975 } 00976 else 00977 { 00978 face1_area = tmp_surf1->measure(); 00979 face2_area = tmp_surf2->measure(); 00980 } 00981 00982 bool sample_deviation = false; 00983 Surface *larger_surface = NULL; 00984 //if the surfaces are non planar and one is much bigger than the other one... 00985 //adjust the tolerance some 00986 if( (tmp_surf1->geometry_type() != PLANE_SURFACE_TYPE && 00987 tmp_surf2->geometry_type() != PLANE_SURFACE_TYPE) ) 00988 { 00989 double length1 = tmp_surf1->bounding_box().diagonal().length(); 00990 double length2 = tmp_surf2->bounding_box().diagonal().length(); 00991 00992 double ratio = 0; 00993 if(length1 > length2) 00994 { 00995 ratio = length1/length2; 00996 larger_surface = tmp_surf1; 00997 } 00998 else 00999 { 01000 ratio = length2/length1; 01001 larger_surface = tmp_surf2; 01002 } 01003 01004 if( ratio > 50 ) 01005 sample_deviation = true; 01006 } 01007 01008 if( face1_area < face2_area ) 01009 overlap_tolerance = face1_area * 0.001; 01010 else 01011 overlap_tolerance = face2_area * 0.001; 01012 01013 01014 //If you're comparing overlap between a large surface and a very small one, 01015 //you might have to adjust tolerances because of the faceting. Here we try 01016 //to determine the deviation of the faceting of the larger surface. I 01017 //take the mid point of the smallest edge on the facet, thinking the smallest 01018 //edge is approximating high curvature so it would deviate the most and thus 01019 //provide the safest tolerance. 01020 int i; 01021 if( sample_deviation ) 01022 { 01023 DLIList<SurfaceOverlapFacet*> *tmp_facet_list = NULL; 01024 if( larger_surface == tmp_surf1 ) 01025 tmp_facet_list = facet_list1; 01026 else 01027 tmp_facet_list = facet_list2; 01028 01029 for( i=tmp_facet_list->size(); i--; ) 01030 { 01031 SurfaceOverlapFacet *tmp_facet = tmp_facet_list->get_and_step(); 01032 //we used to be lucky, where one seventh of the facets would give us a 01033 //decent tolerance...this doesn't work now....not robust enough 01034 // if( (i%7) == 0) // commenting this out....sometimes you haveto 01035 // { 01036 CubitVector point = tmp_facet->smallest_edge_midpoint(); 01037 //determine distance between surface and centroid 01038 01039 CubitVector tmp_point; 01040 larger_surface->closest_point_trimmed( point, tmp_point ); 01041 double tmp_distance = point.distance_between( tmp_point ); 01042 if( tmp_distance > facet_compare_tol ) 01043 { 01044 facet_compare_tol = tmp_distance; 01045 } 01046 // } 01047 } 01048 } 01049 else 01050 { 01051 for( i=facet_list1->size(); i--; ) 01052 facet_compare_tol += facet_list1->get_and_step()->bounding_box().diagonal().length(); 01053 01054 for( i=facet_list2->size(); i--; ) 01055 facet_compare_tol += facet_list2->get_and_step()->bounding_box().diagonal().length(); 01056 01057 if( facet_list1->size() || facet_list2->size() ) 01058 { 01059 facet_compare_tol /= (facet_list1->size() + facet_list2->size() ); 01060 facet_compare_tol *= 0.0025; 01061 } 01062 } 01063 01064 //if the merge tolerance is a larger, use it 01065 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 01066 if( tolerance > facet_compare_tol ) 01067 facet_compare_tol = tolerance; 01068 01069 return CUBIT_TRUE; 01070 } 01071 01072 CubitBoolean SurfaceOverlapTool::check_overlap( 01073 DLIList<SurfaceOverlapFacet*> *facet_list1, 01074 DLIList<SurfaceOverlapFacet*> *facet_list2, 01075 AbstractTree<SurfaceOverlapFacet*> *a_tree, 01076 const double facet_tol, 01077 const double tolerance ) 01078 { 01079 int i, j; 01080 double area = 0; 01081 facet_list1->reset(); 01082 double overlap_tol = tolerance * tolerance; 01083 01084 for( i=facet_list1->size(); i--; ) 01085 { 01086 SurfaceOverlapFacet *facet1 = facet_list1->get_and_step(); 01087 01088 CubitBox facet1_bbox = facet1->bounding_box(); 01089 DLIList<SurfaceOverlapFacet*> close_facets; 01090 if( a_tree ) 01091 { 01092 a_tree->find( facet1_bbox, close_facets ); 01093 facet_list2 = &close_facets; 01094 } 01095 01096 double facet1_perimeter = facet1->perimeter(); 01097 01098 facet_list2->reset(); 01099 for( j=facet_list2->size(); j--; ) 01100 { 01101 SurfaceOverlapFacet *facet2 = facet_list2->get_and_step(); 01102 01103 // Check angle between triangles, must be within criteria 01104 double ang = facet1->angle( *facet2 ); 01105 01106 //rough estimate...must be less than half of 45 01107 if( fabs( 180-ang) < 23.5 || ang < 23.5 ) 01108 { 01109 //make sure midpoint and one other point are within facet_tol+tolerance of plane 01110 //defined by larger facet 01111 bool within_parallel_tol = false; 01112 01113 if( facet1_perimeter > facet2->perimeter() ) 01114 within_parallel_tol = facet1->facet_points_within_tol( facet2, (facet_tol+tolerance) ); 01115 else 01116 within_parallel_tol = facet2->facet_points_within_tol( facet1, (facet_tol+tolerance) ); 01117 01118 if( within_parallel_tol ) 01119 { 01120 // Check distance between triangles, must be within criteria 01121 double dist = facet1->distance( *facet2 ); 01122 if( dist <= facet_tol+tolerance ) 01123 { 01124 // Check for projected overlap 01125 // We want sum of area of ALL overlapping facets 01126 area += facet1->projected_overlap( *facet2 ); 01127 if( area > overlap_tol ) 01128 { 01129 return CUBIT_TRUE; 01130 } 01131 } 01132 } 01133 } 01134 } 01135 } 01136 01137 return CUBIT_FALSE; 01138 } 01139 01140 CubitBoolean SurfaceOverlapTool::check_boundary_contact( 01141 DLIList<SurfaceOverlapFacet*> *facet_list1, 01142 DLIList<SurfaceOverlapFacet*> *facet_list2, 01143 AbstractTree<SurfaceOverlapFacet*> *a_tree, 01144 const double facet_compare_tol, 01145 const double tmp_overlap_tol ) 01146 { 01147 int i, j; 01148 facet_list1->reset(); 01149 for( i=facet_list1->size(); i--; ) 01150 { 01151 SurfaceOverlapFacet *facet1 = facet_list1->get_and_step(); 01152 01153 CubitBox facet1_bbox = facet1->bounding_box(); 01154 DLIList<SurfaceOverlapFacet*> close_facets; 01155 if( a_tree ) 01156 { 01157 a_tree->find( facet1_bbox, close_facets ); 01158 facet_list2 = &close_facets; 01159 } 01160 01161 facet_list2->reset(); 01162 for( j=facet_list2->size(); j--; ) 01163 { 01164 SurfaceOverlapFacet *facet2 = facet_list2->get_and_step(); 01165 01166 // Check boundary contact 01167 // If triangle bounding boxes don't intersect - no overlap 01168 if( facet1->bbox_overlap( facet_compare_tol, *facet2 ) ) 01169 { 01170 // Check distance between triangles, must be within criteria 01171 double dist = facet1->distance( *facet2 ); 01172 if( dist >= gapMin && dist <= facet_compare_tol ) 01173 { 01174 return CUBIT_TRUE; 01175 } 01176 } 01177 } 01178 } 01179 01180 return CUBIT_FALSE; 01181 } 01182 01183 01184 CubitBoolean 01185 SurfaceOverlapTool::check_overlap( DLIList<SurfaceOverlapFacet*> *facet_list1, 01186 DLIList<SurfaceOverlapFacet*> *facet_list2, 01187 AbstractTree<SurfaceOverlapFacet*> *a_tree, 01188 CubitBoolean abort, 01189 CubitBoolean draw_overlap, 01190 double *overlap_area ) 01191 { 01192 double area = 0; 01193 double opp_low = 180.0 - angleMax; 01194 double opp_high = 180.0 - angleMin; 01195 01196 facet_list1->reset(); 01197 int num_tri1 = facet_list1->size(); 01198 int i,j; 01199 for( i=num_tri1; i--; ) 01200 { 01201 if(i%20 == 0) 01202 { 01203 // Cancel button pushed or cntrl-C 01204 if (AppUtil::instance()->interrupt()) 01205 { 01206 PRINT_INFO("Find overlap operation aborted.\n"); 01207 abort = CUBIT_TRUE; 01208 return CUBIT_FALSE; 01209 } 01210 } 01211 01212 SurfaceOverlapFacet *facet1 = facet_list1->get_and_step(); 01213 01214 DLIList<SurfaceOverlapFacet*> close_facets; 01215 if( a_tree ) 01216 { 01217 a_tree->find( facet1->bounding_box(), close_facets ); 01218 facet_list2 = &close_facets; 01219 } 01220 01221 facet_list2->reset(); 01222 for( j=facet_list2->size(); j--; ) 01223 { 01224 if(j%20 == 0) 01225 { 01226 // Cancel button pushed or cntrl-C 01227 if (AppUtil::instance()->interrupt()) 01228 { 01229 PRINT_INFO("Find overlap operation aborted.\n"); 01230 abort = CUBIT_TRUE; 01231 return CUBIT_FALSE; 01232 } 01233 } 01234 01235 SurfaceOverlapFacet *facet2 = facet_list2->get_and_step(); 01236 01237 // Check angle between triangles, must be within criteria 01238 double ang = facet1->angle( *facet2 ); 01239 01240 // Allow overlap for angles close to 180 and 0 degrees 01241 01242 // normalType - 1=any, 2=opposite, 3=same 01243 //ang>=180.0-angt || ang<angt 01244 if( ((normalType==1 && ang>=opp_low && ang<=opp_high) || 01245 (normalType==1 && ang>=angleMin && ang<=angleMax) || 01246 (normalType==2 && ang>=opp_low && ang<=opp_high) || 01247 (normalType==3 && ang>=angleMin && ang<=angleMax) ) && 01248 (normalType != 2 || !skipFacingSurfaces || !facet1->facing( *facet2 )))// check to make sure the surfaces are not facing ) 01249 { 01250 // If triangle bounding boxes don't intersect - no overlap 01251 if( facet1->bbox_overlap( gapMax, *facet2 ) ) 01252 { 01253 // Check distance between triangles, must be within criteria 01254 double dist = facet1->distance( *facet2 ); 01255 01256 if( dist >= gapMin && dist <= gapMax ) 01257 { 01258 // Check for projected overlap 01259 // We want sum of area of ALL overlapping facets 01260 area += facet1->projected_overlap( *facet2, draw_overlap ); 01261 if( area > overlapTolerance && 01262 (draw_overlap == CUBIT_FALSE && overlap_area == NULL ) ) 01263 { 01264 return CUBIT_TRUE; 01265 } 01266 } 01267 } 01268 } 01269 } 01270 } 01271 if( draw_overlap == CUBIT_TRUE ) 01272 { 01273 PRINT_INFO("Total overlapping area = %f\n", area ); 01274 01275 if( area > 0.0 ) 01276 return CUBIT_TRUE; 01277 } 01278 01279 if( overlap_area ) 01280 { 01281 if( area > 0.0 ) 01282 { 01283 *overlap_area = area; 01284 return CUBIT_TRUE; 01285 } 01286 } 01287 01288 return CUBIT_FALSE; 01289 } 01290 01291 CubitBoolean 01292 SurfaceOverlapTool::check_overlap( RefFace *ref_face_ptr1, RefFace *ref_face_ptr2, 01293 CubitBoolean abort, 01294 CubitBoolean draw_overlap, 01295 double *overlap_area ) 01296 { 01297 if( ref_face_ptr1 == ref_face_ptr2 ) 01298 return CUBIT_FALSE; 01299 01300 //if surfaces are not splines and are not of the same type, 01301 //they won't overlap 01302 /* 01303 I am commenting this out because it filters out some cases we need to find with 01304 this overlap check. 01305 if( (ref_face_ptr1->get_surface_ptr()->geometry_type() != SPLINE_SURFACE_TYPE && 01306 ref_face_ptr2->get_surface_ptr()->geometry_type() != SPLINE_SURFACE_TYPE) && 01307 (ref_face_ptr1->get_surface_ptr()->geometry_type() != 01308 ref_face_ptr2->get_surface_ptr()->geometry_type() )) 01309 return CUBIT_FALSE; 01310 */ 01311 01312 AnalyticGeometryTool::instance(); 01313 abort = CUBIT_FALSE; 01314 01315 // Check for overlap between the found surfaces using the facets 01316 TDSurfaceOverlap *tdso_1; 01317 tdso_1 = (TDSurfaceOverlap *)ref_face_ptr1->get_TD(&TDSurfaceOverlap::is_surface_overlap); 01318 if( !tdso_1 ) 01319 { 01320 ref_face_ptr1->add_TD( new TDSurfaceOverlap( ref_face_ptr1, facetAngTol, facetAbsTol, 01321 gapMax ) ); 01322 tdso_1 = (TDSurfaceOverlap *)ref_face_ptr1->get_TD(&TDSurfaceOverlap::is_surface_overlap); 01323 } 01324 01325 TDSurfaceOverlap *tdso_2; 01326 tdso_2 = (TDSurfaceOverlap *)ref_face_ptr2->get_TD(&TDSurfaceOverlap::is_surface_overlap); 01327 if( !tdso_2 ) 01328 { 01329 ref_face_ptr2->add_TD( new TDSurfaceOverlap( ref_face_ptr2, facetAngTol, facetAbsTol, 01330 gapMax ) ); 01331 tdso_2 = (TDSurfaceOverlap *)ref_face_ptr2->get_TD(&TDSurfaceOverlap::is_surface_overlap); 01332 } 01333 01334 // Check if within the same body - maybe we don't need to consider this 01335 if( checkWithinBodies == CUBIT_FALSE ) 01336 { 01337 DLIList<Body*> *body_list_ptr1, *body_list_ptr2; 01338 body_list_ptr1 = tdso_1->get_body_list(); 01339 body_list_ptr2 = tdso_2->get_body_list(); 01340 DLIList<Body*> shared_body_list = *body_list_ptr1; 01341 shared_body_list.intersect( *body_list_ptr2 ); 01342 if( shared_body_list.size() ) 01343 return CUBIT_FALSE; 01344 } 01345 01346 // Check if in different bodies - maybe we don't need to consider this 01347 if( checkAcrossBodies == CUBIT_FALSE ) 01348 { 01349 DLIList<Body*> *body_list_ptr1, *body_list_ptr2; 01350 body_list_ptr1 = tdso_1->get_body_list(); 01351 body_list_ptr2 = tdso_2->get_body_list(); 01352 DLIList<Body*> shared_body_list = *body_list_ptr1; 01353 shared_body_list.intersect( *body_list_ptr2 ); 01354 if( shared_body_list.size() == 0 ) 01355 return CUBIT_FALSE; 01356 } 01357 01358 // Compare facets 01359 DLIList<SurfaceOverlapFacet*> *facet_list1 = tdso_1->get_facet_list(); 01360 int num_tri1 = 0; 01361 if(facet_list1) 01362 num_tri1 = facet_list1->size(); 01363 if( !num_tri1 ) 01364 { 01365 PRINT_WARNING( "Unable to facet surface %d\n", ref_face_ptr1->id() ); 01366 return CUBIT_FALSE; 01367 } 01368 01369 DLIList<SurfaceOverlapFacet*> *facet_list2 = tdso_2->get_facet_list(); 01370 int num_tri2 = 0; 01371 if(facet_list2) 01372 num_tri2 = facet_list2->size(); 01373 if( !num_tri2 ) 01374 { 01375 PRINT_WARNING( "Unable to facet surface %d\n", ref_face_ptr2->id() ); 01376 return CUBIT_FALSE; 01377 } 01378 01379 PRINT_DEBUG_102( " Comparing %d facets in Surface %d with %d facets in Surface %d...\n", 01380 num_tri1, ref_face_ptr1->id(), num_tri2, ref_face_ptr2->id() ); 01381 01382 // Compare least to most - possibly switch the lists 01383 if( facet_list1->size() > facet_list2->size() ) 01384 { 01385 DLIList<SurfaceOverlapFacet*> *temp_list = facet_list1; 01386 facet_list1 = facet_list2; 01387 facet_list2 = temp_list; 01388 TDSurfaceOverlap *temp_tdso = tdso_1; 01389 tdso_2 = tdso_1; 01390 tdso_1 = temp_tdso; 01391 } 01392 01393 // Possibly use an AbstractTree for facet_list2 01394 AbstractTree<SurfaceOverlapFacet*> *a_tree = NULL; 01395 if( facet_list2->size() > NO_FACETS_FOR_ABSTRACTTREE ) 01396 { 01397 // If the same size, use the existing AbstractTree if one has 01398 // one and the other doesn't. This probably won't 01399 // save time, but there is a miniscule chance it might. 01400 if( facet_list1->size() == facet_list2->size() ) 01401 { 01402 if( !tdso_2->has_rtree() && tdso_1->has_rtree() ) 01403 { 01404 // Switch them, just to use the existing AbstractTree 01405 DLIList<SurfaceOverlapFacet*> *temp_list = facet_list1; 01406 facet_list1 = facet_list2; 01407 facet_list2 = temp_list; 01408 TDSurfaceOverlap *temp_tdso = tdso_1; 01409 tdso_2 = tdso_1; 01410 tdso_1 = temp_tdso; 01411 } 01412 } 01413 a_tree = tdso_2->get_facet_rtree(); 01414 } 01415 01416 bool surfs_overlap = check_overlap( facet_list1, facet_list2, a_tree, 01417 abort, draw_overlap, overlap_area ); 01418 01419 return surfs_overlap; 01420 } 01421 01422 void SurfaceOverlapTool::list_settings() 01423 { 01424 char on_off[2][4]; 01425 strcpy( on_off[0], "Off" ); 01426 strcpy( on_off[1], "On" ); 01427 01428 PRINT_INFO( "Surface Overlap Algorithm Settings:\n" ); 01429 if( facetAbsTol == 0.0 ) 01430 PRINT_INFO( " Facetting Absolute Tolerance: 0.0 (using default solid modeler setting)\n" ); 01431 else 01432 PRINT_INFO( " Facetting Absolute Tolerance: %f\n", facetAbsTol ); 01433 01434 if( facetAngTol == 0 ) 01435 PRINT_INFO( " Facetting Angle Tolerance: 0 (using default solid modeler setting)\n" ); 01436 else 01437 PRINT_INFO( " Facetting Angle Tolerance: %d\n", facetAngTol ); 01438 01439 PRINT_INFO( " Gap Range: %f to %f\n", gapMin, gapMax ); 01440 PRINT_INFO( " Angle Range: %.1f to %.1f degrees\n", angleMin, angleMax ); 01441 PRINT_INFO( " Overlap Area Tolerance: %f\n", overlapTolerance ); 01442 01443 switch( normalType ) 01444 { 01445 case 1: 01446 PRINT_INFO( " Pair Normals Allowed: Any\n" ); 01447 break; 01448 case 2: 01449 PRINT_INFO( " Pair Normals Allowed: Opposite\n" ); 01450 break; 01451 case 3: 01452 PRINT_INFO( " Pair Normals Allowed: Same\n" ); 01453 break; 01454 } 01455 01456 PRINT_INFO( " Display Pairs: %s\n", on_off[displayPairs] ); 01457 PRINT_INFO( " List Pairs: %s\n", on_off[listPairs] ); 01458 PRINT_INFO( " Group Results: %s\n", on_off[groupResults] ); 01459 PRINT_INFO( " Across Body|Volume: %s\n", on_off[checkAcrossBodies] ); 01460 PRINT_INFO( " Within Body|Volume: %s\n", on_off[checkWithinBodies] ); 01461 PRINT_INFO( " Imprint: %s\n", on_off[imprintResults] ); 01462 } 01463 01464 CubitString SurfaceOverlapTool::get_normal_type_setting() 01465 { 01466 if (normalType == 2) { 01467 return CubitString("opposite"); 01468 } 01469 else if (normalType == 3) { 01470 return CubitString("same"); 01471 } 01472 else { 01473 return CubitString("any"); 01474 } 01475 } 01476 01477 void SurfaceOverlapTool::set_normal_type_setting(CubitString type ) 01478 { 01479 if (CubitUtil::compare(type.c_str(), "opposite")) { 01480 normalType = 2; 01481 } 01482 else if (CubitUtil::compare(type.c_str(), "same")) { 01483 normalType = 3; 01484 } 01485 else { 01486 normalType = 1; 01487 } 01488 } 01489 01490 int SurfaceOverlapTool::get_group_results_setting() 01491 {return groupResults;} 01492 01493 void SurfaceOverlapTool::set_group_results_setting( int setting ) 01494 {groupResults = (setting) ? CUBIT_TRUE : CUBIT_FALSE;} 01495 01496 int SurfaceOverlapTool::get_list_pairs_setting() 01497 {return listPairs;} 01498 01499 void SurfaceOverlapTool::set_list_pairs_setting( int setting ) 01500 {listPairs = (setting) ? CUBIT_TRUE : CUBIT_FALSE;} 01501 01502 int SurfaceOverlapTool::get_display_pairs_setting() 01503 {return displayPairs;} 01504 01505 void SurfaceOverlapTool::set_display_pairs_setting( int setting ) 01506 {displayPairs = (setting) ? CUBIT_TRUE : CUBIT_FALSE;} 01507 01508 int SurfaceOverlapTool::get_facet_ang_tol_setting() 01509 {return facetAngTol;} 01510 01511 void SurfaceOverlapTool::set_facet_ang_tol_setting( int val ) 01512 {facetAngTol=(unsigned short)val;} 01513 01514 //Imprints the bodies containing the lists of surfaces. Also 01515 //uses the edges imprinting rather than the normal imprint. 01516 CubitStatus SurfaceOverlapTool::imprint(DLIList<RefFace*> &ref_face_list1, 01517 DLIList<RefFace*> &ref_face_list2) 01518 { 01519 //This is a very tricky goal. The goal is to imprint each pair for the 01520 //two lists. The problem is that we need to imprint the bodies of the 01521 //surfaces not just the surfaces since this isn't as robust. The problem 01522 //is that more than one of these surfaces may reference the same body. So 01523 //in fact as we imprint one of the surfaces, the other ones could get deleted and 01524 //create a memory leak. 01525 01526 //The only thing I can think of is to use the id's of the bodies as the constant. 01527 //On the imprint, the body id should not change. So lets create an array of bodies, 01528 //and update the array as they get changed. The array will allow constant access time. 01529 DLIList <Body*> body_list, temp_bodies; 01530 DLIList <int> body_ids1, body_ids2, modified_list; 01531 DLIList <DLIList<RefEdge*>*> edges_list1, edges_list2; 01532 DLIList <RefEdge*> *ref_edges1, *ref_edges2, tmp_edges; 01533 01534 CubitBoolean print = CUBIT_TRUE; 01535 Body *tmp_body; 01536 int i, max_id = -1; 01537 01538 //first get the max id of the bodies here to help us 01539 //get the size of the array. 01540 for ( i = ref_face_list1.size(); i > 0; i-- ) 01541 { 01542 temp_bodies.clean_out(); 01543 RefFace *ref_face1 = ref_face_list1.get_and_step(); 01544 if ( ref_face1 == NULL ) 01545 { 01546 PRINT_ERROR("Bad data sent to imprint overlaps.\n"); 01547 return CUBIT_FAILURE; 01548 } 01549 ref_face1->bodies(temp_bodies); 01550 if ( temp_bodies.size() != 1 ) 01551 { 01552 PRINT_WARNING("Entities must be in one body\n"); 01553 PRINT_WARNING("Skipping that entity\n"); 01554 ref_face_list2.step(); 01555 continue; 01556 } 01557 tmp_body = temp_bodies.get(); 01558 temp_bodies.clean_out(); 01559 RefFace *ref_face2 = ref_face_list2.get_and_step(); 01560 if ( ref_face2 == NULL ) 01561 { 01562 PRINT_ERROR("Bad data sent to imprint overlaps.\n"); 01563 return CUBIT_FAILURE; 01564 } 01565 ref_face2->bodies(temp_bodies); 01566 if ( temp_bodies.size() != 1 ) 01567 { 01568 PRINT_WARNING("Entities must be in one body\n"); 01569 PRINT_WARNING("Skipping that entity\n"); 01570 continue; 01571 } 01572 if ( tmp_body->id() > max_id ) 01573 max_id = tmp_body->id(); 01574 body_list.append(tmp_body); 01575 body_ids1.append(tmp_body->id()); 01576 body_list.append(temp_bodies.get()); 01577 body_ids2.append(temp_bodies.get()->id()); 01578 if ( temp_bodies.get()->id() > max_id ) 01579 max_id = temp_bodies.get()->id(); 01580 //Now set up the edge lists. 01581 ref_edges1 = new DLIList<RefEdge*>; 01582 ref_face1->ref_edges(tmp_edges); 01583 CubitStatus stat = copy_edges_in_list(tmp_edges, *ref_edges1); 01584 if ( stat != CUBIT_SUCCESS ) 01585 return CUBIT_FAILURE; 01586 ref_edges2 = new DLIList<RefEdge*>; 01587 tmp_edges.clean_out(); 01588 ref_face2->ref_edges(tmp_edges); 01589 stat = copy_edges_in_list(tmp_edges, *ref_edges2); 01590 if ( stat != CUBIT_SUCCESS ) 01591 return CUBIT_FAILURE; 01592 edges_list1.append(ref_edges1); 01593 edges_list2.append(ref_edges2); 01594 } 01595 //Now create an array and store all of the bodies. 01596 Body **body_array = new Body* [2*max_id+1]; 01597 //initialize the array to null. 01598 for ( i = 0; i < 2*max_id+1; i++ ) 01599 { 01600 body_array[i] = (Body*)NULL; 01601 } 01602 //Now put the bodies into the array. 01603 for ( i = body_list.size(); i > 0; i-- ) 01604 { 01605 tmp_body = body_list.get_and_step(); 01606 body_array[tmp_body->id()] = tmp_body; 01607 } 01608 //Now go through and pairwise imprint the bodies. 01609 DLIList <Body*> bodies, tmp_modified_bodies; 01610 for( i = body_ids1.size(); i > 0; i-- ) 01611 { 01612 tmp_modified_bodies.clean_out(); 01613 int id1 = body_ids1.get_and_step(); 01614 int id2 = body_ids2.get_and_step(); 01615 ref_edges1 = edges_list1.get_and_step(); 01616 ref_edges2 = edges_list2.get_and_step(); 01617 01618 Body *body1 = body_array[id1]; 01619 Body *body2 = body_array[id2]; 01620 int body1_num = num_descendants(body1); 01621 int body2_num = num_descendants(body2); 01622 bodies.clean_out(); 01623 bodies.append(body2); 01624 CubitStatus stat = GeometryModifyTool::instance()-> 01625 imprint(bodies, *ref_edges1, tmp_modified_bodies, CUBIT_FALSE, CUBIT_FALSE); 01626 if ( stat == CUBIT_SUCCESS && tmp_modified_bodies.size() == 1 ) 01627 { 01628 body2 = tmp_modified_bodies.get(); 01629 } 01630 tmp_modified_bodies.clean_out(); 01631 bodies.clean_out(); 01632 bodies.append(body1); 01633 stat = GeometryModifyTool::instance()-> 01634 imprint(bodies, *ref_edges2, tmp_modified_bodies, CUBIT_FALSE, CUBIT_FALSE); 01635 if ( stat == CUBIT_SUCCESS && tmp_modified_bodies.size() == 1 ) 01636 { 01637 body1 = tmp_modified_bodies.get(); 01638 } 01639 body_array[id1] = body1; 01640 int temp_num = num_descendants(body1); 01641 if ( temp_num != body1_num ) 01642 { 01643 modified_list.append_unique(id1); 01644 } 01645 body_array[id2] = body2; 01646 temp_num = num_descendants(body2); 01647 if ( temp_num != body2_num ) 01648 { 01649 modified_list.append_unique(id2); 01650 } 01651 } 01652 if ( modified_list.size() && print ) 01653 { 01654 if ( modified_list.size() != 1 ) 01655 PRINT_INFO("Imprinting Modified Bodies: "); 01656 else 01657 PRINT_INFO("Imprinting Modified Body: "); 01658 for ( i = 0; i < modified_list.size(); i++ ) 01659 { 01660 if ( i != modified_list.size()-1 ) 01661 { 01662 if (i%10 == 0 && i != 0 ) 01663 PRINT_INFO("%d,\n", modified_list.get_and_step()); 01664 else 01665 PRINT_INFO("%d, ", modified_list.get_and_step()); 01666 } 01667 else 01668 PRINT_INFO("%d.\n", modified_list.get_and_step()); 01669 } 01670 } 01671 else if ( modified_list.size() == 0 && print ) 01672 PRINT_INFO("Imprinting overlaps resulted in no modifications.\n"); 01673 01674 //clean up our memory. 01675 for ( i = edges_list1.size(); i > 0; i-- ) 01676 { 01677 ref_edges1 = edges_list1.remove(); 01678 ref_edges2 = edges_list2.remove(); 01679 delete_edges_in_list(*ref_edges1); 01680 delete_edges_in_list(*ref_edges2); 01681 delete ref_edges1; 01682 delete ref_edges2; 01683 } 01684 delete [] body_array; 01685 return CUBIT_SUCCESS; 01686 } 01687 01688 int SurfaceOverlapTool::num_descendants(Body *body) 01689 { 01690 int counter = 0; 01691 counter += body->num_ref_volumes(); 01692 counter += body->num_ref_faces(); 01693 counter += body->num_ref_edges(); 01694 counter += body->num_ref_vertices(); 01695 return counter; 01696 } 01697 01698 //--------------------------------------------------------- 01699 // copy_edges_in_list: 01700 // copy's each of the edges in the old list, and puts the 01701 // stand alone edges in the new list. 01702 // NOTE: THESE ARE NEWLY CREATED EDGES AND SHOULD BE DELETED 01703 // BY THE CALLING FUNCTION. 01704 // Author: David R. White 01705 // Date: 1/11/02 01706 //--------------------------------------------------------- 01707 CubitStatus SurfaceOverlapTool::copy_edges_in_list(DLIList<RefEdge*> &old_list, 01708 DLIList<RefEdge*> &new_list ) 01709 { 01710 int i; 01711 RefEdge *curr_edge, *new_edge; 01712 RefEntity *curr_entity, *new_entity; 01713 01714 for ( i = old_list.size(); i > 0; i-- ) 01715 { 01716 curr_edge = old_list.get_and_step(); 01717 curr_entity = CAST_TO(curr_edge, RefEntity); 01718 assert(curr_entity != NULL ); 01719 new_entity = GeometryModifyTool::instance()->copy_refentity(curr_entity); 01720 new_edge = CAST_TO(new_entity, RefEdge); 01721 if ( new_edge == NULL ) 01722 { 01723 PRINT_ERROR("Problems copying edges for imprinting overlap.\n"); 01724 assert(new_edge != NULL ); 01725 return CUBIT_FAILURE; 01726 } 01727 new_list.append(new_edge); 01728 } 01729 return CUBIT_SUCCESS; 01730 } 01731 01732 //Initialize all settings in this class 01733 void SurfaceOverlapTool::initialize_settings() 01734 { 01735 SettingHandler::instance()->add_setting("Overlap Facet BBox Absolute", 01736 SurfaceOverlapTool::set_facet_abs_tol, 01737 SurfaceOverlapTool::get_facet_abs_tol); 01738 01739 SettingHandler::instance()->add_setting("Overlap Facet BBox Angle", 01740 SurfaceOverlapTool::set_facet_ang_tol_setting, 01741 SurfaceOverlapTool::get_facet_ang_tol_setting); 01742 01743 SettingHandler::instance()->add_setting("Overlap Minimum Gap", 01744 SurfaceOverlapTool::set_gap_min, 01745 SurfaceOverlapTool::get_gap_min); 01746 01747 SettingHandler::instance()->add_setting("Overlap Maximum Gap", 01748 SurfaceOverlapTool::set_gap_max, 01749 SurfaceOverlapTool::get_gap_max); 01750 01751 SettingHandler::instance()->add_setting("Overlap Minimum Angle", 01752 SurfaceOverlapTool::set_angle_min, 01753 SurfaceOverlapTool::get_angle_min); 01754 01755 SettingHandler::instance()->add_setting("Overlap Maximum Angle", 01756 SurfaceOverlapTool::set_angle_max, 01757 SurfaceOverlapTool::get_angle_max); 01758 01759 SettingHandler::instance()->add_setting("Overlap Normal", 01760 SurfaceOverlapTool::set_normal_type_setting, 01761 SurfaceOverlapTool::get_normal_type_setting); 01762 01763 SettingHandler::instance()->add_setting("Overlap Tolerance", 01764 SurfaceOverlapTool::set_overlap_tolerance, 01765 SurfaceOverlapTool::get_overlap_tolerance); 01766 01767 SettingHandler::instance()->add_setting("Overlap Group", 01768 SurfaceOverlapTool::set_group_results_setting, 01769 SurfaceOverlapTool::get_group_results_setting); 01770 01771 SettingHandler::instance()->add_setting("Overlap List", 01772 SurfaceOverlapTool::set_list_pairs_setting, 01773 SurfaceOverlapTool::get_list_pairs_setting); 01774 01775 SettingHandler::instance()->add_setting("Overlap Display", 01776 SurfaceOverlapTool::set_display_pairs_setting, 01777 SurfaceOverlapTool::get_display_pairs_setting); 01778 01779 SettingHandler::instance()->add_setting("Overlap Within Bodies", 01780 SurfaceOverlapTool::set_check_within_bodies, 01781 SurfaceOverlapTool::get_check_within_bodies); 01782 01783 SettingHandler::instance()->add_setting("Overlap Across Bodies", 01784 SurfaceOverlapTool::set_check_across_bodies, 01785 SurfaceOverlapTool::get_check_across_bodies); 01786 } 01787 01788 CubitStatus SurfaceOverlapTool::delete_edges_in_list(DLIList<RefEdge*> &edge_list ) 01789 { 01790 int i; 01791 RefEdge *curr_edge; 01792 RefEntity *curr_entity; 01793 01794 for ( i = edge_list.size(); i > 0; i-- ) 01795 { 01796 curr_edge = edge_list.remove(); 01797 curr_entity = CAST_TO(curr_edge, RefEntity); 01798 assert(curr_entity != NULL ); 01799 CubitStatus stat = GeometryQueryTool::instance()->delete_RefEntity(curr_entity); 01800 if ( stat != CUBIT_SUCCESS ) 01801 { 01802 PRINT_ERROR("Problems deleting edges after imprinting overlaps\n"); 01803 assert(0); 01804 return CUBIT_FAILURE; 01805 } 01806 } 01807 return CUBIT_SUCCESS; 01808 } 01809 01810 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<Curve*> &curve_list, 01811 DLIList< DLIList<Curve*> *> &overlapping_curve_lists, 01812 std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map, 01813 std::multimap<BodySM*, CubitVector> &body_point_imprint_map, 01814 double overlap_tol) 01815 { 01816 int i; 01817 01818 //put all the curves into a tree 01819 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 01820 if(overlap_tol > 0.0) 01821 tolerance = overlap_tol; 01822 01823 // Populate the Surface AbstractTree 01824 AbstractTree<Curve*> *a_tree = new RTree<Curve*>( tolerance ); 01825 curve_list.reset(); 01826 for( i=curve_list.size(); i--; ) 01827 { 01828 Curve *curve = curve_list.get_and_step(); 01829 a_tree->add( curve ); 01830 } 01831 01832 std::map<Curve*, DLIList<CurveOverlapFacet*>* > facet_map; 01833 std::map<Curve*, DLIList<Curve*>* >::iterator list_iter; 01834 01835 curve_list.reset(); 01836 for( i=curve_list.size(); i--; ) 01837 { 01838 Curve *curve1= curve_list.get_and_step(); 01839 01840 BodySM *curve1_body = curve1->bodysm(); 01841 01842 // Remove this surface from AbstractTree so it is not found and never 01843 // found again 01844 a_tree->remove( curve1 ); 01845 01846 // Find RefFaces from AbstractTree that are within range of this surface 01847 CubitBox curve1_box = curve1->bounding_box(); 01848 DLIList<Curve*> close_curves; 01849 a_tree->find( curve1_box, close_curves ); 01850 01851 int j; 01852 for( j=close_curves.size(); j--; ) 01853 { 01854 Curve *curve2 = close_curves.get_and_step(); 01855 BodySM *curve2_body = curve2->bodysm(); 01856 01857 if( curve2_body == curve1_body ) 01858 continue; 01859 01860 std::multimap<BodySM*, CubitVector> tmp_body_point_imprint_map; 01861 01862 if( check_overlap( curve1, curve2, &facet_map, &tmp_body_point_imprint_map, overlap_tol ) ) 01863 { 01864 //check to see if the curve1 is already overlapping with another curve 01865 list_iter = curve_to_list_map.find( curve1 ); 01866 if( list_iter != curve_to_list_map.end() ) 01867 { 01868 DLIList<Curve*> *tmp_curve_list = list_iter->second; 01869 tmp_curve_list->append( curve2 ); 01870 } 01871 else 01872 { 01873 //list for curve 1 does not exist....make a new one 01874 DLIList<Curve*> *tmp_curve_list = new DLIList<Curve*>; 01875 overlapping_curve_lists.append( tmp_curve_list ); 01876 tmp_curve_list->append( curve1 ); 01877 tmp_curve_list->append( curve2 ); 01878 curve_to_list_map.insert( std::map<Curve*, 01879 DLIList<Curve*>*>::value_type( curve1, tmp_curve_list )); 01880 } 01881 } 01882 else 01883 { 01884 //append what's in body_point_imprint_map to one passed in 01885 body_point_imprint_map.insert( tmp_body_point_imprint_map.begin(), 01886 tmp_body_point_imprint_map.end() ); 01887 } 01888 } 01889 } 01890 01891 //clean up facet map 01892 std::map<Curve*, DLIList<CurveOverlapFacet*>* >::iterator facet_iter; 01893 facet_iter=facet_map.begin(); 01894 for(; facet_iter != facet_map.end(); facet_iter++ ) 01895 { 01896 DLIList<CurveOverlapFacet*> *co_facet_list = facet_iter->second; 01897 01898 //delete all the facets in the list 01899 for( i=co_facet_list->size(); i--; ) 01900 delete co_facet_list->get_and_step(); 01901 delete co_facet_list; 01902 } 01903 01904 delete a_tree; 01905 01906 return CUBIT_SUCCESS; 01907 } 01908 01909 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<Surface*> &surf_list, 01910 DLIList< DLIList<Curve*> *> &overlapping_curve_lists, 01911 std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map, 01912 std::multimap<BodySM*, CubitVector> &body_point_imprint_map) 01913 { 01914 //collect all the surfaces 01915 DLIList<Curve*> curve_list; 01916 int i; 01917 for( i=surf_list.size(); i--; ) 01918 { 01919 Surface *surf = surf_list.get_and_step(); 01920 DLIList<Curve*> curves; 01921 surf->curves_ignore_virtual(curves, false); 01922 // body_sm->curves( curves); 01923 curve_list.merge_unique( curves ); 01924 } 01925 01926 return find_overlapping_curves(curve_list, overlapping_curve_lists, curve_to_list_map, 01927 body_point_imprint_map); 01928 } 01929 01930 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<BodySM*> &body_list, 01931 DLIList< DLIList<Curve*> *> &overlapping_curve_lists, 01932 std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map, 01933 std::multimap<BodySM*, CubitVector> &body_point_imprint_map, 01934 double overlap_tol) 01935 { 01936 //collect all the surfaces 01937 DLIList<Curve*> curve_list; 01938 int i; 01939 for( i=body_list.size(); i--; ) 01940 { 01941 BodySM *body_sm = body_list.get_and_step(); 01942 DLIList<Curve*> curves; 01943 body_sm->curves_ignore_virtual(curves, false); 01944 // body_sm->curves( curves); 01945 curve_list.merge_unique( curves ); 01946 } 01947 01948 return find_overlapping_curves(curve_list, overlapping_curve_lists, curve_to_list_map, 01949 body_point_imprint_map, overlap_tol); 01950 01951 } 01952 01953 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<Body*> &bodies, 01954 std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map, 01955 double maxgap /* =-1*/) 01956 { 01957 std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator list_iter; 01958 01959 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 01960 if (maxgap != -1 && maxgap != 0.0) 01961 tolerance = maxgap; 01962 01963 int i,j; 01964 DLIList<Body*> tmp_body_list = bodies; 01965 for(i=tmp_body_list.size(); i--; ) 01966 { 01967 Body *tmp_body1 = tmp_body_list.pop(); 01968 01969 tmp_body_list.reset(); 01970 for(j=tmp_body_list.size(); j--; ) 01971 { 01972 Body *tmp_body2 = tmp_body_list.get_and_step(); 01973 01974 //determine if bodies are close enough to have overlapping curves 01975 CubitBox body_box1 = tmp_body1->bounding_box(); 01976 CubitBox body_box2 = tmp_body2->bounding_box(); 01977 01978 if( body_box1.overlap( tolerance, body_box2 ) ) 01979 { 01980 // create list of edges on each body. 01981 // put the edges in body2 in edges1 so edges1 contains 01982 // the list of curves contained in the body listed first in the list 01983 DLIList<RefEdge*> edges1, edges2; 01984 tmp_body1->ref_edges( edges2 ); 01985 tmp_body2->ref_edges( edges1 ); 01986 01987 //check individual curves for bounding box interference 01988 if (!find_overlapping_curves(edges1, edges2, overlapping_edge_map, tolerance)) 01989 return CUBIT_FAILURE; 01990 } 01991 } 01992 } 01993 01994 return CUBIT_SUCCESS; 01995 } 01996 01997 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<RefFace*> &faces, 01998 std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map, 01999 double maxgap /*=-1*/) 02000 { 02001 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 02002 02003 if (maxgap != -1 && maxgap != 0.0) 02004 tolerance = maxgap; 02005 02006 // Populate the Surface AbstractTree 02007 AbstractTree<RefFace*> *a_tree = new RTree<RefFace*>( tolerance ); 02008 faces.reset(); 02009 int i; 02010 for( i=faces.size(); i--; ) 02011 { 02012 RefFace* face = faces.get_and_step(); 02013 a_tree->add( face ); 02014 } 02015 02016 faces.reset(); 02017 for( i=faces.size(); i--; ) 02018 { 02019 RefFace* face1 = faces.get_and_step(); 02020 02021 Body *face1_body = face1->body(); 02022 02023 // Remove this face from AbstractTree so it is not found and never 02024 // found again 02025 a_tree->remove( face1 ); 02026 02027 // Find RefFaces from AbstractTree that are within range of this surface 02028 CubitBox face1_box = face1->bounding_box(); 02029 DLIList<RefFace*> close_faces; 02030 a_tree->find( face1_box, close_faces ); 02031 02032 int j; 02033 for( j=close_faces.size(); j--; ) 02034 { 02035 RefFace *face2 = close_faces.get_and_step(); 02036 Body *face2_body = face2->body(); 02037 02038 //don't check for overlapping faces within bodies 02039 if( face1_body == face2_body ) 02040 continue; 02041 02042 DLIList<RefEdge*> edges1, edges2; 02043 face1->ref_edges( edges1 ); 02044 face2->ref_edges( edges2 ); 02045 02046 if (!find_overlapping_curves(edges1, edges2, overlapping_edge_map, tolerance)) 02047 return CUBIT_FAILURE; 02048 02049 } 02050 } 02051 return CUBIT_SUCCESS; 02052 } 02053 02054 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<RefEdge*> &edgelist, 02055 std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map, double maxgap /*=-1*/ ) 02056 { 02057 // for now, check every edge against every other edge 02058 // (the helper function will skip edges if they are in the same body) 02059 02060 DLIList<RefEdge*> edgelist2 = edgelist; 02061 return find_overlapping_curves(edgelist, edgelist2, overlapping_edge_map, maxgap); 02062 } 02063 02064 CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<RefEdge*> &edges1, DLIList<RefEdge*> &edges2, 02065 std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map, 02066 double maxgap /*=-1*/) 02067 { 02068 int i; 02069 std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > facet_map; 02070 std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator list_iter; 02071 02072 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 02073 02074 if (maxgap != -1 && maxgap != 0.0) 02075 tolerance = maxgap; 02076 02077 for( i=edges1.size(); i--; ) 02078 { 02079 RefEdge *edge1 = edges1.get_and_step(); 02080 02081 int j; 02082 for( j=edges2.size(); j--; ) 02083 { 02084 RefEdge *edge2 = edges2.get_and_step(); 02085 02086 if( edge1 == edge2 ) 02087 continue; 02088 02089 std::multimap<RefEdge*, RefEdge*>::iterator it; 02090 it = overlapping_edge_map.find( edge2 ); 02091 if( it != overlapping_edge_map.end() ) 02092 continue; 02093 02094 // check to see if this pair is already in the overlap map. 02095 // If it is, don't need to bother checking it for overlap 02096 /* 02097 std::multimap<RefEdge*, RefEdge*>::iterator it; 02098 std::pair< std::multimap<RefEdge*,RefEdge*>::iterator, std::multimap<RefEdge*,RefEdge*>::iterator > range; 02099 02100 range = overlapping_edge_map.equal_range(edge1); 02101 02102 for (it=range.first; it!=range.second; it++) 02103 { 02104 if ( (it->second == edge2) && (it->first == edge1) ) 02105 pair_already_in_map = true; 02106 } 02107 if (pair_already_in_map) 02108 continue; 02109 02110 */ 02111 02112 if( check_overlap( edge1, edge2, &facet_map, &tolerance ) ) 02113 { 02114 overlapping_edge_map.insert( std::multimap<RefEdge*, RefEdge*> 02115 ::value_type( edge1, edge2)); 02116 //PRINT_INFO("Curve %d and %d overlap.\n", edge1->id(), edge2->id()); 02117 //PRINT_INFO("Insert Curve %d, Curve %d.\n", edge1->id(), edge2->id()); 02118 } 02119 } 02120 } 02121 //clean up facet map 02122 list_iter=facet_map.begin(); 02123 for(; list_iter != facet_map.end(); list_iter++ ) 02124 { 02125 DLIList<CurveOverlapFacet*> *co_facet_list = list_iter->second; 02126 //delete all the facets in the list 02127 for( i=co_facet_list->size(); i--; ) 02128 delete co_facet_list->get_and_step(); 02129 delete co_facet_list; 02130 } 02131 02132 return CUBIT_SUCCESS; 02133 } 02134 02135 CubitBoolean SurfaceOverlapTool::check_overlap( Curve *curve1, Curve *curve2, 02136 std::map<Curve*, DLIList<CurveOverlapFacet*>* > *facet_map, 02137 std::multimap<BodySM*,CubitVector> *body_point_imprint_map, 02138 double overlap_tol) 02139 { 02140 //if surfaces are not splines and are not of the same type, 02141 //they won't overlap 02142 GeometryType curve1_type = curve1->geometry_type(); 02143 GeometryType curve2_type = curve2->geometry_type(); 02144 02145 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 02146 if(overlap_tol > 0.0) 02147 tolerance = overlap_tol; 02148 02149 double facet_tol = tolerance*10; 02150 02151 std::map<Curve*, DLIList<CurveOverlapFacet*>* >::iterator facet_iterator; 02152 02153 CubitBox curve_box1 = curve1->bounding_box(); 02154 CubitBox curve_box2 = curve2->bounding_box(); 02155 02156 DLIList<CurveOverlapFacet*> *facet_list1 = NULL; 02157 DLIList<CurveOverlapFacet*> *facet_list2 = NULL; 02158 02159 //see if curve is in map...if not we have to create faceting for it. 02160 if( facet_map ) 02161 facet_iterator = facet_map->find( curve1 ); 02162 02163 if( facet_map == NULL || facet_iterator == facet_map->end() ) 02164 { 02165 facet_list1 = new DLIList<CurveOverlapFacet*>; 02166 02167 GMem curve_graphics; 02168 curve1->get_geometry_query_engine()->get_graphics( curve1, 02169 &curve_graphics, 0, facet_tol ); 02170 02171 GPoint *points = curve_graphics.point_list(); 02172 int num_points = curve_graphics.pointListCount; 02173 02174 int kk; 02175 for( kk=0; kk<num_points-1; kk++ ) 02176 { 02177 //create a new CurveOverlapFacets 02178 GPoint gpoints[2]; 02179 gpoints[0] = points[kk]; 02180 gpoints[1] = points[kk + 1]; 02181 02182 CurveOverlapFacet *tmp_facet = new CurveOverlapFacet( gpoints ); 02183 facet_list1->append( tmp_facet ); 02184 } 02185 02186 if( facet_map ) 02187 facet_map->insert( std::map<Curve*, 02188 DLIList<CurveOverlapFacet*>*>::value_type( curve1, facet_list1 )); 02189 02190 } 02191 else 02192 facet_list1 = (*facet_iterator).second; 02193 02194 //see if edge is in map...if not we have to create facet for it. 02195 if( facet_map ) 02196 facet_iterator = facet_map->find( curve2 ); 02197 02198 if( facet_map == NULL || facet_iterator == facet_map->end() ) 02199 { 02200 facet_list2 = new DLIList<CurveOverlapFacet*>; 02201 02202 GMem curve_graphics; 02203 curve2->get_geometry_query_engine()->get_graphics( curve2, 02204 &curve_graphics, 0, facet_tol ); 02205 02206 GPoint *points = curve_graphics.point_list(); 02207 int num_points = curve_graphics.pointListCount; 02208 02209 int kk; 02210 for( kk=0; kk<num_points-1; kk++ ) 02211 { 02212 //create a new CurveOverlapFacets 02213 GPoint gpoints[2]; 02214 gpoints[0] = points[kk]; 02215 gpoints[1] = points[kk + 1]; 02216 02217 CurveOverlapFacet *tmp_facet = new CurveOverlapFacet( gpoints ); 02218 facet_list2->append( tmp_facet ); 02219 } 02220 02221 if( facet_map ) 02222 facet_map->insert( std::map<Curve*, 02223 DLIList<CurveOverlapFacet*>*>::value_type( curve2, facet_list2 )); 02224 } 02225 else 02226 facet_list2 = (*facet_iterator).second; 02227 02228 bool overlap = false; 02229 int kk; 02230 if(facet_list1->size() > 0 && facet_list2->size() > 0) 02231 { 02232 //compare smaller list to larger list...want list1 to be smaller 02233 if( facet_list1->size() > facet_list2->size() ) 02234 { 02235 DLIList<CurveOverlapFacet*> *tmp_list = facet_list1; 02236 facet_list1 = facet_list2; 02237 facet_list2 = tmp_list; 02238 Curve *tmp_curve = curve1; 02239 curve1 = curve2; 02240 curve2 = tmp_curve; 02241 } 02242 02243 CubitVector curv1_start_pt; 02244 CubitVector curv2_start_pt; 02245 CubitVector curv1_end_pt; 02246 CubitVector curv2_end_pt; 02247 02248 facet_list1->reset(); 02249 facet_list2->reset(); 02250 //get start/end facet points on curves 02251 if( body_point_imprint_map ) 02252 { 02253 curv1_start_pt = facet_list1->get()->start_point(); 02254 curv2_start_pt = facet_list2->get()->start_point(); 02255 facet_list1->last(); 02256 facet_list2->last(); 02257 curv1_end_pt = facet_list1->get()->end_point(); 02258 curv2_end_pt = facet_list2->get()->end_point(); 02259 } 02260 02261 facet_list1->reset(); 02262 facet_list2->reset(); 02263 double total_overlap = 0.0; 02264 //now determine if enough curve facets overlap 02265 02266 int list_size1 = facet_list1->size(); 02267 for( kk=list_size1; kk--; ) 02268 { 02269 CurveOverlapFacet *curr_facet = facet_list1->get_and_step(); 02270 if( curr_facet->length() < GEOMETRY_RESABS ) 02271 continue; 02272 02273 //if 'curr_facet' is the first or last facet in curve1, 02274 //check to see if the start/end point is on curve2, and not coincident 02275 //with the start/end point of curve2. If so, it's a case where you need 02276 //to imprint this start/end point onto the body of curve2. 02277 if( body_point_imprint_map ) 02278 { 02279 if( kk == list_size1-1 ) //first facet in curve1 02280 { 02281 CubitVector closest_point; 02282 curve2->closest_point_trimmed( curr_facet->start_point(), closest_point ); 02283 if( curv2_start_pt.distance_between( curr_facet->start_point() ) > tolerance && 02284 curv2_end_pt.distance_between( curr_facet->start_point() ) > tolerance && 02285 closest_point.distance_between( curr_facet->start_point() ) < tolerance ) 02286 { 02287 BodySM *tmp_body_sm = curve2->bodysm(); 02288 body_point_imprint_map->insert( std::multimap<BodySM*, 02289 CubitVector>::value_type( 02290 tmp_body_sm, closest_point)); 02291 } 02292 } 02293 if( kk == 0 ) //last facet in curve1 02294 { 02295 CubitVector closest_point; 02296 curve2->closest_point_trimmed( curr_facet->end_point(), closest_point ); 02297 if( curv2_start_pt.distance_between( curr_facet->end_point() ) > tolerance && 02298 curv2_end_pt.distance_between( curr_facet->end_point() ) > tolerance && 02299 closest_point.distance_between( curr_facet->end_point() ) < tolerance ) 02300 { 02301 //insert into vertex-volume imprint map 02302 BodySM *tmp_body_sm = curve2->bodysm(); 02303 body_point_imprint_map->insert( std::multimap<BodySM*, 02304 CubitVector>::value_type( 02305 tmp_body_sm, closest_point)); 02306 } 02307 } 02308 } 02309 02310 //do bounding boxes of facets overlap? 02311 int jj; 02312 int list_size2 = facet_list2->size(); 02313 for( jj=list_size2; jj--; ) 02314 { 02315 CurveOverlapFacet *other_facet = facet_list2->get_and_step(); 02316 02317 if( curr_facet->bbox_overlap( tolerance, other_facet ) ) 02318 { 02319 double distance_between_facets = curr_facet->facet_to_facet_distance( other_facet ); 02320 if( distance_between_facets < tolerance+facet_tol ) 02321 { 02322 if( other_facet->length() < GEOMETRY_RESABS ) 02323 continue; 02324 02325 //if 'other_facet' is the first or last facet in curve1, 02326 //check to see if the start/end point is on curve1, and not coincident 02327 //with the start/end point of curve1. If so, it's a case where you need 02328 //to imprint this start/end point onto the body of curve1. 02329 if( body_point_imprint_map ) 02330 { 02331 if( jj == list_size2-1 ) //first facet in curve1 02332 { 02333 CubitVector closest_point; 02334 curve1->closest_point_trimmed( other_facet->start_point(), closest_point ); 02335 02336 if( curv1_start_pt.distance_between( other_facet->start_point() ) > tolerance && 02337 curv1_end_pt.distance_between( other_facet->start_point() ) > tolerance && 02338 closest_point.distance_between( other_facet->start_point() ) < tolerance ) 02339 { 02340 //insert into vertex-volume imprint map 02341 BodySM *tmp_body_sm = curve1->bodysm(); 02342 body_point_imprint_map->insert( std::multimap<BodySM*, 02343 CubitVector>::value_type( 02344 tmp_body_sm, closest_point )); 02345 } 02346 } 02347 if( jj == 0 ) //last facet in curve1 02348 { 02349 CubitVector closest_point; 02350 curve1->closest_point_trimmed( other_facet->end_point(), closest_point ); 02351 if( curv1_start_pt.distance_between( other_facet->end_point() ) > tolerance && 02352 curv1_end_pt.distance_between( other_facet->end_point() ) > tolerance && 02353 closest_point.distance_between( other_facet->end_point() ) < tolerance ) 02354 { 02355 //insert into vertex-volume imprint map 02356 BodySM *tmp_body_sm = curve1->bodysm(); 02357 body_point_imprint_map->insert( std::multimap<BodySM*, 02358 CubitVector>::value_type( 02359 tmp_body_sm, closest_point )); 02360 } 02361 } 02362 } 02363 02364 //get the long and short facet edge 02365 double curr_facet_length = curr_facet->length(); 02366 double other_facet_length = other_facet->length(); 02367 CurveOverlapFacet *long_facet = ( curr_facet_length > other_facet_length ? 02368 curr_facet : other_facet ); 02369 CurveOverlapFacet *short_facet = curr_facet; 02370 if( long_facet == curr_facet ) 02371 short_facet = other_facet; 02372 02373 //make sure both endpoints or one endpoint and the midpoint 02374 // of the smaller facet edge lie within a radius 02375 //of merge tolerance + facet tolerance to an infinite line defined 02376 // by longer facet edge 02377 CubitVector direction = long_facet->end_point() - long_facet->start_point(); 02378 double dist1 = short_facet->start_point().distance_from_infinite_line( 02379 long_facet->start_point(), direction ); 02380 double dist2 = short_facet->end_point().distance_from_infinite_line( 02381 long_facet->start_point(), direction ); 02382 02383 if( dist2 > tolerance+facet_tol && dist1 > tolerance+facet_tol ) 02384 continue; 02385 02386 CubitVector facet_mid_point = (short_facet->end_point() + short_facet->start_point()) * 0.5; 02387 02388 double dist_to_midpoint = facet_mid_point.distance_from_infinite_line( 02389 long_facet->start_point(), direction ); 02390 02391 if( dist_to_midpoint <= tolerance+facet_tol && (dist2 <= tolerance+facet_tol || dist1 <= tolerance+facet_tol )) 02392 { 02393 double overlap_tolerance = 02394 curr_facet->length() < other_facet->length() ? curr_facet->length(): 02395 other_facet->length(); 02396 overlap_tolerance *= 0.01; 02397 02398 //how much of the facet overlaps? 02399 double tmp_overlap = curr_facet->distance_overlapping( other_facet ) ; 02400 if( tmp_overlap > overlap_tolerance ) 02401 total_overlap += tmp_overlap; 02402 02403 if( total_overlap > tolerance ) 02404 { 02405 overlap = true; 02406 break; 02407 } 02408 } 02409 } 02410 } 02411 } 02412 if( overlap == true ) 02413 break; 02414 } 02415 } 02416 02417 if( facet_map == NULL ) 02418 { 02419 //clean up facets and list 02420 for( kk=facet_list1->size(); kk--; ) 02421 delete facet_list1->get_and_step(); 02422 for( kk=facet_list2->size(); kk--; ) 02423 delete facet_list2->get_and_step(); 02424 02425 delete facet_list1; 02426 delete facet_list2; 02427 } 02428 02429 if( overlap == false ) 02430 return CUBIT_FALSE; 02431 02432 if( curve1_type == SPLINE_CURVE_TYPE || 02433 curve2_type == SPLINE_CURVE_TYPE ) 02434 { 02435 //measure between the 2 curves 02436 double dist_between_curves = 0; 02437 CubitVector point_on_curve1, point_on_curve2; 02438 GeometryQueryTool::instance()->entity_entity_distance(curve1, curve2, 02439 point_on_curve1, point_on_curve2, dist_between_curves); 02440 02441 if( dist_between_curves > tolerance ) 02442 return CUBIT_FALSE; 02443 02444 //the curvature at the same spot on the curve could be almost the same 02445 //if curvatures at midpoint are not the same, they don't overlap 02446 CubitVector curvature1, curvature2; 02447 CubitVector tangent, closest_location; 02448 curve1->closest_point( point_on_curve1, closest_location, &tangent, &curvature1 ); 02449 curve2->closest_point( point_on_curve2, closest_location, &tangent, &curvature2 ); 02450 02451 double rad1 = curvature1.length(); 02452 double rad2 = curvature2.length(); 02453 02454 //if curvatures are more than 10% off 02455 double curvature_diff = fabs( rad1 - rad2 ); 02456 02457 if( rad1 > GEOMETRY_RESABS || rad2 > GEOMETRY_RESABS ) 02458 { 02459 if( curvature_diff/( (fabs(rad1) + fabs(rad2))/2 ) > 0.1 ) 02460 return CUBIT_FALSE; 02461 } 02462 } 02463 else if( curve1_type == ARC_CURVE_TYPE && 02464 curve2_type == ARC_CURVE_TYPE ) 02465 { 02466 //if both curves are arcs, make sure radii are almost the same 02467 CubitVector mid_point1, mid_point2; 02468 curve1->mid_point( mid_point1 ); 02469 curve2->mid_point( mid_point2 ); 02470 02471 CubitVector dummy_vec; 02472 CubitVector curvature1; 02473 CubitVector curvature2; 02474 curve1->closest_point( mid_point1, dummy_vec, NULL, &curvature1 ); 02475 curve2->closest_point( mid_point2, dummy_vec, NULL, &curvature2 ); 02476 02477 double rad1 = 1/curvature1.length(); 02478 double rad2 = 1/curvature2.length(); 02479 02480 if( fabs( rad1 - rad2 ) > tolerance ) 02481 return CUBIT_FALSE; 02482 } 02483 else 02484 return CUBIT_TRUE; 02485 02486 return CUBIT_TRUE; 02487 } 02488 02489 CubitBoolean SurfaceOverlapTool::check_overlap( RefEdge *edge1, RefEdge *edge2, 02490 std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > *facet_map, 02491 double *overlap_tol ) 02492 { 02493 //if edges are not splines and are not of the same type, 02494 //they won't overlap 02495 if( (edge1->get_curve_ptr()->geometry_type() != SPLINE_CURVE_TYPE && 02496 edge2->get_curve_ptr()->geometry_type() != SPLINE_CURVE_TYPE) && 02497 (edge1->get_curve_ptr()->geometry_type() != 02498 edge2->get_curve_ptr()->geometry_type() )) 02499 return CUBIT_FALSE; 02500 02501 // we don't want to consider edges from the same body 02502 if (edge1->body() == edge2->body()) 02503 return CUBIT_FALSE; 02504 02505 02506 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 02507 if( overlap_tol ) 02508 tolerance = *overlap_tol; 02509 02510 02511 std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator facet_iterator; 02512 CubitBox edge_box1 = edge1->bounding_box(); 02513 CubitBox edge_box2 = edge2->bounding_box(); 02514 02515 //do bounding boxes overlap 02516 if( edge_box1.overlap( tolerance, edge_box2 ) ) 02517 { 02518 //curves must overlap at least by 100th of the smaller curve's length 02519 double min_overlap = 0.0; 02520 double edge1_length = edge1->measure(); 02521 double edge2_length = edge2->measure(); 02522 if( edge1_length < edge2_length ) 02523 min_overlap = edge1->measure() * 0.01; 02524 else 02525 min_overlap = edge2->measure() * 0.01; 02526 02527 DLIList<CurveOverlapFacet*> *facet_list1 = NULL; 02528 DLIList<CurveOverlapFacet*> *facet_list2 = NULL; 02529 02530 //see if edge is in map...if not we have to create faceting for it. 02531 if( facet_map ) 02532 facet_iterator = facet_map->find( edge1 ); 02533 02534 if( facet_map == NULL || facet_iterator == facet_map->end() ) 02535 { 02536 facet_list1 = new DLIList<CurveOverlapFacet*>; 02537 02538 GMem curve_graphics; 02539 edge1->get_graphics( curve_graphics ); 02540 02541 GPoint *points = curve_graphics.point_list(); 02542 int num_points = curve_graphics.pointListCount; 02543 02544 int kk; 02545 for( kk=0; kk<num_points-1; kk++ ) 02546 { 02547 //create a new CurveOverlapFacets 02548 GPoint gpoints[2]; 02549 gpoints[0] = points[kk]; 02550 gpoints[1] = points[kk + 1]; 02551 02552 CurveOverlapFacet *tmp_facet = new CurveOverlapFacet( gpoints ); 02553 facet_list1->append( tmp_facet ); 02554 } 02555 02556 if( facet_map ) 02557 facet_map->insert( std::map<RefEdge*, 02558 DLIList<CurveOverlapFacet*>*>::value_type( edge1, facet_list1 )); 02559 } 02560 else 02561 facet_list1 = (*facet_iterator).second; 02562 02563 //see if edge is in map...if not we have to create facet for it. 02564 if( facet_map ) 02565 facet_iterator = facet_map->find( edge2 ); 02566 02567 if( facet_map == NULL || facet_iterator == facet_map->end() ) 02568 { 02569 facet_list2 = new DLIList<CurveOverlapFacet*>; 02570 02571 GMem curve_graphics; 02572 edge2->get_graphics( curve_graphics ); 02573 02574 GPoint *points = curve_graphics.point_list(); 02575 int num_points = curve_graphics.pointListCount; 02576 02577 int kk; 02578 for( kk=0; kk<num_points-1; kk++ ) 02579 { 02580 //create a new CurveOverlapFacets 02581 GPoint gpoints[2]; 02582 gpoints[0] = points[kk]; 02583 gpoints[1] = points[kk + 1]; 02584 02585 CurveOverlapFacet *tmp_facet = new CurveOverlapFacet( gpoints ); 02586 facet_list2->append( tmp_facet ); 02587 } 02588 02589 if( facet_map ) 02590 facet_map->insert( std::map<RefEdge*, 02591 DLIList<CurveOverlapFacet*>*>::value_type( edge2, facet_list2 )); 02592 } 02593 else 02594 facet_list2 = (*facet_iterator).second; 02595 02596 //compare smaller list to larger list...want list1 to be smaller 02597 if( facet_list1->size() > facet_list2->size() ) 02598 { 02599 DLIList<CurveOverlapFacet*> *tmp_list = facet_list1; 02600 facet_list1 = facet_list2; 02601 facet_list2 = tmp_list; 02602 } 02603 02604 facet_list1->reset(); 02605 facet_list2->reset(); 02606 int kk; 02607 double total_overlap = 0.0; 02608 bool overlap = false; 02609 //now determine if enough curve facets overlap 02610 for( kk=facet_list1->size(); kk--; ) 02611 { 02612 CurveOverlapFacet *curr_facet = facet_list1->get_and_step(); 02613 02614 //do bounding boxes of facets overlap? 02615 int jj; 02616 for( jj=facet_list2->size(); jj--; ) 02617 { 02618 CurveOverlapFacet *other_facet = facet_list2->get_and_step(); 02619 02620 if( curr_facet->bbox_overlap( tolerance, other_facet ) ) 02621 { 02622 if( curr_facet->facet_to_facet_distance( other_facet ) < tolerance ) 02623 { 02624 02625 //are facets parallel within some tolerance angle? 02626 double angle = curr_facet->angle( other_facet ); 02627 if( angle < 1 || fabs(180-angle ) < 1 ) 02628 { 02629 double overlap_tolerance = 02630 curr_facet->length() < other_facet->length() ? curr_facet->length(): 02631 other_facet->length(); 02632 overlap_tolerance *= 0.01; 02633 02634 //how much of the facet overlaps? 02635 double tmp_overlap = curr_facet->distance_overlapping( other_facet ) ; 02636 if( tmp_overlap > overlap_tolerance ) 02637 total_overlap += tmp_overlap; 02638 02639 if( total_overlap > min_overlap ) 02640 { 02641 if( facet_map == NULL ) 02642 { 02643 //clean up facets and list 02644 int i; 02645 for( i=facet_list1->size(); i--; ) 02646 delete facet_list1->get_and_step(); 02647 for( i=facet_list2->size(); i--; ) 02648 delete facet_list2->get_and_step(); 02649 02650 delete facet_list1; 02651 delete facet_list2; 02652 } 02653 overlap = true; 02654 break; 02655 } 02656 } 02657 } 02658 } 02659 } 02660 if( overlap == true ) 02661 break; 02662 } 02663 if( overlap == false ) 02664 return CUBIT_FALSE; 02665 02666 if( edge1->get_curve_ptr()->geometry_type() == SPLINE_CURVE_TYPE || 02667 edge2->get_curve_ptr()->geometry_type() == SPLINE_CURVE_TYPE ) 02668 { 02669 //measure between the 2 curves 02670 double dist_between_edges = 0; 02671 CubitVector point_on_edge1, point_on_edge2; 02672 GeometryQueryTool::instance()->entity_entity_distance( edge1, edge2, 02673 point_on_edge1, point_on_edge2, dist_between_edges ); 02674 02675 if( dist_between_edges > tolerance ) 02676 return CUBIT_FALSE; 02677 02678 //the curvature at the same spot on the curve could be almost the same 02679 //if curvature's at midpoint are not the same, they don't overlap 02680 CubitVector curvature1, curvature2; 02681 CubitVector tangent, closest_location; 02682 edge1->closest_point( point_on_edge1, closest_location, &tangent, &curvature1 ); 02683 edge2->closest_point( point_on_edge2, closest_location, &tangent, &curvature2 ); 02684 02685 double rad1 = curvature1.length(); 02686 double rad2 = curvature2.length(); 02687 02688 //if curvatures are more than 10% off 02689 double curvature_diff = fabs( rad1 - rad2 ); 02690 02691 if( (rad1 || rad2 ) && 02692 (rad1 > GEOMETRY_RESABS || //radii must be of significance even look at 02693 rad2 > GEOMETRY_RESABS )) 02694 { 02695 if( curvature_diff/( (fabs(rad1) + fabs(rad2))/2 ) > 0.1 ) 02696 return CUBIT_FALSE; 02697 } 02698 } 02699 else 02700 return CUBIT_TRUE; 02701 } 02702 else 02703 return CUBIT_FALSE; 02704 02705 return CUBIT_TRUE; 02706 }