cgma
|
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 ¢er, 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 ¢er, 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 ¢er, 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 °ree_u, 00502 int °ree_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 }