opennurbs_xform.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 // defines ON_Xform (4 x 4 transformation matrix)
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(ON_XFORM_INC_)
24 #define ON_XFORM_INC_
25 
26 class ON_Matrix;
27 
28 class ON_CLASS ON_Xform
29 {
30 public:
31  // ON_Xform IdentityTransformation diagonal = (1,1,1,1)
33 
34  // ON_Xform ZeroTransformation diagonal = (0,0,0,1)
36 
37  // ON_Xform::Zero4x4 - every coefficient is 0.0.
38  static const ON_Xform Zero4x4;
39 
40  // ON_Xform::Unset - every coefficient is ON_UNSET_VALUE
41  static const ON_Xform Unset;
42 
43  // ON_Xform::Nan - every coefficient is ON_DBL_QNAN
44  static const ON_Xform Nan;
45 
46  double m_xform[4][4]; // [i][j] = row i, column j. I.e.,
47  //
48  // [0][0] [0][1] [0][2] [0][3]
49  // [1][0] [1][1] [1][2] [1][3]
50  // [2][0] [2][1] [2][2] [2][3]
51  // [3][0] [3][1] [3][2] [3][3]
52 
53  // Default constructor transformation has diagonal (0,0,0,1)
54  ON_Xform();
55  ~ON_Xform() = default;
56  ON_Xform(const ON_Xform&) = default;
57  ON_Xform& operator=(const ON_Xform&) = default;
58 
59  bool operator==(const ON_Xform& rhs) const;
60 
61  bool operator!=(const ON_Xform& rhs) const;
62 
63  // Constructs transformation with diagonal (x,x,x,1)
64  explicit ON_Xform(
65  double x
66  );
67 
68  /*
69  Returns:
70  Transformation with diagonal (d,d,d,1).
71  */
72  static const ON_Xform DiagonalTransformation(
73  double d
74  );
75 
76  /*
77  Returns:
78  Transformation with diagonal (d0,d1,d2,1.0).
79  */
80  static const ON_Xform DiagonalTransformation(
81  double d0,
82  double d1,
83  double d2
84  );
85 
86  /*
87  Returns:
88  Transformation with diagonal (d0,d1,d2,1.0).
89  */
90  static const ON_Xform DiagonalTransformation(
91  const ON_3dVector& diagnoal
92  );
93 
94 #if defined(ON_COMPILER_MSC)
95  // Microsoft's compiler won't pass double m[4][4] as a const double[4][4] arg.
96  // Gnu's compiler handles this.
97  explicit ON_Xform( double[4][4] ); // from standard double m[4][4]
98  explicit ON_Xform( float[4][4] ); // from standard float m[4][4]
99 #endif
100 
101  explicit ON_Xform( const double[4][4] ); // from standard double m[4][4]
102  explicit ON_Xform( const float[4][4] ); // from standard float m[4][4]
103 
104  explicit ON_Xform( const double* ); // from array of 16 doubles (row0,row1,row2,row3)
105  explicit ON_Xform( const float* ); // from array of 16 floats (row0,row1,row2,row3)
106 
107  explicit ON_Xform( const ON_Matrix& ); // from upper left 4x4 of an
108  // arbitrary matrix. Any missing
109  // rows/columns are set to identity.
110  ON_Xform(const ON_3dPoint& P, // as a frame.
111  const ON_3dVector& X,
112  const ON_3dVector& Y,
113  const ON_3dVector& Z);
114 
115  double* operator[](int);
116  const double* operator[](int) const;
117 
118  // xform = scalar results in a diagonal 3x3 with bottom row = 0,0,0,1
119  ON_Xform& operator=( const ON_Matrix& ); // from upper left 4x4 of an
120  // arbitrary matrix. Any missing
121  // rows/columns are set to identity.
122 
123  // All non-commutative operations have "this" as left hand side and
124  // argument as right hand side.
125  ON_2dPoint operator*( const ON_2dPoint& ) const;
126  ON_3dPoint operator*( const ON_3dPoint& ) const;
127  ON_4dPoint operator*( const ON_4dPoint& ) const;
128 
129  ON_2dVector operator*( const ON_2dVector& ) const;
130  ON_3dVector operator*( const ON_3dVector& ) const;
131 
132  ON_Xform operator*( const ON_Xform& /*rhs*/ ) const;
133  ON_Xform operator+( const ON_Xform& ) const;
134  ON_Xform operator-( const ON_Xform& /*rhs*/ ) const;
135 
136  /*
137  Description:
138  Test the entries of the transformation matrix
139  to see if they are valid number.
140  Returns:
141  True if ON_IsValid() is true for every coefficient in the transformation matrix.
142  */
143  bool IsValid() const;
144 
145  /*
146  Description:
147  Test the entries of the transformation matrix
148  to see if they are valid number.
149  Returns:
150  True if any coefficient in the transformation matrix is a nan.
151  */
152  bool IsNan() const;
153 
154  bool IsValidAndNotZeroAndNotIdentity(
155  double zero_tolerance = 0.0
156  ) const;
157 
158  /*
159  Returns:
160  true if matrix is the identity transformation
161 
162  1 0 0 0
163  0 1 0 0
164  0 0 1 0
165  0 0 0 1
166  Remarks:
167  An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
168  An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance.
169  If the matrix contains a nan, false is returned.
170  */
171  bool IsIdentity( double zero_tolerance = 0.0) const;
172 
173  /*
174  Returns:
175  true if the matrix is valid and is not the identity transformation
176  Remarks:
177  An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
178  An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance.
179  If the matrix contains a nan, false is returned.
180  */
181  bool IsNotIdentity( double zero_tolerance = 0.0) const;
182 
183  /*
184  Returns:
185  true if matrix is a pure translation
186 
187  1 0 0 dx
188  0 1 0 dy
189  0 0 1 dz
190  0 0 0 1
191  Remarks:
192  The test for zero is fabs(x) <= zero_tolerance.
193  The test for one is fabs(x-1) <= zero_tolerance.
194  */
195  bool IsTranslation( double zero_tolerance = 0.0) const;
196 
197  /*
198  Returns:
199  true if matrix is ON_Xform::Zero4x4, ON_Xform::ZeroTransformation,
200  or some other type of zero. The value xform[3][3] can be anything.
201  0 0 0 0
202  0 0 0 0
203  0 0 0 0
204  0 0 0 *
205  */
206  bool IsZero() const;
207 
208  /*
209  Returns:
210  true if matrix is ON_Xform::Zero4x4
211  The value xform[3][3] must be zero.
212  0 0 0 0
213  0 0 0 0
214  0 0 0 0
215  0 0 0 0
216  */
217  bool IsZero4x4() const;
218 
219  /*
220  Returns:
221  true if matrix is ON_Xform::ZeroTransformation
222  The value xform[3][3] must be 1.
223  0 0 0 0
224  0 0 0 0
225  0 0 0 0
226  0 0 0 1
227  */
228  bool IsZeroTransformation() const;
229 
230 
231  /*
232  Description:
233  A similarity transformation can be broken into a sequence
234  of dialations, translations, rotations, and reflections.
235  Returns:
236  +1: This transformation is an orientation preserving similarity.
237  -1: This transformation is an orientation reversing similarity.
238  0: This transformation is not a similarity.
239  */
240  int IsSimilarity() const;
241 
242  /*
243  Description:
244  A transformation is affine if it is valid and its last row is
245  0 0 0 1
246  An affine transformation can be broken into a linear transformation and a translation.
247  Example:
248  A perspective transformation is not affine.
249  Returns:
250  True if this is an affine transformation.
251  */
252  bool IsAffine() const;
253 
254  /*
255  Description:
256  Well ordered dictionary compare that is nan aware.
257  */
258  int Compare( const ON_Xform& other ) const;
259 
260  // matrix operations
261  void Transpose(); // transposes 4x4 matrix
262 
263  int
264  Rank( // returns 0 to 4
265  double* = nullptr // If not nullptr, returns minimum pivot
266  ) const;
267 
268  double
269  Determinant( // returns determinant of 4x4 matrix
270  double* = nullptr // If not nullptr, returns minimum pivot
271  ) const;
272 
273  bool
274  Invert( // If matrix is non-singular, returns true,
275  // otherwise returns false and sets matrix to
276  // pseudo inverse.
277  double* = nullptr // If not nullptr, returns minimum pivot
278  );
279 
280  ON_Xform
281  Inverse( // If matrix is non-singular, returns inverse,
282  // otherwise returns pseudo inverse.
283  double* = nullptr // If not nullptr, returns minimum pivot
284  ) const;
285 
286  /*
287  Description:
288  When transforming 3d point and surface or mesh normals
289  two different transforms must be used.
290  If P_xform transforms the point, then the inverse
291  transpose of P_xform must be used to tranform normal
292  vectors.
293  Parameters:
294  N_xform - [out]
295  Returns:
296  The determinant of the transformation.
297  If non-zero, "this" is invertable and N_xform can be calculated.
298  False if "this" is not invertable, in which case
299  the returned N_xform = this with the right hand column
300  and bottom row zeroed out.
301  */
302  double GetSurfaceNormalXform( ON_Xform& N_xform ) const;
303 
304  /*
305  Description:
306  If a texture mapping is applied to an object, the object
307  is subsequently transformed by T, and the texture mapping
308  needs to be recalculated, then two transforms are required
309  to recalcalculate the texture mapping.
310  Parameters:
311  P_xform - [out]
312  Transform to apply to points before applying the
313  texture mapping transformation.
314  N_xform - [out]
315  Transform to apply to surface normals before applying
316  the texture mapping transformation.
317  Returns:
318  The determinant of the "this" transformation.
319  If non-zero, "this" is invertable and P_xform and N_xform
320  were calculated.
321  False if "this" is not invertable, in which case
322  the returned P_xform and N_xform are the identity.
323  */
324  double GetMappingXforms( ON_Xform& P_xform, ON_Xform& N_xform ) const;
325 
326  // Description:
327  // Computes matrix * transpose([x,y,z,w]).
328  //
329  // Parameters:
330  // x - [in]
331  // y - [in]
332  // z - [in]
333  // z - [in]
334  // ans - [out] = matrix * transpose([x,y,z,w])
335  void ActOnLeft(
336  double, // x
337  double, // y
338  double, // z
339  double, // w
340  double[4] // ans
341  ) const;
342 
343  // Description:
344  // Computes [x,y,z,w] * matrix.
345  //
346  // Parameters:
347  // x - [in]
348  // y - [in]
349  // z - [in]
350  // z - [in]
351  // ans - [out] = [x,y,z,w] * matrix
352  void ActOnRight(
353  double, // x
354  double, // y
355  double, // z
356  double, // w
357  double[4] // ans
358  ) const;
359 
360  ////////////////////////////////////////////////////////////////
361  // standard transformations
362 
363 
364  // diagonal is (1,1,1,1)
365  ON_DEPRECATED_MSG("Use xform = ON_Xform::IdentityTransformation;")
366  void Identity();
367 
368  ON_DEPRECATED_MSG("Use xform = ON_Xform::DiagonalTransformation(d);")
369  void Diagonal(double d);
370 
371  /*
372  Description:
373  Create non-uniform scale transformation with the origin as
374  a fixed point.
375  Parameters:
376  fixed_point - [in]
377  x_scale_factor - [in]
378  y_scale_factor - [in]
379  z_scale_factor - [in]
380  Remarks:
381  The diagonal is (x_scale_factor, y_scale_factor, z_scale_factor, 1)
382  */
383  ON_DEPRECATED_MSG("Use xform = ON_Xform::DiagonalTransformation(x_scale_factor,z_scale_factor,z_scale_factor);")
384  void Scale(
385  double x_scale_factor,
386  double y_scale_factor,
387  double z_scale_factor
388  );
389 
390  /*
391  Description:
392  Create non-uniform scale transformation with the origin as the fixed point.
393  Parameters:
394  fixed_point - [in]
395  scale_vector - [in]
396  Remarks:
397  The diagonal is (scale_vector.x, scale_vector.y, scale_vector.z, 1)
398  */
399  ON_DEPRECATED_MSG("Use xform = ON_Xform::DiagonalTransformation(scale_vector);")
400  void Scale(
401  const ON_3dVector& scale_vector
402  );
403 
404  /*
405  Description:
406  Create uniform scale transformation with a specified
407  fixed point.
408  Parameters:
409  fixed_point - [in]
410  scale_factor - [in]
411  */
412  ON_DEPRECATED_MSG("Use xform = ON_Xform::ScaleTransformation(fixed_point,scale_factor)")
413  void Scale
414  (
415  ON_3dPoint fixed_point,
416  double scale_factor
417  );
418 
419  static const ON_Xform ScaleTransformation(
420  const ON_3dPoint& fixed_point,
421  double scale_factor
422  );
423 
424  static const ON_Xform ScaleTransformation(
425  const ON_3dPoint& fixed_point,
426  double x_scale_factor,
427  double y_scale_factor,
428  double z_scale_factor
429  );
430 
431  /*
432  Description:
433  Create non-uniform scale transformation with a specified
434  fixed point.
435  Parameters:
436  plane - [in] plane.origin is the fixed point
437  x_scale_factor - [in] plane.xaxis scale factor
438  y_scale_factor - [in] plane.yaxis scale factor
439  z_scale_factor - [in] plane.zaxis scale factor
440  */
441  static const ON_Xform ScaleTransformation
442  (
443  const ON_Plane& plane,
444  double x_scale_factor,
445  double y_scale_factor,
446  double z_scale_factor
447  );
448 
449  /*
450  Description:
451  Create non-uniform scale transformation with a specified
452  fixed point.
453  Parameters:
454  plane - [in] plane.origin is the fixed point
455  x_scale_factor - [in] plane.xaxis scale factor
456  y_scale_factor - [in] plane.yaxis scale factor
457  z_scale_factor - [in] plane.zaxis scale factor
458  */
459  ON_DEPRECATED_MSG("Use xform = ON_Xform::ScaleTransformation(plane,x_scale_factor,y_scale_factor,z_scale_factor)")
460  void Scale
461  (
462  const ON_Plane& plane,
463  double x_scale_factor,
464  double y_scale_factor,
465  double z_scale_factor
466  );
467 
468  /*
469  Description:
470  Create shear transformation.
471  Parameters:
472  plane - [in] plane.origin is the fixed point
473  x1 - [in] plane.xaxis scale factor
474  y1 - [in] plane.yaxis scale factor
475  z1 - [in] plane.zaxis scale factor
476  */
477  static const ON_Xform ShearTransformation(
478  const ON_Plane& plane,
479  const ON_3dVector& x1,
480  const ON_3dVector& y1,
481  const ON_3dVector& z1
482  );
483 
484  ON_DEPRECATED_MSG("Use xform = ON_Xform::ShearTransformation(plane,x1,y1,z1);")
485  void Shear
486  (
487  const ON_Plane& plane,
488  const ON_3dVector& x1,
489  const ON_3dVector& y1,
490  const ON_3dVector& z1
491  );
492 
493  ON_DEPRECATED_MSG("Use xform = ON_Xform::TranslationTransformation(delta);")
494  void Translation(
495  const ON_3dVector& delta
496  );
497 
498  ON_DEPRECATED_MSG("Use xform = ON_Xform::TranslationTransformation(dx,dy,dz);")
499  void Translation(
500  double dx,
501  double dy,
502  double dz
503  );
504 
505  // Right column is (delta.x, delta.y, 0, 1).
506  static const ON_Xform TranslationTransformation(
507  const ON_2dVector& delta
508  );
509 
510  // Right column is (delta.x, delta.y, delta.z, 1).
511  static const ON_Xform TranslationTransformation(
512  const ON_3dVector& delta
513  );
514 
515  // Right column is (dx, dy, dz, 1).
516  static const ON_Xform TranslationTransformation(
517  double dx,
518  double dy,
519  double dz
520  );
521 
522  // Description:
523  // Get transformation that projects to a plane
524  // Parameters:
525  // plane - [in] plane to project to
526  // Remarks:
527  // This transformaton maps a 3d point P to the
528  // point plane.ClosestPointTo(Q).
529  void PlanarProjection(
530  const ON_Plane& plane
531  );
532 
533  // Description:
534  // The Rotation() function is overloaded and provides several
535  // ways to compute a rotation transformation. A positive
536  // rotation angle indicates a counter-clockwise (right hand rule)
537  // rotation about the axis of rotation.
538  //
539  // Parameters:
540  // sin_angle - sin(rotation angle)
541  // cos_angle - cos(rotation angle)
542  // rotation_axis - 3d unit axis of rotation
543  // rotation_center - 3d center of rotation
544  //
545  // Remarks:
546  // In the overloads that take frames, the frames should
547  // be right hand orthonormal frames
548  // (unit vectors with Z = X x Y).
549  // The resulting rotation fixes
550  // the origin (0,0,0), maps initial X to
551  // final X, initial Y to final Y, and initial Z to final Z.
552  //
553  // In the overload that takes frames with center points,
554  // if the initial and final center are equal, then that
555  // center point is the fixed point of the rotation. If
556  // the initial and final point differ, then the resulting
557  // transform is the composition of a rotation fixing P0
558  // and translation from P0 to P1. The resulting
559  // transformation maps P0 to P1, P0+X0 to P1+X1, ...
560  //
561  // The rotation transformations that map frames to frames
562  // are not the same as the change of basis transformations
563  // for those frames. See ON_Xform::ChangeBasis().
564  //
565  void Rotation(
566  double sin_angle,
567  double cos_angle,
568  ON_3dVector rotation_axis,
569  ON_3dPoint rotation_center
570  );
571 
572  // Parameters:
573  // angle - rotation angle in radians
574  // rotation_axis - 3d unit axis of rotation
575  // rotation_center - 3d center of rotation
576  void Rotation(
577  double angle_radians,
578  ON_3dVector rotation_axis,
579  ON_3dPoint rotation_center
580  );
581 
582  /*
583  Description:
584  Calculate the minimal transformation that rotates
585  start_dir to end_dir while fixing rotation_center.
586  */
587  void Rotation(
588  ON_3dVector start_dir,
589  ON_3dVector end_dir,
590  ON_3dPoint rotation_center
591  );
592 
593  // Parameters:
594  // X0 - initial frame X
595  // Y0 - initial frame Y
596  // Z0 - initial frame Z
597  // X1 - final frame X
598  // Y1 - final frame Y
599  // Z1 - final frame Z
600  //
601  void Rotation(
602  const ON_3dVector& X0,
603  const ON_3dVector& Y0,
604  const ON_3dVector& Z0,
605  const ON_3dVector& X1,
606  const ON_3dVector& Y1,
607  const ON_3dVector& Z1
608  );
609 
610  // Parameters:
611  // P0 - initial frame center
612  // X0 - initial frame X
613  // Y0 - initial frame Y
614  // Z0 - initial frame Z
615  // P1 - initial frame center
616  // X1 - final frame X
617  // Y1 - final frame Y
618  // Z1 - final frame Z
619  void Rotation(
620  const ON_3dPoint& P0,
621  const ON_3dVector& X0,
622  const ON_3dVector& Y0,
623  const ON_3dVector& Z0,
624  const ON_3dPoint& P1,
625  const ON_3dVector& X1,
626  const ON_3dVector& Y1,
627  const ON_3dVector& Z1
628  );
629 
630  /*
631  Description:
632  Create rotation transformation that maps plane0 to plane1.
633  Parameters:
634  plane0 - [in]
635  plane1 - [in]
636  */
637  void Rotation(
638  const ON_Plane& plane0,
639  const ON_Plane& plane1
640  );
641 
642  /*
643  Description:
644  Create mirror transformation matrix.
645  Parameters:
646  point_on_mirror_plane - [in] point on mirror plane
647  normal_to_mirror_plane - [in] normal to mirror plane
648  Remarks:
649  The mirror transform maps a point Q to
650  Q - (2*(Q-P)oN)*N, where
651  P = point_on_mirror_plane and N = normal_to_mirror_plane.
652  */
653  void Mirror(
654  ON_3dPoint point_on_mirror_plane,
655  ON_3dVector normal_to_mirror_plane
656  );
657 
658  // Description: The ChangeBasis() function is overloaded
659  // and provides several
660  // ways to compute a change of basis transformation.
661  //
662  // Parameters:
663  // plane0 - inital plane
664  // plane1 - final plane
665  //
666  // Returns:
667  // @untitled table
668  // true success
669  // false vectors for initial frame are not a basis
670  //
671  // Remarks:
672  // If you have points defined with respect to planes, the
673  // version of ChangeBasis() that takes two planes computes
674  // the transformation to change coordinates from one plane to
675  // another. The predefined world plane ON_world_plane can
676  // be used as an argument.
677  //
678  // If P = plane0.Evaluate( a0,b0,c0 ) and
679  //
680  // (a1,b1,c1) = ChangeBasis(plane0,plane1)*ON_3dPoint(a0,b0,c0),
681  //
682  // then P = plane1.Evaluate( a1, b1, c1 )
683  //
684  // The version of ChangeBasis() that takes six vectors
685  // maps (a0,b0,c0) to (a1,b1,c1) where
686  // a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1
687  //
688  // The version of ChangeBasis() that takes six vectors
689  // with center points
690  // maps (a0,b0,c0) to (a1,b1,c1) where
691  // P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1
692  //
693  // The change of basis transformation is not the same as
694  // the rotation transformation that rotates one orthonormal
695  // frame to another. See ON_Xform::Rotation().
696  bool ChangeBasis(
697  const ON_Plane& plane0,
698  const ON_Plane& plane1
699  );
700 
701  // Description:
702  // Get a change of basis transformation.
703  // Parameters:
704  // X0 - initial basis X (X0,Y0,Z0 can be any 3d basis)
705  // Y0 - initial basis Y
706  // Z0 - initial basis Z
707  // X1 - final basis X (X1,Y1,Z1 can be any 3d basis)
708  // Y1 - final basis Y
709  // Z1 - final basis Z
710  // Remarks:
711  // Change of basis transformations and rotation transformations
712  // are often confused. This is a change of basis transformation.
713  // If Q = a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1
714  // then this transform will map the point (a0,b0,c0) to (a1,b1,c1)
715  bool ChangeBasis(
716  const ON_3dVector& X0,
717  const ON_3dVector& Y0,
718  const ON_3dVector& Z0,
719  const ON_3dVector& X1,
720  const ON_3dVector& Y1,
721  const ON_3dVector& Z1
722  );
723 
724  // Parameters:
725  // P0 - initial center
726  // X0 - initial basis X (X0,Y0,Z0 can be any 3d basis)
727  // Y0 - initial basis Y
728  // Z0 - initial basis Z
729  // P1 - final center
730  // X1 - final basis X (X1,Y1,Z1 can be any 3d basis)
731  // Y1 - final basis Y
732  // Z1 - final basis Z
733  // Remarks:
734  // Change of basis transformations and rotation transformations
735  // are often confused. This is a change of basis transformation.
736  // If Q = P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1
737  // then this transform will map the point (a0,b0,c0) to (a1,b1,c1)
738  bool ChangeBasis(
739  const ON_3dPoint& P0,
740  const ON_3dVector& X0,
741  const ON_3dVector& Y0,
742  const ON_3dVector& Z0,
743  const ON_3dPoint& P1,
744  const ON_3dVector& X1,
745  const ON_3dVector& Y1,
746  const ON_3dVector& Z1
747  );
748 
749  // standard viewing transformations
750  void WorldToCamera(
751  const ON_3dPoint&, // CameraLocation
752  const ON_3dVector&, // unit CameraX vector (right)
753  const ON_3dVector&, // unit CameraY vector (up)
754  const ON_3dVector& // unit CameraZ vector (from screen to camera)
755  );
756  void CameraToWorld(
757  const ON_3dPoint&, // CameraLocation
758  const ON_3dVector&, // unit CameraX vector (right)
759  const ON_3dVector&, // unit CameraY vector (up)
760  const ON_3dVector& // unit CameraZ vector (from screen to camera)
761  );
762  bool CameraToClip( // maps viewport frustum to -1 <= x,y,z <= 1 box
763  bool bIsPerspective, // true for perspective, false for orthographic
764  double, double, // left != right (usually left < right )
765  double, double, // bottom != top (usually bottom < top )
766  double, double // near != far (usually 0 < near < far )
767  );
768 
769  // maps -1 <= x,y,z <= 1 box to viewport frustum
770  bool ClipToCamera(
771  bool bIsPerspective, // true for perspective, false for orthographic
772  double, double, // left != right (usually left < right )
773  double, double, // bottom != top (usually bottom < top )
774  double, double // near != far an bot are non-zero (usually 0 < near < far )
775  );
776 
777  // Computes transform that maps the clipping box
778  //
779  // -1<x<1,-1<y<1,-1<z<1
780  //
781  // to the screen box
782  //
783  // (left,right) X (bottom,top) X (near,far)
784  bool ClipToScreen(
785  double, // left
786  double, // right
787  double, // bottom
788  double, // top
789  double, // near_z
790  double // far_z
791  );
792 
793  // Computes transform that maps the screen box
794  //
795  // (left,right) X (bottom,top) X (near,far)
796  //
797  // to the clipping box
798  //
799  // -1<x<1,-1<y<1,-1<z<1
800  bool ScreenToClip(
801  double, // left
802  double, // right
803  double, // bottom
804  double, // top
805  double, // near_z
806  double // far_z
807  );
808 
809  // Description: Computes homogeneous point clipping flags and
810  // returns an int with bits set to indicate if the point
811  // is outside of the clipping box.
812  //
813  // Parameters:
814  // point - [in] 4d homogeneous clipping coordinate point
815  //
816  // Returns:
817  // @table
818  // bit point location
819  // 1 x/w < -1
820  // 2 x/w > +1
821  // 4 y/w < -1
822  // 8 y/w > +1
823  // 16 z/w < -1
824  // 32 z/w > +1
825  //
826  int ClipFlag4d(
827  const double* // point
828  ) const;
829 
830  // Parameters:
831  // count - [in] number of 4d points
832  // stride - [in] (>=4)
833  // points - [in] 4d clipping coordinate points
834  // (array of stride*count doubles)
835  // bTestZ - [in] (default=true) if false, do not test "z" coordinate
836  //
837  int ClipFlag4d(
838  int, // count
839  int, // stride
840  const double*, // points
841  bool bTestZ = true // bTeztZ
842  ) const;
843 
844  // Description:
845  // Computes 3d point clipping flags and
846  // returns an int with bits set to indicate if the point
847  // is outside of the clipping box.
848  //
849  // Parameters:
850  // point - [in] 3d clipping coordinate point
851  //
852  // Returns:
853  // @table
854  // bit point location
855  // 1 x < -1
856  // 2 x > +1
857  // 4 y < -1
858  // 8 y > +1
859  // 16 z < -1
860  // 32 z > +1
861  int ClipFlag3d(
862  const double* // point
863  ) const;
864 
865  // Parameters:
866  // count - [in] number of 3d points
867  // stride - [in] (>=3)
868  // points - [in] 3d clipping coordinate points (array of stride*count doubles)
869  // bTestZ - [in] (default=true) if false, do not test "z" coordinate
870  //
871  int ClipFlag3d(
872  int, // count
873  int, // stride
874  const double*, // points
875  bool bTestZ = true // bTestZ
876  ) const;
877 
878  // Description: Computes 3d clipping flags for a 3d bounding
879  // box and returns an int with bits set to indicate if
880  // the bounding box is outside of the clipping box.
881  //
882  // Parameters:
883  // boxmin - [in] 3d boxmin corner
884  // boxmax - [in] 3d boxmax corner
885  //
886  // Returns:
887  // @table
888  // bit box location
889  // 1 boxmax x < -1
890  // 2 boxmin x > +1
891  // 4 boxmax y < -1
892  // 8 boxmin y > +1
893  // 16 boxmax z < -1
894  // 32 boxmin z > +1
895  int ClipFlag3dBox(
896  const double*, // boxmin
897  const double* // boxmax
898  ) const;
899 
900 
901  /*
902  Description:
903  Calculates the transformation that linearly maps
904  old_interval to new_interval.
905  Parameters:
906  dir - [in] 0 = x, 1 = y, 2= z;
907  old_interval - [in]
908  new_interval - [in]
909  */
910  bool IntervalChange(
911  int dir,
912  ON_Interval old_interval,
913  ON_Interval new_interval
914  );
915 };
916 
917 ON_DECL
918 const ON_Xform operator*(double c, const ON_Xform& xform);
919 
920 ON_DECL
921 const ON_Xform operator*(const ON_Xform& xform, double c);
922 
923 class ON_CLASS ON_ClippingRegion
924 {
925 public:
926  ON_ClippingRegion();
927 
928  /*
929  Description:
930  Sets the object to clip transformation to
931  the viewport's workd to clip transformation.
932  */
933  bool SetObjectToClipTransformation(
934  const class ON_Viewport& viewport
935  );
936 
937  bool SetObjectToClipTransformation(
938  const ON_Xform object_to_clip_transformation
939  );
940 
941  ON_Xform ObjectToClipTransformation() const;
942  ON_Xform InverseObjectToClipTransformation() const;
943 
944 private:
945  // The transformation m_xform transforms the view frustum,
946  // in object coordinates to the (-1,+1)^3 clipping
947  // coordinate box.
948  ON_Xform m_xform;
949  mutable ON_Xform m_inverse_xform; // = m_xform.Inverse().
950 
951 public:
952  /*
953  Parameters:
954  clip_plane_tolerance - [in]
955  3d world coordinates tolerance to use when testing
956  objects to see if the planes in m_clip_plane[] hide
957  the objects.
958  Remarks:
959  The constructor sets this value to zero. Rhino uses
960  values around 1e-5.
961  */
962  void SetClipPlaneTolerance( double clip_plane_tolerance );
963 
964  /*
965  Returns:
966  3d world coordinates tolerance to use when testing
967  objects to see if the planes in m_clip_plane[] hide
968  the objects.
969  Remarks:
970  The constructor sets this value to zero. Rhino uses
971  values around 1e-5.
972  */
973  double ClipPlaneTolerance() const;
974 
975  enum
976  {
977  max_clip_plane_count = 16, // must be <= 25
978  frustum_bitmask = 0x0000003F,
979  near_plane_bitmask = 0x00000020,
980  far_plane_bitmask = 0x00000010,
981  clip_plane_bitmask = 0x7FFFFFC0,
982  negw_bitmask = 0x80000000
983  };
984 
985  // Up to 25 additional clipping planes in object coordinates.
986  // The convex region that is the intersection of the positive
987  // side of these planes is the active region.
988  int m_clip_plane_count; // (0 <= m_clip_plane_count <= max_clip_plane_count)
989 
990 private:
991  double m_clip_plane_tolerance;
992 
993 public:
994  ON_PlaneEquation m_clip_plane[max_clip_plane_count];
995 
996  /*
997  Description:
998  The "view frustum" is the frustum the m_xform transformation
999  maps to clipping coordinate box (-1,+1)^3. These functions
1000  determine if some portion of the convex hull of the test points
1001  is inside the view frustum.
1002  Parameters:
1003  P - [in] point
1004  box - [in] bounding box
1005  count - [in] number of points
1006  p - [in] array of points
1007  bEnableClippingPlanes - [in]
1008  If true, then the additional clipping planes are tested.
1009  If false, then the additional clipping planes are ignored.
1010  Returns:
1011  0 = No part of the of the convex hull of the tested points
1012  is in the view frustum.
1013  1 = A portion of the convex hull of the otested points may
1014  be in the view frustum.
1015  2 = The entire convex hull of the tested points is in the
1016  view frustum.
1017  */
1018  int InViewFrustum(
1019  ON_3dPoint P
1020  ) const;
1021  int InViewFrustum(
1022  const ON_BoundingBox& bbox
1023  ) const;
1024  int InViewFrustum(
1025  int count,
1026  const ON_3fPoint* p
1027  ) const;
1028  int InViewFrustum(
1029  int count,
1030  const ON_3dPoint* p
1031  ) const;
1032  int InViewFrustum(
1033  int count,
1034  const ON_4dPoint* p
1035  ) const;
1036 
1037  /*
1038  Description:
1039  The "clip plane region" is the convex hull of the planes in
1040  the m_clip_plane[] array. These functions determine if
1041  some portion of the convex hull of the test points is inside
1042  the clip plane region.
1043  Parameters:
1044  P - [in] point
1045  box - [in] bounding box
1046  count - [in] number of points
1047  p - [in] array of points
1048  bEnableClippingPlanes - [in]
1049  If true, then the additional clipping planes are tested.
1050  If false, then the additional clipping planes are ignored.
1051  Returns:
1052  0 = No part of the of the convex hull of the tested points
1053  is in the clip plane region.
1054  1 = A portion of the convex hull of the tested points may
1055  be in the clip plane region.
1056  2 = The entire convex hull of the tested points is in the
1057  clip plane region.
1058  */
1059  int InClipPlaneRegion(
1060  ON_3dPoint P
1061  ) const;
1062  int InClipPlaneRegion(
1063  const ON_BoundingBox& bbox
1064  ) const;
1065  int InClipPlaneRegion(
1066  int count,
1067  const ON_3fPoint* p
1068  ) const;
1069  int InClipPlaneRegion(
1070  int count,
1071  const ON_3dPoint* p
1072  ) const;
1073  int InClipPlaneRegion(
1074  int count,
1075  const ON_4dPoint* p
1076  ) const;
1077 
1078 
1079  /*
1080  Description:
1081  The "visible area" is the intersection of the view frustum,
1082  defined by m_xform, and the clipping region, defined by the
1083  m_clip_plane[] array. These functions determing if some
1084  portion of the convex hull of the test points is visible.
1085  Parameters:
1086  P - [in] point
1087  box - [in] bounding box
1088  count - [in] number of points
1089  p - [in] array of points
1090  Returns:
1091  0 = no part of the object is in the region.
1092  1 = a portion of the object is in the region
1093  2 = entire object is in clipping region
1094  */
1095  int IsVisible(
1096  ON_3dPoint P
1097  ) const;
1098  int IsVisible(
1099  const ON_BoundingBox& bbox
1100  ) const;
1101  int IsVisible(
1102  int count,
1103  const ON_3fPoint* p
1104  ) const;
1105  int IsVisible(
1106  int count,
1107  const ON_3dPoint* p
1108  ) const;
1109  int IsVisible(
1110  int count,
1111  const ON_4dPoint* p
1112  ) const;
1113 
1114  /*
1115  Description:
1116  Transform a list of 4d homogenous points while testing
1117  for visibility.
1118  Parameters:
1119  count - [in] number of points
1120  p - [in/out] array of points to test and transform
1121  If 0 is returned, some of the points may not
1122  be transformed. In all other cases, the output
1123  points are transformed by m_xform.
1124  pflags - [out]
1125  0 when the point is in the visible region.
1126  Otherwise the bits are set to indicate which planes clip the
1127  intput point.
1128  0x01 left of the view frusturm
1129  0x02 right of the view frustum
1130  0x04 below the view frustum
1131  0x08 above the view frustum
1132  0x10 behind the view frustum (too far)
1133  0x20 in front of the view frustum (too near)
1134 
1135  0x10 below m_clip_plane[0]
1136  0x20 below m_clip_plane[1]
1137  ...
1138  0x40000000 below m_clip_plane[24]
1139 
1140  0x80000000 transformation created a non-positive weight
1141  Returns:
1142  0 = convex hull of the points is not in the region.
1143  The m_cull_bits field reports which plane or planes
1144  culled the point set.
1145  1 = a portion of the convex hull is in the region.
1146  The m_cull_bits field reports which plane or planes
1147  culled the point set.
1148  2 = all points are in the region.
1149  The m_cull_bits field will be zero.
1150  */
1151  int TransformPoints( int count, ON_4dPoint* p ) const;
1152  int TransformPoints( int count, ON_4dPoint* p, unsigned int* pflags ) const;
1153 
1154 
1155  /*
1156  Description:
1157  Transform a pont and return the clipping information.
1158  Parameters:
1159  P - [in] point ot transform
1160  Q - [out] transformed point
1161  Returns:
1162  0 when the point is in the visible region.
1163  Otherwise the bits are set to indicate which planes clip the
1164  intput point.
1165  0x01 left of the view frusturm
1166  0x02 right of the view frustum
1167  0x04 below the view frustum
1168  0x08 above the view frustum
1169  0x10 behind the view frustum (too far)
1170  0x20 in front of the view frustum (too near)
1171 
1172  0x10 below m_clip_plane[0]
1173  0x20 below m_clip_plane[1]
1174  ...
1175  0x40000000 below m_clip_plane[24]
1176 
1177  0x80000000 transformation created a non-positive weight
1178  */
1179  unsigned int TransformPoint(
1180  const ON_4dPoint& P,
1181  ON_4dPoint& Q
1182  ) const;
1183  unsigned int TransformPoint(
1184  const ON_3dPoint& P,
1185  ON_3dPoint& Q
1186  ) const;
1187  unsigned int TransformPoint(
1188  const ON_3fPoint& P,
1189  ON_3dPoint& Q
1190  ) const;
1192  /*
1193  Description:
1194  Calculate the interval for the segment of a line that
1195  is in the clip plane region.
1196  Parameters:
1197  P0 - [in] start point
1198  P1 - [in] end point
1199  t0 - [out] start parameter
1200  t1 - [out] end parameter
1201  Returns:
1202  True if some portion of the line is visible and
1203  0.0 <= *t0 <= *t1 <= 1.0.
1204  */
1205  bool GetLineClipPlaneParamters(
1206  ON_4dPoint P0,
1207  ON_4dPoint P1,
1208  double* t0,
1209  double* t1
1210  ) const;
1211 
1212 };
1213 
1214 /*
1215 Description:
1216  ON_ClippingRegionPoints is a container for storing or referencing
1217  clip points and clip flags.
1218  The values are typically calcuated by ON_ClippingRegion.TransformPoint().
1219 */
1220 class ON_CLASS ON_ClippingRegionPoints
1221 {
1222 public:
1223  static const ON_ClippingRegionPoints Empty;
1224 
1225  ON_ClippingRegionPoints() = default;
1228  ON_ClippingRegionPoints& operator=(const ON_ClippingRegionPoints& src);
1229 
1230 #if defined(ON_HAS_RVALUEREF)
1231  // rvalue copy constructor
1233 
1234  // The rvalue assignment operator calls ON_Object::operator=(ON_Object&&)
1235  // which could throw exceptions. See the implementation of
1236  // ON_Object::operator=(ON_Object&&) for details.
1238 #endif
1239 
1240  unsigned int PointCapacity() const;
1241 
1242  unsigned int PointCout() const;
1243 
1244  /*
1245  Description:
1246  Sets point count and aggragate flags falues to zero but does not
1247  deallocate the memory buffer. When an ON_ClippingRegionPoints will be used
1248  multiple times, it is more efficient to call Clear() between
1249  uses than calling Destroy().
1250  */
1251  void Clear();
1252 
1253  /*
1254  Description:
1255  Clear() and deallocate the memory buffer.
1256  */
1257  void Destroy();
1258 
1259  /*
1260  Returns:
1261  Clip point location.
1262  */
1263  ON_3dPoint ClipPoint(
1264  unsigned int point_index
1265  ) const;
1266 
1267  /*
1268  Returns:
1269  Clip flag
1270  */
1271  unsigned int ClipFlag(
1272  unsigned int point_index
1273  ) const;
1274 
1275  /*
1276  Description:
1277  Append the clipping point and clipping flag calculated by
1278  clipping_region.TransformPoint(world_point,...).
1279  */
1280  bool AppendClipPoint(
1281  const class ON_ClippingRegion& clipping_region,
1282  ON_3dPoint world_point
1283  );
1284 
1285  /*
1286  Description:
1287  Append the clipping points and clipping flags calculated by
1288  clipping_region.TransformPoint(world_point,...) for every input
1289  world point.
1290  */
1291  bool AppendClipPoints(
1292  const class ON_ClippingRegion& clipping_region,
1293  const ON_SimpleArray<ON_3dPoint>& world_points
1294  );
1295 
1296  /*
1297  Description:
1298  Append the clipping points and clipping flags calculated by
1299  clipping_region.TransformPoint(world_point,...) for every input
1300  world point.
1301  */
1302  bool AppendClipPoints(
1303  const class ON_ClippingRegion& clipping_region,
1304  size_t world_point_count,
1305  const ON_3dPoint* world_points
1306  );
1308  /*
1309  Description:
1310  Append the clipping points and clipping flags calculated by
1311  clipping_region.TransformPoint(world_point,...) for every input
1312  world point.
1313  */
1314  bool AppendClipPoints(
1315  const class ON_ClippingRegion& clipping_region,
1316  size_t world_point_count,
1317  size_t world_point_stride,
1318  const double* world_points
1319  );
1321  /*
1322  Description:
1323  Append the clipping point and clipping flag value.
1324  */
1325  bool AppendClipPoint(
1326  ON_3dPoint clip_point,
1327  unsigned int clip_flag
1328  );
1329 
1330 public:
1331  // These functions and data members are public so they can be used
1332  // by experts to reference information that is managed by other entities.
1333  // If you access or modify them, you are responsible for making
1334  // sure you do it correctly. All the interface functions above
1335  // assume the values below are correctly set.
1336 
1337  /*
1338  Reserve buffer capacity.
1339  */
1340  bool ReserveBufferPointCapacity(
1341  size_t buffer_point_capacity
1342  );
1343 
1344  // All the information below is automatically managed if you use
1345  // the AppendClipPoint() or AppendClipPoints() functions to add
1346  // clipping points.
1347  unsigned int m_point_count = 0;
1348  unsigned int m_point_capacity = 0;
1349  ON_3dPoint* m_clip_points = nullptr;
1350  unsigned int* m_clip_flags = nullptr;
1352  unsigned int m_and_clip_flags = 0;
1353  unsigned int m_or_clip_flags = 0;
1354 
1355 private:
1356  size_t m_buffer_point_capacity = 0;
1357  void* m_buffer = nullptr;
1358 };
1359 
1360 class ON_CLASS ON_PickPoint
1361 {
1362 public:
1363  static const ON_PickPoint Unset;
1364 
1365  ON_PickPoint() = default;
1366  ~ON_PickPoint() = default;
1367  ON_PickPoint(const ON_PickPoint&)= default;
1368  ON_PickPoint& operator=(const ON_PickPoint&) = default;
1369 
1370  /*
1371  Returns:
1372  +1: a is a better pick pont than b.
1373  -1: b is a better pick point than a.
1374  0: a and b are the same.
1375  */
1376  static int Compare(
1377  const ON_PickPoint& a,
1378  const ON_PickPoint& b
1379  );
1380 
1381  /*
1382  Returns:
1383  True if this is set.
1384  */
1385  bool IsSet() const;
1386 
1387  /*
1388  Returns:
1389  True if this is not set.
1390  */
1391  bool IsNotSet() const;
1392 
1394  double m_t[4]; // parameters (unused values are set to ON_UNSET_VALUE)
1395  double m_depth = ON_UNSET_VALUE; // larger values are in front of smaller values.
1396  double m_distance = 1.0e300; // smaller values are closer to pick ray.
1397 };
1398 
1399 class ON_CLASS ON_Localizer
1400 {
1401 public:
1402  ON_Localizer();
1403  ~ON_Localizer();
1404 
1405  ON_Localizer(const ON_Localizer&);
1406  ON_Localizer& operator=(const ON_Localizer&);
1407 
1408  void Destroy();
1409  bool Read(ON_BinaryArchive&);
1410  bool Write(ON_BinaryArchive&) const;
1411 
1412  /*
1413  Descrption:
1414  Creates a cylindrical localizer.
1415  If d = distance from the point to the line,
1416  then the localizer has the following behavior:
1417 
1418  point distance localizer value
1419  d <= r0 < r1 or d >= r0 > r1 0
1420  d >= r1 > r0 or d <= r1 < r0 1
1421 
1422  For values of d between r0 and r1, the localizer
1423  smoothly transitions between 0 to 1.
1424 
1425  Parameters:
1426  P - [in] cylinder axis point
1427  D - [in] cylinder axis direction
1428  r0 - [in]
1429  r1 - [in]
1430  r0 and r1 are radii that control where the localizer is nonzero.
1431  Both r0 and r1 must be postive and the cannot be equal.
1432  If 0 < r0 < r1, then the localizer is zero for points
1433  inside the cylinder of radius r0 and one for points outside
1434  the cylinder of radius r1.
1435  If 0 < r1 < r0, then the localizer is one for points
1436  inside the cylinder of radius r1 and zero for points outside
1437  the cylinder of radius r0.
1438 
1439  Returns:
1440  True if the input is value and the localizer is initialized.
1441  */
1442  bool CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector D, double r0, double r1 );
1443 
1444  /*
1445  Descrption:
1446  Creates a planar localizer.
1447  If d = signed distance from the point to the plane,
1448  then the localizer has the following behavior:
1449 
1450  point distance localizer value
1451  d <= h0 < h1 or d >= h0 > h1 0
1452  d >= h1 > h0 or d <= h1 < h0 1
1453 
1454  For values of d between h0 and h1, the localizer
1455  smoothly transitions between 0 to 1.
1456 
1457  Parameters:
1458  P - [in] point on plane
1459  N - [in] normal to plane
1460  h0 - [in]
1461  h1 - [in]
1462  h0 and h1 are signed distances that control where the
1463  localizer is nonzero.
1464 
1465  Returns:
1466  True if the input is value and the localizer is initialized.
1467  */
1468  bool CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 );
1469 
1470  /*
1471  Descrption:
1472  Creates a spherical localizer.
1473  If d = distance from the point to the center of the sphere,
1474  then the localizer has the following behavior:
1475 
1476  point distance localizer value
1477  d <= r0 < r1 or d >= r0 > r1 0
1478  d >= r1 > r0 or d <= r1 < r0 1
1479 
1480  For values of d between r0 and r1, the localizer
1481  smoothly transitions between 0 to 1.
1483  Parameters:
1484  P - [in] center of sphere
1485  r0 - [in]
1486  r1 - [in]
1487  r0 and r1 are radii that control where the localizer is nonzero.
1488  Both r0 and r1 must be postive and the cannot be equal.
1489  If 0 < r0 < r1, then the localizer is zero for points
1490  inside the cylinder of radius r0 and one for points outside
1491  the cylinder of radius r1.
1492  If 0 < r1 < r0, then the localizer is one for points
1493  inside the cylinder of radius r1 and zero for points outside
1494  the cylinder of radius r0.
1496  Returns:
1497  True if the input is value and the localizer is initialized.
1498  */
1499  bool CreateSphereLocalizer( ON_3dPoint P, double r0, double r1 );
1500 
1501  /*
1502  Description:
1503  Evaluators.
1504  Parameters:
1505  P - [in]
1506  Evaluation point
1507  distance - [in]
1508  Evaluation distance
1509  Returns:
1510  Value of the localizer.
1511  */
1512  double Value(ON_3dPoint P) const;
1513  double Value(double distance) const;
1514 
1515  /*
1516  Parameters:
1517  bbox - [in]
1518  Returns:
1519  True if localizer is identically zero inside bbox.
1520  */
1521  bool IsZero( const ON_BoundingBox& bbox ) const;
1522 
1523  enum TYPE
1524  {
1525  no_type = 0,
1526  sphere_type = 1,
1527  plane_type = 2,
1528  cylinder_type = 3,
1529  curve_type = 4,
1530  surface_type = 5,
1531  distance_type = 6,
1532  force_32bit_localizer_type = 0xFFFFFFFF
1533  };
1534 
1535  TYPE m_type;
1536 
1537  ON_Interval m_d;
1538  ON_3dPoint m_P;
1539  ON_3dVector m_V;
1540  class ON_NurbsCurve* m_nurbs_curve;
1541  class ON_NurbsSurface* m_nurbs_surface;
1542 };
1543 
1544 
1545 class ON_CLASS ON_SpaceMorph
1546 {
1547 public:
1548  ON_SpaceMorph();
1549  virtual ~ON_SpaceMorph();
1550 
1551 
1552  /*
1553  Description:
1554  Provides a quick way to determine if a morph function
1555  is the identity (doesn't move the points) on a region
1556  of space.
1557  Parameters:
1558  bbox - [in] region of space to test.
1559  Returns:
1560  The default always returns false. If you override
1561  this function, then return true when every point
1562  in the bounding box is fixed by the morph.
1563  */
1564  virtual
1565  bool IsIdentity( const ON_BoundingBox& bbox ) const;
1566 
1567  /*
1568  Description:
1569  A slower way to determine if a morph function
1570  is the identity (doesn't move the points) on a set of points, to within a tolerance
1571  Parameters:
1572  Points - [in] Set of points to test.
1573  tol - [in] Distance tolerance.
1574  Returns:
1575  True if none of the points move a distance of tol or more under the morph function.
1576  Uses MorphPoint()
1577  */
1578  bool IsIdentity(const ON_SimpleArray<ON_3dPoint>& Points, double tol) const;
1579 
1580 
1581  /*
1582  Description:
1583  A slower way to determine if a morph function
1584  is the identity (doesn't move the points) on a surface, to within a tolerance
1585  Parameters:
1586  Srf - [in] Surface to be tested.
1587  tol - [in] Distance tolerance.
1588  Returns:
1589  Uses MorphPoint() on a dense sample of points.
1590  True if none of the points move a distance of tol or more under the morph function.
1591  Remark:
1592  Call IsIdentity(Srf.BoundingBox()) first.
1593  Use this on surfaces whose nurb form is rational or has a different parameterization.
1594  */
1595  bool IsIdentity(const class ON_Surface& Srf, double tol) const;
1596 
1597  /*
1598  Description:
1599  A slower way to determine if a morph function
1600  is the identity (doesn't move the points) on a curve, to within a tolerance.
1601  Parameters:
1602  Crv - [in] Curve to be tested.
1603  tol - [in] Distance tolerance.
1604  Returns:
1605  Uses MorphPoint() on a dense sample of points.
1606  True if none of the points move a distance of tol or more under the morph function.
1607  Remark:
1608  Call IsIdentity(Crv.BoundingBox()) first.
1609  Use this on curves whose nurb form is rational or has a different parameterization.
1610  */
1611  bool IsIdentity(const class ON_Curve& Crv, double tol) const;
1612 
1613 
1614  /*
1615  Description:
1616  Returns the desired accuracy of the morph.
1617  This value is primarily used for deforming
1618  surfaces and breps.
1619  Returns:
1620  3d fitting tolerance.
1621  Remarks:
1622  The default is 0.0 and any value <= 0.0 is
1623  ignored by morphing functions.
1624  The value returned by Tolerance() does not
1625  affect the way meshes and points are morphed.
1626  */
1627  double Tolerance() const;
1628 
1629  /*
1630  Description:
1631  Set the 3d fitting tolerance used when morphing
1632  surfaces and breps.
1633  Parameters:
1634  tolerance - [in] values < 0.0 are treated as 0.0.
1635  */
1636  void SetTolerance(
1637  double tolerance
1638  );
1639 
1640  /*
1641  Returns:
1642  True if the morph should be done as quickly as
1643  possible because the result is being used for
1644  some type of dynamic preview. If QuickPreview
1645  is true, the tolerance may be ignored.
1646  Remarks:
1647  The value returned by QuickPreview() does not
1648  affect the way meshes and points are morphed.
1649  The default is false.
1650  */
1651  bool QuickPreview() const;
1652 
1653  /*
1654  Description:
1655  Set the quick preview value.
1656  Parameters:
1657  bQuickPreview - [in]
1658  */
1659  void SetQuickPreview(
1660  bool bQuickPreview
1661  );
1662 
1663  /*
1664  Returns:
1665  True if the morph should be done in a way that
1666  preserves the structure of the geometry.
1667  In particular, for NURBS objects, true
1668  means that only the control points are moved.
1669  Remarks:
1670  The value returned by PreserveStructure() does not
1671  affect the way meshes and points are morphed.
1672  The default is false.
1673  */
1674  bool PreserveStructure() const;
1675 
1676  /*
1677  Description:
1678  Set the preserve structure value.
1679  Parameters:
1680  bPreserveStructure - [in]
1681  */
1682  void SetPreserveStructure(
1683  bool bPreserveStructure
1684  );
1685 
1686 private:
1687  double m_tolerance = 0.0;
1688  ON__UINT_PTR m_reserved1 = 0; // Some reserved field could provide more Morph type information. RH-4091
1689  unsigned int m_reserved2 = 0;
1690  bool m_bQuickPreview = false;
1691  bool m_bPreserveStructure = false;
1692  char m_reserved3 = 0;
1693  char m_reserved4 = 0;
1694 };
1695 
1696 #if defined(ON_DLL_TEMPLATE)
1697 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Xform>;
1698 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_Localizer>;
1699 #endif
1700 
1701 #endif
Definition: opennurbs_nurbssurface.h:62
ON_Curve is a pure virtual class for curve objects
Definition: opennurbs_curve.h:93
static const ON_Xform ZeroTransformation
ON_Xform ZeroTransformation diagonal = (0,0,0,1)
Definition: opennurbs_xform.h:35
Definition: opennurbs_fpoint.h:211
static const ON_Xform Nan
ON_Xform::Nan - every coefficient is ON_DBL_QNAN.
Definition: opennurbs_xform.h:44
Definition: opennurbs_xform.h:1320
Definition: opennurbs_point.h:277
Definition: opennurbs_xform.h:904
ON_ClippingRegionPoints is a container for storing or referencing clip points and clip flags...
Definition: opennurbs_xform.h:1191
Definition: opennurbs_point.h:648
static const ON_Xform IdentityTransformation
ON_Xform IdentityTransformation diagonal = (1,1,1,1)
Definition: opennurbs_xform.h:32
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_xform.h:1502
Definition: opennurbs_xform.h:28
Definition: opennurbs_matrix.h:22
static const ON_3dPoint UnsetPoint
Definition: opennurbs_point.h:474
Definition: opennurbs_nurbscurve.h:26
Definition: opennurbs_archive.h:1783
Definition: opennurbs_viewport.h:31
Definition: opennurbs_point.h:460
static const ON_Xform Unset
ON_Xform::Unset - every coefficient is ON_UNSET_VALUE.
Definition: opennurbs_xform.h:41
Definition: opennurbs_plane.h:20
Definition: opennurbs_surface.h:57
Typically the vector portion is a unit vector and m_d = -(x*P.x + y*P.y + z*P.z) for a point P on the...
Definition: opennurbs_point.h:1433
Definition: opennurbs_point.h:839
static const ON_Xform Zero4x4
ON_Xform::Zero4x4 - every coefficient is 0.0.
Definition: opennurbs_xform.h:38
Definition: opennurbs_point.h:1152
Definition: opennurbs_point.h:46