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