cgma
SubSurface.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : SubSurface.cpp
00003 //
00004 // Purpose       : 
00005 //
00006 // Special Notes : 
00007 //
00008 // Creator       : Jason Kraftcheck
00009 //
00010 // Creation Date : 06/11/98
00011 //-------------------------------------------------------------------------
00012 
00013 #include "SubSurface.hpp"
00014 #include "PartitionEngine.hpp"
00015 #include "PartitionLoop.hpp"
00016 #include "PartitionCurve.hpp"
00017 #include "VGLoopTool.hpp"
00018 #include "CubitFacetData.hpp"
00019 
00020 #include "GMem.hpp"
00021 #include "GeometryQueryTool.hpp"
00022 
00023 //-------------------------------------------------------------------------
00024 // Purpose       : Constructor
00025 //
00026 // Special Notes : 
00027 //
00028 // Creator       : Jason Kraftcheck 
00029 //
00030 // Creation Date : 04/23/02
00031 //-------------------------------------------------------------------------
00032 SubSurface::SubSurface( Surface* real_surf ) 
00033 {
00034   assert( dynamic_cast<SubEntitySet*>(real_surf->owner()) == 0 );
00035   new SubEntitySet( real_surf, this );
00036 
00037   // ensure that the sense is the same on both entities
00038   //if( real_surf->bridge_sense() != this->bridge_sense() )
00039   //  reverse_bridge_sense();
00040 
00041   geometry_sense = CUBIT_FORWARD;
00042 }
00043 
00044 SubSurface::SubSurface( SubSurface* split_from ) 
00045 {
00046   split_from->sub_entity_set().add_partition( this );
00047   geometry_sense = CUBIT_FORWARD;
00048 }
00049 
00050 PartitionSurface* SubSurface::copy()
00051 {
00052   return new SubSurface(this);
00053 }
00054 
00055 //-------------------------------------------------------------------------
00056 // Purpose       : Destructor
00057 //
00058 // Special Notes : 
00059 //
00060 // Creator       : Jason Kraftcheck 
00061 //
00062 // Creation Date : 06/15/98
00063 //-------------------------------------------------------------------------
00064 SubSurface::~SubSurface()
00065   { }
00066 
00067 
00068 
00069 //-------------------------------------------------------------------------
00070 // Purpose       : get bounding box
00071 //
00072 // Special Notes : 
00073 //
00074 // Creator       : Jason Kraftcheck 
00075 //
00076 // Creation Date : 06/11/98
00077 //-------------------------------------------------------------------------
00078 //CubitBox SubSurface::bounding_box() const
00079 //  { return partitioned_surface()->bounding_box(); }
00080 
00081 
00082 //-------------------------------------------------------------------------
00083 // Purpose       : Calculate surface area
00084 //
00085 // Special Notes : 
00086 //
00087 // Creator       : Jason Kraftcheck 
00088 //
00089 // Creation Date : 06/11/98
00090 //-------------------------------------------------------------------------
00091 double SubSurface::measure()
00092 {
00093   if( ! sub_entity_set().has_multiple_sub_entities() )
00094     return partitioned_surface()->measure();
00095   else
00096     return PartitionSurface::measure();
00097 }
00098   
00099 
00100 GeometryType SubSurface::geometry_type()
00101   { return partitioned_surface()->geometry_type(); }
00102 
00103 
00104 CubitStatus SubSurface::get_point_normal( CubitVector& origin, CubitVector& normal )
00105   { return partitioned_surface()->get_point_normal( origin, normal ); }
00106 
00107 
00108 CubitStatus SubSurface::closest_point_uv_guess(  
00109     CubitVector const& location,
00110     double &u, double &v,
00111     CubitVector* closest_location,
00112     CubitVector* unit_normal )
00113 {
00114   CubitStatus ret = partitioned_surface()->
00115     closest_point_uv_guess(location, u, v, closest_location, unit_normal);
00116 
00117   if(unit_normal && geometry_sense == CUBIT_REVERSED)
00118     *unit_normal = -(*unit_normal);
00119 
00120   return ret;
00121 }
00122 
00123 
00124 //-------------------------------------------------------------------------
00125 // Purpose       : Return the closest point on the surface.
00126 //
00127 // Special Notes : 
00128 //
00129 // Creator       : Jason Kraftcheck 
00130 //
00131 // Creation Date : 06/11/98
00132 //-------------------------------------------------------------------------
00133 CubitStatus SubSurface::closest_point( CubitVector const& a, 
00134                                        CubitVector* b,
00135                                        CubitVector* c,
00136                                        CubitVector* d,
00137                                        CubitVector* e )
00138 { 
00139   CubitStatus ret = partitioned_surface()->closest_point( a, b, c, d, e ); 
00140 
00141   if(c && geometry_sense == CUBIT_REVERSED)
00142     *c = -(*c);
00143 
00144   return ret;
00145 }
00146 
00147 //-------------------------------------------------------------------------
00148 // Purpose       : closest point trimmed
00149 //
00150 // Special Notes : 
00151 //
00152 // Creator       : Jason Kraftcheck
00153 //
00154 // Creation Date : 03/28/03
00155 //-------------------------------------------------------------------------
00156 void SubSurface::closest_point_trimmed( CubitVector from, CubitVector& result )
00157 {
00158   PartitionCurve* curve = 0;
00159   if ( point_containment( from, curve ) == CUBIT_PNT_INSIDE )
00160     partitioned_surface()->closest_point( from, &result );
00161   else
00162     curve->closest_point_trimmed( from, result );
00163 }
00164 
00165 //-------------------------------------------------------------------------
00166 // Purpose       : closest point trimmed
00167 //
00168 // Special Notes : 
00169 //
00170 // Creator       : Jason Kraftcheck
00171 //
00172 // Creation Date : 03/28/03
00173 //-------------------------------------------------------------------------
00174 CubitStatus SubSurface::closest_point_along_vector( CubitVector& from_point, 
00175                                              CubitVector& along_vector,
00176                                              CubitVector& point_on_surface)
00177 {
00178   return partitioned_surface()->closest_point_along_vector( from_point, along_vector, point_on_surface );
00179 }
00180 
00181 
00182 //-------------------------------------------------------------------------
00183 // Purpose       : get the principal curvatues at a point
00184 //
00185 // Special Notes : 
00186 //
00187 // Creator       : Jason Kraftcheck 
00188 //
00189 // Creation Date : 06/11/98
00190 //-------------------------------------------------------------------------
00191 CubitStatus SubSurface::principal_curvatures( CubitVector const& a,
00192                                               double& b, double& c,
00193                                               CubitVector* d )
00194   { return partitioned_surface()->principal_curvatures(a,b,c,d); }
00195 
00196 
00197 //-------------------------------------------------------------------------
00198 // Purpose       : return the position for a set of parameter values.
00199 //
00200 // Special Notes : 
00201 //
00202 // Creator       : Jason Kraftcheck 
00203 //
00204 // Creation Date : 06/11/98
00205 //-------------------------------------------------------------------------
00206 CubitVector SubSurface::position_from_u_v( double u, double v )
00207   { return partitioned_surface()->position_from_u_v( u, v ); }
00208 
00209 //-------------------------------------------------------------------------
00210 // Purpose       : return the u and v values at a position
00211 //
00212 // Special Notes : 
00213 //
00214 // Creator       : Jason Kraftcheck 
00215 //
00216 // Creation Date : 06/11/98
00217 //-------------------------------------------------------------------------
00218 CubitStatus SubSurface::u_v_from_position( CubitVector const& location,
00219                                                  double& u, double& v,
00220                                                                                                  CubitVector* closest )
00221   { return partitioned_surface()->u_v_from_position(location,u,v,closest); }
00222 
00223 //-------------------------------------------------------------------------
00224 // Purpose       : Check if surface is periodic.
00225 //
00226 // Special Notes : 
00227 //
00228 // Creator       : Jason Kraftcheck 
00229 //
00230 // Creation Date : 03/31/03
00231 //-------------------------------------------------------------------------
00232 CubitBoolean SubSurface::is_periodic()
00233 { 
00234   double u_period = 0.0, v_period = 0.0;
00235   bool u_periodic = is_periodic_in_U(u_period);
00236   bool v_periodic = is_periodic_in_V(v_period);
00237   if( !u_periodic && !v_periodic )
00238     return CUBIT_FALSE;
00239     
00240   if ( !next_loop(0) ) // sphere
00241     return CUBIT_TRUE; 
00242     
00243   if( u_period < 0.0 )
00244     u_period = -u_period;
00245   if( v_period < 0.0 )
00246     v_period = -v_period; 
00247     
00248     // If a single step exceeds this delta of the parameter
00249     // range, assume the step crossed the "international date
00250     // line" of the parameterization.  Could probably safely
00251     // use a smaller value.
00252   double u_wrap = 0.75 * u_period;
00253   double v_wrap = 0.75 * v_period;
00254   
00255   int num_periodic_loops = 0;
00256   std::vector<CubitVector> loop_polyline;
00257   PartitionLoop* loop = 0;
00258   while( (loop = next_loop(loop) ) != NULL )
00259   {
00260       // Get a polyline representation of the loop
00261     VGLoopTool<PartitionSurface,PartitionLoop,PartitionCoEdge,PartitionCurve,PartitionPoint>
00262       ::get_loop_polyline( loop->first_coedge(), loop_polyline );
00263     
00264     if ( loop_polyline.size() < 2 )
00265       continue;
00266     
00267       // Sum steps (in parameter space) between points in polyline
00268     std::vector<CubitVector>::iterator itor = loop_polyline.begin(),
00269                                        end = loop_polyline.end();
00270     double u_sum = 0, v_sum = 0;
00271     double u_prev, v_prev;
00272     u_v_from_position( loop_polyline[loop_polyline.size()-1], u_prev, v_prev );
00273     for ( ; itor != end; ++itor )
00274     {
00275       double u, v;
00276       u_v_from_position( *itor, u, v );
00277       
00278       double u_step = u - u_prev;
00279       if ( u_step > u_wrap )
00280         u_step = u_period - u_step;
00281       else if ( u_step < -u_wrap )
00282         u_step = -u_period - u_step;
00283       
00284       double v_step = v - v_prev;
00285       if ( v_step > v_wrap )
00286         v_step = v_period - v_step;
00287       else if ( v_step < -v_wrap )
00288         v_step = -v_period - v_step;
00289         
00290       u_sum += u_step;
00291       v_sum += v_step;
00292       u_prev = u;
00293       v_prev = v;
00294     }
00295 
00296       // Sum should be either zero or +/-period if loop
00297       // is non-periodic or periodic respectively.
00298     if ( (u_periodic && fabs(u_sum) > 0.5*u_period) ||
00299          (v_periodic && fabs(v_sum) > 0.5*v_period) )
00300       num_periodic_loops++;
00301   }
00302   
00303   return CubitBoolean(num_periodic_loops > 0);
00304 }
00305       
00306       
00307     
00308 
00309 CubitBoolean SubSurface::is_periodic_in_U( double& period )
00310   { return partitioned_surface()->is_periodic_in_U(period); }
00311 CubitBoolean SubSurface::is_periodic_in_V( double& period )
00312   { return partitioned_surface()->is_periodic_in_V(period); }
00313 
00314 //-------------------------------------------------------------------------
00315 // Purpose       : check if the surface is singular in either parameter
00316 //
00317 // Special Notes : 
00318 //
00319 // Creator       : Jason Kraftcheck 
00320 //
00321 // Creation Date : 06/11/98
00322 //-------------------------------------------------------------------------
00323 CubitBoolean SubSurface::is_singular_in_U( double u_param )
00324   {  return partitioned_surface()->is_singular_in_U(u_param); }
00325 CubitBoolean SubSurface::is_singular_in_V( double v_param )
00326   {  return partitioned_surface()->is_singular_in_V(v_param); }
00327 
00328 //-------------------------------------------------------------------------
00329 // Purpose       : Check if the surface is closed along either parameter.
00330 //
00331 // Special Notes : 
00332 //
00333 // Creator       : Jason Kraftcheck 
00334 //
00335 // Creation Date : 06/11/98
00336 //-------------------------------------------------------------------------
00337 CubitBoolean SubSurface::is_closed_in_U()
00338   { return CUBIT_FALSE; }
00339 CubitBoolean SubSurface::is_closed_in_V()
00340   { return CUBIT_FALSE; }
00341 
00342 //-------------------------------------------------------------------------
00343 // Purpose       : Get uv derivitives
00344 //
00345 // Special Notes : 
00346 //
00347 // Creator       : Jason Kraftcheck 
00348 //
00349 // Creation Date : 06/11/98
00350 //-------------------------------------------------------------------------
00351 CubitStatus SubSurface::uv_derivitives( double u, double v,
00352                                 CubitVector& du, CubitVector& dv )
00353   { return partitioned_surface()->uv_derivitives(u,v,du,dv); }
00354 
00355 //-------------------------------------------------------------------------
00356 // Purpose       : Check if surface is parameterized
00357 //
00358 // Special Notes : 
00359 //
00360 // Creator       : Jason Kraftcheck 
00361 //
00362 // Creation Date : 06/11/98
00363 //-------------------------------------------------------------------------
00364 CubitBoolean SubSurface::is_parametric()
00365   { return partitioned_surface()->is_parametric(); }
00366 
00367 //-------------------------------------------------------------------------
00368 // Purpose       : return the parameter ranges
00369 //
00370 // Special Notes : 
00371 //
00372 // Creator       : Jason Kraftcheck 
00373 //
00374 // Creation Date : 06/11/98
00375 //-------------------------------------------------------------------------
00376 CubitBoolean SubSurface::get_param_range_U(  double& lower, double& upper )
00377   { return partitioned_surface()->get_param_range_U(lower,upper); }
00378 CubitBoolean SubSurface::get_param_range_V(  double& lower, double& upper )
00379   { return partitioned_surface()->get_param_range_V(lower,upper); }
00380 
00381 
00382 //-------------------------------------------------------------------------
00383 // Purpose       : Check if a position lies on this surface.
00384 //
00385 // Special Notes : 
00386 //
00387 // Creator       : Jason Kraftcheck 
00388 //
00389 // Creation Date : 06/11/98
00390 //-------------------------------------------------------------------------
00391 CubitBoolean SubSurface::is_position_on( CubitVector& position )
00392   { return partitioned_surface()->is_position_on( position ); }
00393 
00394 
00395 
00396 CubitStatus SubSurface::combine( PartitionSurface* dead_surface )
00397 {
00398   SubSurface* dead = dynamic_cast<SubSurface*>(dead_surface );
00399   if( !dead )
00400   {
00401     assert(0);
00402     return CUBIT_FAILURE;
00403   }
00404   
00405   return PartitionSurface::combine(dead_surface);
00406 }
00407 
00408 CubitSense SubSurface::get_geometry_sense() 
00409 {
00410   /*
00411 #ifdef ALPHA_TREADSWEEP
00412   return geometry_sense;
00413 #else
00414   */
00415   return CUBIT_FORWARD;
00416   /*
00417 #endif
00418   */
00419 }
00420 
00421 void SubSurface::reverse_sense()
00422 {
00423   reverse_loops();
00424   if( owner() )
00425     owner()->notify_reversed(this);
00426 
00427   if(geometry_sense == CUBIT_FORWARD)
00428     geometry_sense = CUBIT_REVERSED;
00429   else
00430     geometry_sense = CUBIT_FORWARD;
00431 
00432   int j;
00433   DLIList<CubitFacetData*> surf_facets;
00434   this->get_facet_data( surf_facets );
00435   for(j=surf_facets.size(); j--;)
00436     surf_facets.get_and_step()->flip();
00437 }
00438 
00439 CubitStatus SubSurface::save( CubitSimpleAttrib& attrib )
00440 {
00441   DLIList<int> curves;
00442   get_save_topology(curves);
00443   int id = sub_entity_set().get_id(this);
00444   return sub_entity_set().save_geometry( id, 2, 0, 0, &curves, 0, attrib );
00445 }
00446 
00447 
00448 CubitStatus SubSurface::evaluate( double u, double v,
00449                                   CubitVector *position,                                   
00450                                   CubitVector *unit_normal,
00451                                   CubitVector *curvature1,
00452                                   CubitVector *curvature2 )
00453 {
00454   CubitStatus ret = partitioned_surface()->evaluate(u, v, position, unit_normal, curvature1, curvature2 ); 
00455 
00456   if(unit_normal && geometry_sense == CUBIT_REVERSED)
00457     *unit_normal = -(*unit_normal);
00458 
00459   return ret;
00460 }
00461 
00462 CubitStatus SubSurface::get_sphere_params
00463 (
00464   CubitVector &center,
00465   double &radius
00466 ) const
00467 {
00468   PRINT_ERROR("Currently, Cubit is unable to determine sphere parameters for a SubSurface.\n");
00469   return CUBIT_FAILURE;
00470 }
00471 
00472 CubitStatus SubSurface::get_cone_params
00473 (
00474    CubitVector &center,
00475    CubitVector &normal,
00476    CubitVector &major_axis,
00477    double &radius_ratio,
00478    double &sine_angle,
00479    double &cos_angle
00480 ) const
00481 {
00482   PRINT_ERROR("Currently, Cubit is unable to determine cone parameters for SubSurfaces.\n");
00483   return CUBIT_FAILURE;
00484 }
00485 
00486 CubitStatus SubSurface::get_torus_params
00487 (
00488   CubitVector &center,
00489   CubitVector &normal,
00490   double &major_radius,
00491   double &minor_radius
00492 ) const
00493 {
00494   PRINT_ERROR("Currently, Cubit is unable to determine torus parameters for SubSurface.\n");
00495   return CUBIT_FAILURE;
00496 }
00497 
00498 CubitStatus SubSurface::get_nurb_params
00499 (
00500   bool &rational,
00501   int &degree_u,
00502   int &degree_v,
00503   int &num_cntrl_pts_u,
00504   int &num_cntrl_pts_v,
00505   DLIList<CubitVector> &cntrl_pts,
00506   DLIList<double> &cntrl_pt_weights,
00507   DLIList<double> &u_knots,
00508   DLIList<double> &v_knots
00509 ) const
00510 {
00511   PRINT_ERROR("Currently, Cubit is unable to determine nurbs parameters for SubSurface.\n");
00512   return CUBIT_FAILURE;
00513 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines