Point Cloud Library (PCL)  1.9.1-dev
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  double m_xform[4][4]; // [i][j] = row i, column j. I.e.,
32  //
33  // [0][0] [0][1] [0][2] [0][3]
34  // [1][0] [1][1] [1][2] [1][3]
35  // [2][0] [2][1] [2][2] [2][3]
36  // [3][0] [3][1] [3][2] [3][3]
37 
38  // use implicit destructor, copy constructor
39  ON_Xform(); // zero matrix
40 
41  ON_Xform( int ); // diagonal matrix (d,d,d,1)
42  ON_Xform( double ); // diagonal matrix (d,d,d,1)
43 
44 #if defined(ON_COMPILER_MSC)
45  // Microsoft's compiler won't pass double m[4][4] as a const double[4][4] arg.
46  // Gnu's compiler handles this.
47  ON_Xform( double[4][4] ); // from standard double m[4][4]
48  ON_Xform( float[4][4] ); // from standard float m[4][4]
49 #endif
50 
51  ON_Xform( const double[4][4] ); // from standard double m[4][4]
52  ON_Xform( const float[4][4] ); // from standard float m[4][4]
53 
54  ON_Xform( const double* ); // from array of 16 doubles (row0,row1,row2,row3)
55  ON_Xform( const float* ); // from array of 16 floats (row0,row1,row2,row3)
56 
57  ON_Xform( const ON_Matrix& ); // from upper left 4x4 of an
58  // arbitrary matrix. Any missing
59  // rows/columns are set to identity.
60  ON_Xform(const ON_3dPoint& P, // as a frame.
61  const ON_3dVector& X,
62  const ON_3dVector& Y,
63  const ON_3dVector& Z);
64 
65  // use implicit operator=(const ON_3dVector&), operator==
66 
67  double* operator[](int);
68  const double* operator[](int) const;
69 
70  // xform = scalar results in a diagonal 3x3 with bottom row = 0,0,0,1
71  ON_Xform& operator=( int );
72  ON_Xform& operator=( float );
73  ON_Xform& operator=( double );
74  ON_Xform& operator=( const ON_Matrix& ); // from upper left 4x4 of an
75  // arbitrary matrix. Any missing
76  // rows/columns are set to identity.
77 
78  // All non-commutative operations have "this" as left hand side and
79  // argument as right hand side.
80  ON_2dPoint operator*( const ON_2dPoint& ) const;
81  ON_3dPoint operator*( const ON_3dPoint& ) const;
82  ON_4dPoint operator*( const ON_4dPoint& ) const;
83 
84  ON_2dVector operator*( const ON_2dVector& ) const;
85  ON_3dVector operator*( const ON_3dVector& ) const;
86 
87  ON_Xform operator*( const ON_Xform& /*rhs*/ ) const;
88  ON_Xform operator+( const ON_Xform& ) const;
89  ON_Xform operator-( const ON_Xform& /*rhs*/ ) const;
90 
91  /*
92  Description:
93  Test the entries of the transformation matrix
94  to see if they are valid number.
95  Returns:
96  True if ON_IsValid() is true for every number
97  in the transformation matrix.
98  */
99  bool IsValid() const;
100 
101  /*
102  Returns:
103  true if matrix is the identity transformation
104 
105  1 0 0 0
106  0 1 0 0
107  0 0 1 0
108  0 0 0 1
109  Remarks:
110  An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
111  An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance.
112  If the matrix contains a nan, false is returned.
113  */
114  bool IsIdentity( double zero_tolerance = 0.0) const;
115 
116  /*
117  Returns:
118  true if the matrix is valid and is not the identity transformation
119  Remarks:
120  An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
121  An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance.
122  If the matrix contains a nan, false is returned.
123  */
124  bool IsNotIdentity( double zero_tolerance = 0.0) const;
125 
126  /*
127  Returns:
128  true if matrix is a pure translation
129 
130  1 0 0 dx
131  0 1 0 dy
132  0 0 1 dz
133  0 0 0 1
134  Remarks:
135  The test for zero is fabs(x) <= zero_tolerance.
136  The test for one is fabs(x-1) <= zero_tolerance.
137  */
138  bool IsTranslation( double zero_tolerance = 0.0) const;
139 
140  /*
141  Returns:
142  true if matrix is the zero transformation
143 
144  0 0 0 0
145  0 0 0 0
146  0 0 0 0
147  0 0 0 *
148  */
149  bool IsZero() const;
150 
151  /*
152  Description:
153  A similarity transformation can be broken into a sequence
154  of dialations, translations, rotations, and reflections.
155  Returns:
156  +1: This transformation is an orientation preserving similarity.
157  -1: This transformation is an orientation reversing similarity.
158  0: This transformation is not a similarity.
159  */
160  int IsSimilarity() const;
161 
162 
163  int Compare( const ON_Xform& other ) const;
164 
165 
166  // matrix operations
167  void Transpose(); // transposes 4x4 matrix
168 
169  int
170  Rank( // returns 0 to 4
171  double* = NULL // If not NULL, returns minimum pivot
172  ) const;
173 
174  double
175  Determinant( // returns determinant of 4x4 matrix
176  double* = NULL // If not NULL, returns minimum pivot
177  ) const;
178 
179  bool
180  Invert( // If matrix is non-singular, returns true,
181  // otherwise returns false and sets matrix to
182  // pseudo inverse.
183  double* = NULL // If not NULL, returns minimum pivot
184  );
185 
186  ON_Xform
187  Inverse( // If matrix is non-singular, returns inverse,
188  // otherwise returns pseudo inverse.
189  double* = NULL // If not NULL, returns minimum pivot
190  ) const;
191 
192  /*
193  Description:
194  When transforming 3d point and surface or mesh normals
195  two different transforms must be used.
196  If P_xform transforms the point, then the inverse
197  transpose of P_xform must be used to tranform normal
198  vectors.
199  Parameters:
200  N_xform - [out]
201  Returns:
202  The determinant of the transformation.
203  If non-zero, "this" is invertable and N_xform can be calculated.
204  False if "this" is not invertable, in which case
205  the returned N_xform = this with the right hand column
206  and bottom row zeroed out.
207  */
208  double GetSurfaceNormalXform( ON_Xform& N_xform ) const;
209 
210  /*
211  Description:
212  If a texture mapping is applied to an object, the object
213  is subsequently transformed by T, and the texture mapping
214  needs to be recalculated, then two transforms are required
215  to recalcalculate the texture mapping.
216  Parameters:
217  P_xform - [out]
218  Transform to apply to points before applying the
219  texture mapping transformation.
220  N_xform - [out]
221  Transform to apply to surface normals before applying
222  the texture mapping transformation.
223  Returns:
224  The determinant of the "this" transformation.
225  If non-zero, "this" is invertable and P_xform and N_xform
226  were calculated.
227  False if "this" is not invertable, in which case
228  the returned P_xform and N_xform are the identity.
229  */
230  double GetMappingXforms( ON_Xform& P_xform, ON_Xform& N_xform ) const;
231 
232  // Description:
233  // Computes matrix * transpose([x,y,z,w]).
234  //
235  // Parameters:
236  // x - [in]
237  // y - [in]
238  // z - [in]
239  // z - [in]
240  // ans - [out] = matrix * transpose([x,y,z,w])
241  void ActOnLeft(
242  double, // x
243  double, // y
244  double, // z
245  double, // w
246  double[4] // ans
247  ) const;
248 
249  // Description:
250  // Computes [x,y,z,w] * matrix.
251  //
252  // Parameters:
253  // x - [in]
254  // y - [in]
255  // z - [in]
256  // z - [in]
257  // ans - [out] = [x,y,z,w] * matrix
258  void ActOnRight(
259  double, // x
260  double, // y
261  double, // z
262  double, // w
263  double[4] // ans
264  ) const;
265 
266  ////////////////////////////////////////////////////////////////
267  // standard transformations
268 
269  // All zeros including the bottom row.
270  void Zero();
271 
272  // diagonal is (1,1,1,1)
273  void Identity();
274 
275  // diagonal 3x3 with bottom row = 0,0,0,1
276  void Diagonal(double);
277 
278  /*
279  Description:
280  Create non-uniform scale transformation with the origin as
281  a fixed point.
282  Parameters:
283  fixed_point - [in]
284  x_scale_factor - [in]
285  y_scale_factor - [in]
286  z_scale_factor - [in]
287  Remarks:
288  The diagonal is (x_scale_factor, y_scale_factor, z_scale_factor, 1)
289  */
290  void Scale(
291  double x_scale_factor,
292  double y_scale_factor,
293  double z_scale_factor
294  );
295 
296  /*
297  Description:
298  Create non-uniform scale transformation with the origin as
299  a fixed point.
300  Parameters:
301  fixed_point - [in]
302  scale_vector - [in]
303  Remarks:
304  The diagonal is (scale_vector.x, scale_vector.y, scale_vector.z, 1)
305  */
306  void Scale(
307  const ON_3dVector& scale_vector
308  );
309 
310  /*
311  Description:
312  Create uniform scale transformation with a specified
313  fixed point.
314  Parameters:
315  fixed_point - [in]
316  scale_factor - [in]
317  */
318  void Scale
319  (
320  ON_3dPoint fixed_point,
321  double scale_factor
322  );
323 
324  /*
325  Description:
326  Create non-uniform scale transformation with a specified
327  fixed point.
328  Parameters:
329  plane - [in] plane.origin is the fixed point
330  x_scale_factor - [in] plane.xaxis scale factor
331  y_scale_factor - [in] plane.yaxis scale factor
332  z_scale_factor - [in] plane.zaxis scale factor
333  */
334  void Scale
335  (
336  const ON_Plane& plane,
337  double x_scale_factor,
338  double y_scale_factor,
339  double z_scale_factor
340  );
341 
342  /*
343  Description:
344  Create shear transformation.
345  Parameters:
346  plane - [in] plane.origin is the fixed point
347  x1 - [in] plane.xaxis scale factor
348  y1 - [in] plane.yaxis scale factor
349  z1 - [in] plane.zaxis scale factor
350  */
351  void Shear
352  (
353  const ON_Plane& plane,
354  const ON_3dVector& x1,
355  const ON_3dVector& y1,
356  const ON_3dVector& z1
357  );
358 
359  // Right column is (d.x, d.y,d.z, 1).
360  void Translation(
361  const ON_3dVector& // d
362  );
363 
364  // Right column is (dx, dy, dz, 1).
365  void Translation(
366  double, // dx
367  double, // dy
368  double // dz
369  );
370 
371  // Description:
372  // Get transformation that projects to a plane
373  // Parameters:
374  // plane - [in] plane to project to
375  // Remarks:
376  // This transformaton maps a 3d point P to the
377  // point plane.ClosestPointTo(Q).
378  void PlanarProjection(
379  const ON_Plane& plane
380  );
381 
382  // Description:
383  // The Rotation() function is overloaded and provides several
384  // ways to compute a rotation transformation. A positive
385  // rotation angle indicates a counter-clockwise (right hand rule)
386  // rotation about the axis of rotation.
387  //
388  // Parameters:
389  // sin_angle - sin(rotation angle)
390  // cos_angle - cos(rotation angle)
391  // rotation_axis - 3d unit axis of rotation
392  // rotation_center - 3d center of rotation
393  //
394  // Remarks:
395  // In the overloads that take frames, the frames should
396  // be right hand orthonormal frames
397  // (unit vectors with Z = X x Y).
398  // The resulting rotation fixes
399  // the origin (0,0,0), maps initial X to
400  // final X, initial Y to final Y, and initial Z to final Z.
401  //
402  // In the overload that takes frames with center points,
403  // if the initial and final center are equal, then that
404  // center point is the fixed point of the rotation. If
405  // the initial and final point differ, then the resulting
406  // transform is the composition of a rotation fixing P0
407  // and translation from P0 to P1. The resulting
408  // transformation maps P0 to P1, P0+X0 to P1+X1, ...
409  //
410  // The rotation transformations that map frames to frames
411  // are not the same as the change of basis transformations
412  // for those frames. See ON_Xform::ChangeBasis().
413  //
414  void Rotation(
415  double sin_angle,
416  double cos_angle,
417  ON_3dVector rotation_axis,
418  ON_3dPoint rotation_center
419  );
420 
421  // Parameters:
422  // angle - rotation angle in radians
423  // rotation_axis - 3d unit axis of rotation
424  // rotation_center - 3d center of rotation
425  void Rotation(
426  double angle_radians,
427  ON_3dVector rotation_axis,
428  ON_3dPoint rotation_center
429  );
430 
431  /*
432  Description:
433  Calculate the minimal transformation that rotates
434  start_dir to end_dir while fixing rotation_center.
435  */
436  void Rotation(
437  ON_3dVector start_dir,
438  ON_3dVector end_dir,
439  ON_3dPoint rotation_center
440  );
441 
442  // Parameters:
443  // X0 - initial frame X
444  // Y0 - initial frame Y
445  // Z0 - initial frame Z
446  // X1 - final frame X
447  // Y1 - final frame Y
448  // Z1 - final frame Z
449  //
450  void Rotation(
451  const ON_3dVector& X0,
452  const ON_3dVector& Y0,
453  const ON_3dVector& Z0,
454  const ON_3dVector& X1,
455  const ON_3dVector& Y1,
456  const ON_3dVector& Z1
457  );
458 
459  // Parameters:
460  // P0 - initial frame center
461  // X0 - initial frame X
462  // Y0 - initial frame Y
463  // Z0 - initial frame Z
464  // P1 - initial frame center
465  // X1 - final frame X
466  // Y1 - final frame Y
467  // Z1 - final frame Z
468  void Rotation(
469  const ON_3dPoint& P0,
470  const ON_3dVector& X0,
471  const ON_3dVector& Y0,
472  const ON_3dVector& Z0,
473  const ON_3dPoint& P1,
474  const ON_3dVector& X1,
475  const ON_3dVector& Y1,
476  const ON_3dVector& Z1
477  );
478 
479  /*
480  Description:
481  Create rotation transformation that maps plane0 to plane1.
482  Parameters:
483  plane0 - [in]
484  plane1 - [in]
485  */
486  void Rotation(
487  const ON_Plane& plane0,
488  const ON_Plane& plane1
489  );
490 
491  /*
492  Description:
493  Create mirror transformation matrix.
494  Parameters:
495  point_on_mirror_plane - [in] point on mirror plane
496  normal_to_mirror_plane - [in] normal to mirror plane
497  Remarks:
498  The mirror transform maps a point Q to
499  Q - (2*(Q-P)oN)*N, where
500  P = point_on_mirror_plane and N = normal_to_mirror_plane.
501  */
502  void Mirror(
503  ON_3dPoint point_on_mirror_plane,
504  ON_3dVector normal_to_mirror_plane
505  );
506 
507  // Description: The ChangeBasis() function is overloaded
508  // and provides several
509  // ways to compute a change of basis transformation.
510  //
511  // Parameters:
512  // plane0 - inital plane
513  // plane1 - final plane
514  //
515  // Returns:
516  // @untitled table
517  // true success
518  // false vectors for initial frame are not a basis
519  //
520  // Remarks:
521  // If you have points defined with respect to planes, the
522  // version of ChangeBasis() that takes two planes computes
523  // the transformation to change coordinates from one plane to
524  // another. The predefined world plane ON_world_plane can
525  // be used as an argument.
526  //
527  // If P = plane0.Evaluate( a0,b0,c0 ) and
528  //
529  // (a1,b1,c1) = ChangeBasis(plane0,plane1)*ON_3dPoint(a0,b0,c0),
530  //
531  // then P = plane1.Evaluate( a1, b1, c1 )
532  //
533  // The version of ChangeBasis() that takes six vectors
534  // maps (a0,b0,c0) to (a1,b1,c1) where
535  // a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1
536  //
537  // The version of ChangeBasis() that takes six vectors
538  // with center points
539  // maps (a0,b0,c0) to (a1,b1,c1) where
540  // P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1
541  //
542  // The change of basis transformation is not the same as
543  // the rotation transformation that rotates one orthonormal
544  // frame to another. See ON_Xform::Rotation().
545  bool ChangeBasis(
546  const ON_Plane& plane0,
547  const ON_Plane& plane1
548  );
549 
550  // Description:
551  // Get a change of basis transformation.
552  // Parameters:
553  // X0 - initial basis X (X0,Y0,Z0 can be any 3d basis)
554  // Y0 - initial basis Y
555  // Z0 - initial basis Z
556  // X1 - final basis X (X1,Y1,Z1 can be any 3d basis)
557  // Y1 - final basis Y
558  // Z1 - final basis Z
559  // Remarks:
560  // Change of basis transformations and rotation transformations
561  // are often confused. This is a change of basis transformation.
562  // If Q = a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1
563  // then this transform will map the point (a0,b0,c0) to (a1,b1,c1)
564  bool ChangeBasis(
565  const ON_3dVector& X0,
566  const ON_3dVector& Y0,
567  const ON_3dVector& Z0,
568  const ON_3dVector& X1,
569  const ON_3dVector& Y1,
570  const ON_3dVector& Z1
571  );
572 
573  // Parameters:
574  // P0 - initial center
575  // X0 - initial basis X (X0,Y0,Z0 can be any 3d basis)
576  // Y0 - initial basis Y
577  // Z0 - initial basis Z
578  // P1 - final center
579  // X1 - final basis X (X1,Y1,Z1 can be any 3d basis)
580  // Y1 - final basis Y
581  // Z1 - final basis Z
582  // Remarks:
583  // Change of basis transformations and rotation transformations
584  // are often confused. This is a change of basis transformation.
585  // If Q = P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1
586  // then this transform will map the point (a0,b0,c0) to (a1,b1,c1)
587  bool ChangeBasis(
588  const ON_3dPoint& P0,
589  const ON_3dVector& X0,
590  const ON_3dVector& Y0,
591  const ON_3dVector& Z0,
592  const ON_3dPoint& P1,
593  const ON_3dVector& X1,
594  const ON_3dVector& Y1,
595  const ON_3dVector& Z1
596  );
597 
598  // standard viewing transformations
599  void WorldToCamera(
600  const ON_3dPoint&, // CameraLocation
601  const ON_3dVector&, // unit CameraX vector (right)
602  const ON_3dVector&, // unit CameraY vector (up)
603  const ON_3dVector& // unit CameraZ vector (from screen to camera)
604  );
605  void CameraToWorld(
606  const ON_3dPoint&, // CameraLocation
607  const ON_3dVector&, // unit CameraX vector (right)
608  const ON_3dVector&, // unit CameraY vector (up)
609  const ON_3dVector& // unit CameraZ vector (from screen to camera)
610  );
611  bool CameraToClip( // maps viewport frustum to -1 <= x,y,z <= 1 box
612  ON_BOOL32, // true for perspective, false for orthographic
613  double, double, // left != right (usually left < right )
614  double, double, // bottom != top (usually bottom < top )
615  double, double // near != far (usually 0 < near < far )
616  );
617 
618  // maps -1 <= x,y,z <= 1 box to viewport frustum
619  bool ClipToCamera(
620  int, // true for perspective, false for orthographic
621  double, double, // left != right (usually left < right )
622  double, double, // bottom != top (usually bottom < top )
623  double, double // near != far an bot are non-zero (usually 0 < near < far )
624  );
625 
626  // Computes transform that maps the clipping box
627  //
628  // -1<x<1,-1<y<1,-1<z<1
629  //
630  // to the screen box
631  //
632  // (left,right) X (bottom,top) X (near,far)
633  bool ClipToScreen(
634  double, // left
635  double, // right
636  double, // bottom
637  double, // top
638  double, // near_z
639  double // far_z
640  );
641 
642  // Computes transform that maps the screen box
643  //
644  // (left,right) X (bottom,top) X (near,far)
645  //
646  // to the clipping box
647  //
648  // -1<x<1,-1<y<1,-1<z<1
649  bool ScreenToClip(
650  double, // left
651  double, // right
652  double, // bottom
653  double, // top
654  double, // near_z
655  double // far_z
656  );
657 
658  // Description: Computes homogeneous point clipping flags and
659  // returns an int with bits set to indicate if the point
660  // is outside of the clipping box.
661  //
662  // Parameters:
663  // point - [in] 4d homogeneous clipping coordinate point
664  //
665  // Returns:
666  // @table
667  // bit point location
668  // 1 x/w < -1
669  // 2 x/w > +1
670  // 4 y/w < -1
671  // 8 y/w > +1
672  // 16 z/w < -1
673  // 32 z/w > +1
674  //
675  int ClipFlag4d(
676  const double* // point
677  ) const;
678 
679  // Parameters:
680  // count - [in] number of 4d points
681  // stride - [in] (>=4)
682  // points - [in] 4d clipping coordinate points
683  // (array of stride*count doubles)
684  // bTestZ - [in] (default=true) if false, do not test "z" coordinate
685  //
686  int ClipFlag4d(
687  int, // count
688  int, // stride
689  const double*, // points
690  ON_BOOL32 = true // bTeztZ
691  ) const;
692 
693  // Description:
694  // Computes 3d point clipping flags and
695  // returns an int with bits set to indicate if the point
696  // is outside of the clipping box.
697  //
698  // Parameters:
699  // point - [in] 3d clipping coordinate point
700  //
701  // Returns:
702  // @table
703  // bit point location
704  // 1 x < -1
705  // 2 x > +1
706  // 4 y < -1
707  // 8 y > +1
708  // 16 z < -1
709  // 32 z > +1
710  int ClipFlag3d(
711  const double* // point
712  ) const;
713 
714  // Parameters:
715  // count - [in] number of 3d points
716  // stride - [in] (>=3)
717  // points - [in] 3d clipping coordinate points (array of stride*count doubles)
718  // bTestZ - [in] (default=true) if false, do not test "z" coordinate
719  //
720  int ClipFlag3d(
721  int, // count
722  int, // stride
723  const double*, // points
724  ON_BOOL32 = true // bTestZ
725  ) const;
726 
727  // Description: Computes 3d clipping flags for a 3d bounding
728  // box and returns an int with bits set to indicate if
729  // the bounding box is outside of the clipping box.
730  //
731  // Parameters:
732  // boxmin - [in] 3d boxmin corner
733  // boxmax - [in] 3d boxmax corner
734  //
735  // Returns:
736  // @table
737  // bit box location
738  // 1 boxmax x < -1
739  // 2 boxmin x > +1
740  // 4 boxmax y < -1
741  // 8 boxmin y > +1
742  // 16 boxmax z < -1
743  // 32 boxmin z > +1
744  int ClipFlag3dBox(
745  const double*, // boxmin
746  const double* // boxmax
747  ) const;
748 
749 
750  /*
751  Description:
752  Calculates the transformation that linearly maps
753  old_interval to new_interval.
754  Parameters:
755  dir - [in] 0 = x, 1 = y, 2= z;
756  old_interval - [in]
757  new_interval - [in]
758  */
759  bool IntervalChange(
760  int dir,
761  ON_Interval old_interval,
762  ON_Interval new_interval
763  );
764 };
765 
766 class ON_CLASS ON_ClippingRegion
767 {
768 public:
770 
771  // The transformation m_xform transforms the view frustum,
772  // in object coordinates to the (-1,+1)^3 clipping
773  // coordinate box.
775 
776  /*
777  Parameters:
778  clip_plane_tolerance - [in]
779  3d world coordinates tolerance to use when testing
780  objects to see if the planes in m_clip_plane[] hide
781  the objects.
782  Remarks:
783  The constructor sets this value to zero. Rhino uses
784  values around 1e-5.
785  */
786  void SetClipPlaneTolerance( double clip_plane_tolerance );
787 
788  /*
789  Returns:
790  3d world coordinates tolerance to use when testing
791  objects to see if the planes in m_clip_plane[] hide
792  the objects.
793  Remarks:
794  The constructor sets this value to zero. Rhino uses
795  values around 1e-5.
796  */
797  double ClipPlaneTolerance() const;
798 
799  enum
800  {
801  max_clip_plane_count = 16, // must be <= 25
802  frustum_bitmask = 0x0000003F,
803  near_plane_bitmask = 0x00000020,
804  far_plane_bitmask = 0x00000010,
805  clip_plane_bitmask = 0x7FFFFFC0,
806  negw_bitmask = 0x80000000
807  };
808 
809  // Up to 25 additional clipping planes in object coordinates.
810  // The convex region that is the intersection of the positive
811  // side of these planes is the active region.
812  int m_clip_plane_count; // (0 <= m_clip_plane_count <= max_clip_plane_count)
813 
814 private:
815  // The "float" should be a double, but that can't happen
816  // until V6 because it will brake the SDK. Use the
817  // SetClipPlaneTolerance() and ClipPlaneTolerance()
818  // functions to set and get this value.
819  float m_clip_plane_tolerance;
820 
821 public:
822  ON_PlaneEquation m_clip_plane[max_clip_plane_count];
823 
824  /*
825  Description:
826  The "view frustum" is the frustum the m_xform transformation
827  maps to clipping coordinate box (-1,+1)^3. These functions
828  determine if some portion of the convex hull of the test points
829  is inside the view frustum.
830  Parameters:
831  P - [in] point
832  box - [in] bounding box
833  count - [in] number of points
834  p - [in] array of points
835  bEnableClippingPlanes - [in]
836  If true, then the additional clipping planes are tested.
837  If false, then the additional clipping planes are ignored.
838  Returns:
839  0 = No part of the of the convex hull of the tested points
840  is in the view frustum.
841  1 = A portion of the convex hull of the otested points may
842  be in the view frustum.
843  2 = The entire convex hull of the tested points is in the
844  view frustum.
845  */
846  int InViewFrustum(
847  ON_3dPoint P
848  ) const;
849  int InViewFrustum(
850  const ON_BoundingBox& bbox
851  ) const;
852  int InViewFrustum(
853  int count,
854  const ON_3fPoint* p
855  ) const;
856  int InViewFrustum(
857  int count,
858  const ON_3dPoint* p
859  ) const;
860  int InViewFrustum(
861  int count,
862  const ON_4dPoint* p
863  ) const;
864 
865  /*
866  Description:
867  The "clip plane region" is the convex hull of the planes in
868  the m_clip_plane[] array. These functions determine if
869  some portion of the convex hull of the test points is inside
870  the clip plane region.
871  Parameters:
872  P - [in] point
873  box - [in] bounding box
874  count - [in] number of points
875  p - [in] array of points
876  bEnableClippingPlanes - [in]
877  If true, then the additional clipping planes are tested.
878  If false, then the additional clipping planes are ignored.
879  Returns:
880  0 = No part of the of the convex hull of the tested points
881  is in the clip plane region.
882  1 = A portion of the convex hull of the tested points may
883  be in the clip plane region.
884  2 = The entire convex hull of the tested points is in the
885  clip plane region.
886  */
887  int InClipPlaneRegion(
888  ON_3dPoint P
889  ) const;
890  int InClipPlaneRegion(
891  const ON_BoundingBox& bbox
892  ) const;
893  int InClipPlaneRegion(
894  int count,
895  const ON_3fPoint* p
896  ) const;
897  int InClipPlaneRegion(
898  int count,
899  const ON_3dPoint* p
900  ) const;
901  int InClipPlaneRegion(
902  int count,
903  const ON_4dPoint* p
904  ) const;
905 
906 
907  /*
908  Description:
909  The "visible area" is the intersection of the view frustum,
910  defined by m_xform, and the clipping region, defined by the
911  m_clip_plane[] array. These functions determing if some
912  portion of the convex hull of the test points is visible.
913  Parameters:
914  P - [in] point
915  box - [in] bounding box
916  count - [in] number of points
917  p - [in] array of points
918  Returns:
919  0 = no part of the object is in the region.
920  1 = a portion of the object is in the region
921  2 = entire object is in clipping region
922  */
923  int IsVisible(
924  ON_3dPoint P
925  ) const;
926  int IsVisible(
927  const ON_BoundingBox& bbox
928  ) const;
929  int IsVisible(
930  int count,
931  const ON_3fPoint* p
932  ) const;
933  int IsVisible(
934  int count,
935  const ON_3dPoint* p
936  ) const;
937  int IsVisible(
938  int count,
939  const ON_4dPoint* p
940  ) const;
941 
942  /*
943  Description:
944  Transform a list of 4d homogenous points while testing
945  for visibility.
946  Parameters:
947  count - [in] number of points
948  p - [in/out] array of points to test and transform
949  If 0 is returned, some of the points may not
950  be transformed. In all other cases, the output
951  points are transformed by m_xform.
952  pflags - [out]
953  0 when the point is in the visible region.
954  Otherwise the bits are set to indicate which planes clip the
955  intput point.
956  0x01 left of the view frusturm
957  0x02 right of the view frustum
958  0x04 below the view frustum
959  0x08 above the view frustum
960  0x10 behind the view frustum (too far)
961  0x20 in front of the view frustum (too near)
962 
963  0x10 below m_clip_plane[0]
964  0x20 below m_clip_plane[1]
965  ...
966  0x40000000 below m_clip_plane[24]
967 
968  0x80000000 transformation created a non-positive weight
969  Returns:
970  0 = convex hull of the points is not in the region.
971  The m_cull_bits field reports which plane or planes
972  culled the point set.
973  1 = a portion of the convex hull is in the region.
974  The m_cull_bits field reports which plane or planes
975  culled the point set.
976  2 = all points are in the region.
977  The m_cull_bits field will be zero.
978  */
979  int TransformPoints( int count, ON_4dPoint* p ) const;
980  int TransformPoints( int count, ON_4dPoint* p, unsigned int* pflags ) const;
981 
982 
983  /*
984  Description:
985  Transform a pont and return the clipping information.
986  Parameters:
987  P - [in] point ot transform
988  Q - [out] transformed point
989  Returns:
990  0 when the point is in the visible region.
991  Otherwise the bits are set to indicate which planes clip the
992  intput point.
993  0x01 left of the view frusturm
994  0x02 right of the view frustum
995  0x04 below the view frustum
996  0x08 above the view frustum
997  0x10 behind the view frustum (too far)
998  0x20 in front of the view frustum (too near)
999 
1000  0x10 below m_clip_plane[0]
1001  0x20 below m_clip_plane[1]
1002  ...
1003  0x40000000 below m_clip_plane[24]
1004 
1005  0x80000000 transformation created a non-positive weight
1006  */
1007  unsigned int TransformPoint(
1008  const ON_4dPoint& P,
1009  ON_4dPoint& Q
1010  ) const;
1011  unsigned int TransformPoint(
1012  const ON_3dPoint& P,
1013  ON_3dPoint& Q
1014  ) const;
1015  unsigned int TransformPoint(
1016  const ON_3fPoint& P,
1017  ON_3dPoint& Q
1018  ) const;
1019 
1020  /*
1021  Description:
1022  Calculate the interval for the segment of a line that
1023  is in the clip plane region.
1024  Parameters:
1025  P0 - [in] start point
1026  P1 - [in] end point
1027  t0 - [out] start parameter
1028  t1 - [out] end parameter
1029  Returns:
1030  True if some portion of the line is visible and
1031  0.0 <= *t0 <= *t1 <= 1.0.
1032  */
1033  bool GetLineClipPlaneParamters(
1034  ON_4dPoint P0,
1035  ON_4dPoint P1,
1036  double* t0,
1037  double* t1
1038  ) const;
1039 
1040 };
1041 
1042 
1043 class ON_CLASS ON_Localizer
1044 {
1045 public:
1046  ON_Localizer();
1047  ~ON_Localizer();
1048 
1049  ON_Localizer(const ON_Localizer&);
1050  ON_Localizer& operator=(const ON_Localizer&);
1051 
1052  void Destroy();
1053  bool Read(ON_BinaryArchive&);
1054  bool Write(ON_BinaryArchive&) const;
1055 
1056  /*
1057  Descrption:
1058  Creates a cylindrical localizer.
1059  If d = distance from the point to the line,
1060  then the localizer has the following behavior:
1061 
1062  point distance localizer value
1063  d <= r0 < r1 or d >= r0 > r1 0
1064  d >= r1 > r0 or d <= r1 < r0 1
1065 
1066  For values of d between r0 and r1, the localizer
1067  smoothly transitions between 0 to 1.
1068 
1069  Parameters:
1070  P - [in] cylinder axis point
1071  D - [in] cylinder axis direction
1072  r0 - [in]
1073  r1 - [in]
1074  r0 and r1 are radii that control where the localizer is nonzero.
1075  Both r0 and r1 must be postive and the cannot be equal.
1076  If 0 < r0 < r1, then the localizer is zero for points
1077  inside the cylinder of radius r0 and one for points outside
1078  the cylinder of radius r1.
1079  If 0 < r1 < r0, then the localizer is one for points
1080  inside the cylinder of radius r1 and zero for points outside
1081  the cylinder of radius r0.
1082 
1083  Returns:
1084  True if the input is value and the localizer is initialized.
1085  */
1086  bool CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector D, double r0, double r1 );
1087 
1088  /*
1089  Descrption:
1090  Creates a planar localizer.
1091  If d = signed distance from the point to the plane,
1092  then the localizer has the following behavior:
1093 
1094  point distance localizer value
1095  d <= h0 < h1 or d >= h0 > h1 0
1096  d >= h1 > h0 or d <= h1 < h0 1
1097 
1098  For values of d between h0 and h1, the localizer
1099  smoothly transitions between 0 to 1.
1100 
1101  Parameters:
1102  P - [in] point on plane
1103  N - [in] normal to plane
1104  h0 - [in]
1105  h1 - [in]
1106  h0 and h1 are signed distances that control where the
1107  localizer is nonzero.
1108 
1109  Returns:
1110  True if the input is value and the localizer is initialized.
1111  */
1112  bool CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 );
1113 
1114  /*
1115  Descrption:
1116  Creates a spherical localizer.
1117  If d = distance from the point to the center of the sphere,
1118  then the localizer has the following behavior:
1119 
1120  point distance localizer value
1121  d <= r0 < r1 or d >= r0 > r1 0
1122  d >= r1 > r0 or d <= r1 < r0 1
1123 
1124  For values of d between r0 and r1, the localizer
1125  smoothly transitions between 0 to 1.
1126 
1127  Parameters:
1128  P - [in] center of sphere
1129  r0 - [in]
1130  r1 - [in]
1131  r0 and r1 are radii that control where the localizer is nonzero.
1132  Both r0 and r1 must be postive and the cannot be equal.
1133  If 0 < r0 < r1, then the localizer is zero for points
1134  inside the cylinder of radius r0 and one for points outside
1135  the cylinder of radius r1.
1136  If 0 < r1 < r0, then the localizer is one for points
1137  inside the cylinder of radius r1 and zero for points outside
1138  the cylinder of radius r0.
1139 
1140  Returns:
1141  True if the input is value and the localizer is initialized.
1142  */
1143  bool CreateSphereLocalizer( ON_3dPoint P, double r0, double r1 );
1144 
1145  /*
1146  Description:
1147  Evaluators.
1148  Parameters:
1149  P - [in]
1150  Evaluation point
1151  distance - [in]
1152  Evaluation distance
1153  Returns:
1154  Value of the localizer.
1155  */
1156  double Value(ON_3dPoint P) const;
1157  double Value(double distance) const;
1158 
1159  /*
1160  Parameters:
1161  bbox - [in]
1162  Returns:
1163  True if localizer is identically zero inside bbox.
1164  */
1165  bool IsZero( const ON_BoundingBox& bbox ) const;
1166 
1167  enum TYPE
1168  {
1169  no_type = 0,
1170  sphere_type = 1,
1171  plane_type = 2,
1172  cylinder_type = 3,
1173  curve_type = 4,
1174  surface_type = 5,
1175  distance_type = 6,
1176  force_32bit_localizer_type = 0xFFFFFFFF
1177  };
1178 
1180 
1186 };
1187 
1188 
1189 class ON_CLASS ON_SpaceMorph
1190 {
1191 public:
1192  ON_SpaceMorph();
1193  virtual ~ON_SpaceMorph();
1194 
1195  /*
1196  Description:
1197  Provides a quick way to determine if a morph function
1198  is the identity (doesn't move the points) on a region
1199  of space.
1200  Parameters:
1201  bbox - [in] region of space to test.
1202  Returns:
1203  The default always returns false. If you override
1204  this function, then return true when every point
1205  in the bounding box is fixed by the morph.
1206  */
1207  virtual
1208  bool IsIdentity( const ON_BoundingBox& bbox ) const;
1209 
1210  /*
1211  Description:
1212  Returns the desired accuracy of the morph.
1213  This value is primarily used for deforming
1214  surfaces and breps.
1215  Returns:
1216  3d fitting tolerance.
1217  Remarks:
1218  The default is 0.0 and any value <= 0.0 is
1219  ignored by morphing functions.
1220  The value returned by Tolerance() does not
1221  affect the way meshes and points are morphed.
1222  */
1223  double Tolerance() const;
1224 
1225  /*
1226  Description:
1227  Set the 3d fitting tolerance used when morphing
1228  surfaces and breps.
1229  Parameters:
1230  tolerance - [in] values < 0.0 are treated as 0.0.
1231  */
1232  void SetTolerance(
1233  double tolerance
1234  );
1235 
1236  /*
1237  Returns:
1238  True if the morph should be done as quickly as
1239  possible because the result is being used for
1240  some type of dynamic preview. If QuickPreview
1241  is true, the tolerance may be ignored.
1242  Remarks:
1243  The value returned by QuickPreview() does not
1244  affect the way meshes and points are morphed.
1245  The default is false.
1246  */
1247  bool QuickPreview() const;
1248 
1249  /*
1250  Description:
1251  Set the quick preview value.
1252  Parameters:
1253  bQuickPreview - [in]
1254  */
1255  void SetQuickPreview(
1256  bool bQuickPreview
1257  );
1258 
1259  /*
1260  Returns:
1261  True if the morph should be done in a way that
1262  preserves the structure of the geometry.
1263  In particular, for NURBS objects, true
1264  means that only the control points are moved.
1265  Remarks:
1266  The value returned by PreserveStructure() does not
1267  affect the way meshes and points are morphed.
1268  The default is false.
1269  */
1270  bool PreserveStructure() const;
1271 
1272  /*
1273  Description:
1274  Set the preserve structure value.
1275  Parameters:
1276  bPreserveStructure - [in]
1277  */
1278  void SetPreserveStructure(
1279  bool bPreserveStructure
1280  );
1281 
1282 private:
1283  double m_tolerance;
1284  bool m_bQuickPreview;
1285  bool m_bPreserveStructure;
1286 };
1287 
1288 #if defined(ON_DLL_TEMPLATE)
1289 
1290 // This stuff is here because of a limitation in the way Microsoft
1291 // handles templates and DLLs. See Microsoft's knowledge base
1292 // article ID Q168958 for details.
1293 #pragma warning( push )
1294 #pragma warning( disable : 4231 )
1295 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Xform>;
1296 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_Localizer>;
1297 #pragma warning( pop )
1298 #endif
1299 
1300 #endif
ON_3dVector m_V
ON_Interval m_d
float distance(const PointT &p1, const PointT &p2)
Definition: geometry.h:60
ON_3dPoint m_P
class ON_NurbsSurface * m_nurbs_surface
class ON_NurbsCurve * m_nurbs_curve