cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : CompositeSurface.cc 00003 // 00004 // Purpose : Implementation of the CompositeSurface class. 00005 // 00006 // Special Notes : 00007 // 00008 // Creator : Jason Kraftcheck 00009 // 00010 // Creation Date : 03/10/98 00011 // 00012 // Owner : Jason Kraftcheck 00013 //------------------------------------------------------------------------- 00014 00015 #include <assert.h> 00016 00017 #include "VirtualQueryEngine.hpp" 00018 00019 #include "Surface.hpp" 00020 00021 #include "CompositeSurface.hpp" 00022 #include "CompositeLoop.hpp" 00023 #include "CompositeCurve.hpp" 00024 #include "CompositePoint.hpp" 00025 #include "CompositeShell.hpp" 00026 #include "CompositeLump.hpp" 00027 00028 #include "CompositeEngine.hpp" 00029 #include "CompSurfFacets.hpp" 00030 #include "GfxDebug.hpp" 00031 00032 /* 00033 #include "CpuTimer.hpp" 00034 static double trimmed_time = 0.0; 00035 static double contain_time = 0.0; 00036 static double closest_time = 0.0; 00037 static int total_calls = 0; 00038 static int contain_trim_count = 0; 00039 static int error_count = 0; 00040 static CpuTimer timer; 00041 */ 00042 00043 CompositeSurface::CompositeSurface( Surface* surface ) 00044 : HadBridgeRemoved(0), stitchPartner(0), firstCoSurf(0), firstLoop(0), hiddenSet(0), facetTool(0) 00045 { 00046 assert( surface != NULL ); 00047 compGeom = new CompositeGeom(1); 00048 compGeom->append( surface, CUBIT_FORWARD ); 00049 if( surface->owner() ) 00050 surface->owner()->swap_bridge( surface, this, false ); 00051 surface->owner(this); 00052 } 00053 00054 CompositeSurface::CompositeSurface( CompositeGeom* geometry ) 00055 : HadBridgeRemoved(0), 00056 compGeom(geometry), 00057 stitchPartner(0), 00058 firstCoSurf(0), 00059 firstLoop(0), 00060 hiddenSet(0), 00061 facetTool(0) 00062 { 00063 assert( geometry != NULL ); 00064 for( int i = 0; i < compGeom->num_entities(); i++ ) 00065 { 00066 GeometryEntity* entity = compGeom->entity(i); 00067 assert( !entity->owner() ); 00068 entity->owner(this); 00069 } 00070 } 00071 00072 00073 00074 //------------------------------------------------------------------------- 00075 // Purpose : Desctructor 00076 // 00077 // Special Notes : 00078 // 00079 // Creator : Jason Kraftcheck 00080 // 00081 // Creation Date : 00082 //------------------------------------------------------------------------- 00083 CompositeSurface::~CompositeSurface() 00084 { 00085 while( firstCoSurf ) 00086 { 00087 CompositeCoSurf* cosurf = firstCoSurf; 00088 remove( cosurf ); 00089 if( cosurf->get_shell() ) 00090 cosurf->get_shell()->remove( cosurf ); 00091 delete cosurf; 00092 } 00093 00094 while( firstLoop ) 00095 remove( firstLoop ); 00096 00097 for( int j = 0; j < num_surfs(); j++ ) 00098 if( get_surface(j)->owner() == this ) 00099 get_surface(j)->owner(0); 00100 00101 if( stitchPartner ) 00102 { 00103 stitchPartner->stitchPartner = 0; 00104 stitchPartner = 0; 00105 } 00106 00107 delete hiddenSet; 00108 delete compGeom; 00109 delete facetTool; 00110 hiddenSet = (HiddenEntitySet*)0xbdbdbdbd; 00111 compGeom = (CompositeGeom*)0xbdbdbdbd; 00112 } 00113 00114 //------------------------------------------------------------------------- 00115 // Purpose : Add a CompositeLoop to child list 00116 // 00117 // Special Notes : 00118 // 00119 // Creator : Jason Kraftcheck 00120 // 00121 // Creation Date : 03/06/02 00122 //------------------------------------------------------------------------- 00123 CubitStatus CompositeSurface::add( CompositeLoop* loop ) 00124 { 00125 if( loop->mySurface ) 00126 { 00127 assert(0); 00128 return CUBIT_FAILURE; 00129 } 00130 00131 loop->mySurface = this; 00132 loop->loopNext = firstLoop; 00133 firstLoop = loop; 00134 00135 return CUBIT_SUCCESS; 00136 } 00137 00138 //------------------------------------------------------------------------- 00139 // Purpose : Remove a child loop 00140 // 00141 // Special Notes : 00142 // 00143 // Creator : Jason Kraftcheck 00144 // 00145 // Creation Date : 03/06/02 00146 //------------------------------------------------------------------------- 00147 CubitStatus CompositeSurface::remove( CompositeLoop* loop ) 00148 { 00149 if( loop->mySurface != this ) 00150 return CUBIT_FAILURE; 00151 00152 if( firstLoop == loop ) 00153 { 00154 firstLoop = loop->loopNext; 00155 } 00156 else 00157 { 00158 CompositeLoop *prev = firstLoop, 00159 *next = firstLoop->loopNext; 00160 00161 while( next != loop ) 00162 { 00163 assert( next != NULL ); 00164 prev = next; 00165 next = next->loopNext; 00166 } 00167 00168 prev->loopNext = next->loopNext; 00169 } 00170 00171 loop->loopNext = 0; 00172 loop->mySurface = 0; 00173 return CUBIT_SUCCESS; 00174 } 00175 00176 //------------------------------------------------------------------------- 00177 // Purpose : Add a CoSurface to this Surface 00178 // 00179 // Special Notes : 00180 // 00181 // Creator : Jason Kraftcheck 00182 // 00183 // Creation Date : 08/07/02 00184 //------------------------------------------------------------------------- 00185 CubitStatus CompositeSurface::add( CompositeCoSurf* cosurf ) 00186 { 00187 if( cosurf->mySurface ) 00188 return CUBIT_FAILURE; 00189 00190 cosurf->mySurface = this; 00191 cosurf->surfaceNext = firstCoSurf; 00192 firstCoSurf = cosurf; 00193 return CUBIT_SUCCESS; 00194 } 00195 00196 //------------------------------------------------------------------------- 00197 // Purpose : Remove a CoSurface 00198 // 00199 // Special Notes : 00200 // 00201 // Creator : Jason Kraftcheck 00202 // 00203 // Creation Date : 08/07/02 00204 //------------------------------------------------------------------------- 00205 CubitStatus CompositeSurface::remove( CompositeCoSurf* cosurf ) 00206 { 00207 if( cosurf->mySurface != this ) 00208 return CUBIT_FAILURE; 00209 00210 if( cosurf == firstCoSurf ) 00211 firstCoSurf = cosurf->surfaceNext; 00212 else 00213 { 00214 CompositeCoSurf* prev = firstCoSurf; 00215 while( prev && prev->surfaceNext != cosurf ) 00216 prev = prev->surfaceNext; 00217 assert( prev != NULL ); 00218 prev->surfaceNext = cosurf->surfaceNext; 00219 } 00220 00221 cosurf->mySurface = 0; 00222 cosurf->surfaceNext = 0; 00223 return CUBIT_SUCCESS; 00224 } 00225 00226 //------------------------------------------------------------------------- 00227 // Purpose : Get a CoSurface attaching this surface to the passed 00228 // Shell or Lump 00229 // 00230 // Special Notes : 00231 // 00232 // Creator : Jason Kraftcheck 00233 // 00234 // Creation Date : 08/07/02 00235 //------------------------------------------------------------------------- 00236 CompositeCoSurf* CompositeSurface::find_first( CompositeShell* shell ) const 00237 { 00238 CompositeCoSurf* cos = firstCoSurf; 00239 while( cos && cos->get_shell() != shell ) 00240 cos = cos->next_in_surface(); 00241 return cos; 00242 } 00243 CompositeCoSurf* CompositeSurface::find_first( CompositeLump* lump ) const 00244 { 00245 CompositeCoSurf* cos = firstCoSurf; 00246 while( cos && (!cos->get_shell() || cos->get_shell()->get_lump() != lump ) ) 00247 cos = cos->next_in_surface(); 00248 return cos; 00249 } 00250 CompositeCoSurf* CompositeSurface::find_next( CompositeCoSurf* cosurf ) const 00251 { 00252 CompositeCoSurf* cos = cosurf; 00253 while( cos && cos->get_shell() != cosurf->get_shell() ) 00254 cos = cos->next_in_surface(); 00255 return cos; 00256 } 00257 00258 00259 //------------------------------------------------------------------------- 00260 // Purpose : Split this CompositeSurface into two. 00261 // 00262 // Special Notes : 00263 // 00264 // Creator : Jason Kraftcheck 00265 // 00266 // Creation Date : 03/06/02 00267 //------------------------------------------------------------------------- 00268 CompositeSurface* CompositeSurface::split( VGArray<int>& indices_to_move ) 00269 { 00270 int i; 00271 00272 for( i = 0; i < indices_to_move.size(); i++ ) 00273 if( indices_to_move[i] < 0 || indices_to_move[i] >= num_surfs() ) 00274 return 0; 00275 00276 CompositeGeom* new_geom = compGeom->split( indices_to_move ); 00277 if( !new_geom ) 00278 return 0; 00279 00280 for( i = 0; i < new_geom->num_entities(); i++ ) 00281 new_geom->entity(i)->owner( 0 ); 00282 00283 delete facetTool; 00284 facetTool = 0; 00285 00286 return new CompositeSurface( new_geom ); 00287 } 00288 00289 00290 //------------------------------------------------------------------------- 00291 // Purpose : Combine composite surfaces 00292 // 00293 // Special Notes : 00294 // 00295 // Creator : Jason Kraftcheck 00296 // 00297 // Creation Date : 03/06/02 00298 //------------------------------------------------------------------------- 00299 CubitStatus CompositeSurface::combine( CompositeSurface* dead_surf ) 00300 { 00301 int old_size = compGeom->num_entities(); 00302 00303 // Merge the "surfaces_to_ignore" list. 00304 surfacesToIgnore.merge_unique(dead_surf->surfacesToIgnore); 00305 00306 compGeom->merge( *(dead_surf->compGeom) ); 00307 if( dead_surf->hiddenSet != 0 ) 00308 hidden_entities().merge( dead_surf->hiddenSet ); 00309 for( int i = old_size; i < compGeom->num_entities(); i++ ) 00310 { 00311 TopologyBridge* bridge = compGeom->entity(i); 00312 assert( bridge->owner() == dead_surf ); 00313 bridge->owner( this ); 00314 } 00315 00316 delete facetTool; 00317 facetTool = 0; 00318 00319 return CUBIT_SUCCESS; 00320 } 00321 00322 void CompositeSurface::get_ignored_surfs(DLIList<Surface*> &surfs) 00323 { 00324 int i; 00325 00326 if(surfacesToIgnore.size() > 0) 00327 { 00328 for(i=0; i<num_surfs(); i++) 00329 { 00330 Surface *srf = get_surface(i); 00331 if(surfacesToIgnore.is_in_list(srf)) 00332 surfs.append(srf); 00333 } 00334 } 00335 } 00336 00337 //------------------------------------------------------------------------- 00338 // Purpose : Return the bounding box 00339 // 00340 // Special Notes : 00341 // 00342 // Creator : Jason Kraftcheck 00343 // 00344 // Creation Date : 05/28/99 00345 //------------------------------------------------------------------------- 00346 CubitBox CompositeSurface::bounding_box() const 00347 { 00348 return compGeom->bounding_box(); 00349 } 00350 00351 //------------------------------------------------------------------------- 00352 // Purpose : TB Queries 00353 // 00354 // Special Notes : 00355 // 00356 // Creator : Jason Kraftcheck 00357 // 00358 // Creation Date : 03/06/02 00359 //------------------------------------------------------------------------- 00360 void CompositeSurface::get_parents_virt( DLIList<TopologyBridge*>& list ) 00361 { 00362 DLIList<TopologyBridge*> parents, parents2; 00363 for( int i = 0; i < num_surfs(); i++ ) 00364 { 00365 parents.clean_out(); 00366 get_surface(i)->get_parents( parents ); 00367 parents.reset(); 00368 for ( int j = parents.size(); j--; ) 00369 { 00370 TopologyBridge* shell = parents.get_and_step(); 00371 shell->get_parents( parents2 ); 00372 assert (parents2.size() == 1); 00373 if (0 == dynamic_cast<CompositeLump*>(parents2.pop()->owner())) 00374 list.append_unique( shell ); 00375 } 00376 } 00377 00378 CompositeCoSurf* cosurf = 0; 00379 while ((cosurf = next_co_surface( cosurf ))) 00380 list.append_unique( cosurf->get_shell() ); 00381 } 00382 void CompositeSurface::get_children_virt( DLIList<TopologyBridge*>& list ) 00383 { 00384 for( CompositeLoop* loop = firstLoop; loop; loop = loop->loopNext ) 00385 list.append( loop ); 00386 } 00387 00388 00389 //------------------------------------------------------------------------- 00390 // Purpose : Attach a CubitSimpleAttribute 00391 // 00392 // Special Notes : 00393 // 00394 // Creator : Jason Kraftcheck 00395 // 00396 // Creation Date : 03/10/98 00397 //------------------------------------------------------------------------- 00398 void CompositeSurface::append_simple_attribute_virt( 00399 const CubitSimpleAttrib& simple_attrib_ptr ) 00400 { 00401 if(compGeom) 00402 compGeom->add_attribute( simple_attrib_ptr ); 00403 } 00404 00405 //------------------------------------------------------------------------- 00406 // Purpose : Remove an attached CubitSimpleAttrib 00407 // 00408 // Special Notes : 00409 // 00410 // Creator : Jason Kraftcheck 00411 // 00412 // Creation Date : 03/10/98 00413 //------------------------------------------------------------------------- 00414 void CompositeSurface::remove_simple_attribute_virt( 00415 const CubitSimpleAttrib& simple_attrib_ptr ) 00416 { 00417 if(compGeom) 00418 compGeom->rem_attribute( simple_attrib_ptr ); 00419 } 00420 00421 00422 //------------------------------------------------------------------------- 00423 // Purpose : Remove an all attached CubitSimpleAttrib 00424 // 00425 // Special Notes : 00426 // 00427 // Creator : Greg Nielson 00428 // 00429 // Creation Date : 07/10/98 00430 //------------------------------------------------------------------------- 00431 void CompositeSurface::remove_all_simple_attribute_virt() 00432 { 00433 if(compGeom) 00434 compGeom->rem_all_attributes( ); 00435 } 00436 00437 00438 //------------------------------------------------------------------------- 00439 // Purpose : Return the attached CubitSimpleAttribs. 00440 // 00441 // Special Notes : 00442 // 00443 // Creator : Jason Kraftcheck 00444 // 00445 // Creation Date : 03/10/98 00446 //------------------------------------------------------------------------- 00447 CubitStatus CompositeSurface::get_simple_attribute( 00448 DLIList<CubitSimpleAttrib>& attrib_list ) 00449 { 00450 if(!compGeom) 00451 return CUBIT_FAILURE; 00452 compGeom->get_attributes( attrib_list ); 00453 return CUBIT_SUCCESS; 00454 } 00455 CubitStatus CompositeSurface::get_simple_attribute( 00456 const CubitString& name, DLIList<CubitSimpleAttrib>& attrib_list ) 00457 { 00458 if(!compGeom) 00459 return CUBIT_FAILURE; 00460 compGeom->get_attributes( name.c_str(), attrib_list ); 00461 return CUBIT_SUCCESS; 00462 } 00463 00464 00465 //------------------------------------------------------------------------- 00466 // Purpose : Methods from TBOwner 00467 // 00468 // Special Notes : 00469 // 00470 // Creator : Jason Kraftcheck 00471 // 00472 // Creation Date : 03/07/02 00473 //------------------------------------------------------------------------- 00474 CubitStatus CompositeSurface::remove_bridge( TopologyBridge* bridge ) 00475 { 00476 if(!compGeom) 00477 return CUBIT_FAILURE; 00478 00479 int i = compGeom->index_of(bridge); 00480 if( i < 0 ) 00481 return CUBIT_FAILURE; 00482 00483 delete facetTool; 00484 facetTool = 0; 00485 00486 assert( bridge->owner() == this ); 00487 bridge->owner(0); 00488 if (!compGeom->remove(i, true)) 00489 return CUBIT_FAILURE; 00490 00491 if (compGeom->num_entities() == 0) 00492 CompositeEngine::instance().notify_deactivated(this); 00493 HadBridgeRemoved = 1; 00494 return CUBIT_SUCCESS; 00495 } 00496 00497 Surface* CompositeSurface::remove_surface( int index ) 00498 { 00499 Surface* result = get_surface(index); 00500 if ( !result || !compGeom->remove(index,false) ) 00501 return 0; 00502 00503 result->owner(0); 00504 return result; 00505 } 00506 00507 00508 00509 CubitStatus CompositeSurface::swap_bridge( TopologyBridge* o, 00510 TopologyBridge* n, 00511 bool reversed ) 00512 { 00513 if( n->owner() ) 00514 return CUBIT_FAILURE; 00515 00516 int i = compGeom->index_of(o); 00517 GeometryEntity* ge = dynamic_cast<GeometryEntity*>(n); 00518 if( i >= 0 && ge != 0 ) 00519 { 00520 o->owner(0); 00521 n->owner(this); 00522 if ( !compGeom->swap( i, ge ) ) 00523 return CUBIT_FAILURE; 00524 00525 if (reversed) 00526 compGeom->reverse_sense(i); 00527 return CUBIT_SUCCESS; 00528 } 00529 else 00530 return CUBIT_FAILURE; 00531 } 00532 CubitBoolean CompositeSurface::contains_bridge( TopologyBridge* bridge ) const 00533 { 00534 return (CubitBoolean)(compGeom->index_of(bridge) >= 0); 00535 } 00536 00537 00538 00539 00540 00541 //------------------------------------------------------------------------- 00542 // Purpose : Return a pointer to VirtualQueryEngine 00543 // 00544 // Special Notes : 00545 // 00546 // Creator : Jason Kraftcheck 00547 // 00548 // Creation Date : 03/10/98 00549 //------------------------------------------------------------------------- 00550 GeometryQueryEngine* CompositeSurface::get_geometry_query_engine() const 00551 { 00552 return VirtualQueryEngine::instance(); 00553 } 00554 00555 00556 //------------------------------------------------------------------------- 00557 // Purpose : Return the surface area. 00558 // 00559 // Special Notes : 00560 // 00561 // Creator : Jason Kraftcheck 00562 // 00563 // Creation Date : 03/10/98 00564 //------------------------------------------------------------------------- 00565 double CompositeSurface::measure() 00566 { 00567 return compGeom->measure(); 00568 } 00569 00570 00571 //------------------------------------------------------------------------- 00572 // Purpose : Find the closest point to the passed point. 00573 // 00574 // Special Notes : 00575 // 00576 // Creator : Jason Kraftcheck 00577 // 00578 // Creation Date : 03/10/98 00579 //------------------------------------------------------------------------- 00580 void CompositeSurface::closest_point_trimmed( CubitVector from_point, 00581 CubitVector& point_on_surf ) 00582 { 00583 int index = closest_underlying_surface( from_point ); 00584 get_surface(index)->closest_point_trimmed( from_point, point_on_surf ); 00585 } 00586 00587 00588 00589 CubitStatus CompositeSurface::get_point_normal( CubitVector& origin, 00590 CubitVector& normal ) 00591 { 00592 int count = num_surfs(); 00593 CubitVector* vect_list = new CubitVector[count]; 00594 double RESABS_SQUARED = CUBIT_RESABS * CUBIT_RESABS; 00595 normal.set(0.0,0.0,0.0); 00596 00597 if (count == 1) 00598 { 00599 return get_surface(0)->get_point_normal(origin,normal); 00600 } 00601 00602 for( int i = 0; i < count; i++ ) 00603 { 00604 Surface* surf = get_surface(i); 00605 if( surf->get_point_normal(origin,vect_list[i]) == CUBIT_FAILURE ) 00606 { 00607 delete [] vect_list; 00608 return CUBIT_FAILURE; 00609 } 00610 00611 if( compGeom->sense(i) == CUBIT_REVERSED ) 00612 vect_list[i] *= -1.0; 00613 normal += vect_list[i]; 00614 } 00615 //If we reach this point, then all of the underlying surfaces are planar. 00616 //Next check if they are coplanar. 00617 if( normal.length_squared() < RESABS_SQUARED ) 00618 { 00619 delete [] vect_list; 00620 return CUBIT_FAILURE; 00621 } 00622 normal.normalize(); 00623 for( int j = 0; j < count; j++ ) 00624 { 00625 if( fabs( 1.0 - (normal % ~vect_list[j]) ) > CUBIT_RESABS ) 00626 { 00627 delete [] vect_list; 00628 return CUBIT_FAILURE; 00629 } 00630 } 00631 00632 delete [] vect_list; 00633 CubitVector zero( 0.0, 0.0, 0.0 ); 00634 closest_point( zero, &origin ); 00635 return CUBIT_SUCCESS; 00636 } 00637 00638 // The CompositeSurface class has a variable 00639 // "surfacesToIgnore" which specifies which surfaces 00640 // within the composite should be ignored during evaluation. 00641 // The "facetTool" variable has a corresponding list of flags 00642 // and this function syncs the flags in the "facetTool" variable 00643 // with those that are in the "surfacesToIgnore" variable. 00644 void CompositeSurface::update_facets_to_ignore() 00645 { 00646 if(facetTool) 00647 { 00648 int i; 00649 DLIList<int> surfaces_to_ignore; 00650 int num_surfs_in_composite = num_surfs(); 00651 for (i=0; i<num_surfs_in_composite; i++) 00652 { 00653 Surface *cur_surf = get_surface(i); 00654 surfacesToIgnore.reset(); 00655 for(int j=surfacesToIgnore.size(); j--;) 00656 { 00657 if(cur_surf == surfacesToIgnore.get_and_step()) 00658 { 00659 surfaces_to_ignore.append( i ); 00660 j=0; 00661 } 00662 } 00663 } 00664 00665 //do it all at once 00666 facetTool->set_ignore_flag( surfaces_to_ignore, 1 ); 00667 } 00668 } 00669 00670 00671 // This function tells the composite to ignore one of its 00672 // surfaces during evaluation. 00673 void CompositeSurface::ignore_surface(int surface_id) 00674 { 00675 update_facet_tool(); 00676 if(facetTool) 00677 { 00678 int i; 00679 int num_surfs_in_composite = num_surfs(); 00680 for (i=0; i<num_surfs_in_composite; i++) 00681 { 00682 Surface *cur_surf = get_surface(i); 00683 if(cur_surf->get_saved_id() == surface_id) 00684 { 00685 surfacesToIgnore.append_unique(cur_surf); 00686 i = num_surfs_in_composite; 00687 update_facets_to_ignore(); 00688 } 00689 } 00690 } 00691 } 00692 00693 void CompositeSurface::ignore_surface(Surface *surf) 00694 { 00695 update_facet_tool(); 00696 if(facetTool) 00697 { 00698 int i; 00699 int num_surfs_in_composite = num_surfs(); 00700 for (i=0; i<num_surfs_in_composite; i++) 00701 { 00702 Surface *cur_surf = get_surface(i); 00703 if(cur_surf == surf) 00704 { 00705 surfacesToIgnore.append_unique(cur_surf); 00706 i = num_surfs_in_composite; 00707 update_facets_to_ignore(); 00708 } 00709 } 00710 } 00711 } 00712 00713 // This function tells the composite to unset the ignore 00714 // flag for one of its surfaces. 00715 void CompositeSurface::unignore_surface(int surface_id) 00716 { 00717 update_facet_tool(); 00718 if(facetTool) 00719 { 00720 int i; 00721 int num_surfs_in_composite = num_surfs(); 00722 for (i=0; i<num_surfs_in_composite; i++) 00723 { 00724 Surface *cur_surf = get_surface(i); 00725 if(cur_surf->get_saved_id() == surface_id) 00726 { 00727 surfacesToIgnore.remove(cur_surf); 00728 update_facets_to_ignore(); 00729 i = num_surfs_in_composite; 00730 } 00731 } 00732 } 00733 } 00734 00735 void CompositeSurface::update_facet_tool() 00736 { 00737 if( ! facetTool ) 00738 { 00739 std::vector<Surface*> surf_vect(num_surfs()); 00740 for ( int i = 0; i < num_surfs(); i++ ) 00741 surf_vect[i] = get_surface(i); 00742 facetTool = new CompSurfFacets(); 00743 if ( ! facetTool->setup( surf_vect ) ) 00744 { 00745 delete facetTool; 00746 facetTool = 0; 00747 } 00748 else 00749 { 00750 // Make sure to update the facetTool to reflect 00751 // any surfaces we think we need to ignore. 00752 update_facets_to_ignore(); 00753 } 00754 } 00755 } 00756 00757 CubitStatus CompositeSurface::closest_point_uv_guess( 00758 CubitVector const& location, 00759 double &u, double &v, 00760 CubitVector* closest_location, 00761 CubitVector* unit_normal ) 00762 { 00763 if ( num_surfs() == 1) 00764 return get_surface(0)-> 00765 closest_point_uv_guess(location, u, v, closest_location, unit_normal); 00766 else 00767 return closest_point(location, closest_location, unit_normal); 00768 } 00769 00770 CubitStatus CompositeSurface::evaluate( double u, double v, 00771 CubitVector *position, 00772 CubitVector *normal, 00773 CubitVector *curvature1, 00774 CubitVector *curvature2 ) 00775 { 00776 if( position || normal || (curvature1 && curvature2) ) 00777 { 00778 if ( num_surfs() == 1) 00779 return get_surface(0)->evaluate(u, v, position, normal, curvature1, curvature2 ); 00780 else 00781 return CUBIT_FAILURE; 00782 } 00783 else 00784 return CUBIT_FAILURE; 00785 } 00786 00787 00788 00789 /* 00790 //------------------------------------------------------------------------- 00791 // Purpose : Find the closest point to the passed point, on the surface. 00792 // 00793 // Special Notes : 00794 // 00795 // Creator : Jason Kraftcheck 00796 // 00797 // Creation Date : 03/10/98 00798 //------------------------------------------------------------------------- 00799 CubitStatus CompositeSurface::closest_point( 00800 CubitVector const& location, 00801 CubitVector* closest_location, 00802 CubitVector* unit_normal, 00803 CubitVector* curvature1, 00804 CubitVector* curvature2 ) 00805 { 00806 if ( num_surfs() == 1 ) 00807 return get_surface(0)->closest_point( location, 00808 closest_location, unit_normal, curvature1, curvature2 ); 00809 00810 update_facet_tool(); 00811 if ( facetTool ) 00812 { 00813 CubitVector facet_closest, surf_closest; 00814 int index = facetTool->closest_index( location, &facet_closest ); 00815 CubitStatus result = get_surface(index)->closest_point( location, 00816 &surf_closest, unit_normal, curvature1, curvature2 ); 00817 00818 if (!result) 00819 return result; 00820 00821 CubitVector facet_delta = facet_closest - location; 00822 CubitVector surf_delta = surf_closest - location; 00823 double facet_len = facet_delta.length(); 00824 double surf_len = surf_delta.length(); 00825 00826 if ( facet_len > CUBIT_RESABS && surf_len > CUBIT_RESABS ) 00827 { 00828 facet_delta /= facet_len; 00829 surf_delta /= surf_len; 00830 const double cos_angle = facet_delta % surf_delta; 00831 if (0.985 < cos_angle) // angle greater than about 10 degrees 00832 { 00833 result = get_surface(index)->closest_point( facet_closest, 00834 &surf_closest, unit_normal, curvature1, curvature2 ); 00835 00836 if (!result) 00837 return result; 00838 } 00839 } 00840 00841 if (closest_location) 00842 *closest_location = surf_closest; 00843 00844 if (unit_normal && sense(index) == CUBIT_REVERSED) 00845 *unit_normal = -*unit_normal; 00846 00847 return result; 00848 } 00849 00850 00851 double shortest_dist_sqr, current_dist_sqr; 00852 CubitVector closest_point, current_point; 00853 int closest_surf, current_surf; 00854 00855 //initialize CompositeEntity data structures 00856 closest_surf = compGeom->closest_box( location ); 00857 00858 closest_trimmed( closest_surf, location, closest_point ); 00859 shortest_dist_sqr = (location - closest_point).length_squared(); 00860 00861 while( (current_surf = compGeom->next_box_within_dist( shortest_dist_sqr ) ) >= 0 ) 00862 { 00863 closest_trimmed( current_surf, location, current_point ); 00864 current_dist_sqr = (location - current_point).length_squared(); 00865 00866 if( current_dist_sqr < shortest_dist_sqr ) 00867 { 00868 closest_surf = current_surf; 00869 closest_point = current_point; 00870 shortest_dist_sqr = current_dist_sqr; 00871 } 00872 } 00873 00874 if( closest_location ) *closest_location = closest_point; 00875 if( unit_normal || curvature1 || curvature2 ) 00876 { 00877 get_surface( closest_surf )->closest_point( closest_point, NULL, 00878 unit_normal, curvature1, curvature2 ); 00879 if( unit_normal && compGeom->sense(closest_surf) == CUBIT_REVERSED ) 00880 *unit_normal *= -1; 00881 } 00882 00883 return CUBIT_SUCCESS; 00884 } 00885 */ 00886 //------------------------------------------------------------------------- 00887 // Purpose : Find the closest point to the passed point, on the surface. 00888 // 00889 // Special Notes : 00890 // 00891 // Creator : Jason Kraftcheck 00892 // 00893 // Creation Date : 03/10/98 00894 //------------------------------------------------------------------------- 00895 CubitStatus CompositeSurface::closest_point( CubitVector const& location, 00896 CubitVector* closest_location, 00897 CubitVector* unit_normal, 00898 CubitVector* curvature1, 00899 CubitVector* curvature2 ) 00900 { 00901 if ( num_surfs() == 1 ) 00902 return get_surface(0)->closest_point( location, closest_location, 00903 unit_normal, 00904 curvature1, curvature2 ); 00905 00906 update_facet_tool(); 00907 00908 if ( facetTool ) 00909 { 00910 CubitStatus result = CUBIT_SUCCESS; 00911 CubitVector facet_closest; 00912 00913 // look for multiple surfaces if normal is requested 00914 if (unit_normal) 00915 { 00916 DLIList<int> index_list; 00917 int num_found = facetTool->closest_index( location, index_list, 00918 &facet_closest ); 00919 00920 CubitVector normal(0.0, 0.0, 0.0); 00921 int i; 00922 for (i = 0; i < num_found; i++) 00923 { 00924 int index = index_list[i]; 00925 if(index > -1) 00926 { 00927 Surface* surf = get_surface(index); 00928 00929 result = surf->closest_point( facet_closest, closest_location, 00930 &normal, curvature1, curvature2 ); 00931 00932 if (get_sense(index) == CUBIT_REVERSED) 00933 *unit_normal += (-normal); 00934 else 00935 *unit_normal += normal; 00936 } 00937 } 00938 unit_normal->normalize(); 00939 } 00940 else 00941 { 00942 int index = facetTool->closest_index( location, &facet_closest ); 00943 if(index > -1) 00944 { 00945 Surface* surf = get_surface(index); 00946 00947 result = surf->closest_point( location, closest_location, 00948 unit_normal, curvature1, curvature2 ); 00949 00950 // if (unit_normal && get_sense(index) == CUBIT_REVERSED) 00951 // *unit_normal = -*unit_normal; 00952 } 00953 else 00954 result = CUBIT_FAILURE; 00955 } 00956 00957 return result; 00958 00959 // this code is never accessed 00960 Surface* surf = NULL; 00961 int index = -1; 00962 double u, v; 00963 result = surf->u_v_from_position( facet_closest, u, v ); 00964 if (!result) return CUBIT_FAILURE; 00965 00966 CubitVector surf_closest; 00967 result = surf->closest_point_uv_guess( location, u, v, &surf_closest, 00968 unit_normal ); 00969 if (!result) return CUBIT_FAILURE; 00970 00971 if (unit_normal && get_sense(index) == CUBIT_REVERSED) 00972 *unit_normal = -*unit_normal; 00973 00974 if (curvature1 || curvature2) 00975 { 00976 result = surf->closest_point( surf_closest, 0, 0, 00977 curvature1, curvature2 ); 00978 if (!result) return CUBIT_FAILURE; 00979 } 00980 00981 if(closest_location) 00982 *closest_location = surf_closest; 00983 00984 return CUBIT_SUCCESS; 00985 } 00986 00987 double shortest_dist_sqr, current_dist_sqr; 00988 CubitVector closest_point, current_point; 00989 int closest_surf, current_surf; 00990 00991 //initialize CompositeEntity data structures 00992 closest_surf = compGeom->closest_box( location ); 00993 00994 closest_trimmed( closest_surf, location, closest_point ); 00995 shortest_dist_sqr = (location - closest_point).length_squared(); 00996 00997 while( (current_surf = compGeom->next_box_within_dist( shortest_dist_sqr ) ) >= 0 ) 00998 { 00999 closest_trimmed( current_surf, location, current_point ); 01000 current_dist_sqr = (location - current_point).length_squared(); 01001 01002 if( current_dist_sqr < shortest_dist_sqr ) 01003 { 01004 closest_surf = current_surf; 01005 closest_point = current_point; 01006 shortest_dist_sqr = current_dist_sqr; 01007 } 01008 } 01009 01010 if( closest_location ) *closest_location = closest_point; 01011 if( unit_normal || curvature1 || curvature2 ) 01012 { 01013 get_surface( closest_surf )->closest_point( closest_point, NULL, 01014 unit_normal, curvature1, curvature2 ); 01015 if( unit_normal && compGeom->sense(closest_surf) == CUBIT_REVERSED ) 01016 *unit_normal *= -1; 01017 } 01018 01019 return CUBIT_SUCCESS; 01020 } 01021 01022 //------------------------------------------------------------------------- 01023 // Purpose : Find closest underlying surface 01024 // 01025 // Special Notes : 01026 // 01027 // Creator : Jason Kraftcheck 01028 // 01029 // Creation Date : 02/18/03 01030 //------------------------------------------------------------------------- 01031 int CompositeSurface::closest_underlying_surface( const CubitVector& pos ) 01032 { 01033 if( num_surfs() == 1 ) 01034 return 0; 01035 01036 update_facet_tool(); 01037 if( facetTool ) 01038 return facetTool->closest_index( pos ); 01039 01040 double shortest_dist_sqr, current_dist_sqr; 01041 CubitVector closest_point; 01042 int closest_surf, current_surf; 01043 01044 //initialize CompositeEntity data structures 01045 closest_surf = compGeom->closest_box( pos ); 01046 01047 closest_trimmed( closest_surf, pos, closest_point ); 01048 shortest_dist_sqr = (pos - closest_point).length_squared(); 01049 01050 while( (current_surf = compGeom->next_box_within_dist( shortest_dist_sqr ) ) >= 0 ) 01051 { 01052 closest_trimmed( current_surf, pos, closest_point ); 01053 current_dist_sqr = (pos - closest_point).length_squared(); 01054 01055 if( current_dist_sqr < shortest_dist_sqr ) 01056 { 01057 closest_surf = current_surf; 01058 shortest_dist_sqr = current_dist_sqr; 01059 } 01060 } 01061 01062 return closest_surf; 01063 } 01064 01065 //------------------------------------------------------------------------- 01066 // Purpose : Evaluate closest_point_trimmed un an underliying surface 01067 // 01068 // Special Notes : honors use_gme_cpt, and updates stats 01069 // 01070 // Creator : Jason Kraftcheck 01071 // 01072 // Creation Date : 11/10/99 01073 //------------------------------------------------------------------------- 01074 void CompositeSurface::print_cpt_stats() 01075 { 01076 /* 01077 PRINT_INFO("Total Calls %10d\n", total_calls); 01078 PRINT_INFO("ClosestTrimmed %10.0f %10.5f\n", trimmed_time, trimmed_time / total_calls ); 01079 PRINT_INFO("Closest %10.0f %10.5f\n", closest_time, closest_time / total_calls ); 01080 PRINT_INFO("Containment %10.0f %10.5f\n", contain_time, contain_time / total_calls ); 01081 double average_outside = (double)contain_trim_count / total_calls; 01082 PRINT_INFO("Outside Count %10d %10.5f\n", contain_trim_count, average_outside ); 01083 double containment = contain_time + 01084 average_outside * trimmed_time + 01085 (1.0-average_outside) * closest_time; 01086 PRINT_INFO("Contain Est. %10.0f %10.5f\n", containment, containment / total_calls ); 01087 PRINT_INFO("Error Count %10d %10.5f\n", error_count, (double)error_count / total_calls ); 01088 */ 01089 } 01090 void CompositeSurface::reset_cpt_stats() 01091 { 01092 /* 01093 trimmed_time = contain_time = closest_time = 0.0; 01094 total_calls = contain_trim_count = error_count = 0; 01095 */ 01096 } 01097 CubitStatus CompositeSurface::closest_trimmed( int index, 01098 const CubitVector& position, 01099 CubitVector& result ) 01100 { 01101 get_surface(index)->closest_point_trimmed( position, result ); 01102 return CUBIT_SUCCESS; 01103 /* 01104 total_calls++; 01105 CubitVector close, copy(position); 01106 Surface* surf = get_surface(index); 01107 01108 timer.cpu_secs(); 01109 surf->closest_point_trimmed( position, result ); 01110 trimmed_time += timer.cpu_secs(); 01111 01112 surf->closest_point( position, &close ); 01113 closest_time += timer.cpu_secs(); 01114 01115 CubitPointContainment contain = surf->point_containment( copy ); 01116 contain_time += timer.cpu_secs(); 01117 01118 if ( contain == CUBIT_PNT_OUTSIDE ) 01119 contain_trim_count++; 01120 else if( (result - close).length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS) 01121 error_count++; 01122 01123 return CUBIT_SUCCESS; 01124 */ 01125 // if( use_gme_cpt ) 01126 // { 01127 // get_surface( index )->closest_point_trimmed( position, result ); 01128 // return CUBIT_SUCCESS; 01129 // } 01130 /* 01131 DLIList<TopologyBridge*> bridge_list; 01132 Surface* surf_ptr = get_surface(index); 01133 CubitVector surf_pt, normal, curve_pt; 01134 if( !surf_ptr->closest_point( position, &surf_pt, &normal ) ) 01135 return CUBIT_FAILURE; 01136 01137 CoEdgeSM *closest_coedge, *other_coedge = 0; 01138 cptInfo.setup(surf_ptr); 01139 cptInfo.closest_coedge( position, closest_coedge, other_coedge, curve_pt ); 01140 if ( !closest_coedge ) 01141 return CUBIT_FAILURE; 01142 01143 CubitVector coe_normal, cross, tangent1, tangent2, junk; 01144 bool inside; 01145 01146 01147 if ( !other_coedge ) 01148 { 01149 bridge_list.clean_out(); 01150 closest_coedge->get_children_virt( bridge_list ); 01151 Curve* curve_ptr = dynamic_cast<Curve*>(bridge_list.get()); 01152 assert( !!curve_ptr ); 01153 double u = curve_ptr->u_from_position( curve_pt ); 01154 01155 if( !curve_ptr->G1_discontinuous( u, &tangent1, &tangent2 ) ) 01156 { 01157 curve_ptr->closest_point( curve_pt, junk, &tangent1 ); 01158 bool inside = is_inside( tangent1, curve_pt, surf_pt, normal ); 01159 result = inside ? surf_pt : curve_pt; 01160 return CUBIT_SUCCESS; 01161 } 01162 01163 if( closest_coedge->sense() == CUBIT_REVERSED ) 01164 { 01165 tangent1 = -tangent1; 01166 tangent2 = -tangent2; 01167 } 01168 } 01169 else 01170 { 01171 bridge_list.clean_out(); 01172 closest_coedge->get_children_virt( bridge_list ); 01173 Curve* curve1 = dynamic_cast<Curve*>(bridge_list.get()); 01174 bridge_list.clean_out(); 01175 other_coedge->get_children_virt( bridge_list ); 01176 Curve* curve2 = dynamic_cast<Curve*>(bridge_list.get()); 01177 assert(curve1 && curve2); 01178 01179 curve1->closest_point( curve_pt, junk, &tangent1 ); 01180 curve2->closest_point( curve_pt, junk, &tangent2 ); 01181 if( closest_coedge->sense() == CUBIT_REVERSED ) tangent1 = -tangent1; 01182 if( other_coedge->sense() == CUBIT_REVERSED ) tangent2 = -tangent2; 01183 } 01184 01185 surf_ptr->closest_point( curve_pt, 0, &coe_normal ); 01186 cross = tangent1 * tangent2; 01187 bool inside1 = is_inside( tangent1, curve_pt, surf_pt, normal ); 01188 bool inside2 = is_inside( tangent2, curve_pt, surf_pt, normal ); 01189 01190 if ( (cross % coe_normal) > 0.0 ) 01191 inside = inside1 && inside2; 01192 else 01193 inside = inside1 || inside2; 01194 01195 result = inside ? surf_pt : curve_pt; 01196 return CUBIT_SUCCESS; 01197 */ 01198 } 01199 /* 01200 bool CompositeSurface::is_inside( const CubitVector& tangent, 01201 const CubitVector& curve_pt, 01202 const CubitVector& surf_pt, 01203 const CubitVector& normal ) 01204 { 01205 CubitVector cross = tangent * ( surf_pt - curve_pt ); 01206 return cross % normal >= 0.0; 01207 } 01208 */ 01209 01210 01211 //------------------------------------------------------------------------- 01212 // Purpose : Get the magnitudes of the principal curvatures. 01213 // 01214 // Special Notes : 01215 // 01216 // Creator : Jason Kraftcheck 01217 // 01218 // Creation Date : 03/10/98 01219 //------------------------------------------------------------------------- 01220 CubitStatus CompositeSurface::principal_curvatures( 01221 CubitVector const& location, 01222 double& curvature_1, 01223 double& curvature_2, 01224 CubitVector* closest_location ) 01225 { 01226 if (num_surfs() == 1) 01227 return get_surface(0)-> 01228 principal_curvatures(location, curvature_1, curvature_2, closest_location); 01229 01230 CubitVector curvature1, curvature2; 01231 CubitStatus s = closest_point( location, closest_location, NULL, 01232 &curvature1, &curvature2 ); 01233 if( s == CUBIT_FAILURE ) return CUBIT_FAILURE; 01234 01235 curvature_1 = curvature1.length(); 01236 curvature_2 = curvature2.length(); 01237 return CUBIT_SUCCESS; 01238 } 01239 01240 01241 //------------------------------------------------------------------------- 01242 // Purpose : Evaluate the parameter values to get a position on the 01243 // surface. 01244 // 01245 // Special Notes : 01246 // 01247 // Creator : Jason Kraftcheck 01248 // 01249 // Creation Date : 03/10/98 01250 //------------------------------------------------------------------------- 01251 CubitVector CompositeSurface::position_from_u_v( double u, double v ) 01252 { 01253 if (num_surfs() == 1) 01254 return get_surface(0)->position_from_u_v(u,v); 01255 01256 PRINT_ERROR("CompositeSurface::position_from_u_v for non-paramtric surface.\n"); 01257 CubitVector nulvect( 0., 0., 0.); 01258 return nulvect; 01259 } 01260 01261 01262 //------------------------------------------------------------------------- 01263 // Purpose : Determine values of u and v which evaluate to the passed 01264 // position on the surface. 01265 // 01266 // Special Notes : 01267 // 01268 // Creator : Jason Kraftcheck 01269 // 01270 // Creation Date : 03/10/98 01271 //------------------------------------------------------------------------- 01272 CubitStatus CompositeSurface::u_v_from_position( 01273 CubitVector const& pos , 01274 double& u, 01275 double& v, 01276 CubitVector* closest ) 01277 { 01278 if (num_surfs() == 1) 01279 return get_surface(0)->u_v_from_position(pos, u, v, closest); 01280 01281 PRINT_ERROR("CompositeSurface::u_v_from_position for non-paramtric surface.\n"); 01282 u = v = 0.0; 01283 return CUBIT_FAILURE; 01284 } 01285 01286 01287 //------------------------------------------------------------------------- 01288 // Purpose : Is the prameterization of the surface periodic in nature? 01289 // 01290 // Special Notes : Always false, because the surface is not parametric. 01291 // 01292 // Creator : Jason Kraftcheck 01293 // 01294 // Creation Date : 03/10/98 01295 //------------------------------------------------------------------------- 01296 CubitBoolean CompositeSurface::is_periodic() 01297 { 01298 if (num_surfs() == 1) 01299 return get_surface(0)->is_periodic(); 01300 01301 return CUBIT_FALSE; 01302 } 01303 01304 //------------------------------------------------------------------------- 01305 // Purpose : Is the prameterization of the surface periodic in nature? 01306 // 01307 // Special Notes : Always false, because the surface is not parametric. 01308 // 01309 // Creator : Jason Kraftcheck 01310 // 01311 // Creation Date : 03/10/98 01312 //------------------------------------------------------------------------- 01313 CubitBoolean CompositeSurface::is_periodic_in_U( double& period ) 01314 { 01315 if (num_surfs() == 1) 01316 return get_surface(0)->is_periodic_in_U(period); 01317 01318 period = 0.0; 01319 return CUBIT_FALSE; 01320 } 01321 CubitBoolean CompositeSurface::is_periodic_in_V( double& period ) 01322 { 01323 if (num_surfs() == 1) 01324 return get_surface(0)->is_periodic_in_V(period); 01325 01326 period = 0.0; 01327 return CUBIT_FALSE; 01328 } 01329 01330 //------------------------------------------------------------------------- 01331 // Purpose : Is the parameterization singular at the passed parameter 01332 // value. 01333 // 01334 // Special Notes : Never: surface is not parametric. 01335 // 01336 // Creator : Jason Kraftcheck 01337 // 01338 // Creation Date : 03/10/98 01339 //------------------------------------------------------------------------- 01340 CubitBoolean CompositeSurface::is_singular_in_U( double param ) 01341 { 01342 if (num_surfs() == 1) 01343 return get_surface(0)->is_singular_in_U(param); 01344 01345 return CUBIT_FALSE; 01346 } 01347 CubitBoolean CompositeSurface::is_singular_in_V( double param ) 01348 { 01349 if (num_surfs() == 1) 01350 return get_surface(0)->is_singular_in_V(param); 01351 01352 return CUBIT_FALSE; 01353 } 01354 01355 01356 //------------------------------------------------------------------------- 01357 // Purpose : Is the surface closed along a param. 01358 // 01359 // Special Notes : 01360 // 01361 // Creator : Jason Kraftcheck 01362 // 01363 // Creation Date : 03/10/98 01364 //------------------------------------------------------------------------- 01365 CubitBoolean CompositeSurface::is_closed_in_U() 01366 { 01367 if (num_surfs() == 1) 01368 return get_surface(0)->is_closed_in_U(); 01369 01370 return CUBIT_FALSE; 01371 } 01372 CubitBoolean CompositeSurface::is_closed_in_V() 01373 { 01374 if (num_surfs() == 1) 01375 return get_surface(0)->is_closed_in_V(); 01376 01377 return CUBIT_FALSE; 01378 } 01379 01380 01381 //------------------------------------------------------------------------- 01382 // Purpose : Find u and v derivitives at the specified location. 01383 // 01384 // Special Notes : 01385 // 01386 // Creator : Jason Kraftcheck 01387 // 01388 // Creation Date : 03/10/98 01389 //------------------------------------------------------------------------- 01390 CubitStatus CompositeSurface::uv_derivitives( double u, 01391 double v, 01392 CubitVector& du, 01393 CubitVector& dv ) 01394 { 01395 if (num_surfs() == 1) 01396 return get_surface(0)->uv_derivitives(u, v, du, dv); 01397 01398 PRINT_ERROR("CompositeSurface::uv_derivitives for non-paramtric surface.\n"); 01399 return CUBIT_FAILURE; 01400 } 01401 01402 01403 //------------------------------------------------------------------------- 01404 // Purpose : Is the surface parametric. 01405 // 01406 // Special Notes : 01407 // 01408 // Creator : Jason Kraftcheck 01409 // 01410 // Creation Date : 03/10/98 01411 //------------------------------------------------------------------------- 01412 CubitBoolean CompositeSurface::is_parametric() 01413 { 01414 if (num_surfs() == 1) 01415 return get_surface(0)->is_parametric(); 01416 01417 return CUBIT_FALSE; 01418 } 01419 01420 01421 //------------------------------------------------------------------------- 01422 // Purpose : Get the range of a parameter. 01423 // 01424 // Special Notes : 01425 // 01426 // Creator : Jason Kraftcheck 01427 // 01428 // Creation Date : 03/10/98 01429 //------------------------------------------------------------------------- 01430 CubitBoolean CompositeSurface::get_param_range_U( double& lower, 01431 double& upper ) 01432 { 01433 if (num_surfs() == 1) 01434 return get_surface(0)->get_param_range_U(lower, upper); 01435 01436 lower = upper = 0; 01437 return CUBIT_FALSE; 01438 } 01439 CubitBoolean CompositeSurface::get_param_range_V( double& lower, 01440 double& upper ) 01441 { 01442 if (num_surfs() == 1) 01443 return get_surface(0)->get_param_range_V(lower, upper); 01444 01445 lower = upper = 0; 01446 return CUBIT_FALSE; 01447 } 01448 01449 01450 //------------------------------------------------------------------------- 01451 // Purpose : Check if the passed position is on the surface. 01452 // 01453 // Special Notes : 01454 // 01455 // Creator : Jason Kraftcheck 01456 // 01457 // Creation Date : 03/10/98 01458 //------------------------------------------------------------------------- 01459 CubitBoolean CompositeSurface::is_position_on(CubitVector& position) 01460 { 01461 for( int i = 0; i < compGeom->num_entities(); i++ ) 01462 { 01463 Surface* surf = get_surface(i); 01464 if( surf->is_position_on( position ) ) return CUBIT_TRUE; 01465 } 01466 01467 return CUBIT_FALSE; 01468 } 01469 01470 //------------------------------------------------------------------------- 01471 // Purpose : Check if the passed position is outside, inside or 01472 // on the boundary of the surface. 01473 // 01474 // Special Notes : 01475 // 01476 // Creator : Steve Storm 01477 // 01478 // Creation Date : 12/01/00 01479 //------------------------------------------------------------------------- 01480 CubitPointContainment CompositeSurface::point_containment( const CubitVector &point ) 01481 { 01482 bool boundary = false; 01483 for( int i = 0; i < num_surfs(); i++ ) 01484 { 01485 CubitPointContainment cpc = get_surface(i)->point_containment( point ); 01486 switch( cpc ) 01487 { 01488 case CUBIT_PNT_OUTSIDE: 01489 //case CUBIT_PNT_OFF: 01490 break; 01491 case CUBIT_PNT_INSIDE: 01492 //case CUBIT_PNT_ON: 01493 return cpc; 01494 case CUBIT_PNT_BOUNDARY: 01495 boundary = true; 01496 break; 01497 case CUBIT_PNT_UNKNOWN: 01498 default: 01499 return CUBIT_PNT_UNKNOWN; 01500 } 01501 } 01502 01503 if( boundary ) 01504 return CUBIT_PNT_BOUNDARY; 01505 else 01506 return CUBIT_PNT_OUTSIDE; 01507 } 01508 /* 01509 CubitPointContainment CompositeSurface::point_containment( CubitVector &point, 01510 double , 01511 double ) 01512 { 01513 return point_containment( point ); 01514 } 01515 */ 01516 CubitPointContainment CompositeSurface::point_containment( double u, 01517 double v ) 01518 { 01519 if (num_surfs() == 1) 01520 return get_surface(0)->point_containment(u,v); 01521 // Set this up when uv parameters are defined for composite surfaces. 01522 return CUBIT_PNT_UNKNOWN; 01523 } 01524 01525 //------------------------------------------------------------------------- 01526 // Purpose : Relative sense of Surface wrt geometry underneath. 01527 // 01528 // Special Notes : 01529 // 01530 // Creator : Jason Kraftcheck 01531 // 01532 // Creation Date : 03/10/98 01533 //------------------------------------------------------------------------- 01534 CubitSense CompositeSurface::get_geometry_sense() 01535 { 01536 return CUBIT_FORWARD; 01537 } 01538 void CompositeSurface::reverse_sense() 01539 { 01540 compGeom->reverse(); 01541 } 01542 01543 01544 void CompositeSurface::get_curves( DLIList<CompositeCurve*>& result ) 01545 { 01546 for( CompositeLoop* loop = firstLoop; loop; loop = loop->loopNext ) 01547 { 01548 CompositeCoEdge* coedge = loop->first_coedge(); 01549 while( coedge ) 01550 { 01551 result.append_unique( coedge->get_curve() ); 01552 coedge = loop->next_coedge( coedge ); 01553 } 01554 } 01555 } 01556 01557 01558 bool CompositeSurface::has_hidden_entities() const 01559 { 01560 return hiddenSet && !hiddenSet->is_empty(); 01561 } 01562 01563 GeometryType CompositeSurface::geometry_type() 01564 { return UNDEFINED_SURFACE_TYPE; } 01565 01566 void CompositeSurface::get_hidden_curves( DLIList<Curve*>& curves ) 01567 { 01568 if( hiddenSet ) 01569 hiddenSet->hidden_curves( curves ); 01570 } 01571 01572 void CompositeSurface::print_debug_info( const char* line_prefix, 01573 bool brief ) 01574 { 01575 if( line_prefix == 0 ) line_prefix = ""; 01576 CompositeLoop* loop = 0; 01577 01578 if( brief ) 01579 { 01580 int count = 0; 01581 while ( (loop = next_loop(loop) ) != NULL ) 01582 count++; 01583 #ifdef TOPOLOGY_BRIDGE_IDS 01584 PRINT_INFO("%sCompositeSurface %d : %d loops ", line_prefix, get_id(), count ); 01585 if ( num_surfs() == 1 ) 01586 PRINT_INFO("%s %d\n", fix_type_name(typeid(*get_surface(0)).name()), get_surface(0)->get_id()); 01587 else 01588 PRINT_INFO("%d surfaces.\n", num_surfs()); 01589 01590 #else 01591 PRINT_INFO("%sCompositeSurface %p : %d loops ", line_prefix, (void*)this, count ); 01592 if ( num_surfs() == 1 ) 01593 PRINT_INFO("%s %d\n", fix_type_name(typeid(*get_surface(0)).name()), get_surface(0)->get_saved_id()); 01594 // PRINT_INFO("%s %p\n", fix_type_name(typeid(*get_surface(0)).name()), get_surface(0)); 01595 else 01596 PRINT_INFO("%d surfaces.\n", num_surfs()); 01597 #endif 01598 return; 01599 } 01600 01601 char* new_prefix = new char[strlen(line_prefix)+3]; 01602 strcpy( new_prefix, line_prefix ); 01603 strcat( new_prefix, " " ); 01604 #ifdef TOPOLOGY_BRIDGE_IDS 01605 PRINT_INFO("%sCompositeSurface %d\n", line_prefix, get_id() ); 01606 #else 01607 PRINT_INFO("%sCompositeSurface %d\n", line_prefix, this->get_saved_id() ); 01608 // PRINT_INFO("%sCompositeSurface %p\n", line_prefix, this ); 01609 #endif 01610 compGeom->print_debug_info( new_prefix ); 01611 01612 // Print out info about any surfaces we are ingoring 01613 // during evaluation. 01614 if(surfacesToIgnore.size() > 0) 01615 { 01616 PRINT_INFO("%sSurfaces which are ignored:\n", new_prefix); 01617 for(int k=surfacesToIgnore.size(); k--;) 01618 { 01619 PRINT_INFO("%sSurface: %d\n", 01620 new_prefix, surfacesToIgnore.get_and_step()->get_saved_id()); 01621 } 01622 } 01623 if( hiddenSet ) hiddenSet->print_debug_info( new_prefix ); 01624 else PRINT_INFO("%s No Hidden Entities.\n", line_prefix ); 01625 while( (loop = next_loop(loop) ) != NULL ) 01626 loop->print_debug_info( new_prefix ); 01627 delete [] new_prefix; 01628 01629 update_facet_tool(); 01630 if ( facetTool ) 01631 { 01632 facetTool->debug_draw_facets(); 01633 // bool* reversed = new bool[num_surfs()]; 01634 // for (int i = 0; i < num_surfs(); i++ ) 01635 // reversed[i] = get_sense(i) == CUBIT_REVERSED; 01636 // facetTool->consolidate_points(reversed, GEOMETRY_RESABS); 01637 // delete [] reversed; 01638 } 01639 } 01640 01641 //------------------------------------------------------------------------- 01642 // Purpose : Get sense in Shell 01643 // 01644 // Special Notes : 01645 // 01646 // Creator : Jason Kraftcheck 01647 // 01648 // Creation Date : 08/27/02 01649 //------------------------------------------------------------------------- 01650 CubitSense CompositeSurface::get_shell_sense( ShellSM* shellsm_ptr ) const 01651 { 01652 CompositeShell* shell = dynamic_cast<CompositeShell*>(shellsm_ptr); 01653 if( shell ) 01654 return shell->find_sense(this); 01655 01656 DLIList<TopologyBridge*> parents; 01657 for( int i = 0; i < num_surfs(); i++ ) 01658 { 01659 parents.clean_out(); 01660 get_surface(i)->get_parents( parents ); 01661 if( parents.is_in_list( shellsm_ptr ) ) 01662 { 01663 CubitSense result = get_surface(i)->get_shell_sense(shellsm_ptr); 01664 if( get_sense(i) == CUBIT_REVERSED ) 01665 { 01666 if( result == CUBIT_FORWARD ) 01667 result = CUBIT_REVERSED; 01668 else if( result == CUBIT_REVERSED ) 01669 result = CUBIT_FORWARD; 01670 } 01671 return result; 01672 } 01673 } 01674 return CUBIT_UNKNOWN; 01675 } 01676 01677 void CompositeSurface::notify_reversed( TopologyBridge* bridge ) 01678 { 01679 int index = compGeom->index_of(bridge); 01680 if( index >= 0 ) 01681 compGeom->reverse_sense(index); 01682 } 01683 01684 CubitStatus CompositeSurface::stitch( CompositeSurface* partner ) 01685 { 01686 if( this == partner || this->stitchPartner || partner->stitchPartner ) 01687 { 01688 assert(0); 01689 return CUBIT_FAILURE; 01690 } 01691 01692 this->stitchPartner = partner; 01693 partner->stitchPartner = this; 01694 return CUBIT_SUCCESS; 01695 } 01696 01697 CompositeSurface* CompositeSurface::unstitch() 01698 { 01699 CompositeSurface* result = this->stitchPartner; 01700 if( result ) 01701 this->stitchPartner = result->stitchPartner = 0; 01702 return result; 01703 } 01704 01705 //------------------------------------------------------------------------- 01706 // Purpose : Update for change in underlying topology 01707 // 01708 // Special Notes : 01709 // 01710 // Creator : Jason Kraftcheck 01711 // 01712 // Creation Date : 12/19/02 01713 //------------------------------------------------------------------------- 01714 void CompositeSurface::notify_topology_modified( TopologyBridge* bridge ) 01715 { 01716 DLIList<CompositeCurve*> new_curves; 01717 Surface* surf = dynamic_cast<Surface*>(bridge); 01718 assert( surf && index_of(surf) >= 0 ); 01719 update_modified(); 01720 update_modified( surf, new_curves ); 01721 01722 // for( int i = new_curves.size(); i--; ) 01723 // if( !CompositeEngine::instance().restore_curve(new_curves.get_and_step()) ) 01724 // assert(0); 01725 } 01726 01727 void CompositeSurface::update_modified( Surface* surf, 01728 DLIList<CompositeCurve*>& new_curves ) 01729 { 01730 int i; 01731 //int i = index_of(surf); 01732 //assert(i >= 0); 01733 //CubitSense rel_sense = get_sense(i); 01734 01735 // find any new coedges in the surface 01736 DLIList<TopologyBridge*> bridge_list; 01737 DLIList<LoopSM*> loops; 01738 DLIList<CoEdgeSM*> coedges; 01739 01740 surf->get_children_virt( bridge_list ); 01741 CAST_LIST( bridge_list, loops, LoopSM ); 01742 assert( bridge_list.size() == loops.size() ); 01743 bridge_list.clean_out(); 01744 01745 for( i = loops.size(); i--; ) 01746 { 01747 loops.get_and_step()->get_children_virt( bridge_list ); 01748 while( bridge_list.size() ) 01749 { 01750 CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(bridge_list.pop()); 01751 assert(0 != coedge); 01752 coedges.append(coedge); 01753 } 01754 } 01755 01756 for( i = coedges.size(); i--; ) 01757 { 01758 CoEdgeSM* coedge = coedges.get_and_step(); 01759 bridge_list.clean_out(); 01760 coedge->get_children_virt( bridge_list ); 01761 assert( bridge_list.size() == 1 ); 01762 Curve* curve = dynamic_cast<Curve*>(bridge_list.get()); 01763 assert( 0 != curve ); 01764 01765 CompositeCoEdge* ccoedge = dynamic_cast<CompositeCoEdge*>(coedge->owner()); 01766 if (ccoedge) 01767 { 01768 // If replace-curve was already done for the curve 01769 // when processing the other surface, the composite 01770 // coedge will have been created already. Add it to 01771 // the hidden set. 01772 if( !ccoedge->owner() && ccoedge->get_curve()->owner() == &hidden_entities()) 01773 hidden_entities().hide( ccoedge ); 01774 01775 // If the coedge is a composite, the curve must be one 01776 // already as well. Done with this coedge. 01777 continue; 01778 } 01779 01780 // Replace curve with composite, and hide composite curve 01781 // and any new child points. 01782 CompositeCurve* ccurve = CompositeEngine::instance().replace_curve(curve); 01783 assert(0 != ccurve); 01784 new_curves.append(ccurve); 01785 hidden_entities().hide( ccurve ); 01786 CompositePoint* start = ccurve->start_point(); 01787 if( ! start->owner() ) 01788 hidden_entities().hide(start); 01789 CompositePoint* end = ccurve->start_point(); 01790 if( ! end->owner() ) 01791 hidden_entities().hide(end); 01792 01793 // CompositeCoEdge was created by replace_curve(..) 01794 // Add it to the HiddenEntitySet 01795 ccoedge = dynamic_cast<CompositeCoEdge*>(coedge->owner()); 01796 assert(ccoedge && !ccoedge->owner()); 01797 hidden_entities().hide( ccoedge ); 01798 } 01799 } 01800 01801 01802 01803 01804 01805 //------------------------------------------------------------------------- 01806 // Purpose : Update for split in underlying surface 01807 // 01808 // Special Notes : 01809 // 01810 // Creator : Jason Kraftcheck 01811 // 01812 // Creation Date : 12/19/02 01813 //------------------------------------------------------------------------- 01814 void CompositeSurface::notify_split( TopologyBridge* new_bridge, 01815 TopologyBridge* old_bridge ) 01816 { 01817 assert(!new_bridge->owner()); 01818 01819 Surface* old_surf = dynamic_cast<Surface*>(old_bridge); 01820 Surface* new_surf = dynamic_cast<Surface*>(new_bridge); 01821 assert( old_surf && new_surf ); 01822 int old_surf_index = index_of(old_surf); 01823 assert(old_surf_index >= 0); 01824 01825 compGeom->append(new_surf, compGeom->sense(old_surf_index)); 01826 new_surf->owner(this); 01827 01828 DLIList<CompositeCurve*> new_curves; 01829 update_modified(); 01830 update_modified( old_surf, new_curves ); 01831 update_modified( new_surf, new_curves ); 01832 01833 // for( int i = new_curves.size(); i--; ) 01834 // if( !CompositeEngine::instance().restore_curve(new_curves.get_and_step()) ) 01835 // assert(0); 01836 } 01837 01838 bool CompositeSurface::is_dead_coedge( CompositeCoEdge* coedge ) 01839 { 01840 if (coedge->num_coedges() > 0) 01841 return false; 01842 01843 CompositeCurve* curve = coedge->get_curve(); 01844 if (!curve) 01845 return true; 01846 01847 if (curve->num_curves() == 0) // point-curve 01848 { 01849 CompositePoint* comp = curve->start_point(); 01850 assert(comp == curve->end_point()); 01851 return !(comp->get_point()); 01852 } 01853 01854 return false; 01855 } 01856 01857 void CompositeSurface::update_modified( ) 01858 { 01859 // search for dead CoEdge-Curve pairs 01860 DLIList<CoEdgeSM*> coedge_list; 01861 if ( hiddenSet ) 01862 hiddenSet->hidden_coedges( coedge_list ); 01863 01864 while (coedge_list.size()) 01865 { 01866 CompositeCoEdge* coedge = dynamic_cast<CompositeCoEdge*>(coedge_list.pop()); 01867 if ( is_dead_coedge(coedge) ) 01868 remove_dead_coedge(coedge); 01869 } 01870 01871 CompositeLoop* loop = next_loop(); 01872 while (loop) 01873 { 01874 CompositeLoop* next = next_loop(loop); 01875 CompositeCoEdge* coedge = loop->first_coedge(); 01876 while (coedge && is_dead_coedge(coedge)) 01877 { 01878 remove_dead_coedge(coedge); 01879 coedge = loop->first_coedge(); 01880 } 01881 01882 if (coedge) 01883 { 01884 coedge = coedge->next(); 01885 while ( coedge != loop->first_coedge() ) 01886 { 01887 CompositeCoEdge* next_coe = coedge->next(); 01888 if (is_dead_coedge(coedge)) 01889 remove_dead_coedge(coedge); 01890 coedge = next_coe; 01891 } 01892 } 01893 01894 if (loop->first_coedge() == NULL) 01895 { 01896 remove(loop); 01897 delete loop; 01898 } 01899 01900 loop = next; 01901 } 01902 01903 } 01904 01905 void CompositeSurface::remove_dead_coedge( CompositeCoEdge* coedge ) 01906 { 01907 assert(is_dead_coedge(coedge)); 01908 01909 CompositeCurve* curve = coedge->get_curve(); 01910 assert(curve->num_curves() == 0); 01911 curve->remove(coedge); 01912 delete coedge; 01913 if (curve->next_coedge(NULL)) 01914 return; 01915 01916 CompositePoint* start = curve->start_point(); 01917 CompositePoint* end = curve->end_point(); 01918 curve->start_point(0); 01919 curve->end_point(0); 01920 delete curve; 01921 01922 if ( start->next_curve(NULL) == NULL ) 01923 { 01924 if ( start->get_point() ) 01925 CompositeEngine::instance().restore_point_in_curve(start); 01926 else 01927 delete start; 01928 } 01929 01930 if ( end != start && end->next_curve(NULL) == NULL ) 01931 { 01932 if ( end->get_point() ) 01933 CompositeEngine::instance().restore_point_in_curve(end); 01934 else 01935 delete end; 01936 } 01937 } 01938 01939 //------------------------------------------------------------------------- 01940 // Purpose : Get graphics from cached facet data 01941 // 01942 // Special Notes : 01943 // 01944 // Creator : Jason Kraftcheck 01945 // 01946 // Creation Date : 08/18/03 01947 //------------------------------------------------------------------------- 01948 CubitStatus CompositeSurface::get_graphics( GMem& gmem ) 01949 { 01950 if (!facetTool) 01951 update_facet_tool(); 01952 01953 if (!facetTool) 01954 return CUBIT_FAILURE; 01955 01956 facetTool->graphics( GEOMETRY_RESABS, gmem); 01957 return CUBIT_SUCCESS; 01958 } 01959 01960 //------------------------------------------------------------------------- 01961 // Purpose : Update for transform 01962 // 01963 // Special Notes : 01964 // 01965 // Creator : Jason Kraftcheck 01966 // 01967 // Creation Date : 10/17/03 01968 //------------------------------------------------------------------------- 01969 void CompositeSurface::notify_transformed() 01970 { 01971 if (facetTool) 01972 { 01973 delete facetTool; 01974 facetTool = 0; 01975 } 01976 } 01977 01978 01979 01980 CubitStatus CompositeSurface::get_projected_distance_on_surface( CubitVector *pos1, 01981 CubitVector *pos2, 01982 double &distance ) 01983 { 01984 if ( num_surfs() == 1) 01985 return get_surface(0)->get_projected_distance_on_surface( pos1, pos2, distance ); 01986 else 01987 return CUBIT_FAILURE; 01988 return CUBIT_FAILURE; 01989 } 01990 CubitStatus CompositeSurface::get_sphere_params 01991 ( 01992 CubitVector ¢er, 01993 double &radius 01994 ) const 01995 { 01996 PRINT_ERROR("Currently, Cubit is unable to determine sphere parameters for CompositeSurfaces.\n"); 01997 return CUBIT_FAILURE; 01998 } 01999 02000 CubitStatus CompositeSurface::get_cone_params 02001 ( 02002 CubitVector ¢er, 02003 CubitVector &normal, 02004 CubitVector &major_axis, 02005 double &radius_ratio, 02006 double &sine_angle, 02007 double &cos_angle 02008 ) const 02009 { 02010 PRINT_ERROR("Currently, Cubit is unable to determine cone parameters for CompositeSurfaces.\n"); 02011 return CUBIT_FAILURE; 02012 } 02013 02014 CubitStatus CompositeSurface::get_torus_params 02015 ( 02016 CubitVector ¢er, 02017 CubitVector &normal, 02018 double &major_radius, 02019 double &minor_radius 02020 ) const 02021 { 02022 PRINT_ERROR("Currently, Cubit is unable to determine torus parameters for CompositeSurface.\n"); 02023 return CUBIT_FAILURE; 02024 } 02025 02026 CubitStatus CompositeSurface::get_nurb_params 02027 ( 02028 bool &rational, 02029 int °ree_u, 02030 int °ree_v, 02031 int &num_cntrl_pts_u, 02032 int &num_cntrl_pts_v, 02033 DLIList<CubitVector> &cntrl_pts, 02034 DLIList<double> &cntrl_pt_weights, 02035 DLIList<double> &u_knots, 02036 DLIList<double> &v_knots 02037 ) const 02038 { 02039 PRINT_ERROR("Currently, Cubit is unable to determine nurbs parameters for CompositeSurface.\n"); 02040 return CUBIT_FAILURE; 02041 } 02042 02043 02044 CubitStatus CompositeSurface::closest_point_along_vector(CubitVector& from_point, 02045 CubitVector& along_vector, 02046 CubitVector& point_on_surface) 02047 { 02048 int index = closest_underlying_surface( from_point ); 02049 CubitStatus status = get_surface(index)->closest_point_along_vector( from_point, along_vector, point_on_surface ); 02050 02051 if( CUBIT_FAILURE == status ) 02052 { 02053 //find the next closest surface and try it 02054 double shortest_dist_sqr = CUBIT_DBL_MAX; 02055 double current_dist_sqr; 02056 CubitVector closest_point; 02057 int closest_surf = 0; 02058 02059 for( int k=0; k<compGeom->num_entities(); k++ ) 02060 { 02061 if( k==index ) 02062 continue; 02063 02064 closest_trimmed( k, from_point, closest_point ); 02065 current_dist_sqr = (from_point - closest_point).length_squared(); 02066 02067 if( current_dist_sqr < shortest_dist_sqr ) 02068 { 02069 closest_surf = k; 02070 shortest_dist_sqr = current_dist_sqr; 02071 } 02072 } 02073 status = get_surface(closest_surf)->closest_point_along_vector( from_point, along_vector, point_on_surface ); 02074 } 02075 02076 02077 return status; 02078 }