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