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