Point Cloud Library (PCL)  1.14.1-dev
opennurbs_bezier.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 #if !defined(OPENNURBS_BEZIER_INC_)
18 #define OPENNURBS_BEZIER_INC_
19 
20 class ON_PolynomialCurve;
22 class ON_BezierCurve;
23 class ON_BezierSurface;
24 class ON_TextLog;
25 class ON_NurbsCurve;
26 class ON_NurbsSurface;
27 class ON_X_EVENT;
28 
29 class ON_CLASS ON_PolynomialCurve
30 {
31 public:
33 
34  // Description:
35  // See ON_PolynomialCurve::Create.
36  // Parameters:
37  // dim - [in] dimension of the curve
38  // bIsRational - [in] true if rational
39  // order - [in] (>=2) order = degree+1
41  int dim,
42  ON_BOOL32 bIsRational,
43  int order
44  );
45 
47 
49 
51 
53 
55 
56  // Description:
57  // Initializes fields and allocates the m_cv array.
58  // Parameters:
59  // dim - [in] dimension of the curve
60  // bIsRational - [in] true if rational
61  // order - [in] (>=2) order = degree+1
62  ON_BOOL32 Create(
63  int dim,
64  ON_BOOL32 bIsRational,
65  int order
66  );
67 
68  // Description:
69  // Deallocates the m_cv array and sets fields to zero.
70  void Destroy();
71 
72  // Description:
73  // Evaluate a polynomial curve.
74  // Parameters:
75  // t - [in] evaluation parameter ( usually in Domain() ).
76  // der_count - [in] (>=0) number of derivatives to evaluate
77  // v_stride - [in] (>=Dimension()) stride to use for the v[] array
78  // v - [out] array of length (der_count+1)*v_stride
79  // curve(t) is returned in (v[0],...,v[m_dim-1]),
80  // curve'(t) is retuned in (v[v_stride],...,v[v_stride+m_dim-1]),
81  // curve"(t) is retuned in (v[2*v_stride],...,v[2*v_stride+m_dim-1]),
82  // etc.
83  // Returns:
84  // false if unable to evaluate.
85  ON_BOOL32 Evaluate(
86  double t,
87  int der_count,
88  int v_stride,
89  double* v
90  ) const;
91 
92  // dimension of polynomial curve (1,2, or 3)
93  int m_dim;
94 
95  // 1 if polynomial curve is rational, 0 if polynomial curve is not rational
96  int m_is_rat;
97 
98  // order (=degree+1) of polynomial
99  int m_order;
100 
101  // coefficients ( m_cv.Count() = order of monomial )
103 
104  // domain of polynomial
106 };
107 
108 class ON_CLASS ON_PolynomialSurface
109 {
110 public:
113  int, // dim,
114  ON_BOOL32, // true if rational
115  int, // "u" order
116  int // "v" order
117  );
123 
124  ON_BOOL32 Create(
125  int, // dim,
126  ON_BOOL32, // true if rational
127  int, // "u" order
128  int // "v" order
129  );
130  void Destroy();
131 
132  ON_BOOL32 Evaluate( // returns false if unable to evaluate
133  double s,
134  double t, // evaluation parameter
135  int der_count, // number of derivatives (>=0)
136  int v_stride, // array stride (>=Dimension())
137  double* v // array of length stride*(ndir+1)*(ndir+2)/2
138  ) const;
139 
140  int m_dim; // 1,2, or 3
141  int m_is_rat; // 1 if rational, 0 if not rational
142  int m_order[2];
143  ON_4dPointArray m_cv; // coefficients ( m_C.Length() = m_order[0]*m_order[1]
144  // coefficient of s^m*t^n = m_cv[m_order[1]*m+n]
145  ON_Interval m_domain[2];
146 };
147 
148 class ON_CLASS ON_BezierCurve
149 {
150 public:
151 
153 
154  // Description:
155  // Creates a bezier with cv memory allocated.
156  // Parameters:
157  // dim - [in] (>0) dimension of bezier curve
158  // bIsRational - [in] true for a rational bezier
159  // order - [in] (>=2) order (=degree+1) of bezier curve
161  int dim,
162  ON_BOOL32 bIsRational,
163  int order
164  );
165 
169  ON_BezierCurve(const ON_2dPointArray&); // sets control points
170  ON_BezierCurve(const ON_3dPointArray&); // sets control points
171  ON_BezierCurve(const ON_4dPointArray&); // sets control points
174 
175 
176  ON_BezierCurve& operator=(const ON_2dPointArray&); // sets control points
177  ON_BezierCurve& operator=(const ON_3dPointArray&); // sets control points
178  ON_BezierCurve& operator=(const ON_4dPointArray&); // sets control points
179 
180  bool IsValid() const;
181 
182  void Dump( ON_TextLog& ) const; // for debugging
183 
184  // Returns:
185  // Dimension of bezier.
186  int Dimension() const;
187 
188  // Description:
189  // Creates a bezier with cv memory allocated.
190  // Parameters:
191  // dim - [in] (>0) dimension of bezier curve
192  // bIsRational - [in] true for a rational bezier
193  // order - [in] (>=2) order (=degree+1) of bezier curve
194  // Returns:
195  // true if successful.
196  bool Create(
197  int dim,
198  ON_BOOL32 bIsRational,
199  int order
200  );
201 
202  // Description:
203  // Deallocates m_cv memory.
204  void Destroy();
205 
206  void EmergencyDestroy(); // call if memory used by ON_NurbsCurve becomes invalid
207 
208  // Description:
209  // Loft a bezier curve through a list of points.
210  // Parameters:
211  // points - [in] an array of 2 or more points to interpolate
212  // Returns:
213  // true if successful
214  // Remarks:
215  // The result has order = points.Count() and the loft uses the
216  // uniform parameterizaton curve( i/(points.Count()-1) ) = points[i].
217  bool Loft(
218  const ON_3dPointArray& points
219  );
220 
221  // Description:
222  // Loft a bezier curve through a list of points.
223  // Parameters:
224  // pt_dim - [in] dimension of points to interpolate
225  // pt_count - [in] number of points (>=2)
226  // pt_stride - [in] (>=pt_dim) pt[] array stride
227  // pt - [in] array of points
228  // t_stride - [in] (>=1) t[] array stride
229  // t - [in] strictly increasing array of interpolation parameters
230  // Returns:
231  // true if successful
232  // Remarks:
233  // The result has order = points.Count() and the loft uses the
234  // parameterizaton curve( t[i] ) = points[i].
235  bool Loft(
236  int pt_dim,
237  int pt_count,
238  int pt_stride,
239  const double* pt,
240  int t_stride,
241  const double* t
242  );
243 
244  // Description:
245  // Gets bounding box.
246  // Parameters:
247  // box_min - [out] minimum corner of axis aligned bounding box
248  // The box_min[] array must have size m_dim.
249  // box_max - [out] maximum corner of axis aligned bounding box
250  // The box_max[] array must have size m_dim.
251  // bGrowBox - [in] if true, input box_min/box_max must be set
252  // to valid bounding box corners and this box is enlarged to
253  // be the union of the input box and the bezier's bounding
254  // box.
255  // Returns:
256  // true if successful.
257  bool GetBBox( // returns true if successful
258  double* box_min,
259  double* box_max,
260  int bGrowBox = false
261  ) const;
262 
263  // Description:
264  // Gets bounding box.
265  // Parameters:
266  // bbox - [out] axis aligned bounding box returned here.
267  // bGrowBox - [in] if true, input bbox must be a valid
268  // bounding box and this box is enlarged to
269  // be the union of the input box and the
270  // bezier's bounding box.
271  // Returns:
272  // true if successful.
274  ON_BoundingBox& bbox,
275  int bGrowBox = false
276  ) const;
277 
278  // Description:
279  // Gets bounding box.
280  // Returns:
281  // Axis aligned bounding box.
283 
284  /*
285  Description:
286  Get tight bounding box of the bezier.
287  Parameters:
288  tight_bbox - [in/out] tight bounding box
289  bGrowBox -[in] (default=false)
290  If true and the input tight_bbox is valid, then returned
291  tight_bbox is the union of the input tight_bbox and the
292  tight bounding box of the bezier curve.
293  xform -[in] (default=NULL)
294  If not NULL, the tight bounding box of the transformed
295  bezier is calculated. The bezier curve is not modified.
296  Returns:
297  True if the returned tight_bbox is set to a valid
298  bounding box.
299  */
301  ON_BoundingBox& tight_bbox,
302  int bGrowBox = false,
303  const ON_Xform* xform = 0
304  ) const;
305 
306  // Description:
307  // Transform the bezier.
308  // Parameters:
309  // xform - [in] transformation to apply to bezier
310  // Returns:
311  // true if successful. false if bezier is invalid
312  // and cannot be transformed.
313  bool Transform(
314  const ON_Xform& xform
315  );
316 
317  // Description:
318  // Rotates the bezier curve about the specified axis. A positive
319  // rotation angle results in a counter-clockwise rotation
320  // about the axis (right hand rule).
321  // Parameters:
322  // sin_angle - [in] sine of rotation angle
323  // cos_angle - [in] sine of rotation angle
324  // rotation_axis - [in] direction of the axis of rotation
325  // rotation_center - [in] point on the axis of rotation
326  // Returns:
327  // true if bezier curve successfully rotated
328  // Remarks:
329  // Uses ON_BezierCurve::Transform() function to calculate the result.
330  bool Rotate(
331  double sin_angle,
332  double cos_angle,
333  const ON_3dVector& rotation_axis,
334  const ON_3dPoint& rotation_center
335  );
336 
337  // Description:
338  // Rotates the bezier curve about the specified axis. A positive
339  // rotation angle results in a counter-clockwise rotation
340  // about the axis (right hand rule).
341  // Parameters:
342  // rotation_angle - [in] angle of rotation in radians
343  // rotation_axis - [in] direction of the axis of rotation
344  // rotation_center - [in] point on the axis of rotation
345  // Returns:
346  // true if bezier curve successfully rotated
347  // Remarks:
348  // Uses ON_BezierCurve::Transform() function to calculate the result.
349  bool Rotate(
350  double rotation_angle,
351  const ON_3dVector& rotation_axis,
352  const ON_3dPoint& rotation_center
353  );
354 
355  // Description:
356  // Translates the bezier curve along the specified vector.
357  // Parameters:
358  // translation_vector - [in] translation vector
359  // Returns:
360  // true if bezier curve successfully translated
361  // Remarks:
362  // Uses ON_BezierCurve::Transform() function to calculate the result.
363  bool Translate(
364  const ON_3dVector& translation_vector
365  );
366 
367  // Description:
368  // Scales the bezier curve by the specified facotor. The scale is
369  // centered at the origin.
370  // Parameters:
371  // scale_factor - [in] scale factor
372  // Returns:
373  // true if bezier curve successfully scaled
374  // Remarks:
375  // Uses ON_BezierCurve::Transform() function to calculate the result.
376  bool Scale(
377  double scale_factor
378  );
379 
380  // Returns:
381  // Domain of bezier (always [0,1]).
383 
384  // Description:
385  // Reverses bezier by reversing the order
386  // of the control points.
387  bool Reverse();
388 
389  // Description:
390  // Evaluate point at a parameter.
391  // Parameters:
392  // t - [in] evaluation parameter
393  // Returns:
394  // Point (location of curve at the parameter t).
396  double t
397  ) const;
398 
399  // Description:
400  // Evaluate first derivative at a parameter.
401  // Parameters:
402  // t - [in] evaluation parameter
403  // Returns:
404  // First derivative of the curve at the parameter t.
405  // Remarks:
406  // No error handling.
407  // See Also:
408  // ON_Curve::Ev1Der
410  double t
411  ) const;
412 
413  // Description:
414  // Evaluate unit tangent vector at a parameter.
415  // Parameters:
416  // t - [in] evaluation parameter
417  // Returns:
418  // Unit tangent vector of the curve at the parameter t.
419  // Remarks:
420  // No error handling.
421  // See Also:
422  // ON_Curve::EvTangent
424  double t
425  ) const;
426 
427  // Description:
428  // Evaluate the curvature vector at a parameter.
429  // Parameters:
430  // t - [in] evaluation parameter
431  // Returns:
432  // curvature vector of the curve at the parameter t.
433  // Remarks:
434  // No error handling.
435  // See Also:
436  // ON_Curve::EvCurvature
438  double t
439  ) const;
440 
441  // Description:
442  // Evaluate point at a parameter with error checking.
443  // Parameters:
444  // t - [in] evaluation parameter
445  // point - [out] value of curve at t
446  // Returns:
447  // false if unable to evaluate.
448  bool EvPoint(
449  double t,
450  ON_3dPoint& point
451  ) const;
452 
453  // Description:
454  // Evaluate first derivative at a parameter with error checking.
455  // Parameters:
456  // t - [in] evaluation parameter
457  // point - [out] value of curve at t
458  // first_derivative - [out] value of first derivative at t
459  // Returns:
460  // false if unable to evaluate.
461  bool Ev1Der(
462  double t,
463  ON_3dPoint& point,
464  ON_3dVector& first_derivative
465  ) const;
466 
467  // Description:
468  // Evaluate second derivative at a parameter with error checking.
469  // Parameters:
470  // t - [in] evaluation parameter
471  // point - [out] value of curve at t
472  // first_derivative - [out] value of first derivative at t
473  // second_derivative - [out] value of second derivative at t
474  // Returns:
475  // false if unable to evaluate.
476  bool Ev2Der(
477  double t,
478  ON_3dPoint& point,
479  ON_3dVector& first_derivative,
480  ON_3dVector& second_derivative
481  ) const;
482 
483  /*
484  Description:
485  Evaluate unit tangent at a parameter with error checking.
486  Parameters:
487  t - [in] evaluation parameter
488  point - [out] value of curve at t
489  tangent - [out] value of unit tangent
490  Returns:
491  false if unable to evaluate.
492  See Also:
493  ON_Curve::TangentAt
494  ON_Curve::Ev1Der
495  */
496  bool EvTangent(
497  double t,
498  ON_3dPoint& point,
499  ON_3dVector& tangent
500  ) const;
501 
502  /*
503  Description:
504  Evaluate unit tangent and curvature at a parameter with error checking.
505  Parameters:
506  t - [in] evaluation parameter
507  point - [out] value of curve at t
508  tangent - [out] value of unit tangent
509  kappa - [out] value of curvature vector
510  Returns:
511  false if unable to evaluate.
512  */
514  double t,
515  ON_3dPoint& point,
516  ON_3dVector& tangent,
517  ON_3dVector& kappa
518  ) const;
519 
520  // Description:
521  // Evaluate a bezier.
522  // Parameters:
523  // t - [in] evaluation parameter (usually 0 <= t <= 1)
524  // der_count - [in] (>=0) number of derivatives to evaluate
525  // v_stride - [in] (>=m_dim) stride to use for the v[] array
526  // v - [out] array of length (der_count+1)*v_stride
527  // bez(t) is returned in (v[0],...,v[m_dim-1]),
528  // bez'(t) is retuned in (v[v_stride],...,v[v_stride+m_dim-1]),
529  // bez"(t) is retuned in (v[2*v_stride],...,v[2*v_stride+m_dim-1]),
530  // etc.
531  // Returns:
532  // true if successful
533  bool Evaluate(
534  double t,
535  int der_count,
536  int v_stride,
537  double* v
538  ) const;
539 
540  // Description:
541  // Get ON_NurbsCurve form of a bezier.
542  // Parameters:
543  // nurbs_curve - [out] NURBS curve form of a bezier.
544  // The domain is [0,1].
545  // Returns:
546  // true if successful
547  bool GetNurbForm(
548  ON_NurbsCurve& nurbs_curve
549  ) const;
550 
551  // Returns:
552  // true if bezier is rational.
553  bool IsRational() const;
554 
555  // Returns:
556  // Number of doubles per control vertex.
557  // (= IsRational() ? Dim()+1 : Dim())
558  int CVSize() const;
559 
560  // Returns:
561  // Number of control vertices in the bezier.
562  // This is always the same as the order of the bezier.
563  int CVCount() const;
564 
565  // Returns:
566  // Order of the bezier. (order=degree+1)
567  int Order() const; // order = degree + 1
568 
569  // Returns:
570  // Degree of the bezier. (degree=order-1)
571  int Degree() const;
572 
573  /*
574  Description:
575  Expert user function to get a pointer to control vertex
576  memory. If you are not an expert user, please use
577  ON_BezierCurve::GetCV( ON_3dPoint& ) or
578  ON_BezierCurve::GetCV( ON_4dPoint& ).
579  Parameters:
580  cv_index - [in] (0 <= cv_index < m_order)
581  Returns:
582  Pointer to control vertex.
583  Remarks:
584  If the Bezier curve is rational, the format of the
585  returned array is a homogeneos rational point with
586  length m_dim+1. If the Bezier curve is not rational,
587  the format of the returned array is a nonrational
588  euclidean point with length m_dim.
589  See Also
590  ON_BezierCurve::CVStyle
591  ON_BezierCurve::GetCV
592  ON_BezierCurve::Weight
593  */
594  double* CV(
595  int cv_index
596  ) const;
597 
598  /*
599  Description:
600  Returns the style of control vertices in the m_cv array.
601  Returns:
602  @untitled table
603  ON::not_rational m_is_rat is false
604  ON::homogeneous_rational m_is_rat is true
605  */
606  ON::point_style CVStyle() const;
607 
608  // Parameters:
609  // cv_index - [in] control vertex index (0<=i<m_order)
610  // Returns:
611  // Weight of the i-th control vertex.
612  double Weight(
613  int cv_index
614  ) const;
615 
616  // Description:
617  // Set weight of a control vertex.
618  // Parameters:
619  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
620  // weight - [in] weight
621  // Returns:
622  // true if the weight can be set. If weight is not 1 and
623  // the bezier is not rational, then false is returned.
624  // Use ON_BezierCurve::MakeRational to make a bezier curve
625  // rational.
626  // See Also:
627  // ON_BezierCurve::SetCV, ON_BezierCurve::MakeRational,
628  // ON_BezierCurve::IsRational, ON_BezierCurve::Weight
629  bool SetWeight(
630  int cv_index,
631  double weight
632  );
633 
634  // Description:
635  // Set control vertex
636  // Parameters:
637  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
638  // pointstyle - [in] specifes what kind of values are passed
639  // in the cv array.
640  // ON::not_rational
641  // cv[] is an array of length m_dim that defines
642  // a euclidean (world coordinate) point
643  // ON::homogeneous_rational
644  // cv[] is an array of length (m_dim+1) that defines
645  // a rational homogeneous point.
646  // ON::euclidean_rational
647  // cv[] is an array of length (m_dim+1). The first
648  // m_dim values define the euclidean (world coordinate)
649  // location of the point. cv[m_dim] is the weight
650  // ON::intrinsic_point_style
651  // If m_is_rat is true, cv[] has ON::homogeneous_rational
652  // point style. If m_is_rat is false, cv[] has
653  // ON::not_rational point style.
654  // cv - [in] array with control vertex value.
655  // Returns:
656  // true if the point can be set.
657  bool SetCV(
658  int cv_index,
659  ON::point_style pointstyle,
660  const double* cv
661  );
662 
663  // Description:
664  // Set location of a control vertex.
665  // Parameters:
666  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
667  // point - [in] control vertex location. If the bezier
668  // is rational, the weight will be set to 1.
669  // Returns:
670  // true if successful.
671  // See Also:
672  // ON_BezierCurve::CV, ON_BezierCurve::SetCV,
673  // ON_BezierCurve::SetWeight, ON_BezierCurve::Weight
674  bool SetCV(
675  int cv_index,
676  const ON_3dPoint& point
677  );
678 
679  // Description:
680  // Set value of a control vertex.
681  // Parameters:
682  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
683  // point - [in] control vertex value. If the bezier
684  // is not rational, the euclidean location of
685  // homogenoeous point will be used.
686  // Returns:
687  // true if successful.
688  // See Also:
689  // ON_BezierCurve::CV, ON_BezierCurve::SetCV,
690  // ON_BezierCurve::SetWeight, ON_BezierCurve::Weight
691  bool SetCV(
692  int cv_index,
693  const ON_4dPoint& point
694  );
695 
696  // Description:
697  // Get location of a control vertex.
698  // Parameters:
699  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
700  // pointstyle - [in] specifes what kind of values to get
701  // ON::not_rational
702  // cv[] is an array of length m_dim that defines
703  // a euclidean (world coordinate) point
704  // ON::homogeneous_rational
705  // cv[] is an array of length (m_dim+1) that defines
706  // a rational homogeneous point.
707  // ON::euclidean_rational
708  // cv[] is an array of length (m_dim+1). The first
709  // m_dim values define the euclidean (world coordinate)
710  // location of the point. cv[m_dim] is the weight
711  // ON::intrinsic_point_style
712  // If m_is_rat is true, cv[] has ON::homogeneous_rational
713  // point style. If m_is_rat is false, cv[] has
714  // ON::not_rational point style.
715  // cv - [out] array with control vertex value.
716  // Returns:
717  // true if successful. false if cv_index is invalid.
718  bool GetCV(
719  int cv_index,
720  ON::point_style pointstyle,
721  double* cv
722  ) const;
723 
724  // Description:
725  // Get location of a control vertex.
726  // Parameters:
727  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
728  // point - [out] Location of control vertex. If the bezier
729  // is rational, the euclidean location is returned.
730  // Returns:
731  // true if successful.
732  bool GetCV(
733  int cv_index,
734  ON_3dPoint& point
735  ) const;
736 
737  // Description:
738  // Get value of a control vertex.
739  // Parameters:
740  // cv_index - [in] control vertex index (0 <= cv_index < m_order)
741  // point - [out] Homogenous value of control vertex.
742  // If the bezier is not rational, the weight is 1.
743  // Returns:
744  // true if successful.
745  bool GetCV(
746  int cv_index,
747  ON_4dPoint& point
748  ) const;
749 
750  // Description:
751  // Zeros control vertices and, if rational, sets weights to 1.
752  bool ZeroCVs();
753 
754  // Description:
755  // Make beizer rational.
756  // Returns:
757  // true if successful.
758  // See Also:
759  // ON_Bezier::MakeNonRational
760  bool MakeRational();
761 
762  // Description:
763  // Make beizer not rational by setting all control
764  // vertices to their euclidean locations and setting
765  // m_is_rat to false.
766  // See Also:
767  // ON_Bezier::MakeRational
769 
770  // Description:
771  // Increase degree of bezier.
772  // Parameters:
773  // desired_degree - [in]
774  // Returns:
775  // true if successful. false if desired_degree < current degree.
777  int desired_degree
778  );
779 
780  // Description:
781  // Change dimension of bezier.
782  // Parameters:
783  // desired_dimension - [in]
784  // Returns:
785  // true if successful. false if desired_dimension < 1
787  int desired_dimension
788  );
789 
790  /////////////////////////////////////////////////////////////////
791  // Tools for managing CV and knot memory
792 
793  // Description:
794  // Make sure m_cv array has a certain length.
795  // Parameters:
796  // desired_cv_capacity - [in] minimum length of m_cv array.
797  // Returns:
798  // true if successful.
800  int desired_cv_capacity
801  );
802 
803  // Description:
804  // Trims (or extends) the bezier so the bezier so that the
805  // result starts bezier(interval[0]) and ends at
806  // bezier(interval[1]) (Evaluation performed on input bezier.)
807  // Parameters:
808  // interval -[in]
809  // Example:
810  // An interval of [0,1] leaves the bezier unchanged. An
811  // interval of [0.5,1] would trim away the left half. An
812  // interval of [0.0,2.0] would extend the right end.
813  bool Trim(
814  const ON_Interval& interval
815  );
816 
817  // Description:
818  // Split() divides the Bezier curve at the specified parameter.
819  // The parameter must satisfy 0 < t < 1. You may pass *this as
820  // one of the curves to be returned.
821  // Parameters:
822  // t - [in] (0 < t < 1 ) parameter to split at
823  // left_side - [out]
824  // right_side - [out]
825  // Example:
826  // ON_BezierCurve crv = ...;
827  // ON_BezierCurve right_side;
828  // crv.Split( 0.5, crv, right_side );
829  // would split crv at the 1/2, put the left side in crv,
830  // and return the right side in right_side.
831  bool Split(
832  double t,
833  ON_BezierCurve& left_side,
834  ON_BezierCurve& right_side
835  ) const;
836 
837  // Description:
838  // returns the length of the control polygon
839  double ControlPolygonLength() const;
840 
841  /*
842  Description:
843  Use a linear fractional tranformation for [0,1] to reparameterize
844  the bezier. The locus of the curve is not changed, but the
845  parameterization is changed.
846  Parameters:
847  c - [in]
848  reparameterization constant (generally speaking, c should be > 0).
849  If c != 1, then the returned bezier will be rational.
850  Returns:
851  true if successful.
852  Remarks:
853  The reparameterization is performed by composing the input Bezier with
854  the function lambda: [0,1] -> [0,1] given by
855 
856  t -> c*t / ( (c-1)*t + 1 )
857 
858  Note that lambda(0) = 0, lambda(1) = 1, lambda'(t) > 0,
859  lambda'(0) = c and lambda'(1) = 1/c.
860 
861  If the input Bezier has control vertices {B_0, ..., B_d}, then the
862  output Bezier has control vertices
863 
864  (B_0, ... c^i * B_i, ..., c^d * B_d).
865 
866  To derive this formula, simply compute the i-th Bernstein polynomial
867  composed with lambda().
868 
869  The inverse parameterization is given by 1/c. That is, the
870  cumulative effect of the two calls
871 
872  Reparameterize(c)
873  Reparameterize(1.0/c)
874 
875  is to leave the bezier unchanged.
876  See Also:
877  ON_Bezier::ScaleConrolPoints
878  */
880  double c
881  );
882 
883  // misspelled function name is obsolete
884  ON_DEPRECATED bool Reparametrize(double);
885 
886  /*
887  Description:
888  Scale a rational Bezier's control vertices to set a weight to a
889  specified value.
890  Parameters:
891  i - [in] (0 <= i < order)
892  w - [in] w != 0.0
893  Returns:
894  True if successful. The i-th control vertex will have weight w.
895  Remarks:
896  Each control point is multiplied by w/w0, where w0 is the
897  input value of Weight(i).
898  See Also:
899  ON_Bezier::Reparameterize
900  ON_Bezier::ChangeWeights
901  */
903  int i,
904  double w
905  );
906 
907  /*
908  Description:
909  Use a combination of scaling and reparameterization to set two
910  rational Bezier weights to specified values.
911  Parameters:
912  i0 - [in] control point index (0 <= i0 < order, i0 != i1)
913  w0 - [in] Desired weight for i0-th control point
914  i1 - [in] control point index (0 <= i1 < order, i0 != i1)
915  w1 - [in] Desired weight for i1-th control point
916  Returns:
917  True if successful. The returned bezier has the same locus but
918  probably has a different parameterization.
919  Remarks:
920  The i0-th cv will have weight w0 and the i1-rst cv will have
921  weight w1. If v0 and v1 are the cv's input weights,
922  then v0, v1, w0 and w1 must all be nonzero, and w0*v0
923  and w1*v1 must have the same sign.
924 
925  The equations
926 
927  s * r^i0 = w0/v0
928  s * r^i1 = w1/v1
929 
930  determine the scaling and reparameterization necessary to
931  change v0,v1 to w0,w1.
932 
933  If the input Bezier has control vertices
934 
935  (B_0, ..., B_d),
936 
937  then the output Bezier has control vertices
938 
939  (s*B_0, ... s*r^i * B_i, ..., s*r^d * B_d).
940  See Also:
941  ON_Bezier::Reparameterize
942  ON_Bezier::ScaleConrolPoints
943  */
945  int i0,
946  double w0,
947  int i1,
948  double w1
949  );
950 
951  /////////////////////////////////////////////////////////////////
952  // Implementation
953 public:
954  // NOTE: These members are left "public" so that expert users may efficiently
955  // create bezier curves using the default constructor and borrow the
956  // knot and CV arrays from their native NURBS representation.
957  // No technical support will be provided for users who access these
958  // members directly. If you can't get your stuff to work, then use
959  // the constructor with the arguments and the SetKnot() and SetCV()
960  // functions to fill in the arrays.
961 
962 
963  // dimension of bezier (>=1)
964  int m_dim;
965 
966  // 1 if bezier is rational, 0 if bezier is not rational
967  int m_is_rat;
968 
969  // order = degree+1
970  int m_order;
971 
972  // Number of doubles per cv ( >= ((m_is_rat)?m_dim+1:m_dim) )
974 
975  // The i-th cv begins at cv[i*m_cv_stride].
976  double* m_cv;
977 
978  // Number of doubles in m_cv array. If m_cv_capacity is zero
979  // and m_cv is not NULL, an expert user is managing the m_cv
980  // memory. ~ON_BezierCurve will not deallocate m_cv unless
981  // m_cv_capacity is greater than zero.
983 
984 #if 8 == ON_SIZEOF_POINTER
985  // pad to a multiple of 8 bytes so custom allocators
986  // will keep m_cv aligned and tail-padding reuse will
987  // not be an issue.
988  int m_reserved_ON_BezierCurve;
989 #endif
990 };
991 
992 
993 class ON_CLASS ON_BezierSurface
994 {
995 public:
998  int dim,
999  int is_rat,
1000  int order0,
1001  int order1
1002  );
1003 
1009 
1010  bool IsValid() const;
1011  void Dump( ON_TextLog& ) const; // for debugging
1012  int Dimension() const;
1013 
1014  bool Create(
1015  int dim,
1016  int is_rat,
1017  int order0,
1018  int order1
1019  );
1020 
1021  void Destroy();
1022  void EmergencyDestroy(); // call if memory used by ON_NurbsCurve becomes invalid
1023 
1024  /*
1025  Description:
1026  Loft a bezier surface through a list of bezier curves.
1027  Parameters:
1028  curve_list - [in] list of curves that have the same degree.
1029  Returns:
1030  True if successful.
1031  */
1032  bool Loft( const ON_ClassArray<ON_BezierCurve>& curve_list );
1033 
1034  /*
1035  Description:
1036  Loft a bezier surface through a list of bezier curves.
1037  Parameters:
1038  curve_count - [in] number of curves in curve_list
1039  curve_list - [in] array of pointers to curves that have the same degree.
1040  Returns:
1041  True if successful.
1042  */
1043  bool Loft(
1044  int count,
1045  const ON_BezierCurve* const* curve_list
1046  );
1047 
1048  bool GetBBox( // returns true if successful
1049  double*, // minimum
1050  double*, // maximum
1051  int bGrowBox = false // true means grow box
1052  ) const;
1053 
1055  ON_BoundingBox& bbox,
1056  int bGrowBox
1057  ) const;
1058 
1060 
1061  bool Transform(
1062  const ON_Xform&
1063  );
1064 
1065  // Description:
1066  // Rotates the bezier surface about the specified axis. A positive
1067  // rotation angle results in a counter-clockwise rotation
1068  // about the axis (right hand rule).
1069  // Parameters:
1070  // sin_angle - [in] sine of rotation angle
1071  // cos_angle - [in] sine of rotation angle
1072  // rotation_axis - [in] direction of the axis of rotation
1073  // rotation_center - [in] point on the axis of rotation
1074  // Returns:
1075  // true if bezier surface successfully rotated
1076  // Remarks:
1077  // Uses ON_BezierSurface::Transform() function to calculate the result.
1078  bool Rotate(
1079  double sin_angle,
1080  double cos_angle,
1081  const ON_3dVector& rotation_axis,
1082  const ON_3dPoint& rotation_center
1083  );
1084 
1085  // Description:
1086  // Rotates the bezier surface about the specified axis. A positive
1087  // rotation angle results in a counter-clockwise rotation
1088  // about the axis (right hand rule).
1089  // Parameters:
1090  // rotation_angle - [in] angle of rotation in radians
1091  // rotation_axis - [in] direction of the axis of rotation
1092  // rotation_center - [in] point on the axis of rotation
1093  // Returns:
1094  // true if bezier surface successfully rotated
1095  // Remarks:
1096  // Uses ON_BezierSurface::Transform() function to calculate the result.
1097  bool Rotate(
1098  double rotation_angle,
1099  const ON_3dVector& rotation_axis,
1100  const ON_3dPoint& rotation_center
1101  );
1102 
1103  // Description:
1104  // Translates the bezier surface along the specified vector.
1105  // Parameters:
1106  // translation_vector - [in] translation vector
1107  // Returns:
1108  // true if bezier surface successfully translated
1109  // Remarks:
1110  // Uses ON_BezierSurface::Transform() function to calculate the result.
1111  bool Translate(
1112  const ON_3dVector& translation_vector
1113  );
1114 
1115  // Description:
1116  // Scales the bezier surface by the specified facotor. The scale is
1117  // centered at the origin.
1118  // Parameters:
1119  // scale_factor - [in] scale factor
1120  // Returns:
1121  // true if bezier surface successfully scaled
1122  // Remarks:
1123  // Uses ON_BezierSurface::Transform() function to calculate the result.
1124  bool Scale(
1125  double scale_factor
1126  );
1127 
1129  int // 0 = "u" domain, 1 = "v" domain
1130  ) const;
1131 
1132  bool Reverse( int ); // reverse parameterizatrion
1133  // Domain changes from [a,b] to [-b,-a]
1134 
1135  bool Transpose(); // transpose surface parameterization (swap "s" and "t")
1136 
1137  bool Evaluate( // returns false if unable to evaluate
1138  double, double, // evaluation parameter
1139  int, // number of derivatives (>=0)
1140  int, // array stride (>=Dimension())
1141  double* // array of length stride*(ndir+1)*(ndir+2)/2
1142  ) const;
1143 
1144  ON_3dPoint PointAt(double s, double t) const;
1145 
1147 
1148  bool IsRational() const; // true if NURBS curve is rational
1149 
1150  int CVSize() const; // number of doubles per control vertex
1151  // = IsRational() ? Dim()+1 : Dim()
1152 
1153  int Order( // order = degree + 1
1154  int // dir
1155  ) const;
1156 
1157  int Degree( // degree = order - 1
1158  int // dir
1159  ) const;
1160 
1161  /*
1162  Description:
1163  Expert user function to get a pointer to control vertex
1164  memory. If you are not an expert user, please use
1165  ON_BezierSurface::GetCV( ON_3dPoint& ) or
1166  ON_BezierSurface::GetCV( ON_4dPoint& ).
1167  Parameters:
1168  cv_index0 - [in] (0 <= cv_index0 < m_order[0])
1169  cv_index1 - [in] (0 <= cv_index1 < m_order[1])
1170  Returns:
1171  Pointer to control vertex.
1172  Remarks:
1173  If the Bezier surface is rational, the format of the
1174  returned array is a homogeneos rational point with
1175  length m_dim+1. If the Bezier surface is not rational,
1176  the format of the returned array is a nonrational
1177  euclidean point with length m_dim.
1178  See Also
1179  ON_BezierSurface::CVStyle
1180  ON_BezierSurface::GetCV
1181  ON_BezierSurface::Weight
1182  */
1183  double* CV(
1184  int cv_index0,
1185  int cv_index1
1186  ) const;
1187 
1188  /*
1189  Description:
1190  Returns the style of control vertices in the m_cv array.
1191  Returns:
1192  @untitled table
1193  ON::not_rational m_is_rat is false
1194  ON::homogeneous_rational m_is_rat is true
1195  */
1196  ON::point_style CVStyle() const;
1197 
1198  double Weight( // get value of control vertex weight
1199  int,int // CV index ( >= 0 and < CVCount() )
1200  ) const;
1201 
1202  bool SetWeight( // set value of control vertex weight
1203  int,int, // CV index ( >= 0 and < CVCount() )
1204  double
1205  );
1206 
1207  bool SetCV( // set a single control vertex
1208  int,int, // CV index ( >= 0 and < CVCount() )
1209  ON::point_style, // style of input point
1210  const double* // value of control vertex
1211  );
1212 
1213  bool SetCV( // set a single control vertex
1214  int,int, // CV index ( >= 0 and < CVCount() )
1215  const ON_3dPoint& // value of control vertex
1216  // If NURBS is rational, weight
1217  // will be set to 1.
1218  );
1219 
1220  bool SetCV( // set a single control vertex
1221  int,int, // CV index ( >= 0 and < CVCount() )
1222  const ON_4dPoint& // value of control vertex
1223  // If NURBS is not rational, euclidean
1224  // location of homogeneous point will
1225  // be used.
1226  );
1227 
1228  bool GetCV( // get a single control vertex
1229  int,int, // CV index ( >= 0 and < CVCount() )
1230  ON::point_style, // style to use for output point
1231  double* // array of length >= CVSize()
1232  ) const;
1233 
1234  bool GetCV( // get a single control vertex
1235  int,int, // CV index ( >= 0 and < CVCount() )
1236  ON_3dPoint& // gets euclidean cv when NURBS is rational
1237  ) const;
1238 
1239  bool GetCV( // get a single control vertex
1240  int,int, // CV index ( >= 0 and < CVCount() )
1241  ON_4dPoint& // gets homogeneous cv
1242  ) const;
1243 
1244  bool ZeroCVs(); // zeros control vertices and, if rational, sets weights to 1
1245 
1247 
1249 
1250  bool Split(
1251  int, // 0 split at "u"=t, 1= split at "v"=t
1252  double, // t = splitting parameter must 0 < t < 1
1253  ON_BezierSurface&, // west/south side returned here (can pass *this)
1254  ON_BezierSurface& // east/north side returned here (can pass *this)
1255  ) const;
1256 
1257  bool Trim(
1258  int dir,
1259  const ON_Interval& domain
1260  );
1261 
1262  // returns the isocurve.
1264  int dir, // 0 first parameter varies and second parameter is constant
1265  // e.g., point on IsoCurve(0,c) at t is srf(t,c)
1266  // 1 first parameter is constant and second parameter varies
1267  // e.g., point on IsoCurve(1,c) at t is srf(c,t)
1268  double c, // value of constant parameter
1269  ON_BezierCurve* iso=NULL // When NULL result is constructed on the heap.
1270  ) const;
1271 
1272  bool IsSingular( // true if surface side is collapsed to a point
1273  int // side of parameter space to test
1274  // 0 = south, 1 = east, 2 = north, 3 = west
1275  ) const;
1276 
1277 
1278  /////////////////////////////////////////////////////////////////
1279  // Tools for managing CV and knot memory
1281  int // number of doubles to reserve
1282  );
1283 
1284  /////////////////////////////////////////////////////////////////
1285  // Implementation
1286 public:
1287  // NOTE: These members are left "public" so that expert users may efficiently
1288  // create bezier curves using the default constructor and borrow the
1289  // knot and CV arrays from their native NURBS representation.
1290  // No technical support will be provided for users who access these
1291  // members directly. If you can't get your stuff to work, then use
1292  // the constructor with the arguments and the SetKnot() and SetCV()
1293  // functions to fill in the arrays.
1294 
1295 
1296  int m_dim; // >= 1
1297  int m_is_rat; // 0 = no, 1 = yes
1298  int m_order[2]; // order = degree+1 >= 2
1299  int m_cv_stride[2];
1300  double* m_cv;
1301  int m_cv_capacity; // if 0, then destructor does not free m_cv
1302 #if 8 == ON_SIZEOF_POINTER
1303  // pad to a multiple of 8 bytes so custom allocators
1304  // will keep m_cv aligned and tail-padding reuse will
1305  // not be an issue.
1306  int m_reserved_ON_BezierSurface;
1307 #endif
1308 };
1309 
1310 
1311 
1312 
1313 class ON_CLASS ON_BezierCage
1314 {
1315 public:
1317 
1319  int dim,
1320  bool is_rat,
1321  int order0,
1322  int order1,
1323  int order2
1324  );
1325 
1326 
1327  /*
1328  Description:
1329  Construct a bezier volume that maps the unit cube
1330  to a bounding box.
1331  Parameters:
1332  bbox - [in] target bounding box
1333  order0 - [in]
1334  order1 - [in]
1335  order2 - [in]
1336  */
1338  const ON_BoundingBox& bbox,
1339  int order0,
1340  int order1,
1341  int order2
1342  );
1343 
1344 
1345  /*
1346  Description:
1347  Construct a bezier volume that maps the unit cube
1348  to an eight sided box.
1349  Parameters:
1350  box_corners - [in] 8 points that define corners of the
1351  target volume.
1352 
1353  7______________6
1354  |\ |\
1355  | \ | \
1356  | \ _____________\
1357  | 4 | 5
1358  | | | |
1359  | | | |
1360  3---|----------2 |
1361  \ | \ |
1362  \ |t \ |
1363  s \ | \ |
1364  \0_____________\1
1365  r
1366 
1367  order0 - [in]
1368  order1 - [in]
1369  order2 - [in]
1370  */
1372  const ON_3dPoint* box_corners,
1373  int order0,
1374  int order1,
1375  int order2
1376  );
1377 
1379 
1381 
1383 
1384 
1385  /*
1386  Description:
1387  Tests class to make sure members are correctly initialized.
1388  Returns:
1389  True if the orders are all >= 2, dimension is positive,
1390  and the rest of the members have settings that are
1391  valid for the orders and dimension.
1392  */
1393  bool IsValid() const;
1394 
1395  void Dump( ON_TextLog& text_log) const;
1396 
1397 
1398  /*
1399  Description:
1400  The dimension of the image of the bazier volume map.
1401  This is generally three, but can be any positive
1402  integer.
1403  Returns:
1404  Dimesion of the image space.
1405  */
1406  int Dimension() const;
1407 
1408 
1409  /*
1410  Description:
1411  Creates a bezier volume with specified orders.
1412  Parameters:
1413  dim - [in]
1414  is_rat - [in]
1415  order0 - [in]
1416  order1 - [in]
1417  order2 - [in]
1418  Returns:
1419  True if input was valid and creation succeeded.
1420  */
1421  bool Create(
1422  int dim,
1423  bool is_rat,
1424  int order0,
1425  int order1,
1426  int order2
1427  );
1428 
1429  /*
1430  Description:
1431  Create a Bezier volume with corners defined by a bounding box.
1432  Parameters:
1433  bbox - [in] target bounding box - the bezier will
1434  map the unit cube onto this bounding box.
1435  order0 - [in]
1436  order1 - [in]
1437  order2 - [in]
1438  */
1439  bool Create(
1440  const ON_BoundingBox& bbox,
1441  int order0,
1442  int order1,
1443  int order2
1444  );
1445 
1446  /*
1447  Description:
1448  Create a bezier volume from a 3d box
1449  Parameters:
1450  box_corners - [in] 8 points that define corners of the volume
1451 
1452  7______________6
1453  |\ |\
1454  | \ | \
1455  | \ _____________\
1456  | 4 | 5
1457  | | | |
1458  | | | |
1459  3---|----------2 |
1460  \ | \ |
1461  \ |t \ |
1462  s \ | \ |
1463  \0_____________\1
1464  r
1465 
1466  */
1467  bool Create(
1468  const ON_3dPoint* box_corners,
1469  int order0,
1470  int order1,
1471  int order2
1472  );
1473 
1474 
1475  /*
1476  Description:
1477  Frees the CV array and sets all members to zero.
1478  */
1479  void Destroy();
1480 
1481  /*
1482  Description:
1483  Sets all members to zero. Does not free the CV array
1484  even when m_cv is not NULL. Generally used when the
1485  CVs were allocated from a memory pool that no longer
1486  exists and the free done in ~ON_BezierCage would
1487  cause a crash.
1488  */
1490 
1491 
1492  /*
1493  Description:
1494  Reads the definition of this class from an
1495  archive previously saved by ON_BezierVolue::Write.
1496  Parameters:
1497  archive - [in] target archive
1498  Returns:
1499  True if successful.
1500  */
1501  bool Read(ON_BinaryArchive& archive);
1502 
1503  /*
1504  Description:
1505  Saves the definition of this class in serial binary
1506  form that can be read by ON_BezierVolue::Read.
1507  Parameters:
1508  archive - [in] target archive
1509  Returns:
1510  True if successful.
1511  */
1512  bool Write(ON_BinaryArchive& archive) const;
1513 
1514 
1515  /*
1516  Description:
1517  Gets the axis aligned bounding box that contains
1518  the bezier's control points. The bezier volume
1519  maps the unit cube into this box.
1520  Parameters:
1521  boxmin - [in] array of Dimension() doubles
1522  boxmax - [in] array of Dimension() doubles
1523  bGrowBox = [in] if true and the input is a valid box
1524  then the input box is grown to
1525  include this object's bounding box.
1526  Returns:
1527  true if successful.
1528  */
1529  bool GetBBox(
1530  double* boxmin,
1531  double* boxmax,
1532  int bGrowBox = false
1533  ) const;
1534 
1535  bool Transform(
1536  const ON_Xform& xform
1537  );
1538 
1539  // Description:
1540  // Rotates the bezier surface about the specified axis. A positive
1541  // rotation angle results in a counter-clockwise rotation
1542  // about the axis (right hand rule).
1543  // Parameters:
1544  // sin_angle - [in] sine of rotation angle
1545  // cos_angle - [in] sine of rotation angle
1546  // rotation_axis - [in] direction of the axis of rotation
1547  // rotation_center - [in] point on the axis of rotation
1548  // Returns:
1549  // true if bezier surface successfully rotated
1550  // Remarks:
1551  // Uses ON_BezierCage::Transform() function to calculate the result.
1552  bool Rotate(
1553  double sin_angle,
1554  double cos_angle,
1555  const ON_3dVector& rotation_axis,
1556  const ON_3dPoint& rotation_center
1557  );
1558 
1559  // Description:
1560  // Rotates the bezier surface about the specified axis. A positive
1561  // rotation angle results in a counter-clockwise rotation
1562  // about the axis (right hand rule).
1563  // Parameters:
1564  // rotation_angle - [in] angle of rotation in radians
1565  // rotation_axis - [in] direction of the axis of rotation
1566  // rotation_center - [in] point on the axis of rotation
1567  // Returns:
1568  // true if bezier surface successfully rotated
1569  // Remarks:
1570  // Uses ON_BezierCage::Transform() function to calculate the result.
1571  bool Rotate(
1572  double rotation_angle,
1573  const ON_3dVector& rotation_axis,
1574  const ON_3dPoint& rotation_center
1575  );
1576 
1577  // Description:
1578  // Translates the bezier surface along the specified vector.
1579  // Parameters:
1580  // translation_vector - [in] translation vector
1581  // Returns:
1582  // true if bezier surface successfully translated
1583  // Remarks:
1584  // Uses ON_BezierCage::Transform() function to calculate the result.
1585  bool Translate(
1586  const ON_3dVector& translation_vector
1587  );
1588 
1589  // Description:
1590  // Scales the bezier surface by the specified facotor. The scale is
1591  // centered at the origin.
1592  // Parameters:
1593  // scale_factor - [in] scale factor
1594  // Returns:
1595  // true if bezier surface successfully scaled
1596  // Remarks:
1597  // Uses ON_BezierCage::Transform() function to calculate the result.
1598  bool Scale(
1599  double scale_factor
1600  );
1601 
1603  int // 0 = "u" domain, 1 = "v" domain, 2 = "w" domain
1604  ) const;
1605 
1606  // returns false if unable to evaluate
1607  bool Evaluate(
1608  double r,
1609  double s,
1610  double t,
1611  int der_count,
1612  int v_stride,
1613  double* v // array of length stride*(ndir+1)*(ndir+2)/2
1614  ) const;
1615 
1616  /*
1617  Description:
1618  Evaluates bezer volume map.
1619  Parameters:
1620  rst - [in]
1621  Returns:
1622  Value of the bezier volume map at (r,s,t).
1623  */
1625  double r,
1626  double s,
1627  double t
1628  ) const;
1629 
1630  /*
1631  Description:
1632  Evaluates bezer volume map.
1633  Parameters:
1634  rst - [in]
1635  Returns:
1636  Value of the bezier volume map at (rst.x,rst.y,rst.z).
1637  */
1639  ON_3dPoint rst
1640  ) const;
1641 
1642  bool IsRational() const; // true if NURBS curve is rational
1643 
1644  bool IsSingular( // true if surface side is collapsed to a point
1645  int // side of parameter space to test
1646  // 0 = south, 1 = east, 2 = north, 3 = west
1647  ) const;
1648 
1649  int CVSize() const; // number of doubles per control vertex
1650  // = IsRational() ? Dim()+1 : Dim()
1651 
1652  int Order( // order = degree + 1
1653  int // dir
1654  ) const;
1655 
1656  int Degree( // degree = order - 1
1657  int // dir
1658  ) const;
1659 
1660  /*
1661  Description:
1662  Expert user function to get a pointer to control vertex
1663  memory. If you are not an expert user, please use
1664  ON_BezierCage::GetCV( ON_3dPoint& ) or
1665  ON_BezierCage::GetCV( ON_4dPoint& ).
1666  Parameters:
1667  cv_index0 - [in] (0 <= cv_index0 < m_order[0])
1668  cv_index1 - [in] (0 <= cv_index1 < m_order[1])
1669  Returns:
1670  Pointer to control vertex.
1671  Remarks:
1672  If the Bezier surface is rational, the format of the
1673  returned array is a homogeneos rational point with
1674  length m_dim+1. If the Bezier surface is not rational,
1675  the format of the returned array is a nonrational
1676  euclidean point with length m_dim.
1677  See Also
1678  ON_BezierCage::CVStyle
1679  ON_BezierCage::GetCV
1680  ON_BezierCage::Weight
1681  */
1682  double* CV(
1683  int i,
1684  int j,
1685  int k
1686  ) const;
1687 
1688  /*
1689  Description:
1690  Returns the style of control vertices in the m_cv array.
1691  Returns:
1692  @untitled table
1693  ON::not_rational m_is_rat is false
1694  ON::homogeneous_rational m_is_rat is true
1695  */
1696  ON::point_style CVStyle() const;
1697 
1698  double Weight( // get value of control vertex weight
1699  int i,
1700  int j,
1701  int k
1702  ) const;
1703 
1704  bool SetWeight( // set value of control vertex weight
1705  int i,
1706  int j,
1707  int k,
1708  double w
1709  );
1710 
1711  bool SetCV( // set a single control vertex
1712  int i,
1713  int j,
1714  int k,
1715  ON::point_style, // style of input point
1716  const double* // value of control vertex
1717  );
1718 
1719  // set a single control vertex
1720  // If NURBS is rational, weight
1721  // will be set to 1.
1722  bool SetCV(
1723  int i,
1724  int j,
1725  int k,
1726  const ON_3dPoint& point
1727  );
1728 
1729  // set a single control vertex
1730  // value of control vertex
1731  // If NURBS is not rational, euclidean
1732  // location of homogeneous point will
1733  // be used.
1734  bool SetCV(
1735  int i,
1736  int j,
1737  int k,
1738  const ON_4dPoint& hpoint
1739  );
1740 
1741  bool GetCV( // get a single control vertex
1742  int i,
1743  int j,
1744  int k,
1745  ON::point_style, // style to use for output point
1746  double* // array of length >= CVSize()
1747  ) const;
1748 
1749  bool GetCV( // get a single control vertex
1750  int i,
1751  int j,
1752  int k,
1753  ON_3dPoint& // gets euclidean cv when NURBS is rational
1754  ) const;
1755 
1756  bool GetCV( // get a single control vertex
1757  int i,
1758  int j,
1759  int k,
1760  ON_4dPoint& // gets homogeneous cv
1761  ) const;
1762 
1763  bool ZeroCVs(); // zeros control vertices and, if rational, sets weights to 1
1764 
1766 
1768 
1769 
1770  /////////////////////////////////////////////////////////////////
1771  // Tools for managing CV and knot memory
1772 
1773  /*
1774  Description:
1775  cv_capacity - [in] number of doubles to reserve
1776  */
1778  int cv_capacity
1779  );
1780 
1781  /////////////////////////////////////////////////////////////////
1782  // Implementation
1783 public:
1784  // NOTE: These members are left "public" so that expert users may efficiently
1785  // create bezier curves using the default constructor and borrow the
1786  // knot and CV arrays from their native NURBS representation.
1787  // No technical support will be provided for users who access these
1788  // members directly. If you can't get your stuff to work, then use
1789  // the constructor with the arguments and the SetKnot() and SetCV()
1790  // functions to fill in the arrays.
1791 
1792 
1793  int m_dim;
1794  bool m_is_rat;
1795  int m_order[3];
1796  int m_cv_stride[3];
1798  double* m_cv;
1799 };
1800 
1801 
1802 class ON_CLASS ON_BezierCageMorph : public ON_SpaceMorph
1803 {
1804 public:
1807 
1808  /*
1809  Description:
1810  Create a Bezier volume.
1811  Parameters:
1812  P0 - [in]
1813  P1 - [in]
1814  P2 - [in]
1815  P3 - [in]
1816  P0,P1,P2,P3 defines a parallepiped in world space. The morph
1817  maps this parallepiped to the (0,1)x(0,1)x(0,1) unit cube
1818  and then applies the BezierCage map.
1819 
1820 
1821  ______________
1822  |\ |\
1823  | \ | \
1824  | \P3____________\
1825  | | | |
1826  | | | |
1827  | | | |
1828  P2---|---------- |
1829  \ | \ |
1830  \ |z \ |
1831  y \ | \ |
1832  \P0____________P1
1833  x
1834 
1835 
1836  point_countX - [in]
1837  point_countY - [in]
1838  point_countZ - [in]
1839  Number of control points in the bezier volume map. The
1840  bezier volume in the returned morph is the identity map
1841  which can be modified as needed.
1842  Returns:
1843  True if resulting morph is valid.
1844  See Also:
1845  ON_BezierCage::SetBezierCage
1846  ON_BezierCage::SetXform
1847  */
1848  bool Create(
1849  ON_3dPoint P0,
1850  ON_3dPoint P1,
1851  ON_3dPoint P2,
1852  ON_3dPoint P3,
1853  int point_countX,
1854  int point_countY,
1855  int point_countZ
1856  );
1857 
1858  /*
1859  Description:
1860  Set the world to unit cube map.
1861  Parameters:
1862  world2unitcube - [in]
1863  Tranformation matrix that maps world coordinates
1864  to the unit cube (0,1)x(0,1)x(0,1).
1865  Returns
1866  True if current bezier volum and input transformation
1867  matrix are valid. In all cases, the morph's m_xyz2rst
1868  member is set.
1869  See Also:
1870  ON_BezierCage::Create
1871  ON_BezierCage::SetBezierCage
1872  */
1873  bool SetXform( ON_Xform world2unitcube );
1874 
1875  /*
1876  Description:
1877  Set the unit cube to world map.
1878  Parameters:
1879  world2unitcube - [in]
1880  Bezier volume map from the unit cube (0,1)x(0,1)x(0,1)
1881  to world space.
1882  Returns
1883  True if current transformation matrix and input
1884  bezier volume are valid. In all cases, the
1885  morph's m_rst2xyz member is set.
1886  See Also:
1887  ON_BezierCage::Create
1888  ON_BezierCage::SetXform
1889  */
1890  bool SetBezierCage( ON_BezierCage& unitcube2world );
1891 
1892  const ON_Xform& WorldToUnitCube() const;
1893  const ON_BezierCage& BezierCage() const;
1894 
1895  bool Read(ON_BinaryArchive& archive);
1896  bool Write(ON_BinaryArchive& archive) const;
1897 
1898  /*
1899  Description:
1900  Transforms the morph by transforming the bezier volume map.
1901  Parameters:
1902  xform - [in]
1903  Returns
1904  True if input is valid.
1905  */
1906  bool Transform(const ON_Xform& xform);
1907 
1908 private:
1909  bool m_bValid;
1910 
1911  // transforms world (x,y,z) coordinate into
1912  // unit cube.
1913  ON_Xform m_xyz2rst;
1914 
1915  // function that maps unit cube into world
1916  ON_BezierCage m_rst2xyz;
1917 };
1918 
1919 #if defined(ON_DLL_TEMPLATE)
1920 
1921 // This stuff is here because of a limitation in the way Microsoft
1922 // handles templates and DLLs. See Microsoft's knowledge base
1923 // article ID Q168958 for details.
1924 #pragma warning( push )
1925 #pragma warning( disable : 4231 )
1926 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_BezierCurve>;
1927 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BezierCurve*>;
1928 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_BezierSurface>;
1929 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BezierSurface*>;
1930 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_BezierCage>;
1931 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BezierCage*>;
1932 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_BezierCageMorph>;
1933 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BezierCageMorph*>;
1934 #pragma warning( pop )
1935 
1936 #endif
1937 
1938 #endif
bool MakeRational()
bool MakeNonRational()
bool SetCV(int i, int j, int k, const ON_3dPoint &point)
bool GetBBox(double *boxmin, double *boxmax, int bGrowBox=false) const
bool GetCV(int i, int j, int k, ON_4dPoint &) const
bool SetWeight(int i, int j, int k, double w)
bool IsRational() const
int Degree(int) const
ON_Interval Domain(int) const
bool Write(ON_BinaryArchive &archive) const
bool SetCV(int i, int j, int k, ON::point_style, const double *)
ON_3dPoint PointAt(double r, double s, double t) const
bool SetCV(int i, int j, int k, const ON_4dPoint &hpoint)
bool Create(const ON_3dPoint *box_corners, int order0, int order1, int order2)
bool Translate(const ON_3dVector &translation_vector)
bool Rotate(double rotation_angle, const ON_3dVector &rotation_axis, const ON_3dPoint &rotation_center)
int CVSize() const
bool ReserveCVCapacity(int cv_capacity)
bool Read(ON_BinaryArchive &archive)
void Dump(ON_TextLog &text_log) const
ON_BezierCage(int dim, bool is_rat, int order0, int order1, int order2)
double * CV(int i, int j, int k) const
bool GetCV(int i, int j, int k, ON::point_style, double *) const
int Dimension() const
ON_3dPoint PointAt(ON_3dPoint rst) const
int Order(int) const
ON_BezierCage(const ON_BoundingBox &bbox, int order0, int order1, int order2)
bool Rotate(double sin_angle, double cos_angle, const ON_3dVector &rotation_axis, const ON_3dPoint &rotation_center)
bool IsSingular(int) const
bool GetCV(int i, int j, int k, ON_3dPoint &) const
bool IsValid() const
double Weight(int i, int j, int k) const
bool Evaluate(double r, double s, double t, int der_count, int v_stride, double *v) const
bool Transform(const ON_Xform &xform)
ON_BezierCage(const ON_BezierCage &src)
ON_BezierCage(const ON_3dPoint *box_corners, int order0, int order1, int order2)
void EmergencyDestroy()
bool Create(int dim, bool is_rat, int order0, int order1, int order2)
bool Scale(double scale_factor)
ON::point_style CVStyle() const
bool Create(const ON_BoundingBox &bbox, int order0, int order1, int order2)
ON_BezierCage & operator=(const ON_BezierCage &src)
bool SetBezierCage(ON_BezierCage &unitcube2world)
const ON_Xform & WorldToUnitCube() const
const ON_BezierCage & BezierCage() const
bool Write(ON_BinaryArchive &archive) const
bool Transform(const ON_Xform &xform)
bool Read(ON_BinaryArchive &archive)
bool Create(ON_3dPoint P0, ON_3dPoint P1, ON_3dPoint P2, ON_3dPoint P3, int point_countX, int point_countY, int point_countZ)
bool SetXform(ON_Xform world2unitcube)
bool Ev2Der(double t, ON_3dPoint &point, ON_3dVector &first_derivative, ON_3dVector &second_derivative) const
bool MakeNonRational()
bool MakeRational()
ON_BezierCurve & operator=(const ON_PolynomialCurve &)
ON_Interval Domain() const
bool ChangeDimension(int desired_dimension)
bool GetCV(int cv_index, ON_3dPoint &point) const
int Order() const
void EmergencyDestroy()
bool Transform(const ON_Xform &xform)
ON_BezierCurve(const ON_BezierCurve &)
bool SetCV(int cv_index, ON::point_style pointstyle, const double *cv)
bool GetCV(int cv_index, ON::point_style pointstyle, double *cv) const
bool GetTightBoundingBox(ON_BoundingBox &tight_bbox, int bGrowBox=false, const ON_Xform *xform=0) const
bool Ev1Der(double t, ON_3dPoint &point, ON_3dVector &first_derivative) const
bool SetCV(int cv_index, const ON_3dPoint &point)
bool Rotate(double sin_angle, double cos_angle, const ON_3dVector &rotation_axis, const ON_3dPoint &rotation_center)
int Degree() const
bool Evaluate(double t, int der_count, int v_stride, double *v) const
bool GetNurbForm(ON_NurbsCurve &nurbs_curve) const
bool GetBBox(double *box_min, double *box_max, int bGrowBox=false) const
bool Rotate(double rotation_angle, const ON_3dVector &rotation_axis, const ON_3dPoint &rotation_center)
bool Split(double t, ON_BezierCurve &left_side, ON_BezierCurve &right_side) const
ON_DEPRECATED bool Reparametrize(double)
ON::point_style CVStyle() const
bool IncreaseDegree(int desired_degree)
bool Loft(const ON_3dPointArray &points)
bool ChangeWeights(int i0, double w0, int i1, double w1)
bool SetWeight(int cv_index, double weight)
ON_BezierCurve & operator=(const ON_BezierCurve &)
double Weight(int cv_index) const
int Dimension() const
bool EvTangent(double t, ON_3dPoint &point, ON_3dVector &tangent) const
bool GetBoundingBox(ON_BoundingBox &bbox, int bGrowBox=false) const
ON_3dVector TangentAt(double t) const
bool Reparameterize(double c)
bool EvPoint(double t, ON_3dPoint &point) const
ON_3dVector CurvatureAt(double t) const
int CVSize() const
bool ReserveCVCapacity(int desired_cv_capacity)
bool Create(int dim, ON_BOOL32 bIsRational, int order)
ON_BezierCurve & operator=(const ON_3dPointArray &)
ON_BoundingBox BoundingBox() const
ON_BezierCurve & operator=(const ON_2dPointArray &)
bool SetCV(int cv_index, const ON_4dPoint &point)
ON_BezierCurve & operator=(const ON_4dPointArray &)
ON_BezierCurve(const ON_PolynomialCurve &)
bool GetCV(int cv_index, ON_4dPoint &point) const
ON_BezierCurve(int dim, ON_BOOL32 bIsRational, int order)
ON_BezierCurve(const ON_4dPointArray &)
bool Scale(double scale_factor)
bool Translate(const ON_3dVector &translation_vector)
ON_3dPoint PointAt(double t) const
bool Trim(const ON_Interval &interval)
bool Loft(int pt_dim, int pt_count, int pt_stride, const double *pt, int t_stride, const double *t)
double ControlPolygonLength() const
ON_BezierCurve(const ON_3dPointArray &)
ON_BezierCurve(const ON_2dPointArray &)
ON_3dVector DerivativeAt(double t) const
bool IsRational() const
int CVCount() const
double * CV(int cv_index) const
bool EvCurvature(double t, ON_3dPoint &point, ON_3dVector &tangent, ON_3dVector &kappa) const
bool IsValid() const
bool ScaleConrolPoints(int i, double w)
void Dump(ON_TextLog &) const
int Degree(int) const
ON_3dPoint PointAt(double s, double t) const
bool MakeNonRational()
bool Scale(double scale_factor)
ON_BezierSurface(const ON_PolynomialSurface &)
bool SetWeight(int, int, double)
bool GetCV(int, int, ON_4dPoint &) const
bool SetCV(int, int, const ON_3dPoint &)
bool Rotate(double rotation_angle, const ON_3dVector &rotation_axis, const ON_3dPoint &rotation_center)
bool Loft(int count, const ON_BezierCurve *const *curve_list)
bool ReserveCVCapacity(int)
void Dump(ON_TextLog &) const
bool SetCV(int, int, ON::point_style, const double *)
bool GetBBox(double *, double *, int bGrowBox=false) const
ON_BezierSurface(const ON_BezierSurface &)
double * CV(int cv_index0, int cv_index1) const
ON_BezierSurface & operator=(const ON_PolynomialSurface &)
ON_BezierCurve * IsoCurve(int dir, double c, ON_BezierCurve *iso=NULL) const
int CVSize() const
bool GetCV(int, int, ON_3dPoint &) const
void EmergencyDestroy()
bool IsRational() const
bool Translate(const ON_3dVector &translation_vector)
bool IsSingular(int) const
ON_BoundingBox BoundingBox() const
bool Trim(int dir, const ON_Interval &domain)
bool Transform(const ON_Xform &)
bool GetNurbForm(ON_NurbsSurface &) const
bool GetBoundingBox(ON_BoundingBox &bbox, int bGrowBox) const
bool Create(int dim, int is_rat, int order0, int order1)
bool Evaluate(double, double, int, int, double *) const
bool Split(int, double, ON_BezierSurface &, ON_BezierSurface &) const
bool Rotate(double sin_angle, double cos_angle, const ON_3dVector &rotation_axis, const ON_3dPoint &rotation_center)
ON::point_style CVStyle() const
ON_Interval Domain(int) const
ON_BezierSurface(int dim, int is_rat, int order0, int order1)
bool SetCV(int, int, const ON_4dPoint &)
int Order(int) const
bool GetCV(int, int, ON::point_style, double *) const
double Weight(int, int) const
bool Reverse(int)
ON_BezierSurface & operator=(const ON_BezierSurface &)
bool Loft(const ON_ClassArray< ON_BezierCurve > &curve_list)
bool IsValid() const
int Dimension() const
ON_4dPointArray m_cv
ON_PolynomialCurve & operator=(const ON_BezierCurve &)
ON_PolynomialCurve & operator=(const ON_PolynomialCurve &)
ON_BOOL32 Evaluate(double t, int der_count, int v_stride, double *v) const
ON_PolynomialCurve(const ON_PolynomialCurve &)
ON_PolynomialCurve(int dim, ON_BOOL32 bIsRational, int order)
ON_PolynomialCurve(const ON_BezierCurve &)
ON_BOOL32 Create(int dim, ON_BOOL32 bIsRational, int order)
ON_BOOL32 Evaluate(double s, double t, int der_count, int v_stride, double *v) const
ON_PolynomialSurface(const ON_BezierSurface &)
ON_PolynomialSurface(const ON_PolynomialSurface &)
ON_PolynomialSurface & operator=(const ON_PolynomialSurface &)
ON_BOOL32 Create(int, ON_BOOL32, int, int)
ON_PolynomialSurface & operator=(const ON_BezierSurface &)
ON_PolynomialSurface(int, ON_BOOL32, int, int)
ON_4dPointArray m_cv