00001 /* $NoKeywords: $ */ 00002 /* 00003 // 00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. 00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert 00006 // McNeel & Associates. 00007 // 00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED. 00011 // 00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>. 00013 // 00015 */ 00016 00017 #if !defined(OPENNURBS_REVSURFACE_INC_) 00018 #define OPENNURBS_REVSURFACE_INC_ 00019 00020 // surface of revolution 00021 class ON_CLASS ON_RevSurface : public ON_Surface 00022 { 00023 ON_OBJECT_DECLARE(ON_RevSurface); 00024 00025 public: 00026 // virtual ON_Object::DestroyRuntimeCache override 00027 void DestroyRuntimeCache( bool bDelete = true ); 00028 00029 public: 00030 // Revolute curve. 00031 // If m_curve is not NULL, then ~ON_RevSurface() deletes m_curve. 00032 ON_Curve* m_curve; 00033 00034 // Axis of revolution. 00035 ON_Line m_axis; 00036 00037 // Start and end angles of revolution in radians. 00038 // The interval m_angle must be increasing and satisfiy 00039 // ON_ZERO_TOLERANCE < m_angle.Length() <= 2.0*ON_PI 00040 ON_Interval m_angle; 00041 00042 // The interval m_t specifies the parameterization for the 00043 // angular parameter; m_t must be an increasing interval. 00044 // The parameter m_t[0] corresonds to angle m_angle[0] and 00045 // the parameter m_t[1] corresponds to angle m_angle[1]. 00046 // Changing m_t and leaving m_angle unchanged will change the 00047 // parameterization but not change the locus of the surface. 00048 // Changing m_angle and leaving m_t unchanged, will change the 00049 // locus of the surface but not change the evaluation domain. 00050 ON_Interval m_t; 00051 00052 // If false, the "u" parameter is the angle parameter 00053 // and the "v" parameter is the curve parameter. 00054 // If true, the "u" parameter is the curve parameter 00055 // and the "v" parameter is the angle parameter. 00056 ON_BOOL32 m_bTransposed; 00057 00058 // Bounding box of the surface of revolution. 00059 ON_BoundingBox m_bbox; 00060 00061 /* 00062 Description: 00063 Use ON_RevSurface::New(...) instead of new ON_RevSurface(...) 00064 Returns: 00065 Pointer to an ON_RevSurface. Destroy by calling delete. 00066 Remarks: 00067 See static ON_Brep* ON_Brep::New() for details. 00068 */ 00069 static ON_RevSurface* New(); 00070 static ON_RevSurface* New( const ON_RevSurface& rev_surface ); 00071 00072 00073 ON_RevSurface(); 00074 ~ON_RevSurface(); 00075 ON_RevSurface( const ON_RevSurface& ); 00076 ON_RevSurface& operator=( const ON_RevSurface& ); 00077 00078 void Destroy(); 00079 00080 ON_BOOL32 SetAngleRadians( 00081 double start_angle_radians, 00082 double end_angle_radians 00083 ); 00084 00085 ON_BOOL32 SetAngleDegrees( 00086 double start_angle_degrees, 00087 double end_angle_degrees 00088 ); 00089 00091 // 00092 // overrides of virtual ON_Object functions 00093 // 00094 00095 // virtual ON_Object::SizeOf override 00096 unsigned int SizeOf() const; 00097 00098 // virtual ON_Object::DataCRC override 00099 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const; 00100 00101 /* 00102 Description: 00103 Tests an object to see if its data members are correctly 00104 initialized. 00105 Parameters: 00106 text_log - [in] if the object is not valid and text_log 00107 is not NULL, then a brief englis description of the 00108 reason the object is not valid is appened to the log. 00109 The information appended to text_log is suitable for 00110 low-level debugging purposes by programmers and is 00111 not intended to be useful as a high level user 00112 interface tool. 00113 Returns: 00114 @untitled table 00115 true object is valid 00116 false object is invalid, uninitialized, etc. 00117 Remarks: 00118 Overrides virtual ON_Object::IsValid 00119 */ 00120 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const; 00121 00122 void Dump( ON_TextLog& ) const; // for debugging 00123 00124 // Use ON_BinaryArchive::WriteObject() and ON_BinaryArchive::ReadObject() 00125 // for top level serialization. These Read()/Write() members should just 00126 // write/read specific definitions. In particular, they should not write/ 00127 // read any chunk typecode or length information. The default 00128 // implementations return false and do nothing. 00129 ON_BOOL32 Write( 00130 ON_BinaryArchive& // serialize definition to binary archive 00131 ) const; 00132 00133 ON_BOOL32 Read( 00134 ON_BinaryArchive& // restore definition from binary archive 00135 ); 00136 00138 // 00139 // overrides of virtual ON_Geometry functions 00140 // 00141 int Dimension() const; 00142 00143 ON_BOOL32 GetBBox( // returns true if successful 00144 double*, // boxmin[dim] 00145 double*, // boxmax[dim] 00146 ON_BOOL32 = false // true means grow box 00147 ) const; 00148 00149 void ClearBoundingBox(); 00150 00151 ON_BOOL32 Transform( 00152 const ON_Xform& 00153 ); 00154 00156 // 00157 // overrides of virtual ON_Surface functions 00158 // 00159 00160 ON_BOOL32 SetDomain( 00161 int dir, // 0 sets first parameter's domain, 1 gets second parameter's domain 00162 double t0, 00163 double t1 00164 ); 00165 00166 ON_Interval Domain( 00167 int // 0 gets first parameter's domain, 1 gets second parameter's domain 00168 ) const; 00169 00170 /* 00171 Description: 00172 Get an estimate of the size of the rectangle that would 00173 be created if the 3d surface where flattened into a rectangle. 00174 Parameters: 00175 width - [out] (corresponds to the first surface parameter) 00176 height - [out] (corresponds to the first surface parameter) 00177 Remarks: 00178 overrides virtual ON_Surface::GetSurfaceSize 00179 Returns: 00180 true if successful. 00181 */ 00182 ON_BOOL32 GetSurfaceSize( 00183 double* width, 00184 double* height 00185 ) const; 00186 00187 int SpanCount( 00188 int // 0 gets first parameter's domain, 1 gets second parameter's domain 00189 ) const; // number of smooth spans in curve 00190 00191 ON_BOOL32 GetSpanVector( // span "knots" 00192 int, // 0 gets first parameter's domain, 1 gets second parameter's domain 00193 double* // array of length SpanCount() + 1 00194 ) const; // 00195 00196 int Degree( // returns maximum algebraic degree of any span 00197 // ( or a good estimate if curve spans are not algebraic ) 00198 int // 0 gets first parameter's domain, 1 gets second parameter's domain 00199 ) const; 00200 00201 ON_BOOL32 GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus 00202 int, // 0 gets first parameter, 1 gets second parameter 00203 double, // t = parameter in domain 00204 double*, // tminus 00205 double* // tplus 00206 ) const; 00207 00208 /* 00209 Description: 00210 Test a surface of revolution to see if it is a portion 00211 of a sphere. 00212 Parameters: 00213 sphere - [out] if not NULL and true is returned, 00214 the sphere parameters are filled in. 00215 tolerance - [in] tolerance to use when checking 00216 Returns: 00217 true if the surface of revolution is a portion of a sphere. 00218 */ 00219 ON_BOOL32 IsSpherical( 00220 ON_Sphere* sphere = NULL, 00221 double tolerance = ON_ZERO_TOLERANCE 00222 ) const; 00223 00224 /* 00225 Description: 00226 Test a surface of revolution to see if it is a portion 00227 of a cylinder. 00228 Parameters: 00229 cylinder - [out] if not NULL and true is returned, 00230 the cylinder parameters are filled in. 00231 tolerance - [in] tolerance to use when checking 00232 Returns: 00233 true if the surface of revolution is a portion of a cylinder. 00234 */ 00235 ON_BOOL32 IsCylindrical( 00236 ON_Cylinder* cylinder = NULL, 00237 double tolerance = ON_ZERO_TOLERANCE 00238 ) const; 00239 00240 /* 00241 Description: 00242 Test a surface of revolution to see if it is a portion 00243 of a cone. 00244 Parameters: 00245 cone - [out] if not NULL and true is returned, 00246 the cone parameters are filled in. 00247 tolerance - [in] tolerance to use when checking 00248 Returns: 00249 true if the surface of revolution is a portion of a cone. 00250 */ 00251 ON_BOOL32 IsConical( 00252 ON_Cone* cone = NULL, 00253 double tolerance = ON_ZERO_TOLERANCE 00254 ) const; 00255 00256 /* 00257 Description: 00258 Test a surface to see if it is planar. 00259 Parameters: 00260 plane - [out] if not NULL and true is returned, 00261 the plane parameters are filled in. 00262 tolerance - [in] tolerance to use when checking 00263 Returns: 00264 true if there is a plane such that the maximum distance from 00265 the surface to the plane is <= tolerance. 00266 Remarks: 00267 Overrides virtual ON_Surface::IsPlanar. 00268 */ 00269 ON_BOOL32 IsPlanar( 00270 ON_Plane* plane = NULL, 00271 double tolerance = ON_ZERO_TOLERANCE 00272 ) const; 00273 00274 ON_BOOL32 IsClosed( // true if surface is closed in direction 00275 int // dir 0 = "s", 1 = "t" 00276 ) const; 00277 00278 ON_BOOL32 IsPeriodic( // true if surface is periodic in direction 00279 int // dir 0 = "s", 1 = "t" 00280 ) const; 00281 00282 ON_BOOL32 IsSingular( // true if surface side is collapsed to a point 00283 int // side of parameter space to test 00284 // 0 = south, 1 = east, 2 = north, 3 = west 00285 ) const; 00286 00287 /* 00288 Description: 00289 Search for a derivatitive, tangent, or curvature 00290 discontinuity. 00291 Parameters: 00292 dir - [in] If 0, then "u" parameter is checked. If 1, then 00293 the "v" parameter is checked. 00294 c - [in] type of continity to test for. 00295 t0 - [in] Search begins at t0. If there is a discontinuity 00296 at t0, it will be ignored. This makes it 00297 possible to repeatedly call GetNextDiscontinuity 00298 and step through the discontinuities. 00299 t1 - [in] (t0 != t1) If there is a discontinuity at t1 is 00300 will be ingored unless c is a locus discontinuity 00301 type and t1 is at the start or end of the curve. 00302 t - [out] if a discontinuity is found, then *t reports the 00303 parameter at the discontinuity. 00304 hint - [in/out] if GetNextDiscontinuity will be called 00305 repeatedly, passing a "hint" with initial value *hint=0 00306 will increase the speed of the search. 00307 dtype - [out] if not NULL, *dtype reports the kind of 00308 discontinuity found at *t. A value of 1 means the first 00309 derivative or unit tangent was discontinuous. A value 00310 of 2 means the second derivative or curvature was 00311 discontinuous. A value of 0 means teh curve is not 00312 closed, a locus discontinuity test was applied, and 00313 t1 is at the start of end of the curve. 00314 cos_angle_tolerance - [in] default = cos(1 degree) Used only 00315 when c is ON::G1_continuous or ON::G2_continuous. If the 00316 cosine of the angle between two tangent vectors is 00317 <= cos_angle_tolerance, then a G1 discontinuity is reported. 00318 curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used 00319 only when c is ON::G2_continuous. If K0 and K1 are 00320 curvatures evaluated from above and below and 00321 |K0 - K1| > curvature_tolerance, then a curvature 00322 discontinuity is reported. 00323 Returns: 00324 Parametric continuity tests c = (C0_continuous, ..., G2_continuous): 00325 00326 true if a parametric discontinuity was found strictly 00327 between t0 and t1. Note well that all curves are 00328 parametrically continuous at the ends of their domains. 00329 00330 Locus continuity tests c = (C0_locus_continuous, ...,G2_locus_continuous): 00331 00332 true if a locus discontinuity was found strictly between 00333 t0 and t1 or at t1 is the at the end of a curve. 00334 Note well that all open curves (IsClosed()=false) are locus 00335 discontinuous at the ends of their domains. All closed 00336 curves (IsClosed()=true) are at least C0_locus_continuous at 00337 the ends of their domains. 00338 */ 00339 bool GetNextDiscontinuity( 00340 int dir, 00341 ON::continuity c, 00342 double t0, 00343 double t1, 00344 double* t, 00345 int* hint=NULL, 00346 int* dtype=NULL, 00347 double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE, 00348 double curvature_tolerance=ON_SQRT_EPSILON 00349 ) const; 00350 00351 /* 00352 Description: 00353 Test continuity at a surface parameter value. 00354 Parameters: 00355 c - [in] continuity to test for 00356 s - [in] surface parameter to test 00357 t - [in] surface parameter to test 00358 hint - [in] evaluation hint 00359 point_tolerance - [in] if the distance between two points is 00360 greater than point_tolerance, then the surface is not C0. 00361 d1_tolerance - [in] if the difference between two first derivatives is 00362 greater than d1_tolerance, then the surface is not C1. 00363 d2_tolerance - [in] if the difference between two second derivatives is 00364 greater than d2_tolerance, then the surface is not C2. 00365 cos_angle_tolerance - [in] default = cos(1 degree) Used only when 00366 c is ON::G1_continuous or ON::G2_continuous. If the cosine 00367 of the angle between two normal vectors 00368 is <= cos_angle_tolerance, then a G1 discontinuity is reported. 00369 curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when 00370 c is ON::G2_continuous. If K0 and K1 are curvatures evaluated 00371 from above and below and |K0 - K1| > curvature_tolerance, 00372 then a curvature discontinuity is reported. 00373 Returns: 00374 true if the surface has at least the c type continuity at the parameter t. 00375 Remarks: 00376 Overrides virtual ON_Surface::IsContinuous 00377 */ 00378 bool IsContinuous( 00379 ON::continuity c, 00380 double s, 00381 double t, 00382 int* hint = NULL, 00383 double point_tolerance=ON_ZERO_TOLERANCE, 00384 double d1_tolerance=ON_ZERO_TOLERANCE, 00385 double d2_tolerance=ON_ZERO_TOLERANCE, 00386 double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE, 00387 double curvature_tolerance=ON_SQRT_EPSILON 00388 ) const; 00389 00390 ON_BOOL32 Reverse( // reverse parameterizatrion, Domain changes from [a,b] to [-b,-a] 00391 int // dir 0 = "s", 1 = "t" 00392 ); 00393 00394 ON_BOOL32 Transpose(); // transpose surface parameterization (swap "s" and "t") 00395 00396 ON_BOOL32 Evaluate( // returns false if unable to evaluate 00397 double, double, // evaluation parameters (see m_bTransposed) 00398 int, // number of derivatives (>=0) 00399 int, // array stride (>=Dimension()) 00400 double*, // array of length stride*(ndir+1)*(ndir+2)/2 00401 int = 0, // optional - determines which quadrant to evaluate from 00402 // 0 = default 00403 // 1 from NE quadrant 00404 // 2 from NW quadrant 00405 // 3 from SW quadrant 00406 // 4 from SE quadrant 00407 int* = 0 // optional - evaluation hint (int[2]) used to speed 00408 // repeated evaluations 00409 ) const; 00410 00411 /* 00412 Description: 00413 Get isoparametric curve. 00414 Overrides virtual ON_Surface::IsoCurve. 00415 Parameters: 00416 dir - [in] 0 first parameter varies and second parameter is constant 00417 e.g., point on IsoCurve(0,c) at t is srf(t,c) 00418 1 first parameter is constant and second parameter varies 00419 e.g., point on IsoCurve(1,c) at t is srf(c,t) 00420 00421 c - [in] value of constant parameter 00422 Returns: 00423 Isoparametric curve. 00424 */ 00425 ON_Curve* IsoCurve( 00426 int dir, 00427 double c 00428 ) const; 00429 00430 /* 00431 Description: 00432 Removes the portions of the surface outside of the specified interval. 00433 00434 Parameters: 00435 dir - [in] 0 The domain specifies an sub-interval of Domain(0) 00436 (the first surface parameter). 00437 1 The domain specifies an sub-interval of Domain(1) 00438 (the second surface parameter). 00439 domain - [in] interval of the surface to keep. If dir is 0, then 00440 the portions of the surface with parameters (s,t) satisfying 00441 s < Domain(0).Min() or s > Domain(0).Max() are trimmed away. 00442 If dir is 1, then the portions of the surface with parameters 00443 (s,t) satisfying t < Domain(1).Min() or t > Domain(1).Max() 00444 are trimmed away. 00445 */ 00446 ON_BOOL32 Trim( 00447 int dir, 00448 const ON_Interval& domain 00449 ); 00450 00451 /* 00452 Description: 00453 Where possible, analytically extends surface to include domain. 00454 Parameters: 00455 dir - [in] 0 new Domain(0) will include domain. 00456 (the first surface parameter). 00457 1 new Domain(1) will include domain. 00458 (the second surface parameter). 00459 domain - [in] if domain is not included in surface domain, 00460 surface will be extended so that its domain includes domain. 00461 Will not work if surface is closed in direction dir. 00462 Original surface is identical to the restriction of the 00463 resulting surface to the original surface domain, 00464 Returns: 00465 true if successful. 00466 */ 00467 bool Extend( 00468 int dir, 00469 const ON_Interval& domain 00470 ); 00471 00472 /* 00473 Description: 00474 Splits (divides) the surface into two parts at the 00475 specified parameter. 00476 00477 Parameters: 00478 dir - [in] 0 The surface is split vertically. The "west" side 00479 is returned in "west_or_south_side" and the "east" 00480 side is returned in "east_or_north_side". 00481 1 The surface is split horizontally. The "south" side 00482 is returned in "west_or_south_side" and the "north" 00483 side is returned in "east_or_north_side". 00484 c - [in] value of constant parameter in interval returned 00485 by Domain(dir) 00486 west_or_south_side - [out] west/south portion of surface returned here 00487 east_or_north_side - [out] east/north portion of surface returned here 00488 00489 Example: 00490 00491 ON_NurbsSurface srf = ...; 00492 int dir = 1; 00493 ON_RevSurface* south_side = 0; 00494 ON_RevSurface* north_side = 0; 00495 srf.Split( dir, srf.Domain(dir).Mid() south_side, north_side ); 00496 00497 */ 00498 ON_BOOL32 Split( 00499 int dir, 00500 double c, 00501 ON_Surface*& west_or_south_side, 00502 ON_Surface*& east_or_north_side 00503 ) const; 00504 00505 int GetNurbForm( // returns 0: unable to create NURBS representation 00506 // with desired accuracy. 00507 // 1: success - returned NURBS parameterization 00508 // matches the surface's to wthe desired accuracy 00509 // 2: success - returned NURBS point locus matches 00510 // the surfaces's to the desired accuracy but, on 00511 // the interior of the surface's domain, the 00512 // surface's parameterization and the NURBS 00513 // parameterization may not match to the 00514 // desired accuracy. 00515 ON_NurbsSurface&, 00516 double = 0.0 00517 ) const; 00518 00519 int HasNurbForm( // returns 0: unable to create NURBS representation 00520 // with desired accuracy. 00521 // 1: success - returned NURBS parameterization 00522 // matches the surface's to wthe desired accuracy 00523 // 2: success - returned NURBS point locus matches 00524 // the surfaces's to the desired accuracy but, on 00525 // the interior of the surface's domain, the 00526 // surface's parameterization and the NURBS 00527 // parameterization may not match to the 00528 // desired accuracy. 00529 ) const; 00530 00531 bool GetSurfaceParameterFromNurbFormParameter( 00532 double nurbs_s, double nurbs_t, 00533 double* surface_s, double* surface_t 00534 ) const; 00535 00536 bool GetNurbFormParameterFromSurfaceParameter( 00537 double surface_s, double surface_t, 00538 double* nurbs_s, double* nurbs_t 00539 ) const; 00540 }; 00541 00542 #endif