opennurbs_nurbscurve.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 // Definition of NURBS curve
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(OPENNURBS_NURBSCURVE_INC_)
24 #define OPENNURBS_NURBSCURVE_INC_
25 
26 class ON_CLASS ON_NurbsCurve : public ON_Curve
27 {
28  ON_OBJECT_DECLARE(ON_NurbsCurve);
29 
30 public:
31  ON_NurbsCurve() ON_NOEXCEPT;
32  virtual ~ON_NurbsCurve();
35 
36 #if defined(ON_HAS_RVALUEREF)
37  // rvalue copy constructor
38  ON_NurbsCurve( ON_NurbsCurve&& ) ON_NOEXCEPT;
39 
40  // The rvalue assignment operator calls ON_Object::operator=(ON_Object&&)
41  // which could throw exceptions. See the implementation of
42  // ON_Object::operator=(ON_Object&&) for details.
44 #endif
45 
46 public:
47  /*
48  Description:
49  Use ON_NurbsCurve::New(...) instead of new ON_NurbsCurve(...)
50  Returns:
51  Pointer to an ON_NurbsCurve. Destroy by calling delete.
52  Remarks:
53  See static ON_Brep* ON_Brep::New() for details.
54  */
55  static ON_NurbsCurve* New();
56  static ON_NurbsCurve* New(
57  const ON_NurbsCurve& nurbs_curve
58  );
59  static ON_NurbsCurve* New(
60  const ON_BezierCurve& bezier_curve
61  );
62  static ON_NurbsCurve* New(
63  int dimension,
64  bool bIsRational,
65  int order,
66  int cv_count
67  );
68 
69 
70 
71  // Description:
72  // Create a NURBS curve equal to bezier with domain [0,1].
73  // Parameters:
74  // bezier_curve - [in]
76  const ON_BezierCurve& bezier_curve
77  );
78 
79  // Description:
80  // Create a NURBS curve with knot a cv memory allocated.
81  // Parameters:
82  // dimension - [in] (>= 1)
83  // bIsRational - [in] true to make a rational NURBS
84  // order - [in] (>= 2) The order=degree+1
85  // cv_count - [in] (>= order) number of control vertices
87  int dimension,
88  bool bIsRational,
89  int order,
90  int cv_count
91  );
92 
93  // virtual ON_Object::SizeOf override
94  unsigned int SizeOf() const override;
95 
96  // virtual ON_Object::DataCRC override
97  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const override;
98 
99  /*
100  Description:
101  See if this and other are same NURBS geometry.
102  Parameters:
103  other - [in] other NURBS curve
104  bIgnoreParameterization - [in] if true, parameterization
105  and orientaion are ignored.
106  tolerance - [in] tolerance to use when comparing
107  control points.
108  Returns:
109  true if curves are tne same.
110  */
111  bool IsDuplicate(
112  const ON_NurbsCurve& other,
113  bool bIgnoreParameterization,
114  double tolerance = ON_ZERO_TOLERANCE
115  ) const;
116 
117  // Description:
118  // Zeros all fields.
119  void Initialize(void);
120 
121  // Description:
122  // Create a NURBS curve with knot a cv memory allocated.
123  // Parameters:
124  // dimension - [in] (>= 1)
125  // bIsRational - [in] true to make a rational NURBS
126  // order - [in] (>= 2) The order=degree+1
127  // cv_count - [in] (>= order) number of control vertices
128  bool Create(
129  int dimension,
130  bool bIsRational,
131  int order,
132  int cv_count
133  );
134 
135  // Description:
136  // Create a clamped uniform NURBS curve from a list
137  // of control points
138  // Parameters:
139  // dimension - [in] 1, 2 or 3
140  // order - [in] (>=2) order=degree+1
141  // point_count - [in] (>=order) number of control vertices
142  // point - [in] array of control vertex locations.
143  // knot_delta - [in] (>0.0) knot spacing
144  // Returns:
145  // true if successful
146  bool CreateClampedUniformNurbs(
147  int dimension,
148  int order,
149  int point_count,
150  const ON_3dPoint* point,
151  double knot_delta = 1.0
152  );
153 
154  // Description:
155  // Create a periodic uniform NURBS curve from a list
156  // of control points
157  // Parameters:
158  // dimension - [in] 1, 2 or 3
159  // order - [in] (>=2) order=degree+1
160  // point_count - [in] (>=max(3,order-1)) number of distinct control vertices
161  // point - [in] array of distinct control vertex locations.
162  // knot_delta - [in] (>0.0) knot spacing
163  // Returns:
164  // true if successful
165  bool CreatePeriodicUniformNurbs(
166  int dimension,
167  int order,
168  int point_count,
169  const ON_3dPoint* point,
170  double knot_delta = 1.0
171  );
172 
173  // Description:
174  // Deallocate knot and cv memory. Zeros all fields.
175  void Destroy();
176 
177 
178  // Description:
179  // Call if memory used by ON_NurbsCurve becomes invalid.
180  void EmergencyDestroy();
181 
182 
183  // Description:
184  // Set NURBS curve equal to bezier with domain [0,1].
185  // Parameters:
186  // bezier_curve - [in]
188  const ON_BezierCurve& bezier_curve
189  );
190 
191  /////////////////////////////////////////////////////////////////
192  // ON_Object overrides
193 
194  bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
195 
196  // Description:
197  // virtual ON_Object::Dump override
198  void Dump(
199  ON_TextLog& dump
200  ) const override;
201 
202  // Description:
203  // virtual ON_Object::Write override
204  bool Write(
205  ON_BinaryArchive& binary_archive
206  ) const override;
207 
208  // Description:
209  // virtual ON_Object::Read override
210  bool Read(
211  ON_BinaryArchive& binary_archive
212  ) override;
213 
214  /////////////////////////////////////////////////////////////////
215  // ON_Geometry overrides
216 
217  // Description:
218  // virtual ON_Geometry::Dimension override
219  // Returns:
220  // value of m_dim
221  int Dimension() const override;
222 
223  // virtual ON_Geometry GetBBox override
224  bool GetBBox( double* boxmin, double* boxmax, bool bGrowBox = false ) const override;
225 
226  // Description:
227  // virtual ON_Geometry::Transform override.
228  // Transforms the NURBS curve.
229  //
230  // Parameters:
231  // xform - [in] transformation to apply to object.
232  //
233  // Remarks:
234  // When overriding this function, be sure to include a call
235  // to ON_Object::TransformUserData() which takes care of
236  // transforming any ON_UserData that may be attached to
237  // the object.
238  bool Transform(
239  const ON_Xform& xform
240  ) override;
241 
242  // virtual ON_Geometry::IsDeformable() override
243  bool IsDeformable() const override;
244 
245  // virtual ON_Geometry::MakeDeformable() override
246  bool MakeDeformable() override;
247 
248  // Description:
249  // virtual ON_Geometry::SwapCoordinates override.
250  // Swaps control vertex coordinate values with indices i and j.
251  // Parameters:
252  // i - [in] coordinate index
253  // j - [in] coordinate index
254  bool SwapCoordinates(
255  int i,
256  int j
257  ) override;
258 
259 
260  /////////////////////////////////////////////////////////////////
261  // ON_Curve overrides
262 
263  // Description:
264  // virtual ON_Curve::Domain override.
265  // Returns:
266  // domain of the NURBS curve.
267  ON_Interval Domain() const override;
268 
269  // Description:
270  // virtual ON_Curve::SetDomain override.
271  // Set the domain of the curve
272  // Parameters:
273  // t0 - [in]
274  // t1 - [in] new domain will be [t0,t1]
275  // Returns:
276  // true if successful.
277  bool SetDomain(
278  double t0,
279  double t1
280  ) override;
281 
282  /*
283  Description:
284  If this curve is closed, then modify it so that
285  the start/end point is at curve parameter t.
286  Parameters:
287  t - [in] curve parameter of new start/end point. The
288  returned curves domain will start at t.
289  Returns:
290  true if successful.
291  Remarks:
292  Overrides virtual ON_Curve::ChangeClosedCurveSeam
293  */
294  bool ChangeClosedCurveSeam(
295  double t
296  ) override;
297 
298  // Description:
299  // virtual ON_Curve::SpanCount override.
300  // Get number of nonempty smooth (c-infinity) spans in curve
301  // Returns:
302  // Number of nonempty smooth (c-infinity) spans.
303  // Remarks:
304  // A nonempty span is bracked by knots m_knot[i] < m_knot[i+1]
305  // with m_order-2 <= i < m_cv_count-1.
306  int SpanCount() const override;
307 
308  // Description:
309  // virtual ON_Curve::GetSpanVector override.
310  // Get number of parameters of distinct knots in NURBS curve's domain.
311  // Parameters:
312  // knot_values - [out] an array of length SpanCount()+1 is
313  // filled in with the distinct knot values in the list
314  /// (m_knot[m_order-2],...,m_knot[m_cv_count-1)
315  // Returns:
316  // true if successful
317  bool GetSpanVector(
318  double* knot_values
319  ) const override; //
320 
321  // Description:
322  // virtual ON_Curve::Degree override.
323  // Returns:
324  // m_order-1
325  int Degree() const override;
326 
327  // Description:
328  // virtual ON_Curve::GetParameterTolerance override.
329  bool GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus
330  double t,
331  double* tminus,
332  double* tplus
333  ) const override;
334 
335  // Description:
336  // virtual ON_Curve::IsLinear override.
337  bool IsLinear(
338  double tolerance = ON_ZERO_TOLERANCE
339  ) const override;
340 
341  /*
342  Description:
343  Several types of ON_Curve can have the form of a polyline including
344  a degree 1 ON_NurbsCurve, an ON_PolylineCurve, and an ON_PolyCurve
345  all of whose segments are some form of polyline. IsPolyline tests
346  a curve to see if it can be represented as a polyline.
347  Parameters:
348  pline_points - [out] if not nullptr and true is returned, then the
349  points of the polyline form are returned here.
350  t - [out] if not nullptr and true is returned, then the parameters of
351  the polyline points are returned here.
352  Returns:
353  @untitled table
354  0 curve is not some form of a polyline
355  >=2 number of points in polyline form
356  */
357  int IsPolyline(
358  ON_SimpleArray<ON_3dPoint>* pline_points = nullptr,
359  ON_SimpleArray<double>* pline_t = nullptr
360  ) const override;
361 
362  // Description:
363  // virtual ON_Curve::IsArc override.
364  bool IsArc(
365  const ON_Plane* plane = nullptr,
366  ON_Arc* arc = nullptr,
367  double tolerance = ON_ZERO_TOLERANCE
368  ) const override;
369 
370  // Description:
371  // virtual ON_Curve::IsPlanar override.
372  bool IsPlanar(
373  ON_Plane* plane = nullptr,
374  double tolerance = ON_ZERO_TOLERANCE
375  ) const override;
376 
377  // Description:
378  // virtual ON_Curve::IsInPlane override.
379  bool IsInPlane(
380  const ON_Plane& test_plane,
381  double tolerance = ON_ZERO_TOLERANCE
382  ) const override;
383 
384  // Description:
385  // virtual ON_Curve::IsClosed override.
386  // Returns:
387  // true if NURBS curve is closed. (Either curve has
388  // clamped end knots and euclidean location of start
389  // CV = euclidean location of end CV, or curve is
390  // periodic.)
391  bool IsClosed() const override;
392 
393  // Description:
394  // virtual ON_Curve::IsPeriodic override.
395  // Returns:
396  // true if NURBS curve is periodic (degree > 1,
397  // periodic knot vector, last degree many CVs
398  // are duplicates of first degree many CVs).
399  bool IsPeriodic() const override;
400 
401  /*
402  Description:
403  Search for a derivatitive, tangent, or curvature discontinuity.
404  Parameters:
405  c - [in] type of continity to test for. If ON::continuity::C1_continuous
406  t0 - [in] search begins at t0
407  t1 - [in] (t0 < t1) search ends at t1
408  t - [out] if a discontinuity is found, the *t reports the
409  parameter at the discontinuity.
410  hint - [in/out] if GetNextDiscontinuity will be called repeatedly,
411  passing a "hint" with initial value *hint=0 will increase the speed
412  of the search.
413  dtype - [out] if not nullptr, *dtype reports the kind of discontinuity
414  found at *t. A value of 1 means the first derivative or unit tangent
415  was discontinuous. A value of 2 means the second derivative or
416  curvature was discontinuous.
417  cos_angle_tolerance - [in] default = cos(1 degree) Used only when
418  c is ON::continuity::G1_continuous or ON::continuity::G2_continuous. If the cosine
419  of the angle between two tangent vectors
420  is <= cos_angle_tolerance, then a G1 discontinuity is reported.
421  curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
422  c is ON::continuity::G2_continuous or ON::continuity::Gsmooth_continuous.
423  ON::continuity::G2_continuous:
424  If K0 and K1 are curvatures evaluated
425  from above and below and |K0 - K1| > curvature_tolerance,
426  then a curvature discontinuity is reported.
427  ON::continuity::Gsmooth_continuous:
428  If K0 and K1 are curvatures evaluated from above and below
429  and the angle between K0 and K1 is at least twice angle tolerance
430  or ||K0| - |K1|| > (max(|K0|,|K1|) > curvature_tolerance,
431  then a curvature discontinuity is reported.
432  Returns:
433  true if a discontinuity was found on the interior of the interval (t0,t1).
434  Remarks:
435  Overrides ON_Curve::GetNextDiscontinuity.
436  */
437  bool GetNextDiscontinuity(
438  ON::continuity c,
439  double t0,
440  double t1,
441  double* t,
442  int* hint=nullptr,
443  int* dtype=nullptr,
444  double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
445  double curvature_tolerance=ON_SQRT_EPSILON
446  ) const override;
447 
448  /*
449  Description:
450  Test continuity at a curve parameter value.
451  Parameters:
452  c - [in] continuity to test for
453  t - [in] parameter to test
454  hint - [in] evaluation hint
455  point_tolerance - [in] if the distance between two points is
456  greater than point_tolerance, then the curve is not C0.
457  d1_tolerance - [in] if the difference between two first derivatives is
458  greater than d1_tolerance, then the curve is not C1.
459  d2_tolerance - [in] if the difference between two second derivatives is
460  greater than d2_tolerance, then the curve is not C2.
461  cos_angle_tolerance - [in] default = cos(1 degree) Used only when
462  c is ON::continuity::G1_continuous or ON::continuity::G2_continuous. If the cosine
463  of the angle between two tangent vectors
464  is <= cos_angle_tolerance, then a G1 discontinuity is reported.
465  curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
466  c is ON::continuity::G2_continuous or ON::continuity::Gsmooth_continuous.
467  ON::continuity::G2_continuous:
468  If K0 and K1 are curvatures evaluated
469  from above and below and |K0 - K1| > curvature_tolerance,
470  then a curvature discontinuity is reported.
471  ON::continuity::Gsmooth_continuous:
472  If K0 and K1 are curvatures evaluated from above and below
473  and the angle between K0 and K1 is at least twice angle tolerance
474  or ||K0| - |K1|| > (max(|K0|,|K1|) > curvature_tolerance,
475  then a curvature discontinuity is reported.
476  Returns:
477  true if the curve has at least the c type continuity at the parameter t.
478  Remarks:
479  Overrides ON_Curve::IsContinuous.
480  */
481  bool IsContinuous(
482  ON::continuity c,
483  double t,
484  int* hint = nullptr,
485  double point_tolerance=ON_ZERO_TOLERANCE,
486  double d1_tolerance=ON_ZERO_TOLERANCE,
487  double d2_tolerance=ON_ZERO_TOLERANCE,
488  double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
489  double curvature_tolerance=ON_SQRT_EPSILON
490  ) const override;
491 
492  /*
493  Description:
494  Force the curve to start at a specified point.
495  Parameters:
496  start_point - [in]
497  Returns:
498  true if successful.
499  Remarks:
500  Some end points cannot be moved. Be sure to check return
501  code.
502  See Also:
503  ON_Curve::SetEndPoint
504  ON_Curve::PointAtStart
505  ON_Curve::PointAtEnd
506  */
507  //virtual
508  bool SetStartPoint(
509  ON_3dPoint start_point
510  ) override;
511 
512  /*
513  Description:
514  Force the curve to end at a specified point.
515  Parameters:
516  end_point - [in]
517  Returns:
518  true if successful.
519  Remarks:
520  Some end points cannot be moved. Be sure to check return
521  code.
522  See Also:
523  ON_Curve::SetStartPoint
524  ON_Curve::PointAtStart
525  ON_Curve::PointAtEnd
526  */
527  //virtual
528  bool SetEndPoint(
529  ON_3dPoint end_point
530  ) override;
531 
532  // Description:
533  // virtual ON_Curve::Reverse override.
534  // Reverse parameterizatrion by negating all knots
535  // and reversing the order of the control vertices.
536  // Remarks:
537  // Domain changes from [a,b] to [-b,-a]
538  bool Reverse() override;
539 
540  // Description:
541  // virtual ON_Curve::Evaluate override.
542  bool Evaluate( // returns false if unable to evaluate
543  double, // evaluation parameter
544  int, // number of derivatives (>=0)
545  int, // array stride (>=Dimension())
546  double*, // array of length stride*(ndir+1)
547  int = 0, // optional - determines which side to evaluate from
548  // 0 = default
549  // < 0 to evaluate from below,
550  // > 0 to evaluate from above
551  int* = 0 // optional - evaluation hint (int) used to speed
552  // repeated evaluations
553  ) const override;
554 
555 
556  /*
557  Parameters:
558  span_index - [in]
559  (0 <= span_index <= m_cv_count-m_order)
560  min_length -[in]
561  minimum length of a linear span
562  tolerance -[in]
563  distance tolerance to use when checking control points
564  between the span ends
565  Returns
566  true if the span is a non-degenrate line. This means:
567  - dimension = 2 or 3
568  - There are full multiplicity knots at each end of the span.
569  - The length of the the line segment from the span's initial
570  control point to the span's final control point is
571  >= min_length.
572  - The distance from the line segment to the interior control points
573  is <= tolerance and the projections of these points onto
574  the line increases monotonically.
575  */
576  bool SpanIsLinear(
577  int span_index,
578  double min_length,
579  double tolerance
580  ) const;
581 
582  bool SpanIsLinear(
583  int span_index,
584  double min_length,
585  double tolerance,
586  ON_Line* line
587  ) const;
588 
589 
590  /*
591  Description:
592  Looks for problems caused by knots that are close together
593  or have mulitplicity >= order. If bRepair is true, the problems
594  are fixed. Does not change the domain.
595  Parameters:
596  knot_tolerance - [in] >= 0 When in doubt, use zero.
597  bRepair - [in] If true, then problems are repaired.
598  Otherwise this function looks for problemsn that
599  can be repaired, but does not modify the curve.
600  Returns:
601  True if bad knots were found and can be repaired.
602  See Also:
603  ON_NurbsCurve::RemoveShortSegments
604  */
605  bool RepairBadKnots(
606  double knot_tolerance=0.0,
607  bool bRepair = true
608  );
609 
610  // Description:
611  // virtual ON_Curve::Trim override.
612  bool Trim( const ON_Interval& ) override;
613 
614 
615 
616  // Description:
617  // Where possible, analytically extends curve to include domain.
618  // Parameters:
619  // domain - [in] if domain is not included in curve domain,
620  // curve will be extended so that its domain includes domain.
621  // Will not work if curve is closed. Original curve is identical
622  // to the restriction of the resulting curve to the original curve domain,
623  // Returns:
624  // true if successful.
625  bool Extend(
626  const ON_Interval& domain
627  ) override;
628 
629  // Description:
630  // virtual ON_Curve::Split override.
631  //
632  // Split() divides the curve at the specified parameter. The parameter
633  // must be in the interior of the curve's domain. The pointers passed
634  // to ON_NurbsCurve::Split must either be nullptr or point to an ON_NurbsCurve.
635  // If the pointer is nullptr, then a curve will be created
636  // in Split(). You may pass "this" as one of the pointers to Split().
637  // For example,
638  //
639  // ON_NurbsCurve right_side;
640  // crv.Split( crv.Domain().Mid() &crv, &right_side );
641  //
642  // would split crv at the parametric midpoint, put the left side in crv,
643  // and return the right side in right_side.
644  bool Split(
645  double split_param, // t = curve parameter to split curve at
646  ON_Curve*& left_result, // left portion returned here (must be an ON_NurbsCurve)
647  ON_Curve*& right_result // right portion returned here (must be an ON_NurbsCurve)
648  ) const override;
649 
650  // Description:
651  // virtual ON_Curve::GetNurbForm override.
652  int GetNurbForm( // returns 0: unable to create NURBS representation
653  // with desired accuracy.
654  // 1: success - returned NURBS parameterization
655  // matches the curve's to wthe desired accuracy
656  // 2: success - returned NURBS point locus matches
657  // the curve's to the desired accuracy but, on
658  // the interior of the curve's domain, the
659  // curve's parameterization and the NURBS
660  // parameterization may not match to the
661  // desired accuracy.
662  ON_NurbsCurve& nurbsform,
663  double tolerance = 0.0,
664  const ON_Interval* subdomain = nullptr // OPTIONAL subdomain of curve
665  ) const override;
666 
667  // Description:
668  // virtual ON_Curve::HasNurbForm override.
669  int HasNurbForm( // returns 0: unable to create NURBS representation
670  // with desired accuracy.
671  // 1: success - returned NURBS parameterization
672  // matches the curve's to wthe desired accuracy
673  // 2: success - returned NURBS point locus matches
674  // the curve's to the desired accuracy but, on
675  // the interior of the curve's domain, the
676  // curve's parameterization and the NURBS
677  // parameterization may not match to the
678  // desired accuracy.
679  ) const override;
680 
681  // Description:
682  // virtual ON_Curve::GetCurveParameterFromNurbFormParameter override
684  double nurbs_t,
685  double* curve_t
686  ) const override;
687 
688  // Description:
689  // virtual ON_Curve::GetNurbFormParameterFromCurveParameter override
691  double curve_t,
692  double* nurbs_t
693  ) const override;
694 
695 public:
696 
697  /////////////////////////////////////////////////////////////////
698  // Interface
699 
700  bool IsRational( // true if NURBS curve is rational
701  void
702  ) const;
703 
704  int CVSize( // number of doubles per control vertex
705  void // = IsRational() ? Dim()+1 : Dim()
706  ) const;
707 
708  int Order( // order = degree + 1
709  void
710  ) const;
711 
712  int CVCount( // number of control vertices
713  void
714  ) const;
715 
716  int KnotCount( // total number of knots in knot vector
717  void
718  ) const;
719 
720  /*
721  Description:
722  Expert user function to get a pointer to control vertex
723  memory. If you are not an expert user, please use
724  ON_NurbsCurve::GetCV( ON_3dPoint& ) or
725  ON_NurbsCurve::GetCV( ON_4dPoint& ).
726  Parameters:
727  cv_index - [in]
728  Returns:
729  Pointer to control vertex.
730  Remarks:
731  If the NURBS curve is rational, the format of the
732  returned array is a homogeneos rational point with
733  length m_dim+1. If the NURBS curve is not rational,
734  the format of the returned array is a nonrational
735  euclidean point with length m_dim.
736  See Also
737  ON_NurbsCurve::CVStyle
738  ON_NurbsCurve::GetCV
739  ON_NurbsCurve::Weight
740  */
741  double* CV(
742  int cv_index
743  ) const;
744 
745  /*
746  Parameters:
747  cv_index - [in]
748  zero based control point index
749  Returns:
750  Control point as an ON_4dPoint.
751  Remarks:
752  If cv_index or the nurbs curve is not valid, then ON_4dPoint::Nan is returned.
753  If dim < 3, unused coordinates are zero.
754  If dim >= 4, the first three coordinates are returned.
755  If is_rat is false, the weight is 1.
756  */
757  const ON_4dPoint ControlPoint(
758  int cv_index
759  ) const;
760 
761  /*
762  Description:
763  Returns the style of control vertices in the m_cv array.
764  Returns:
765  @untitled table
766  ON::not_rational m_is_rat is false
767  ON::homogeneous_rational m_is_rat is true
768  */
769  ON::point_style CVStyle() const;
770 
771 
772  double Weight( // get value of control vertex weight
773  int // CV index ( >= 0 and < CVCount() )
774  ) const;
775 
776  /*
777  Description:
778  Set value of control vertex weight.
779  If curve is non-rational, it will be converted to rational.
780  */
781  bool SetWeight(
782  int, // CV index ( >= 0 and < CVCount() )
783  double // value of control point weight
784  );
785 
786  bool SetCV( // set a single control vertex
787  int, // CV index ( >= 0 and < CVCount() )
788  ON::point_style, // style of input point
789  const double* // value of control vertex
790  );
791 
792  bool SetCV( // set a single control vertex
793  int, // CV index ( >= 0 and < CVCount() )
794  const ON_3dPoint& // value of control vertex
795  // If NURBS is rational, weight
796  // will be set to 1.
797  );
798 
799  bool SetCV( // set a single control vertex
800  int, // CV index ( >= 0 and < CVCount() )
801  const ON_4dPoint& // value of control vertex
802  // If NURBS is not rational, euclidean
803  // location of homogeneous point will
804  // be used.
805  );
806 
807  bool GetCV( // get a single control vertex
808  int, // CV index ( >= 0 and < CVCount() )
809  ON::point_style, // style to use for output point
810  double* // array of length >= CVSize()
811  ) const;
812 
813  bool GetCV( // get a single control vertex
814  int, // CV index ( >= 0 and < CVCount() )
815  ON_3dPoint& // gets euclidean cv when NURBS is rational
816  ) const;
817 
818  bool GetCV( // get a single control vertex
819  int, // CV index ( >= 0 and < CVCount() )
820  ON_4dPoint& // gets homogeneous cv
821  ) const;
822 
823  // Description:
824  // Set knot value.
825  // Parameters:
826  // knot_index - [in] 0 <= knot_index <= KnotCount()-1
827  // knot_value - [in]
828  // Remarks:
829  // m_knot[] must exist. Use ReserveKnotCapacity to
830  // allocate m_knot[].
831  // Returns:
832  // true if successful
833  // See Also:
834  // ON_NurbsCurve::ReserveKnotCapacity
835  bool SetKnot(
836  int knot_index,
837  double knot_value
838  );
839 
840  // Description:
841  // Get knot value.
842  // Parameters:
843  // knot_index - [in] 0 <= knot_index <= KnotCount()-1
844  // Returns:
845  // knot value = m_knot[knot_index]
846  // See Also:
847  // ON_NurbsCurve::SetKnot, ON_NurbsCurve::KnotMultiplicity
848  double Knot(
849  int knot_index
850  ) const;
851 
852  // Description:
853  // Get knot multiplicity.
854  // Parameters:
855  // knot_index - [in] 0 <= knot_index <= KnotCount()-1
856  // Returns:
857  // knot multiplicity = m_knot[knot_index]
858  // See Also:
859  // ON_NurbsCurve::SetKnot, ON_NurbsCurve::Knot,
860  // ON_NurbsCurve::InsertKnot
861  int KnotMultiplicity(
862  int knot_index
863  ) const;
864 
865  // Description:
866  // Get pointer to knot vector array.
867  // Returns:
868  // pointer to knot vector array (m_knot).
869  // See Also:
870  // ON_NurbsCurve::SetKnot, ON_NurbsCurve::Knot,
871  // ON_NurbsCurve::InsertKnot
872  const double* Knot() const;
873 
874  // Description:
875  // Make knot vector a clamped uniform knot vector
876  // based on the current values of m_order and m_cv_count.
877  // Does not change values of control vertices.
878  // Parameters:
879  // delta - [in] (>0.0) knot spacing.
880  // Returns:
881  // true if successful.
882  // Remarks:
883  // Allocates m_knot[] if it is not big enough.
884  // See Also:
885  // ON_MakeClampedUniformKnotVector
886  bool MakeClampedUniformKnotVector(
887  double delta = 1.0
888  );
889 
890  // Description:
891  // Make knot vector a periodic uniform knot vector
892  // based on the current values of m_order and m_cv_count.
893  // Does not change values of control vertices.
894  // Parameters:
895  // delta - [in] (>0.0) knot spacing.
896  // Returns:
897  // true if successful.
898  // Remarks:
899  // Allocates m_knot[] if it is not big enough.
900  // See Also:
901  // ON_MakePeriodicUniformKnotVector
902  bool MakePeriodicUniformKnotVector(
903  double delta = 1.0
904  );
905 
906  bool IsClamped( // determine if knot vector is clamped
907  int = 2 // end to check: 0 = start, 1 = end, 2 = start and end
908  ) const;
909 
910  double SuperfluousKnot(
911  int // 0 = start, 1 = end
912  ) const;
913 
914  double GrevilleAbcissa(
915  int // index (0 <= index < CVCount(dir)
916  ) const;
917 
918  bool GetGrevilleAbcissae( // see ON_GetGrevilleAbcissae() for details
919  double* // g[cv_count]
920  ) const;
921 
922  bool ZeroCVs(); // zeros control vertices and, if rational, sets weights to 1
923 
924  // Description:
925  // Clamp end knots. Does not modify control points.
926  // Parameters:
927  // end - [in] 0 = clamp start, 1 = clamp end, 2 = clamp start and end
928  // Returns:
929  // true if successful
930  bool ClampEnd(
931  int end
932  );
933 
934  // Description:
935  // Insert a knot and update cv locations.
936  // Parameters:
937  // knot_value - [in] m_knot[order-2] < knot_value < m_knot[m_cv_count-1]
938  // knot_multiplicity - [in] 1 to degree - includes multiplicity of existing knots.
939  // Remarks:
940  // Does not change parameterization or locus of curve.
941  // Returns:
942  // true if successful
943  bool InsertKnot(
944  double knot_value,
945  int knot_multiplicity
946  );
947 
948  bool MakeRational();
949 
950  bool MakeNonRational();
951 
952  bool IncreaseDegree(
953  int desired_degree
954  );
955 
956  bool ChangeDimension(
957  int desired_dimension
958  ) override;
959 
960  bool Append( const ON_NurbsCurve& );
961 
962  /////////////////////////////////////////////////////////////////
963  // Tools for managing CV and knot memory
964  bool ReserveCVCapacity(
965  int // number of doubles to reserve
966  );
967  bool ReserveKnotCapacity(
968  int // number of doubles to reserve
969  );
970 
971  //////////
972  // returns the length of the control polygon
973  double ControlPolygonLength() const;
974 
975  ////////
976  // Converts a span of the NURBS curve into a bezier. If
977  // the span is empty
978  // (m_knot[span_index+m_order-2] == m_knot[span_index+m_order-1]),
979  // then false is returned.
980  bool ConvertSpanToBezier(
981  int, // span_index (0 <= span_index <= m_cv_count-m_order)
982  ON_BezierCurve& // bezier returned here
983  ) const;
984 
985  /*
986  Paramaters:
987  span_index - [in]
988  The index of a non-empty span to test.
989  span_index >= 0
990  span_index <= m_cv_count-m_order
991  m_knot[span_index+m_order-2] < m_knot[span_index+m_order-1]
992  Returns:
993  true if the span_index parameter is valid and the span is singular
994  (collapsed to a point).
995  false if the span is not singular or span_index does not identify
996  a non-empty span.
997  */
998  bool SpanIsSingular(
999  int span_index
1000  ) const;
1001 
1002  /*
1003  Returns:
1004  True if every span in the NURBS curve is singular.
1005  See Also:
1006  ON_NurbsCurve::RepairBadKnots()
1007  ON_NurbsCurve::RemoveShortSegments()
1008  */
1009  bool IsSingular() const;
1010 
1011  /*
1012  Paramaters:
1013  span_index - [in]
1014  The index of a non-empty span to remove.
1015  span_index >= 0
1016  span_index <= m_cv_count-m_order
1017  m_knot[span_index+m_order-2] < m_knot[span_index+m_order-1]
1018  Returns:
1019  True if the span was successfully removed.
1020  Remarks:
1021  The NURBS curve must have 2 or more spans (m_cv_count > m_order).
1022  Set m0 = mulitiplicity of the knot at m_knot[span_index+m_order-2]
1023  and m1 = mulitiplicity of the knot at m_knot[span_index+m_order-1].
1024  If (m0 + m1) < degree, then the degree-(m0+m1) cvs will be added
1025  to the NURBS curve. If (m0+m1) > degree, then (m0+m1)-degree cvs will
1026  be removed from the curve.
1027  See Also:
1028  ON_NurbsCurve::RepairBadKnots()
1029  ON_NurbsCurve::RemoveShortSegments()
1030  */
1031  bool RemoveSpan(
1032  int span_index
1033  );
1034 
1035  /*
1036  Returns:
1037  Number of spans removed.
1038  */
1039  int RemoveSingularSpans();
1040 
1041  ////////
1042  // Returns true if the NURBS curve has bezier spans
1043  // (all distinct knots have multiplitity = degree)
1044  bool HasBezierSpans() const;
1045 
1046  /*
1047  Description:
1048  Clamps ends and adds knots so the NURBS curve has bezier spans
1049  (all distinct knots have multiplitity = degree).
1050  Paremeters:
1051  bSetEndWeightsToOne - [in] If true and the first or last weight is
1052  not one, then the first and last spans are reparameterized so
1053  that the end weights are one.
1054  Returns:
1055  true if successful.
1056  */
1057  bool MakePiecewiseBezier(
1058  bool bSetEndWeightsToOne = false
1059  );
1060 
1061  /*
1062  Description:
1063  Use a combination of scaling and reparameterization to change
1064  the end weights to the specified values.
1065  Parameters:
1066  w0 - [in] weight for first cv
1067  w1 - [in] weight for last cv
1068  Returns:
1069  true if successful.
1070  See Also:
1071  ON_ChangeRationalNurbsCurveEndWeights
1072  Remarks:
1073  The domain, eucleanean locations of the control points,
1074  and locus of the curve do not change, but the weights,
1075  homogeneous cv values and internal knot values may change.
1076  If w0 and w1 are 1 and the curve is not rational, the
1077  curve is not changed.
1078  */
1079  bool ChangeEndWeights( double w0, double w1 );
1080 
1081  /*
1082  Description:
1083  Use a linear fractional transformation to reparameterize
1084  the NURBS curve. This does not change the curve's domain.
1085  Parameters:
1086  c - [in]
1087  reparameterization constant (generally speaking, c should be > 0).
1088  The control points and knots are adjusted so that
1089  output_nurbs(t) = input_nurbs(lambda(t)), where
1090  lambda(t) = c*t/( (c-1)*t + 1 ).
1091  Note that lambda(0) = 0, lambda(1) = 1, lambda'(t) > 0,
1092  lambda'(0) = c and lambda'(1) = 1/c.
1093  Returns:
1094  true if successful.
1095  Remarks:
1096  The cv and knot values are values are changed so that
1097  output_nurbs(t) = input_nurbs(lambda(t)).
1098  See Also:
1099  ON_ReparameterizeRationalNurbsCurve
1100  */
1101  bool Reparameterize( double c );
1102 
1103 
1104 
1105  /////////////////////////////////////////////////////////////////
1106  // Implementation
1107 public:
1108  // NOTE: These members are left "public" so that expert users may efficiently
1109  // create NURBS curves using the default constructor and borrow the
1110  // knot and CV arrays from their native NURBS representation.
1111  // No technical support will be provided for users who access these
1112  // members directly. If you can't get your stuff to work, then use
1113  // the constructor with the arguments and the SetKnot() and SetCV()
1114  // functions to fill in the arrays.
1115 
1116  int m_dim; // (>=1)
1117 
1118  int m_is_rat; // 1 for rational B-splines.
1119  // Rational control vertices use homogeneous form
1120  // and explicit weight values are in m_cv[] array.
1121  // 0 for non-rational B-splines.
1122  // Control verticies have an implicit weight value
1123  // of 1.0. An explicit weight value is not
1124  // set in the m_cv[] array.
1125 
1126  int m_order; // order = degree+1 ( order >=2 )
1127 
1128  int m_cv_count; // number of control vertices ( >= order )
1129 
1130  // knot vector memory
1131 
1132  int m_knot_capacity; // If m_knot_capacity > 0, then m_knot[]
1133  // is an array of at least m_knot_capacity
1134  // doubles whose memory is managed by the
1135  // ON_NurbsCurve class using onmalloc(),
1136  // onrealloc(), and onfree().
1137  // If m_knot_capacity is 0 and m_knot is
1138  // not nullptr, then m_knot[] is assumed to
1139  // be big enough for any requested operation
1140  // and m_knot[] is not deleted by the
1141  // destructor.
1142 
1143  double* m_knot; // Knot vector. ( The knot vector has length
1144  // m_order+m_cv_count-2. )
1145 
1146  // control vertex net memory
1147 
1148  int m_cv_stride; // The pointer to start of "CV[i]" is
1149  // m_cv + i*m_cv_stride.
1150 
1151  int m_cv_capacity; // If m_cv_capacity > 0, then m_cv[] is an array
1152  // of at least m_cv_capacity doubles whose
1153  // memory is managed by the ON_NurbsCurve
1154  // class using onmalloc(), onrealloc(), and onfree().
1155  // If m_cv_capacity is 0 and m_cv is not
1156  // nullptr, then m_cv[] is assumed to be big enough
1157  // for any requested operation and m_cv[] is not
1158  // deleted by the destructor.
1159 
1160  double* m_cv; // Control points.
1161  // - The i-th control point begins at
1162  // CV(i) = m_cv + (i*m_cv_stride).
1163  // - If m_is_rat is false, then the i-th control
1164  // point is ( CV(i)[0], ..., CV(i)[m_dim-1] ).
1165  // - If m_is_rat is true, then the i-th control
1166  // point is stored in HOMOGENEOUS form and is
1167  // [ CV(i)[0], ..., CV(i)[m_dim] ].
1168 };
1169 
1170 #endif
virtual bool IsClosed() const
Test a curve to see if it is closed.
virtual int SpanCount() const =0
Get number of nonempty smooth (c-infinity) spans in curve
virtual bool IsContinuous(ON::continuity c, double t, int *hint=nullptr, double point_tolerance=ON_ZERO_TOLERANCE, double d1_tolerance=ON_ZERO_TOLERANCE, double d2_tolerance=ON_ZERO_TOLERANCE, double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE, double curvature_tolerance=ON_SQRT_EPSILON) const
Test continuity at a curve parameter value.
virtual bool GetNextDiscontinuity(ON::continuity c, double t0, double t1, double *t, int *hint=nullptr, int *dtype=nullptr, double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE, double curvature_tolerance=ON_SQRT_EPSILON) const
Search for a derivatitive, tangent, or curvature discontinuity.
virtual int Dimension() const
Dimension of the object.
An ON_Arc is a subcurve of 3d circle.
Definition: opennurbs_arc.h:33
virtual bool GetBBox(double *boxmin, double *boxmax, bool bGrowBox=false) const
This is the virtual function that actually calculates axis aligned bounding boxes.
virtual bool IsArc(const ON_Plane *plane=nullptr, ON_Arc *arc=nullptr, double tolerance=ON_ZERO_TOLERANCE) const
Test a curve to see if the locus if its points is an arc or circle.
virtual bool SetStartPoint(ON_3dPoint start_point)
Force the curve to start at a specified point.
virtual int HasNurbForm() const
Does a NURBS curve representation of this curve.
virtual bool GetSpanVector(double *knots) const =0
Get number of parameters of "knots".
virtual bool MakeDeformable()
If possible, converts the object into a form that can be accuratly modified with "squishy" transforma...
virtual bool Reverse()=0
Reverse the direction of the curve.
virtual bool GetParameterTolerance(double t, double *tminus, double *tplus) const
Returns maximum algebraic degree of any span or a good estimate if curve spans are not algebraic...
virtual bool Extend(const ON_Interval &domain)
Pure virtual function. Default returns false. Where possible, analytically extends curve to include d...
ON_Curve is a pure virtual class for curve objects
Definition: opennurbs_curve.h:93
virtual int GetNurbForm(ON_NurbsCurve &nurbs_curve, double tolerance=0.0, const ON_Interval *subdomain=nullptr) const
Get a NURBS curve representation of this curve.
virtual int Degree() const =0
Returns maximum algebraic degree of any span or a good estimate if curve spans are not algebraic...
virtual bool IsPlanar(ON_Plane *plane=nullptr, double tolerance=ON_ZERO_TOLERANCE) const
Test a curve to see if it is planar.
virtual bool SwapCoordinates(int i, int j)
Swaps object coordinate values with indices i and j.
virtual bool GetNurbFormParameterFromCurveParameter(double curve_t, double *nurbs_t) const
Convert a curve parameter to a NURBS curve parameter.
virtual bool ChangeDimension(int desired_dimension)
Change the dimension of a curve.
virtual bool IsInPlane(const ON_Plane &test_plane, double tolerance=ON_ZERO_TOLERANCE) const =0
Test a curve to see if it lies in a specific plane.
bool Transform(const ON_Xform &xform) override
overrides virtual ON_Geometry::Transform(). ON_Curve::Transform() calls ON_Geometry::Transform(xform)...
virtual int IsPolyline(ON_SimpleArray< ON_3dPoint > *pline_points=nullptr, ON_SimpleArray< double > *pline_t=nullptr) const
Several types of ON_Curve can have the form of a polyline including a degree 1 ON_NurbsCurve, an ON_PolylineCurve, and an ON_PolyCurve all of whose segments are some form of polyline. IsPolyline tests a curve to see if it can be represented as a polyline.
virtual bool ChangeClosedCurveSeam(double t)
If this curve is closed, then modify it so that the start/end point is at curve parameter t...
Definition: opennurbs_point.h:648
Definition: opennurbs_xform.h:28
virtual void Dump(ON_TextLog &) const
Creates a text dump of the object.
void EmergencyDestroy()
Sets m_user_data_list = 0.
virtual bool IsDeformable() const
ON_Curve & operator=(const ON_Curve &)
virtual bool IsPeriodic() const
Test a curve to see if it is periodic.
Definition: opennurbs_line.h:20
bool SetDomain(ON_Interval domain)
Set the domain of the curve.
virtual bool GetCurveParameterFromNurbFormParameter(double nurbs_t, double *curve_t) const
Convert a NURBS curve parameter to a curve parameter
virtual bool Trim(const ON_Interval &domain)
Removes portions of the curve outside the specified interval.
virtual bool SetEndPoint(ON_3dPoint end_point)
Force the curve to end at a specified point.
virtual bool Evaluate(double t, int der_count, int v_stride, double *v, int side=0, int *hint=0) const =0
This evaluator actually does all the work. The other ON_Curve evaluation tools call this virtual func...
Definition: opennurbs_bezier.h:150
Definition: opennurbs_nurbscurve.h:26
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
virtual bool Read(ON_BinaryArchive &binary_archive)
Low level archive writing tool used by ON_BinaryArchive::ReadObject().
Definition: opennurbs_point.h:460
bool IsValid(class ON_TextLog *text_log=nullptr) const override
Tests an object to see if its data members are correctly initialized.
virtual bool Write(ON_BinaryArchive &binary_archive) const
Low level archive writing tool used by ON_BinaryArchive::WriteObject().
virtual ON__UINT32 DataCRC(ON__UINT32 current_remainder) const
Returns a CRC calculated from the information that defines the object. This CRC can be used as a quic...
Definition: opennurbs_plane.h:20
unsigned int SizeOf() const override
virtual ON_Object::SizeOf override
virtual bool IsLinear(double tolerance=ON_ZERO_TOLERANCE) const
Test a curve to see if the locus if its points is a line segment.
Definition: opennurbs_point.h:46
virtual ON_Interval Domain() const =0
virtual bool Split(double t, ON_Curve *&left_side, ON_Curve *&right_side) const
Splits (divides) the curve at the specified parameter. The parameter must be in the interior of the c...