cgma
CompositeSurface.cpp
Go to the documentation of this file.
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 &center,
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 &center,
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 &center,
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 &degree_u,
02030   int &degree_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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines