1 /* $NoKeywords: $ */ 2 /* 3 // 4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. 5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert 6 // McNeel & Associates. 7 // 8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 10 // MERCHANTABILITY ARE HEREBY DISCLAIMED. 11 // 12 // For complete openNURBS copyright information see <http://www.opennurbs.org>. 13 // 14 //////////////////////////////////////////////////////////////// 15 */ 16 17 //////////////////////////////////////////////////////////////// 18 // 19 // Definition of NURBS surface 20 // 21 //////////////////////////////////////////////////////////////// 22 23 #if !defined(OPENNURBS_NURBSSURFACE_INC_) 24 #define OPENNURBS_NURBSSURFACE_INC_ 25 26 class ON_CLASS ON_TensorProduct 27 { 28 // Pure virtual tensor passed to ON_NurbsSurface::TensorProduct() 29 public: 30 ON_TensorProduct(); 31 32 virtual 33 ~ON_TensorProduct(); 34 35 // Evaluate() must define a function T:R^dimA X R^dimB -> R^Dimension() 36 // such that 37 // 38 // T(a*A0 + (1-a)*A1, B) = a*T(A0,B) + (1-a)*T(A1,B) and 39 // T(A, b*B0 + (1-b)*B1) = b*T(A,B0) + (1-b)*T(A,B1). 40 virtual 41 int DimensionA() const = 0; // dimension of A space 42 43 virtual 44 int DimensionB() const = 0; // dimension of B space 45 46 virtual 47 int DimensionC() const = 0; // dimension of range space 48 49 virtual 50 bool Evaluate( double, // a 51 const double*, // A 52 double, // b 53 const double*, // B 54 double* // C 55 ) = 0; 56 57 }; 58 59 class ON_Brep; 60 class ON_NurbsSurface; 61 62 class ON_CLASS ON_NurbsSurface : public ON_Surface 63 { 64 ON_OBJECT_DECLARE(ON_NurbsSurface); 65 66 public: 67 /* 68 Description: 69 Use ON_NurbsSurface::New(...) instead of new ON_NurbsSurface(...) 70 Returns: 71 Pointer to an ON_NurbsSurface. Destroy by calling delete. 72 Remarks: 73 See static ON_Brep* ON_Brep::New() for details. 74 */ 75 static ON_NurbsSurface* New(); 76 static ON_NurbsSurface* New( 77 const ON_NurbsSurface& nurbs_surface 78 ); 79 static ON_NurbsSurface* New( 80 const ON_BezierSurface& bezier_surface 81 ); 82 static ON_NurbsSurface* New( 83 int dimension, 84 ON_BOOL32 bIsRational, 85 int order0, 86 int order1, 87 int cv_count0, 88 int cv_count1 89 ); 90 91 ON_NurbsSurface(); 92 ON_NurbsSurface(const ON_NurbsSurface& nurbs_surface); 93 ON_NurbsSurface(const ON_BezierSurface& bezier_surface); 94 ON_NurbsSurface( 95 int dimension, // dimension (>= 1) 96 ON_BOOL32 bIsRational, // true to make a rational NURBS 97 int order0, // order0 (>= 2) 98 int order1, // order1 (>= 2) 99 int cv_count0, // cv count0 (>= order0) 100 int cv_count1 // cv count1 (>= order1) 101 ); 102 103 // virtual ON_Object::SizeOf override 104 unsigned int SizeOf() const; 105 106 // virtual ON_Object::DataCRC override 107 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const; 108 109 /* 110 Description: 111 See if this and other are same NURBS geometry. 112 Parameters: 113 other - [in] other NURBS surface 114 bIgnoreParameterization - [in] if true, parameterization 115 and orientaion are ignored. 116 tolerance - [in] tolerance to use when comparing 117 control points. 118 Returns: 119 true if curves are tne same. 120 */ 121 bool IsDuplicate( 122 const ON_NurbsSurface& other, 123 bool bIgnoreParameterization, 124 double tolerance = ON_ZERO_TOLERANCE 125 ) const; 126 127 void Initialize(void); // zeros all fields 128 129 ON_BOOL32 Create( 130 int dim, // dimension (>= 1) 131 ON_BOOL32 is_rat, // true to make a rational NURBS 132 int order0, // order0 (>= 2) 133 int order1, // order1 (>= 2) 134 int cv_count0, // cv count0 (>= order0) 135 int cv_count1 // cv count1 (>= order1) 136 ); 137 138 /* 139 Description: 140 Create a ruled surface from two curves. 141 Parameters: 142 curveA - [in] (must have same NURBS form knots as curveB) 143 curveB - [in] (must have same NURBS form knots as curveA) 144 curveA_domain - [in] if not NULL, then this is a subdomain 145 of curveA to use for the ruled surface. 146 curveB_domain - [in] if not NULL, then this is a subdomain 147 of curveA to use for the ruled surface. 148 Returns: 149 @untitled table 150 0 failure 151 1 success - parameterization is exact 152 2 success - parameterization is not exact 153 Remarks: 154 The ruling parameter is the second surface parameter and 155 it is in the interval [0,1]. 156 The true ruled surface has parameterization 157 srf(s,t) = (1.0-t)*curveA(s) + t*curveB(s). 158 The returned NURBS surface has parameterization 159 srf(s,t) = (1.0-t)*nurbs_curveA(s) + t*nurbs_curveB(s), 160 where nurbs_curveX is the NURBS form of curveX. If the 161 parameterization of nurbs_curveX does not match the 162 parameterization of curveX, then 2 is returned. 163 */ 164 virtual 165 int CreateRuledSurface( 166 const ON_Curve& curveA, 167 const ON_Curve& curveB, 168 const ON_Interval* curveA_domain = NULL, 169 const ON_Interval* curveB_domain = NULL 170 ); 171 172 /* 173 Description: 174 Create a cone surface from a curve to a point. 175 Parameters: 176 apex_point - [in] 177 curve - [in] 178 curve_domain - [in] if not NULL, then this is a subdomain 179 of curve to use for the ruled surface. 180 Returns: 181 @untitled table 182 0 failure 183 1 success - parameterization is exact 184 2 success - parameterization is not exact 185 Remarks: 186 The ruling parameter is the second surface parameter and 187 it is in the interval [0,1]. 188 The true cone surface has parameterization 189 srf(s,t) = (1.0-t)*curve(s) + t*apex_point. 190 The returned NURBS surface has parameterization 191 srf(s,t) = (1.0-t)*nurbs_curve(s) + t*apex_point, 192 where nurbs_curve is the NURBS form of curve. If the 193 parameterization of nurbs_curve does not match the 194 parameterization of curve, then 2 is returned. 195 */ 196 int CreateConeSurface( 197 ON_3dPoint apex_point, 198 const ON_Curve& curve, 199 const ON_Interval* curve_domain = NULL 200 ); 201 202 /* 203 Description: 204 Collapse the side of a NURBS surface to a single point. 205 Parameters: 206 side - [in] 0 = collapse south side, 207 1 = collapse east side, 208 2 = collapse north side, 209 3 = collapse west side 210 point - [in] point to collapse to. If point is ON_unset_point, 211 the the current location of the start of the side 212 is used. 213 Returns: 214 True if successful. 215 Remarks: 216 If the surface is rational, the weights of the side control 217 points must be set before calling CollapseSide. 218 */ 219 bool CollapseSide( 220 int side, 221 ON_3dPoint point = ON_unset_point 222 ); 223 224 void Destroy(); 225 226 virtual ~ON_NurbsSurface(); 227 228 void EmergencyDestroy(); // call if memory used by this class becomes invalid 229 230 ON_NurbsSurface& operator=(const ON_NurbsSurface&); 231 232 /* 233 Description: 234 Set NURBS surface equal to bezier surface with domain [0,1]x[0,1]. 235 Parameters: 236 bezier_surface - [in] 237 */ 238 ON_NurbsSurface& operator=( 239 const ON_BezierSurface& bezier_surface 240 ); 241 242 ///////////////////////////////////////////////////////////////// 243 // ON_Object overrides 244 245 /* 246 Description: 247 Tests an object to see if its data members are correctly 248 initialized. 249 Parameters: 250 text_log - [in] if the object is not valid and text_log 251 is not NULL, then a brief englis description of the 252 reason the object is not valid is appened to the log. 253 The information appended to text_log is suitable for 254 low-level debugging purposes by programmers and is 255 not intended to be useful as a high level user 256 interface tool. 257 Returns: 258 @untitled table 259 true object is valid 260 false object is invalid, uninitialized, etc. 261 Remarks: 262 Overrides virtual ON_Object::IsValid 263 */ 264 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const; 265 266 void Dump( ON_TextLog& ) const; // for debugging 267 268 ON_BOOL32 Write( 269 ON_BinaryArchive& // open binary file 270 ) const; 271 272 ON_BOOL32 Read( 273 ON_BinaryArchive& // open binary file 274 ); 275 276 ///////////////////////////////////////////////////////////////// 277 // ON_Geometry overrides 278 279 int Dimension() const; 280 281 ON_BOOL32 GetBBox( // returns true if successful 282 double*, // minimum 283 double*, // maximum 284 ON_BOOL32 = false // true means grow box 285 ) const; 286 287 ON_BOOL32 Transform( 288 const ON_Xform& 289 ); 290 291 // virtual ON_Geometry::IsDeformable() override 292 bool IsDeformable() const; 293 294 // virtual ON_Geometry::MakeDeformable() override 295 bool MakeDeformable(); 296 297 ON_BOOL32 SwapCoordinates( 298 int, int // indices of coords to swap 299 ); 300 301 ///////////////////////////////////////////////////////////////// 302 // ON_Surface overrides 303 304 ON_BOOL32 SetDomain( 305 int dir, // 0 sets first parameter's domain, 1 gets second parameter's domain 306 double t0, 307 double t1 308 ); 309 310 ON_Interval Domain( 311 int // 0 gets first parameter's domain, 1 gets second parameter's domain 312 ) const; 313 314 315 /* 316 Description: 317 Get an estimate of the size of the rectangle that would 318 be created if the 3d surface where flattened into a rectangle. 319 Parameters: 320 width - [out] (corresponds to the first surface parameter) 321 height - [out] (corresponds to the first surface parameter) 322 Remarks: 323 overrides virtual ON_Surface::GetSurfaceSize 324 Returns: 325 true if successful. 326 */ 327 ON_BOOL32 GetSurfaceSize( 328 double* width, 329 double* height 330 ) const; 331 332 int SpanCount( 333 int // 0 gets first parameter's domain, 1 gets second parameter's domain 334 ) const; // number of smooth spans in curve 335 336 ON_BOOL32 GetSpanVector( // span "knots" 337 int, // 0 gets first parameter's domain, 1 gets second parameter's domain 338 double* // array of length SpanCount() + 1 339 ) const; // 340 341 int Degree( // returns maximum algebraic degree of any span 342 // ( or a good estimate if curve spans are not algebraic ) 343 int // 0 gets first parameter's domain, 1 gets second parameter's domain 344 ) const; 345 346 ON_BOOL32 GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus 347 int, // 0 gets first parameter, 1 gets second parameter 348 double, // t = parameter in domain 349 double*, // tminus 350 double* // tplus 351 ) const; 352 353 /* 354 Description: 355 Test a surface to see if it is planar. 356 Parameters: 357 plane - [out] if not NULL and true is returned, 358 the plane parameters are filled in. 359 tolerance - [in] tolerance to use when checking 360 Returns: 361 true if there is a plane such that the maximum distance from 362 the surface to the plane is <= tolerance. 363 Remarks: 364 Overrides virtual ON_Surface::IsPlanar. 365 */ 366 ON_BOOL32 IsPlanar( 367 ON_Plane* plane = NULL, 368 double tolerance = ON_ZERO_TOLERANCE 369 ) const; 370 371 ON_BOOL32 IsClosed( // true if NURBS surface is closed (either surface has 372 int // dir // clamped end knots and euclidean location of start 373 ) const; // CV = euclidean location of end CV, or surface is 374 // periodic.) 375 376 ON_BOOL32 IsPeriodic( // true if NURBS surface is periodic (degree > 1, 377 int // dir // periodic knot vector, last degree many CVs 378 ) const; // are duplicates of first degree many CVs.) 379 380 ON_BOOL32 IsSingular( // true if surface side is collapsed to a point 381 int // side of parameter space to test 382 // 0 = south, 1 = east, 2 = north, 3 = west 383 ) const; 384 385 /* 386 Description: 387 Search for a derivatitive, tangent, or curvature 388 discontinuity. 389 Parameters: 390 dir - [in] If 0, then "u" parameter is checked. If 1, then 391 the "v" parameter is checked. 392 c - [in] type of continity to test for. 393 t0 - [in] Search begins at t0. If there is a discontinuity 394 at t0, it will be ignored. This makes it 395 possible to repeatedly call GetNextDiscontinuity 396 and step through the discontinuities. 397 t1 - [in] (t0 != t1) If there is a discontinuity at t1 is 398 will be ingored unless c is a locus discontinuity 399 type and t1 is at the start or end of the curve. 400 t - [out] if a discontinuity is found, then *t reports the 401 parameter at the discontinuity. 402 hint - [in/out] if GetNextDiscontinuity will be called 403 repeatedly, passing a "hint" with initial value *hint=0 404 will increase the speed of the search. 405 dtype - [out] if not NULL, *dtype reports the kind of 406 discontinuity found at *t. A value of 1 means the first 407 derivative or unit tangent was discontinuous. A value 408 of 2 means the second derivative or curvature was 409 discontinuous. A value of 0 means teh curve is not 410 closed, a locus discontinuity test was applied, and 411 t1 is at the start of end of the curve. 412 cos_angle_tolerance - [in] default = cos(1 degree) Used only 413 when c is ON::G1_continuous or ON::G2_continuous. If the 414 cosine of the angle between two tangent vectors is 415 <= cos_angle_tolerance, then a G1 discontinuity is reported. 416 curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used 417 only when c is ON::G2_continuous. If K0 and K1 are 418 curvatures evaluated from above and below and 419 |K0 - K1| > curvature_tolerance, then a curvature 420 discontinuity is reported. 421 Returns: 422 Parametric continuity tests c = (C0_continuous, ..., G2_continuous): 423 424 true if a parametric discontinuity was found strictly 425 between t0 and t1. Note well that all curves are 426 parametrically continuous at the ends of their domains. 427 428 Locus continuity tests c = (C0_locus_continuous, ...,G2_locus_continuous): 429 430 true if a locus discontinuity was found strictly between 431 t0 and t1 or at t1 is the at the end of a curve. 432 Note well that all open curves (IsClosed()=false) are locus 433 discontinuous at the ends of their domains. All closed 434 curves (IsClosed()=true) are at least C0_locus_continuous at 435 the ends of their domains. 436 */ 437 bool GetNextDiscontinuity( 438 int dir, 439 ON::continuity c, 440 double t0, 441 double t1, 442 double* t, 443 int* hint=NULL, 444 int* dtype=NULL, 445 double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE, 446 double curvature_tolerance=ON_SQRT_EPSILON 447 ) const; 448 449 /* 450 Description: 451 Test continuity at a surface parameter value. 452 Parameters: 453 c - [in] continuity to test for 454 s - [in] surface parameter to test 455 t - [in] surface parameter to test 456 hint - [in] evaluation hint 457 point_tolerance - [in] if the distance between two points is 458 greater than point_tolerance, then the surface is not C0. 459 d1_tolerance - [in] if the difference between two first derivatives is 460 greater than d1_tolerance, then the surface is not C1. 461 d2_tolerance - [in] if the difference between two second derivatives is 462 greater than d2_tolerance, then the surface is not C2. 463 cos_angle_tolerance - [in] default = cos(1 degree) Used only when 464 c is ON::G1_continuous or ON::G2_continuous. If the cosine 465 of the angle between two normal vectors 466 is <= cos_angle_tolerance, then a G1 discontinuity is reported. 467 curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when 468 c is ON::G2_continuous. If K0 and K1 are curvatures evaluated 469 from above and below and |K0 - K1| > curvature_tolerance, 470 then a curvature discontinuity is reported. 471 Returns: 472 true if the surface has at least the c type continuity at the parameter t. 473 Remarks: 474 Overrides virtual ON_Surface::IsContinuous 475 */ 476 bool IsContinuous( 477 ON::continuity c, 478 double s, 479 double t, 480 int* hint = NULL, 481 double point_tolerance=ON_ZERO_TOLERANCE, 482 double d1_tolerance=ON_ZERO_TOLERANCE, 483 double d2_tolerance=ON_ZERO_TOLERANCE, 484 double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE, 485 double curvature_tolerance=ON_SQRT_EPSILON 486 ) const; 487 488 ON_BOOL32 Reverse( // reverse parameterizatrion, Domain changes from [a,b] to [-b,-a] 489 int // dir 0 = "s", 1 = "t" 490 ); 491 492 ON_BOOL32 Transpose(); // transpose surface parameterization (swap "s" and "t") 493 494 ON_BOOL32 Evaluate( // returns false if unable to evaluate 495 double, double, // evaluation parameter 496 int, // number of derivatives (>=0) 497 int, // array stride (>=Dimension()) 498 double*, // array of length stride*(ndir+1)*(ndir+2)/2 499 int = 0, // optional - determines which quadrant to evaluate from 500 // 0 = default 501 // 1 from NE quadrant 502 // 2 from NW quadrant 503 // 3 from SW quadrant 504 // 4 from SE quadrant 505 int* = 0 // optional - evaluation hint (int[2]) used to speed 506 // repeated evaluations 507 ) const; 508 509 /* 510 Description: 511 Get isoparametric curve. 512 Overrides virtual ON_Surface::IsoCurve. 513 Parameters: 514 dir - [in] 0 first parameter varies and second parameter is constant 515 e.g., point on IsoCurve(0,c) at t is srf(t,c) 516 1 first parameter is constant and second parameter varies 517 e.g., point on IsoCurve(1,c) at t is srf(c,t) 518 519 c - [in] value of constant parameter 520 Returns: 521 Isoparametric curve. 522 */ 523 ON_Curve* IsoCurve( 524 int dir, 525 double c 526 ) const; 527 528 /* 529 Description: 530 Removes the portions of the surface outside of the specified interval. 531 Overrides virtual ON_Surface::Trim. 532 533 Parameters: 534 dir - [in] 0 The domain specifies an sub-interval of Domain(0) 535 (the first surface parameter). 536 1 The domain specifies an sub-interval of Domain(1) 537 (the second surface parameter). 538 domain - [in] interval of the surface to keep. If dir is 0, then 539 the portions of the surface with parameters (s,t) satisfying 540 s < Domain(0).Min() or s > Domain(0).Max() are trimmed away. 541 If dir is 1, then the portions of the surface with parameters 542 (s,t) satisfying t < Domain(1).Min() or t > Domain(1).Max() 543 are trimmed away. 544 */ 545 ON_BOOL32 Trim( 546 int dir, 547 const ON_Interval& domain 548 ); 549 550 /* 551 Description: 552 Where possible, analytically extends surface to include domain. 553 Parameters: 554 dir - [in] 0 new Domain(0) will include domain. 555 (the first surface parameter). 556 1 new Domain(1) will include domain. 557 (the second surface parameter). 558 domain - [in] if domain is not included in surface domain, 559 surface will be extended so that its domain includes domain. 560 Will not work if surface is closed in direction dir. 561 Original surface is identical to the restriction of the 562 resulting surface to the original surface domain, 563 Returns: 564 true if successful. 565 */ 566 bool Extend( 567 int dir, 568 const ON_Interval& domain 569 ); 570 571 572 /* 573 Description: 574 Splits (divides) the surface into two parts at the 575 specified parameter. 576 Overrides virtual ON_Surface::Split. 577 578 Parameters: 579 dir - [in] 0 The surface is split vertically. The "west" side 580 is returned in "west_or_south_side" and the "east" 581 side is returned in "east_or_north_side". 582 1 The surface is split horizontally. The "south" side 583 is returned in "west_or_south_side" and the "north" 584 side is returned in "east_or_north_side". 585 c - [in] value of constant parameter in interval returned 586 by Domain(dir) 587 west_or_south_side - [out] west/south portion of surface returned here 588 east_or_north_side - [out] east/north portion of surface returned here 589 590 Example: 591 592 ON_NurbsSurface srf = ...; 593 int dir = 1; 594 ON_NurbsSurface* south_side = 0; 595 ON_NurbsSurface* north_side = 0; 596 srf.Split( dir, srf.Domain(dir).Mid() south_side, north_side ); 597 598 */ 599 ON_BOOL32 Split( 600 int dir, 601 double c, 602 ON_Surface*& west_or_south_side, 603 ON_Surface*& east_or_north_side 604 ) const; 605 606 /* 607 Description: 608 Offset surface. 609 Parameters: 610 offset_distance - [in] offset distance 611 tolerance - [in] Some surfaces do not have an exact offset that 612 can be represented using the same class of surface definition. 613 In that case, the tolerance specifies the desired accuracy. 614 max_deviation - [out] If this parameter is not NULL, the maximum 615 deviation from the returned offset to the true offset is returned 616 here. This deviation is zero except for cases where an exact 617 offset cannot be computed using the same class of surface definition. 618 Returns: 619 Offset surface. 620 */ 621 ON_Surface* Offset( 622 double offset_distance, 623 double tolerance, 624 double* max_deviation = NULL 625 ) const; 626 627 int GetNurbForm( // returns 0: unable to create NURBS representation 628 // with desired accuracy. 629 // 1: success - returned NURBS parameterization 630 // matches the surface's to wthe desired accuracy 631 // 2: success - returned NURBS point locus matches 632 // the surfaces's to the desired accuracy but, on 633 // the interior of the surface's domain, the 634 // surface's parameterization and the NURBS 635 // parameterization may not match to the 636 // desired accuracy. 637 ON_NurbsSurface&, 638 double = 0.0 // tolerance 639 ) const; 640 641 ///////////////////////////////////////////////////////////////// 642 // Interface 643 644 /* 645 Description: 646 Get the maximum length of a nurb surface's control polygon 647 rows and/or columns 648 Parameters: 649 dir - [in] 0 to get "u" direction length, 1 to get "v" 650 direction length 651 length - [out] maximum length of a polygon "row" in the 652 specified direction 653 Returns: 654 true if successful. 655 */ 656 double ControlPolygonLength( int dir ) const; 657 658 659 bool IsRational( // true if NURBS surface is rational 660 void 661 ) const; 662 663 int CVSize( // number of doubles per control vertex 664 void // = IsRational() ? Dim()+1 : Dim() 665 ) const; 666 667 int Order( // order = degree + 1 668 int // dir 0 = "s", 1 = "t" 669 ) const; 670 671 int CVCount( // number of control vertices 672 int // dir 0 = "s", 1 = "t" 673 ) const; 674 675 int CVCount( // total number of control vertices 676 void 677 ) const; 678 679 int KnotCount( // total number of knots in knot vector 680 int dir // dir 0 = "s", 1 = "t" 681 ) const; 682 683 /* 684 Description: 685 Expert user function to get a pointer to control vertex 686 memory. If you are not an expert user, please use 687 ON_NurbsSurface::GetCV( ON_3dPoint& ) or 688 ON_NurbsSurface::GetCV( ON_4dPoint& ). 689 Parameters: 690 i - [in] (0 <= i < m_cv_count[0]) 691 j - [in] (0 <= j < m_cv_count[1]) 692 Returns: 693 Pointer to control vertex. 694 Remarks: 695 If the NURBS surface is rational, the format of the 696 returned array is a homogeneos rational point with 697 length m_dim+1. If the NURBS surface is not rational, 698 the format of the returned array is a nonrational 699 euclidean point with length m_dim. 700 See Also 701 ON_NurbsSurface::CVStyle 702 ON_NurbsSurface::GetCV 703 ON_NurbsSurface::Weight 704 */ 705 double* CV( 706 int i, 707 int j 708 ) const; 709 710 /* 711 Description: 712 Returns the style of control vertices in the m_cv array. 713 Returns: 714 @untitled table 715 ON::not_rational m_is_rat is false 716 ON::homogeneous_rational m_is_rat is true 717 */ 718 ON::point_style CVStyle() const; 719 720 double Weight( // get value of control vertex weight 721 int i, int j // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 722 ) const; 723 724 ON_BOOL32 SetWeight( // get value of control vertex weight 725 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 726 double weight 727 ); 728 729 ON_BOOL32 SetCV( // set a single control vertex 730 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 731 ON::point_style, // style of input point 732 const double* cv // value of control vertex 733 ); 734 735 ON_BOOL32 SetCV( // set a single control vertex 736 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 737 const ON_3dPoint& cv// value of control vertex 738 // If NURBS is rational, weight 739 // will be set to 1. 740 ); 741 742 ON_BOOL32 SetCV( // set a single control vertex 743 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 744 const ON_4dPoint& cv// value of control vertex 745 ); 746 747 ON_BOOL32 SetCVRow( // Sets CV( *, row_index ) 748 int row_index, // row_index >= 0 and < m_cv_count[1] 749 const ON_3dPoint& cv // value of control vertex 750 // If NURBS is rational, weight 751 // will be set to 1. 752 ); 753 754 ON_BOOL32 SetCVRow( // Sets CV( *, row_index ) 755 int row_index, // row_index >= 0 and < m_cv_count[1] 756 int v_stride, // v stride 757 const double* v // v[] = values (same dim and is_rat as surface) 758 ); 759 760 ON_BOOL32 SetCVColumn( // Sets CV( col_index, * ) 761 int col_index, // col_index >= 0 and < m_cv_count[0] 762 const ON_3dPoint& cv // value of control vertex 763 // If NURBS is rational, weight 764 // will be set to 1. 765 ); 766 767 ON_BOOL32 SetCVColumn( // Sets CV( col_index, * ) 768 int col_index, // col_index >= 0 and < m_cv_count[0] 769 int v_stride, // v stride 770 const double* v // v[] = values (same dim and is_rat as surface) 771 ); 772 773 ON_BOOL32 GetCV( // get a single control vertex 774 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 775 ON::point_style, // style to use for output point 776 double* cv // array of length >= CVSize() 777 ) const; 778 779 ON_BOOL32 GetCV( // get a single control vertex 780 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 781 ON_3dPoint& cv // gets euclidean cv when NURBS is rational 782 ) const; 783 784 ON_BOOL32 GetCV( // get a single control vertex 785 int i, int j, // CV index ( 0 <= i <= CVCount(0), 0 <= j <= CVCount(1) 786 ON_4dPoint& cv // gets homogeneous cv 787 ) const; 788 789 int SetKnot( 790 int dir, // dir 0 = "s", 1 = "t" 791 int knot_index, // knot index ( 0 to KnotCount - 1 ) 792 double knot_value // value for knot 793 ); 794 795 double Knot( 796 int dir, // dir 0 = "s", 1 = "t" 797 int knot_index // knot index ( >= 0 and < Order + CV_count - 2 ) 798 ) const; 799 800 int KnotMultiplicity( 801 int dir, // dir 0 = "s", 1 = "t" 802 int knot_index // knot index ( >= 0 and < Order + CV_count - 2 ) 803 ) const; 804 805 const double* Knot( // knot[] array 806 int dir // dir 0 = "s", 1 = "t" 807 ) const; 808 809 // Description: 810 // Make knot vector a clamped uniform knot vector 811 // based on the current values of m_order and m_cv_count. 812 // Does not change values of control vertices. 813 // Parameters: 814 // dir - [in] 0 = u knots, 1 = v knots 815 // delta - [in] (>0.0) knot spacing. 816 // Returns: 817 // true if successful. 818 // Remarks: 819 // Allocates m_knot[] if it is not big enough. 820 // See Also: 821 // ON_MakeClampedUniformKnotVector 822 bool MakeClampedUniformKnotVector( 823 int dir, 824 double delta = 1.0 825 ); 826 827 // Description: 828 // Make knot vector a periodic uniform knot vector 829 // based on the current values of m_order and m_cv_count. 830 // Does not change values of control vertices. 831 // Parameters: 832 // dir - [in] 0 = u knots, 1 = v knots 833 // delta - [in] (>0.0) knot spacing. 834 // Returns: 835 // true if successful. 836 // Remarks: 837 // Allocates m_knot[] if it is not big enough. 838 // See Also: 839 // ON_MakePeriodicUniformKnotVector 840 bool MakePeriodicUniformKnotVector( 841 int dir, 842 double delta = 1.0 843 ); 844 845 846 bool IsClamped( // determine if knot vector is clamped 847 int dir, // dir 0 = "s", 1 = "t" 848 int end = 2 // end to check: 0 = start, 1 = end, 2 = start and end 849 ) const; 850 851 double SuperfluousKnot( 852 int dir, // dir 0 = "s", 1 = "t" 853 int end // 0 = start, 1 = end 854 ) const; 855 856 double GrevilleAbcissa( 857 int dir, // dir 858 int cv_index // index (0 <= index < CVCount(dir) 859 ) const; 860 861 bool GetGrevilleAbcissae( // see ON_GetGrevilleAbcissa() for details 862 int dir, // dir 863 double* g // g[cv count] 864 ) const; 865 866 bool SetClampedGrevilleKnotVector( 867 int dir, // dir 868 int g_stride, // g_stride 869 const double* g // g[], CVCount(dir) many Greville abcissa 870 ); 871 872 bool SetPeriodicGrevilleKnotVector( 873 int dir, // dir 874 int g_stride, // g_stride 875 const double* g // g[], Greville abcissa 876 ); 877 878 bool ZeroCVs(); // zeros all CVs (any weights set to 1); 879 880 bool ClampEnd( 881 int dir, // dir 0 = "s", 1 = "t" 882 int end // 0 = clamp start, 1 = clamp end, 2 = clamp start and end 883 ); 884 885 bool InsertKnot( 886 int dir, // dir 0 = "s", 1 = "t" 887 double knot_value, // value of knot 888 int knot_multiplicity=1 // multiplicity of knot ( >= 1 and <= degree ) 889 ); 890 891 bool MakeRational(); 892 893 bool MakeNonRational(); 894 895 bool IncreaseDegree( 896 int dir, // dir 0 = "s", 1 = "t" 897 int desired_degree // desired_degree 898 ); 899 900 bool ChangeDimension( 901 int desired_dimension // desired_dimension 902 ); 903 904 /* 905 Description: 906 If the surface is closed in direction dir, then modify it so that 907 the seam is at parameter t in the dir direction. 908 Parameters: 909 dir - [in] must be 0 or 1 910 t - [in] dir parameter of seam, must have Domain(dir).Includes(t). 911 The resulting surface domain in the dir direction will start at t. 912 Returns: 913 true if successful. 914 */ 915 ON_BOOL32 ChangeSurfaceSeam( 916 int dir, 917 double t 918 ); 919 920 921 // Creates a tensor product nurbs surface with srf(s,t) = T(A(s),B(t)); 922 ON_BOOL32 TensorProduct( 923 const ON_NurbsCurve&, // A 924 const ON_NurbsCurve&, // B 925 ON_TensorProduct& // T 926 ); 927 928 ///////////////////////////////////////////////////////////////// 929 // Tools for managing CV and knot memory 930 ON_BOOL32 ReserveKnotCapacity( // returns false if allocation fails 931 // does not change m_order or m_cv_count 932 int dir, // dir 0 = "s", 1 = "t" 933 int knot_array_capacity // minimum capacity of m_knot[] array 934 ); 935 ON_BOOL32 ReserveCVCapacity( // returns false if allocation fails 936 // does not change m_order or m_cv_count 937 int cv_array_capacity // minimum capacity of m_cv[] array 938 ); 939 940 /* 941 Description: 942 Convert a NURBS surface bispan into a bezier surface. 943 Parameters: 944 span_index0 - [in] Specifies the "u" span and must satisfy 945 0 <= span_index0 <= m_cv_count[0]-m_order[0] 946 m_knot[0][span_index0+m_order[0]-2] < m_knot[0][span_index0+m_order[0]-1] 947 span_index1 - [in] Specifies the "v" span and must satisfy 948 0 <= span_index1 <= m_cv_count[1]-m_order[1] 949 m_knot[1][span_index1+m_order[1]-2] < m_knot[1][span_index1+m_order[1]-1] 950 bezier_surface - [out] bezier surface returned here 951 Returns: 952 true if successful 953 false if input is not valid 954 */ 955 ON_BOOL32 ConvertSpanToBezier( 956 int span_index0, 957 int span_index1, 958 ON_BezierSurface& bezier_surface 959 ) const; 960 961 ///////////////////////////////////////////////////////////////// 962 // Implementation 963 public: 964 // NOTE: These members are left "public" so that expert users may efficiently 965 // create NURBS curves using the default constructor and borrow the 966 // knot and CV arrays from their native NURBS representation. 967 // No technical support will be provided for users who access these 968 // members directly. If you can't get your stuff to work, then use 969 // the constructor with the arguments and the SetKnot() and SetCV() 970 // functions to fill in the arrays. 971 972 int m_dim; // (>=1) 973 974 int m_is_rat; // 1 for rational B-splines. (Control vertices 975 // use homogeneous form.) 976 // 0 for non-rational B-splines. (Control 977 // verticies do not have a weight coordinate.) 978 979 int m_order[2]; // order = degree+1 (>=2) 980 981 int m_cv_count[2]; // number of control vertices ( >= order ) 982 983 // knot vector memory 984 985 int m_knot_capacity[2]; // If m_knot_capacity > 0, then m_knot[] 986 // is an array of at least m_knot_capacity 987 // doubles whose memory is managed by the 988 // ON_NurbsSurface class using rhmalloc(), 989 // onrealloc(), and rhfree(). 990 // If m_knot_capacity is 0 and m_knot is 991 // not NULL, then m_knot[] is assumed to 992 // be big enough for any requested operation 993 // and m_knot[] is not deleted by the 994 // destructor. 995 996 double* m_knot[2]; // Knot vector. ( The knot vector has length 997 // m_order+m_cv_count-2. ) 998 999 // control vertex net memory 1000 1001 int m_cv_stride[2]; // The pointer to start of "CV[i]" is 1002 // m_cv + i*m_cv_stride. 1003 1004 int m_cv_capacity; // If m_cv_capacity > 0, then m_cv[] is an array 1005 // of at least m_cv_capacity doubles whose 1006 // memory is managed by the ON_NurbsSurface 1007 // class using rhmalloc(), onrealloc(), and rhfree(). 1008 // If m_cv_capacity is 0 and m_cv is not 1009 // NULL, then m_cv[] is assumed to be big enough 1010 // for any requested operation and m_cv[] is not 1011 // deleted by the destructor. 1012 1013 double* m_cv; // Control points. 1014 // If m_is_rat is false, then control point is 1015 // 1016 // ( CV(i)[0], ..., CV(i)[m_dim-1] ). 1017 // 1018 // If m_is_rat is true, then the control point 1019 // is stored in HOMOGENEOUS form and is 1020 // 1021 // [ CV(i)[0], ..., CV(i)[m_dim] ]. 1022 // 1023 }; 1024 1025 1026 class ON_CLASS ON_NurbsCage : public ON_Geometry 1027 { 1028 ON_OBJECT_DECLARE(ON_NurbsCage); 1029 1030 public: 1031 ON_NurbsCage(); 1032 1033 ON_NurbsCage( 1034 int dim, 1035 bool is_rat, 1036 int order0, 1037 int order1, 1038 int order2, 1039 int cv_count0, 1040 int cv_count1, 1041 int cv_count2 1042 ); 1043 1044 ON_NurbsCage( 1045 const ON_BoundingBox& bbox, 1046 int order0, 1047 int order1, 1048 int order2, 1049 int cv_count0, 1050 int cv_count1, 1051 int cv_count2 1052 ); 1053 1054 ON_NurbsCage( 1055 const ON_3dPoint* box_corners, // array of 8 3d points 1056 int order0, 1057 int order1, 1058 int order2, 1059 int cv_count0, 1060 int cv_count1, 1061 int cv_count2 1062 ); 1063 1064 ON_NurbsCage( const ON_BezierCage& src ); 1065 1066 ~ON_NurbsCage(); 1067 1068 ON_NurbsCage(const ON_NurbsCage& src); 1069 1070 ON_NurbsCage& operator=(const ON_NurbsCage& src); 1071 1072 ON_NurbsCage& operator=(const ON_BezierCage& src); 1073 1074 1075 /* 1076 Description: 1077 Overrides the pure virtual ON_Object::IsValid function. 1078 Parameters: 1079 text_log - [in] If not null and the object is invalid, 1080 a brief description of the problem 1081 suitable for debugging C++ code 1082 is printed in this log. 1083 Returns: 1084 True if the orders are at least two, dimension is positive, 1085 knot vectors are valid, and the other fields are valid 1086 for the specified orders and dimension. 1087 */ 1088 ON_BOOL32 IsValid( 1089 ON_TextLog* text_log = NULL 1090 ) const; 1091 1092 /* 1093 Description: 1094 Overrides the pure virtual ON_Object::Dump function. 1095 Parameters: 1096 text_log - [in] A listing of the values of the members. 1097 */ 1098 void Dump( ON_TextLog& text_log) const; 1099 1100 /* 1101 Description: 1102 Overrides the pure virtual ON_Object::SizeOf function. 1103 Returns: 1104 An estimate of the amount of memory used by the class 1105 and its members. 1106 */ 1107 unsigned int SizeOf() const; 1108 1109 // virtual ON_Object::DataCRC override 1110 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const; 1111 1112 /* 1113 Description: 1114 Overrides the pure virtual ON_Object::Read function. 1115 Reads the definition of this class from an 1116 archive previously saved by ON_BezierVolue::Write. 1117 Parameters: 1118 archive - [in] target archive 1119 Returns: 1120 True if successful. 1121 */ 1122 ON_BOOL32 Read( 1123 ON_BinaryArchive& archive 1124 ); 1125 1126 /* 1127 Description: 1128 Overrides the pure virtual ON_Object::Write function. 1129 Saves the definition of this class in serial binary 1130 form that can be read by ON_BezierVolue::Read. 1131 Parameters: 1132 archive - [in] target archive 1133 Returns: 1134 True if successful. 1135 */ 1136 ON_BOOL32 Write( 1137 ON_BinaryArchive& archive 1138 ) const; 1139 1140 /* 1141 Description: 1142 Overrides the pure virtual ON_Object::ObjectType function. 1143 Saves the definition of this class in serial binary 1144 form that can be read by ON_BezierVolue::Read. 1145 Parameters: 1146 archive - [in] target archive 1147 Returns: 1148 True if successful. 1149 */ 1150 ON::object_type ObjectType() const; 1151 1152 /* 1153 Description: 1154 Overrides the pure virtual ON_Object::DestroyRuntimeCache function. 1155 Saves the definition of this class in serial binary 1156 form that can be read by ON_BezierVolue::Read. 1157 Parameters: 1158 bDelete - [in] if true, the cache is deleted. If false, the 1159 pointers to the cache are set to zero; this is done when 1160 the cache memory was allocated from a pool that has 1161 been destroyed and an attempt to free the memory would 1162 result in a crash. 1163 Returns: 1164 True if successful. 1165 */ 1166 void DestroyRuntimeCache( 1167 bool bDelete = true 1168 ); 1169 1170 1171 /* 1172 Description: 1173 Overrides virtual ON_Geometry::Dimension function. 1174 Gets a tight bounding box with respect to the coordinate 1175 system specified by the frame parameter. 1176 Parameters: 1177 bbox - [in/out] 1178 bGrowBox - [in] If true, the input bbox is grown to include 1179 this object's bounding box. 1180 frame - [in] if not null, this specifies the coordinate system 1181 frame. 1182 Returns: 1183 True if successful. 1184 */ 1185 int Dimension() const; 1186 1187 /* 1188 Description: 1189 Overrides virtual ON_Geometry::GetBBox function. 1190 Gets the world axis aligned bounding box that contains 1191 the NURBS volume's control points. The NURBS volume 1192 maps the unit cube into this box. 1193 Parameters: 1194 boxmin - [in] array of Dimension() doubles 1195 boxmax - [in] array of Dimension() doubles 1196 bGrowBox = [in] if true and the input is a valid box 1197 then the input box is grown to 1198 include this object's bounding box. 1199 Returns: 1200 true if successful. 1201 */ 1202 ON_BOOL32 GetBBox( 1203 double* boxmin, 1204 double* boxmax, 1205 int bGrowBox = false 1206 ) const; 1207 1208 /* 1209 Description: 1210 Get tight bounding box. 1211 Parameters: 1212 tight_bbox - [in/out] tight bounding box 1213 bGrowBox -[in] (default=false) 1214 If true and the input tight_bbox is valid, then returned 1215 tight_bbox is the union of the input tight_bbox and the 1216 surface's tight bounding box. 1217 xform -[in] (default=NULL) 1218 If not NULL, the tight bounding box of the transformed 1219 surface is calculated. The surface is not modified. 1220 Returns: 1221 True if a valid tight_bbox is returned. 1222 */ 1223 bool GetTightBoundingBox( 1224 ON_BoundingBox& tight_bbox, 1225 int bGrowBox = false, 1226 const ON_Xform* xform = 0 1227 ) const; 1228 1229 /* 1230 Description: 1231 Overrides virtual ON_Geometry::Transform function. 1232 Transforms NURBS volume. 1233 Parameters: 1234 xform - [in] 1235 Returns: 1236 true if successful. 1237 */ 1238 ON_BOOL32 Transform( 1239 const ON_Xform& xform 1240 ); 1241 1242 /* 1243 Description: 1244 Overrides virtual ON_Geometry::IsDeformable function. 1245 Returns: 1246 True because a NURBS volume can be accuratly modified 1247 with "squishy" transformations like projections, 1248 shears, an non-uniform scaling. 1249 */ 1250 bool IsDeformable() const; 1251 1252 /* 1253 Description: 1254 Overrides virtual ON_Geometry::MakeDeformable function. 1255 Returns: 1256 True because NURBS volumes are deformable. 1257 */ 1258 bool MakeDeformable(); 1259 1260 /* 1261 Returns: 1262 True if the cage is a parallelogram within the tolerance. 1263 This means the cage can be used as a starting point 1264 for cage deformations. 1265 */ 1266 bool IsParallelogram(double tolerance) const; 1267 1268 bool Create( 1269 int dim, 1270 bool is_rat, 1271 int order0, 1272 int order1, 1273 int order2, 1274 int cv_count0, 1275 int cv_count1, 1276 int cv_count2 1277 ); 1278 1279 /* 1280 Description: 1281 Create a Nurbs volume with corners defined by a bounding box. 1282 Parameters: 1283 box_corners - [in] 8 points that define corners of the volume 1284 1285 7______________6 1286 |\ |\ 1287 | \ | \ 1288 | \ _____________\ 1289 | 4 | 5 1290 | | | | 1291 | | | | 1292 3---|----------2 | 1293 \ | \ | 1294 \ |z \ | 1295 y \ | \ | 1296 \0_____________\1 1297 x 1298 1299 */ 1300 bool Create( 1301 const ON_BoundingBox& bbox, 1302 int order0, 1303 int order1, 1304 int order2, 1305 int cv_count0, 1306 int cv_count1, 1307 int cv_count2 1308 ); 1309 1310 /* 1311 Description: 1312 Create a nurbs volume from a 3d box 1313 Parameters: 1314 box_corners - [in] 8 points that define corners of the volume 1315 1316 7______________6 1317 |\ |\ 1318 | \ | \ 1319 | \ _____________\ 1320 | 4 | 5 1321 | | | | 1322 | | | | 1323 3---|----------2 | 1324 \ | \ | 1325 \ |t \ | 1326 s \ | \ | 1327 \0_____________\1 1328 r 1329 1330 */ 1331 bool Create( 1332 const ON_3dPoint* box_corners, 1333 int order0, 1334 int order1, 1335 int order2, 1336 int cv_count0, 1337 int cv_count1, 1338 int cv_count2 1339 ); 1340 1341 void Destroy(); 1342 1343 void EmergencyDestroy(); // call if memory used by ON_NurbsCage becomes invalid 1344 1345 ON_Interval Domain( 1346 int // dir 0 = "r", 1 = "s", 2 = "t" 1347 ) const; 1348 1349 bool Reverse( 1350 int dir // dir 0 = "r", 1 = "s", 2 = "t" 1351 ); 1352 1353 bool Transpose( 1354 int dir0, 1355 int dir1 1356 ); 1357 1358 bool ClampEnd( 1359 int dir, // dir 0 = "r", 1 = "s", 2 = "t" 1360 int end // 0 = clamp start, 1 = clamp end, 2 = clamp start and end 1361 ); 1362 1363 bool InsertKnot( 1364 int dir, // dir 0 = "r", 1 = "s", 2 = "t" 1365 double knot_value, // value of knot 1366 int knot_multiplicity=1 // multiplicity of knot ( >= 1 and <= degree ) 1367 ); 1368 1369 ON_BOOL32 IncreaseDegree( 1370 int dir, // dir 0 = "r", 1 = "s", 2 = "t" 1371 int desired_degree // desired_degree 1372 ); 1373 1374 ON_BOOL32 ChangeDimension( 1375 int desired_dimension // desired_dimension 1376 ); 1377 1378 /* 1379 Description: 1380 Evaluate the NURBS cage 1381 Parameters: 1382 r - [in] 1383 s - [in] 1384 t - [in] (r,s,t) = evaluation parameters 1385 der_count - [in] (>= 0) 1386 v_stride - [in] (>= m_dim) 1387 v - [out] An array of length v_stride*(der_count+1)(der_count+2)*(der_count+3)/6. 1388 The evaluation results are stored in this array. 1389 1390 P = v[0],...,v[m_dim-1] 1391 Dr = v[v_stride],... 1392 Ds = v[2*v_stride],... 1393 Dt = v[3*v_stride],... 1394 1395 In general, Dr^i Ds^j Dt^k is returned in v[n],...,v[n+m_dim-1], where 1396 1397 d = (i+j+k) 1398 n = v_stride*( d*(d+1)*(d+2)/6 + (j+k)*(j+k+1)/2 + k) 1399 1400 side - [in] specifies the span to use for the evaluation 1401 when r, s, or t is at a knot value. 1402 0 = default 1403 1 = from upper NE quadrant 1404 2 = from upper NW quadrant 1405 3 = from upper SW quadrant 1406 4 = from upper SE quadrant 1407 5 = from lower NE quadrant 1408 6 = from lower NW quadrant 1409 7 = from lower SW quadrant 1410 8 = from lower SE quadrant 1411 hint - [in/out] If a bunch of evaluations will be performed that 1412 tend to occur in the same region, then 1413 hint[3] can be used to speed the search for 1414 the evaluation span. The input value is 1415 used as a search hint and the output value 1416 records the span used for that evaluation. 1417 Example: 1418 1419 int der_count = 2; 1420 int v_stride = dim; 1421 double v[v_stride*(der_count+1)*(der_count+2)*(der_count+3)/6]; 1422 int side = 0; 1423 int hint[3]; hint[0] = 0; hint[1] = 0; hint[2] = 0; 1424 bool rc = cage.Evaluate(r,s,t,der_count,v_stride,v,side,hint); 1425 1426 ON_3dPoint P = v; 1427 1428 // first order partial derivatives 1429 ON_3dVector Dr = v + v_stride; 1430 ON_3dVector Ds = v + 2*v_stride; 1431 ON_3dVector Dt = v + 3*v_stride; 1432 1433 // second order partial derivatives 1434 ON_3dVector Drr = v + 4*v_stride; 1435 ON_3dVector Drs = v + 5*v_stride; 1436 ON_3dVector Drt = v + 6*v_stride; 1437 ON_3dVector Dss = v + 7*v_stride; 1438 ON_3dVector Dst = v + 8*v_stride; 1439 ON_3dVector Dtt = v + 8*v_stride; 1440 1441 Returns: 1442 True if successful 1443 See Also: 1444 ON_NurbsCage::PointAt 1445 */ 1446 bool Evaluate( 1447 double r, 1448 double s, 1449 double t, 1450 int der_count, 1451 int v_stride, 1452 double* v, 1453 int side=0, 1454 int* hint=0 1455 ) const; 1456 1457 /* 1458 Description: 1459 Evaluates bezer volume map. 1460 Parameters: 1461 rst - [in] 1462 Returns: 1463 Value of the nurbs volume map at (r,s,t). 1464 */ 1465 ON_3dPoint PointAt( 1466 double r, 1467 double s, 1468 double t 1469 ) const; 1470 1471 ON_NurbsSurface* IsoSurface( 1472 int dir, 1473 double c, 1474 ON_NurbsSurface* srf = 0 1475 ) const; 1476 1477 bool Trim( 1478 int dir, 1479 const ON_Interval& domain 1480 ); 1481 1482 bool Extend( 1483 int dir, 1484 const ON_Interval& domain 1485 ); 1486 1487 /* 1488 Description: 1489 Evaluates bezer volume map. 1490 Parameters: 1491 rst - [in] 1492 Returns: 1493 Value of the nurbs volume map at (rst.x,rst.y,rst.z). 1494 */ 1495 ON_3dPoint PointAt( 1496 ON_3dPoint rst 1497 ) const; 1498 1499 bool IsRational() const; 1500 1501 int CVSize() const; 1502 1503 int Order( 1504 int dir // dir 0 = "r", 1 = "s", 2 = "t" 1505 ) const; 1506 1507 int CVCount( // number of control vertices 1508 int // dir 0 = "r", 1 = "s", 2 = "t" 1509 ) const; 1510 1511 int CVCount( // total number of control vertices 1512 void 1513 ) const; 1514 1515 int KnotCount( // total number of knots in knot vector 1516 int dir // dir 0 = "r", 1 = "s", 2 = "t" 1517 ) const; 1518 1519 int Degree( 1520 int dir 1521 ) const; 1522 1523 1524 int SpanCount( 1525 int dir // dir 0 = "r", 1 = "s", 2 = "t" 1526 ) const; 1527 1528 bool GetSpanVector( 1529 int dir, // dir 0 = "r", 1 = "s", 2 = "t" 1530 double* span_vector 1531 ) const; 1532 1533 /* 1534 Description: 1535 Expert user function to get a pointer to control vertex 1536 memory. If you are not an expert user, please use 1537 ON_NurbsCage::GetCV( ON_3dPoint& ) or 1538 ON_NurbsCage::GetCV( ON_4dPoint& ). 1539 Parameters: 1540 cv_index0 - [in] (0 <= cv_index0 < m_order[0]) 1541 cv_index1 - [in] (0 <= cv_index1 < m_order[1]) 1542 Returns: 1543 Pointer to control vertex. 1544 Remarks: 1545 If the Nurbs surface is rational, the format of the 1546 returned array is a homogeneos rational point with 1547 length m_dim+1. If the Nurbs surface is not rational, 1548 the format of the returned array is a nonrational 1549 euclidean point with length m_dim. 1550 See Also 1551 ON_NurbsCage::CVStyle 1552 ON_NurbsCage::GetCV 1553 ON_NurbsCage::Weight 1554 */ 1555 double* CV( 1556 int i, 1557 int j, 1558 int k 1559 ) const; 1560 1561 /* 1562 Description: 1563 Returns the style of control vertices in the m_cv array. 1564 Returns: 1565 @untitled table 1566 ON::not_rational m_is_rat is false 1567 ON::homogeneous_rational m_is_rat is true 1568 */ 1569 ON::point_style CVStyle() const; 1570 1571 double Weight( // get value of control vertex weight 1572 int i, 1573 int j, 1574 int k 1575 ) const; 1576 1577 bool SetWeight( // get value of control vertex weight 1578 int i, 1579 int j, 1580 int k, 1581 double w 1582 ); 1583 1584 bool SetCV( // set a single control vertex 1585 int i, 1586 int j, 1587 int k, 1588 ON::point_style, // style of input point 1589 const double* // value of control vertex 1590 ); 1591 1592 // set a single control vertex 1593 // If NURBS is rational, weight 1594 // will be set to 1. 1595 bool SetCV( 1596 int i, 1597 int j, 1598 int k, 1599 const ON_3dPoint& point 1600 ); 1601 1602 // set a single control vertex 1603 // value of control vertex 1604 // If NURBS is not rational, euclidean 1605 // location of homogeneous point will 1606 // be used. 1607 bool SetCV( 1608 int i, 1609 int j, 1610 int k, 1611 const ON_4dPoint& hpoint 1612 ); 1613 1614 bool GetCV( // get a single control vertex 1615 int i, 1616 int j, 1617 int k, 1618 ON::point_style, // style to use for output point 1619 double* // array of length >= CVSize() 1620 ) const; 1621 1622 bool GetCV( // get a single control vertex 1623 int i, 1624 int j, 1625 int k, 1626 ON_3dPoint& // gets euclidean cv when NURBS is rational 1627 ) const; 1628 1629 bool GetCV( // get a single control vertex 1630 int i, 1631 int j, 1632 int k, 1633 ON_4dPoint& // gets homogeneous cv 1634 ) const; 1635 1636 /* 1637 Parameters: 1638 dir - [in] 0 = "r", 1 = "s", 2 = "t" 1639 knot_index - [in] 0 <= knot_index < KnotCount(dir) 1640 knot_value - [in] 1641 Returns: 1642 True if dir and knot_index parameters were valid and knot value 1643 was set. 1644 */ 1645 bool SetKnot( 1646 int dir, 1647 int knot_index, 1648 double knot_value 1649 ); 1650 1651 /* 1652 Parameters: 1653 dir - [in] 0 = "r", 1 = "s", 2 = "t" 1654 knot_index - [in] 0 <= knot_index < KnotCount(dir) 1655 Returns: 1656 Value of knot or ON_UNSET_VALUE if input parameters are not valid. 1657 */ 1658 double Knot( 1659 int dir, 1660 int knot_index 1661 ) const; 1662 1663 bool ZeroCVs(); // zeros control vertices and, if rational, sets weights to 1 1664 1665 bool MakeRational(); 1666 1667 bool MakeNonRational(); 1668 1669 bool IsClosed( // true if NURBS cage is closed (either cage has 1670 int // dir // clamped end knots and euclidean location of start 1671 ) const; // CV = euclidean location of end CV, or cage is 1672 // periodic.) 1673 1674 bool IsPeriodic( // true if NURBS cage is periodic (degree > 1, 1675 int // dir // periodic knot vector, last degree many CVs 1676 ) const; // are duplicates of first degree many CVs.) 1677 1678 bool IsSingular( // true if cage side is collapsed to a point 1679 int // side of parameter space to test 1680 // 0 = south, 1 = east, 2 = north, 3 = west 1681 ) const; 1682 1683 double GrevilleAbcissa( 1684 int dir, // dir 1685 int gindex // index (0 <= index < CVCount(dir) 1686 ) const; 1687 1688 ///////////////////////////////////////////////////////////////// 1689 // Tools for managing CV and knot memory 1690 1691 /* 1692 Description: 1693 cv_capacity - [in] number of doubles to reserve 1694 */ 1695 bool ReserveCVCapacity( 1696 int cv_capacity 1697 ); 1698 1699 bool ReserveKnotCapacity( 1700 int dir, 1701 int cv_capacity 1702 ); 1703 1704 ///////////////////////////////////////////////////////////////// 1705 // Implementation 1706 public: 1707 // NOTE: These members are left "public" so that expert users may efficiently 1708 // create nurbs curves using the default constructor and borrow the 1709 // knot and CV arrays from their native NURBS representation. 1710 // No technical support will be provided for users who access these 1711 // members directly. If you can't get your stuff to work, then use 1712 // the constructor with the arguments and the SetKnot() and SetCV() 1713 // functions to fill in the arrays. 1714 1715 1716 int m_dim; 1717 bool m_is_rat; 1718 int m_order[3]; 1719 int m_cv_count[3]; 1720 int m_knot_capacity[3]; 1721 double* m_knot[3]; 1722 int m_cv_stride[3]; 1723 int m_cv_capacity; 1724 double* m_cv; 1725 }; 1726 1727 ON_DECL 1728 bool ON_GetCageXform( 1729 const ON_NurbsCage& cage, 1730 ON_Xform& cage_xform 1731 ); 1732 1733 1734 class ON_CLASS ON_MorphControl : public ON_Geometry 1735 { 1736 ON_OBJECT_DECLARE(ON_MorphControl); 1737 1738 public: 1739 ON_MorphControl(); 1740 ~ON_MorphControl(); 1741 // C++ default copy construction and operator= work fine. 1742 1743 1744 void Destroy(); 1745 1746 1747 ///////////////////////////////////////////////////////// 1748 // 1749 // ON_Object virtual functions 1750 // 1751 1752 void MemoryRelocate(); 1753 1754 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const; 1755 1756 void Dump( ON_TextLog& ) const; 1757 1758 unsigned int SizeOf() const; 1759 1760 ON_BOOL32 Write( 1761 ON_BinaryArchive& archive 1762 ) const; 1763 1764 ON_BOOL32 Read( 1765 ON_BinaryArchive& archive 1766 ); 1767 1768 ON::object_type ObjectType() const; 1769 1770 void DestroyRuntimeCache( bool bDelete = true ); 1771 1772 ///////////////////////////////////////////////////////// 1773 // 1774 // ON_Geometry virtual functions 1775 // 1776 1777 int Dimension() const; 1778 1779 ON_BOOL32 GetBBox( 1780 double* boxmin, 1781 double* boxmax, 1782 int bGrowBox = false 1783 ) const; 1784 1785 bool GetTightBoundingBox( 1786 ON_BoundingBox& tight_bbox, 1787 int bGrowBox = false, 1788 const ON_Xform* xform = 0 1789 ) const; 1790 1791 void ClearBoundingBox(); 1792 1793 ON_BOOL32 Transform( 1794 const ON_Xform& xform 1795 ); 1796 1797 ON_BOOL32 HasBrepForm() const; 1798 1799 ON_Brep* BrepForm( ON_Brep* brep = NULL ) const; 1800 1801 1802 /* 1803 Returns: 1804 True if the target NURBS object is rational 1805 */ 1806 bool IsRational() const; 1807 1808 /* 1809 Description: 1810 Makes the target NURBS object rational. 1811 */ 1812 bool MakeRational(); 1813 1814 /* 1815 Description: 1816 Makes the target NURBS object non-rational. 1817 */ 1818 bool MakeNonRational(); 1819 1820 /* 1821 Returns: 1822 Number of control points in the target NURBS object. 1823 */ 1824 int CVCount() const; 1825 1826 int CVCount(int dir) const; 1827 int Order(int dir) const; 1828 const double* Knot(int dir) const; 1829 ON_3dex MaxCVIndex() const; 1830 const double* CV(ON_3dex) const; 1831 double Weight(ON_3dex) const; 1832 1833 ///////////////////////////////////////////////////////// 1834 // 1835 // Localizers 1836 // 1837 1838 /* 1839 Description: 1840 Adds localizer with support near the controling NURBS object. 1841 Parameters: 1842 support_distance - [in] >= 0 1843 If the distance a point to the controls NURBS 1844 curve/surface/cage is less than or equal to support_distance, 1845 then MorphPoint() deformation has 100% effect. 1846 1847 falloff_distance - [in] > 0 1848 If the distance a point to the controls NURBS 1849 curve/surface/cage is more than support_distance+falloff_distance, 1850 then MorphPoint() deformation does not move the point. 1851 As the distance varies from support_distance to 1852 support_distance+falloff_distance the deformation attenuates 1853 from 100% to 0%. 1854 */ 1855 bool AddControlLocalizer( 1856 double support_distance, 1857 double falloff_distance 1858 ); 1859 1860 bool AddSphereLocalizer( 1861 ON_3dPoint center, 1862 double support_distance, 1863 double falloff_distance 1864 ); 1865 1866 bool AddCylinderLocalizer( 1867 ON_Line axis, 1868 double support_distance, 1869 double falloff_distance 1870 ); 1871 1872 bool AddBoxLocalizer( 1873 ON_BoundingBox bbox, 1874 double support_distance, 1875 double falloff_distance 1876 ); 1877 1878 bool AddPlaneLocalizer( 1879 const ON_Plane& plane, 1880 double support_distance, 1881 double falloff_distance 1882 ); 1883 1884 bool AddConvexPolygonLocalizer( 1885 const ON_SimpleArray<ON_Plane>& planes, 1886 double support_distance, 1887 double falloff_distance 1888 ); 1889 1890 ///////////////////////////////////////////////////////// 1891 // 1892 // 1893 1894 // Get a cage_morph that can be passed to Morph functions 1895 bool GetCageMorph( class ON_CageMorph& cage_morph ) const; 1896 1897 bool IsIdentity( const ON_BoundingBox& bbox ) const; 1898 1899 int m_varient; // 1= curve, 2 = surface, 3 = cage 1900 1901 // The value of m_varient determines which nurbs object 1902 // controls the cage 1903 ON_NurbsCurve m_nurbs_curve0; 1904 ON_NurbsCurve m_nurbs_curve; 1905 ON_Interval m_nurbs_curve_domain; 1906 1907 ON_NurbsSurface m_nurbs_surface0; 1908 ON_NurbsSurface m_nurbs_surface; 1909 ON_Interval m_nurbs_surface_domain[2]; 1910 1911 ON_Xform m_nurbs_cage0; 1912 ON_NurbsCage m_nurbs_cage; 1913 1914 // Rhino captive object ids 1915 ON_UuidList m_captive_id; 1916 1917 // Use ON_GetCageXform to set m_cage_xform. 1918 1919 // Used to localize the deformation 1920 ON_ClassArray<ON_Localizer> m_localizers; 1921 1922 // ON_SpaceMorphOptions 1923 double m_sporh_tolerance; 1924 bool m_sporh_bQuickPreview; 1925 bool m_sporh_bPreserveStructure; 1926 }; 1927 1928 1929 class ON_CLASS ON_CageMorph : public ON_SpaceMorph 1930 { 1931 public: 1932 ON_CageMorph(); 1933 ~ON_CageMorph(); 1934 1935 bool IsIdentity( const ON_BoundingBox& bbox ) const; 1936 1937 const ON_MorphControl* m_control; 1938 }; 1939 1940 1941 // Description: 1942 // Get an ON_NurbsSurface definition of a quadrilateral. 1943 // Parameters: 1944 // P - [in] 1945 // Q - [in] 1946 // R - [in] 1947 // S - [in] corners in counter clockwise layer 1948 // nurbs_surface - [in] if this pointer is not NULL, 1949 // then this ON_NurbsSurface is used to return 1950 // the quadrilateral. 1951 // Returns: 1952 // An ON_NurbsSurface representation of the quadrilateral. 1953 ON_DECL 1954 ON_NurbsSurface* ON_NurbsSurfaceQuadrilateral( 1955 const ON_3dPoint& P, 1956 const ON_3dPoint& Q, 1957 const ON_3dPoint& R, 1958 const ON_3dPoint& S, 1959 ON_NurbsSurface* nurbs_surface = NULL 1960 ); 1961 1962 #if defined(ON_DLL_TEMPLATE) 1963 // This stuff is here because of a limitation in the way Microsoft 1964 // handles templates and DLLs. See Microsoft's knowledge base 1965 // article ID Q168958 for details. 1966 #pragma warning( push ) 1967 #pragma warning( disable : 4231 ) 1968 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_NurbsCurve>; 1969 ON_DLL_TEMPLATE template class ON_CLASS ON_ObjectArray<ON_NurbsCurve>; 1970 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_NurbsCurve*>; 1971 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_NurbsSurface>; 1972 ON_DLL_TEMPLATE template class ON_CLASS ON_ObjectArray<ON_NurbsSurface>; 1973 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_NurbsSurface*>; 1974 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_NurbsCage>; 1975 ON_DLL_TEMPLATE template class ON_CLASS ON_ObjectArray<ON_NurbsCage>; 1976 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_NurbsCage*>; 1977 #pragma warning( pop ) 1978 #endif 1979 1980 #endif 1981