00001 /* $NoKeywords: $ */ 00002 /* 00003 // 00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. 00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert 00006 // McNeel & Associates. 00007 // 00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED. 00011 // 00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>. 00013 // 00015 */ 00016 00018 // 00019 // defines ON_Xform (4 x 4 transformation matrix) 00020 // 00022 00023 #if !defined(ON_XFORM_INC_) 00024 #define ON_XFORM_INC_ 00025 00026 class ON_Matrix; 00027 00028 class ON_CLASS ON_Xform 00029 { 00030 public: 00031 double m_xform[4][4]; // [i][j] = row i, column j. I.e., 00032 // 00033 // [0][0] [0][1] [0][2] [0][3] 00034 // [1][0] [1][1] [1][2] [1][3] 00035 // [2][0] [2][1] [2][2] [2][3] 00036 // [3][0] [3][1] [3][2] [3][3] 00037 00038 // use implicit destructor, copy constructor 00039 ON_Xform(); // zero matrix 00040 00041 ON_Xform( int ); // diagonal matrix (d,d,d,1) 00042 ON_Xform( double ); // diagonal matrix (d,d,d,1) 00043 00044 #if defined(ON_COMPILER_MSC) 00045 // Microsoft's compiler won't pass double m[4][4] as a const double[4][4] arg. 00046 // Gnu's compiler handles this. 00047 ON_Xform( double[4][4] ); // from standard double m[4][4] 00048 ON_Xform( float[4][4] ); // from standard float m[4][4] 00049 #endif 00050 00051 ON_Xform( const double[4][4] ); // from standard double m[4][4] 00052 ON_Xform( const float[4][4] ); // from standard float m[4][4] 00053 00054 ON_Xform( const double* ); // from array of 16 doubles (row0,row1,row2,row3) 00055 ON_Xform( const float* ); // from array of 16 floats (row0,row1,row2,row3) 00056 00057 ON_Xform( const ON_Matrix& ); // from upper left 4x4 of an 00058 // arbitrary matrix. Any missing 00059 // rows/columns are set to identity. 00060 ON_Xform(const ON_3dPoint& P, // as a frame. 00061 const ON_3dVector& X, 00062 const ON_3dVector& Y, 00063 const ON_3dVector& Z); 00064 00065 // use implicit operator=(const ON_3dVector&), operator== 00066 00067 double* operator[](int); 00068 const double* operator[](int) const; 00069 00070 // xform = scalar results in a diagonal 3x3 with bottom row = 0,0,0,1 00071 ON_Xform& operator=( int ); 00072 ON_Xform& operator=( float ); 00073 ON_Xform& operator=( double ); 00074 ON_Xform& operator=( const ON_Matrix& ); // from upper left 4x4 of an 00075 // arbitrary matrix. Any missing 00076 // rows/columns are set to identity. 00077 00078 // All non-commutative operations have "this" as left hand side and 00079 // argument as right hand side. 00080 ON_2dPoint operator*( const ON_2dPoint& ) const; 00081 ON_3dPoint operator*( const ON_3dPoint& ) const; 00082 ON_4dPoint operator*( const ON_4dPoint& ) const; 00083 00084 ON_2dVector operator*( const ON_2dVector& ) const; 00085 ON_3dVector operator*( const ON_3dVector& ) const; 00086 00087 ON_Xform operator*( const ON_Xform& /*rhs*/ ) const; 00088 ON_Xform operator+( const ON_Xform& ) const; 00089 ON_Xform operator-( const ON_Xform& /*rhs*/ ) const; 00090 00091 /* 00092 Description: 00093 Test the entries of the transformation matrix 00094 to see if they are valid number. 00095 Returns: 00096 True if ON_IsValid() is true for every number 00097 in the transformation matrix. 00098 */ 00099 bool IsValid() const; 00100 00101 /* 00102 Returns: 00103 true if matrix is the identity transformation 00104 00105 1 0 0 0 00106 0 1 0 0 00107 0 0 1 0 00108 0 0 0 1 00109 Remarks: 00110 An element of the matrix is "zero" if fabs(x) <= zero_tolerance. 00111 An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance. 00112 If the matrix contains a nan, false is returned. 00113 */ 00114 bool IsIdentity( double zero_tolerance = 0.0) const; 00115 00116 /* 00117 Returns: 00118 true if the matrix is valid and is not the identity transformation 00119 Remarks: 00120 An element of the matrix is "zero" if fabs(x) <= zero_tolerance. 00121 An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance. 00122 If the matrix contains a nan, false is returned. 00123 */ 00124 bool IsNotIdentity( double zero_tolerance = 0.0) const; 00125 00126 /* 00127 Returns: 00128 true if matrix is a pure translation 00129 00130 1 0 0 dx 00131 0 1 0 dy 00132 0 0 1 dz 00133 0 0 0 1 00134 Remarks: 00135 The test for zero is fabs(x) <= zero_tolerance. 00136 The test for one is fabs(x-1) <= zero_tolerance. 00137 */ 00138 bool IsTranslation( double zero_tolerance = 0.0) const; 00139 00140 /* 00141 Returns: 00142 true if matrix is the zero transformation 00143 00144 0 0 0 0 00145 0 0 0 0 00146 0 0 0 0 00147 0 0 0 * 00148 */ 00149 bool IsZero() const; 00150 00151 /* 00152 Description: 00153 A similarity transformation can be broken into a sequence 00154 of dialations, translations, rotations, and reflections. 00155 Returns: 00156 +1: This transformation is an orientation preserving similarity. 00157 -1: This transformation is an orientation reversing similarity. 00158 0: This transformation is not a similarity. 00159 */ 00160 int IsSimilarity() const; 00161 00162 00163 int Compare( const ON_Xform& other ) const; 00164 00165 00166 // matrix operations 00167 void Transpose(); // transposes 4x4 matrix 00168 00169 int 00170 Rank( // returns 0 to 4 00171 double* = NULL // If not NULL, returns minimum pivot 00172 ) const; 00173 00174 double 00175 Determinant( // returns determinant of 4x4 matrix 00176 double* = NULL // If not NULL, returns minimum pivot 00177 ) const; 00178 00179 bool 00180 Invert( // If matrix is non-singular, returns true, 00181 // otherwise returns false and sets matrix to 00182 // pseudo inverse. 00183 double* = NULL // If not NULL, returns minimum pivot 00184 ); 00185 00186 ON_Xform 00187 Inverse( // If matrix is non-singular, returns inverse, 00188 // otherwise returns pseudo inverse. 00189 double* = NULL // If not NULL, returns minimum pivot 00190 ) const; 00191 00192 /* 00193 Description: 00194 When transforming 3d point and surface or mesh normals 00195 two different transforms must be used. 00196 If P_xform transforms the point, then the inverse 00197 transpose of P_xform must be used to tranform normal 00198 vectors. 00199 Parameters: 00200 N_xform - [out] 00201 Returns: 00202 The determinant of the transformation. 00203 If non-zero, "this" is invertable and N_xform can be calculated. 00204 False if "this" is not invertable, in which case 00205 the returned N_xform = this with the right hand column 00206 and bottom row zeroed out. 00207 */ 00208 double GetSurfaceNormalXform( ON_Xform& N_xform ) const; 00209 00210 /* 00211 Description: 00212 If a texture mapping is applied to an object, the object 00213 is subsequently transformed by T, and the texture mapping 00214 needs to be recalculated, then two transforms are required 00215 to recalcalculate the texture mapping. 00216 Parameters: 00217 P_xform - [out] 00218 Transform to apply to points before applying the 00219 texture mapping transformation. 00220 N_xform - [out] 00221 Transform to apply to surface normals before applying 00222 the texture mapping transformation. 00223 Returns: 00224 The determinant of the "this" transformation. 00225 If non-zero, "this" is invertable and P_xform and N_xform 00226 were calculated. 00227 False if "this" is not invertable, in which case 00228 the returned P_xform and N_xform are the identity. 00229 */ 00230 double GetMappingXforms( ON_Xform& P_xform, ON_Xform& N_xform ) const; 00231 00232 // Description: 00233 // Computes matrix * transpose([x,y,z,w]). 00234 // 00235 // Parameters: 00236 // x - [in] 00237 // y - [in] 00238 // z - [in] 00239 // z - [in] 00240 // ans - [out] = matrix * transpose([x,y,z,w]) 00241 void ActOnLeft( 00242 double, // x 00243 double, // y 00244 double, // z 00245 double, // w 00246 double[4] // ans 00247 ) const; 00248 00249 // Description: 00250 // Computes [x,y,z,w] * matrix. 00251 // 00252 // Parameters: 00253 // x - [in] 00254 // y - [in] 00255 // z - [in] 00256 // z - [in] 00257 // ans - [out] = [x,y,z,w] * matrix 00258 void ActOnRight( 00259 double, // x 00260 double, // y 00261 double, // z 00262 double, // w 00263 double[4] // ans 00264 ) const; 00265 00267 // standard transformations 00268 00269 // All zeros including the bottom row. 00270 void Zero(); 00271 00272 // diagonal is (1,1,1,1) 00273 void Identity(); 00274 00275 // diagonal 3x3 with bottom row = 0,0,0,1 00276 void Diagonal(double); 00277 00278 /* 00279 Description: 00280 Create non-uniform scale transformation with the origin as 00281 a fixed point. 00282 Parameters: 00283 fixed_point - [in] 00284 x_scale_factor - [in] 00285 y_scale_factor - [in] 00286 z_scale_factor - [in] 00287 Remarks: 00288 The diagonal is (x_scale_factor, y_scale_factor, z_scale_factor, 1) 00289 */ 00290 void Scale( 00291 double x_scale_factor, 00292 double y_scale_factor, 00293 double z_scale_factor 00294 ); 00295 00296 /* 00297 Description: 00298 Create non-uniform scale transformation with the origin as 00299 a fixed point. 00300 Parameters: 00301 fixed_point - [in] 00302 scale_vector - [in] 00303 Remarks: 00304 The diagonal is (scale_vector.x, scale_vector.y, scale_vector.z, 1) 00305 */ 00306 void Scale( 00307 const ON_3dVector& scale_vector 00308 ); 00309 00310 /* 00311 Description: 00312 Create uniform scale transformation with a specified 00313 fixed point. 00314 Parameters: 00315 fixed_point - [in] 00316 scale_factor - [in] 00317 */ 00318 void Scale 00319 ( 00320 ON_3dPoint fixed_point, 00321 double scale_factor 00322 ); 00323 00324 /* 00325 Description: 00326 Create non-uniform scale transformation with a specified 00327 fixed point. 00328 Parameters: 00329 plane - [in] plane.origin is the fixed point 00330 x_scale_factor - [in] plane.xaxis scale factor 00331 y_scale_factor - [in] plane.yaxis scale factor 00332 z_scale_factor - [in] plane.zaxis scale factor 00333 */ 00334 void Scale 00335 ( 00336 const ON_Plane& plane, 00337 double x_scale_factor, 00338 double y_scale_factor, 00339 double z_scale_factor 00340 ); 00341 00342 /* 00343 Description: 00344 Create shear transformation. 00345 Parameters: 00346 plane - [in] plane.origin is the fixed point 00347 x1 - [in] plane.xaxis scale factor 00348 y1 - [in] plane.yaxis scale factor 00349 z1 - [in] plane.zaxis scale factor 00350 */ 00351 void Shear 00352 ( 00353 const ON_Plane& plane, 00354 const ON_3dVector& x1, 00355 const ON_3dVector& y1, 00356 const ON_3dVector& z1 00357 ); 00358 00359 // Right column is (d.x, d.y,d.z, 1). 00360 void Translation( 00361 const ON_3dVector& // d 00362 ); 00363 00364 // Right column is (dx, dy, dz, 1). 00365 void Translation( 00366 double, // dx 00367 double, // dy 00368 double // dz 00369 ); 00370 00371 // Description: 00372 // Get transformation that projects to a plane 00373 // Parameters: 00374 // plane - [in] plane to project to 00375 // Remarks: 00376 // This transformaton maps a 3d point P to the 00377 // point plane.ClosestPointTo(Q). 00378 void PlanarProjection( 00379 const ON_Plane& plane 00380 ); 00381 00382 // Description: 00383 // The Rotation() function is overloaded and provides several 00384 // ways to compute a rotation transformation. A positive 00385 // rotation angle indicates a counter-clockwise (right hand rule) 00386 // rotation about the axis of rotation. 00387 // 00388 // Parameters: 00389 // sin_angle - sin(rotation angle) 00390 // cos_angle - cos(rotation angle) 00391 // rotation_axis - 3d unit axis of rotation 00392 // rotation_center - 3d center of rotation 00393 // 00394 // Remarks: 00395 // In the overloads that take frames, the frames should 00396 // be right hand orthonormal frames 00397 // (unit vectors with Z = X x Y). 00398 // The resulting rotation fixes 00399 // the origin (0,0,0), maps initial X to 00400 // final X, initial Y to final Y, and initial Z to final Z. 00401 // 00402 // In the overload that takes frames with center points, 00403 // if the initial and final center are equal, then that 00404 // center point is the fixed point of the rotation. If 00405 // the initial and final point differ, then the resulting 00406 // transform is the composition of a rotation fixing P0 00407 // and translation from P0 to P1. The resulting 00408 // transformation maps P0 to P1, P0+X0 to P1+X1, ... 00409 // 00410 // The rotation transformations that map frames to frames 00411 // are not the same as the change of basis transformations 00412 // for those frames. See ON_Xform::ChangeBasis(). 00413 // 00414 void Rotation( 00415 double sin_angle, 00416 double cos_angle, 00417 ON_3dVector rotation_axis, 00418 ON_3dPoint rotation_center 00419 ); 00420 00421 // Parameters: 00422 // angle - rotation angle in radians 00423 // rotation_axis - 3d unit axis of rotation 00424 // rotation_center - 3d center of rotation 00425 void Rotation( 00426 double angle_radians, 00427 ON_3dVector rotation_axis, 00428 ON_3dPoint rotation_center 00429 ); 00430 00431 /* 00432 Description: 00433 Calculate the minimal transformation that rotates 00434 start_dir to end_dir while fixing rotation_center. 00435 */ 00436 void Rotation( 00437 ON_3dVector start_dir, 00438 ON_3dVector end_dir, 00439 ON_3dPoint rotation_center 00440 ); 00441 00442 // Parameters: 00443 // X0 - initial frame X 00444 // Y0 - initial frame Y 00445 // Z0 - initial frame Z 00446 // X1 - final frame X 00447 // Y1 - final frame Y 00448 // Z1 - final frame Z 00449 // 00450 void Rotation( 00451 const ON_3dVector& X0, 00452 const ON_3dVector& Y0, 00453 const ON_3dVector& Z0, 00454 const ON_3dVector& X1, 00455 const ON_3dVector& Y1, 00456 const ON_3dVector& Z1 00457 ); 00458 00459 // Parameters: 00460 // P0 - initial frame center 00461 // X0 - initial frame X 00462 // Y0 - initial frame Y 00463 // Z0 - initial frame Z 00464 // P1 - initial frame center 00465 // X1 - final frame X 00466 // Y1 - final frame Y 00467 // Z1 - final frame Z 00468 void Rotation( 00469 const ON_3dPoint& P0, 00470 const ON_3dVector& X0, 00471 const ON_3dVector& Y0, 00472 const ON_3dVector& Z0, 00473 const ON_3dPoint& P1, 00474 const ON_3dVector& X1, 00475 const ON_3dVector& Y1, 00476 const ON_3dVector& Z1 00477 ); 00478 00479 /* 00480 Description: 00481 Create rotation transformation that maps plane0 to plane1. 00482 Parameters: 00483 plane0 - [in] 00484 plane1 - [in] 00485 */ 00486 void Rotation( 00487 const ON_Plane& plane0, 00488 const ON_Plane& plane1 00489 ); 00490 00491 /* 00492 Description: 00493 Create mirror transformation matrix. 00494 Parameters: 00495 point_on_mirror_plane - [in] point on mirror plane 00496 normal_to_mirror_plane - [in] normal to mirror plane 00497 Remarks: 00498 The mirror transform maps a point Q to 00499 Q - (2*(Q-P)oN)*N, where 00500 P = point_on_mirror_plane and N = normal_to_mirror_plane. 00501 */ 00502 void Mirror( 00503 ON_3dPoint point_on_mirror_plane, 00504 ON_3dVector normal_to_mirror_plane 00505 ); 00506 00507 // Description: The ChangeBasis() function is overloaded 00508 // and provides several 00509 // ways to compute a change of basis transformation. 00510 // 00511 // Parameters: 00512 // plane0 - inital plane 00513 // plane1 - final plane 00514 // 00515 // Returns: 00516 // @untitled table 00517 // true success 00518 // false vectors for initial frame are not a basis 00519 // 00520 // Remarks: 00521 // If you have points defined with respect to planes, the 00522 // version of ChangeBasis() that takes two planes computes 00523 // the transformation to change coordinates from one plane to 00524 // another. The predefined world plane ON_world_plane can 00525 // be used as an argument. 00526 // 00527 // If P = plane0.Evaluate( a0,b0,c0 ) and 00528 // 00529 // (a1,b1,c1) = ChangeBasis(plane0,plane1)*ON_3dPoint(a0,b0,c0), 00530 // 00531 // then P = plane1.Evaluate( a1, b1, c1 ) 00532 // 00533 // The version of ChangeBasis() that takes six vectors 00534 // maps (a0,b0,c0) to (a1,b1,c1) where 00535 // a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1 00536 // 00537 // The version of ChangeBasis() that takes six vectors 00538 // with center points 00539 // maps (a0,b0,c0) to (a1,b1,c1) where 00540 // P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1 00541 // 00542 // The change of basis transformation is not the same as 00543 // the rotation transformation that rotates one orthonormal 00544 // frame to another. See ON_Xform::Rotation(). 00545 bool ChangeBasis( 00546 const ON_Plane& plane0, 00547 const ON_Plane& plane1 00548 ); 00549 00550 // Description: 00551 // Get a change of basis transformation. 00552 // Parameters: 00553 // X0 - initial basis X (X0,Y0,Z0 can be any 3d basis) 00554 // Y0 - initial basis Y 00555 // Z0 - initial basis Z 00556 // X1 - final basis X (X1,Y1,Z1 can be any 3d basis) 00557 // Y1 - final basis Y 00558 // Z1 - final basis Z 00559 // Remarks: 00560 // Change of basis transformations and rotation transformations 00561 // are often confused. This is a change of basis transformation. 00562 // If Q = a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1 00563 // then this transform will map the point (a0,b0,c0) to (a1,b1,c1) 00564 bool ChangeBasis( 00565 const ON_3dVector& X0, 00566 const ON_3dVector& Y0, 00567 const ON_3dVector& Z0, 00568 const ON_3dVector& X1, 00569 const ON_3dVector& Y1, 00570 const ON_3dVector& Z1 00571 ); 00572 00573 // Parameters: 00574 // P0 - initial center 00575 // X0 - initial basis X (X0,Y0,Z0 can be any 3d basis) 00576 // Y0 - initial basis Y 00577 // Z0 - initial basis Z 00578 // P1 - final center 00579 // X1 - final basis X (X1,Y1,Z1 can be any 3d basis) 00580 // Y1 - final basis Y 00581 // Z1 - final basis Z 00582 // Remarks: 00583 // Change of basis transformations and rotation transformations 00584 // are often confused. This is a change of basis transformation. 00585 // If Q = P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1 00586 // then this transform will map the point (a0,b0,c0) to (a1,b1,c1) 00587 bool ChangeBasis( 00588 const ON_3dPoint& P0, 00589 const ON_3dVector& X0, 00590 const ON_3dVector& Y0, 00591 const ON_3dVector& Z0, 00592 const ON_3dPoint& P1, 00593 const ON_3dVector& X1, 00594 const ON_3dVector& Y1, 00595 const ON_3dVector& Z1 00596 ); 00597 00598 // standard viewing transformations 00599 void WorldToCamera( 00600 const ON_3dPoint&, // CameraLocation 00601 const ON_3dVector&, // unit CameraX vector (right) 00602 const ON_3dVector&, // unit CameraY vector (up) 00603 const ON_3dVector& // unit CameraZ vector (from screen to camera) 00604 ); 00605 void CameraToWorld( 00606 const ON_3dPoint&, // CameraLocation 00607 const ON_3dVector&, // unit CameraX vector (right) 00608 const ON_3dVector&, // unit CameraY vector (up) 00609 const ON_3dVector& // unit CameraZ vector (from screen to camera) 00610 ); 00611 bool CameraToClip( // maps viewport frustum to -1 <= x,y,z <= 1 box 00612 ON_BOOL32, // true for perspective, false for orthographic 00613 double, double, // left != right (usually left < right ) 00614 double, double, // bottom != top (usually bottom < top ) 00615 double, double // near != far (usually 0 < near < far ) 00616 ); 00617 00618 // maps -1 <= x,y,z <= 1 box to viewport frustum 00619 bool ClipToCamera( 00620 int, // true for perspective, false for orthographic 00621 double, double, // left != right (usually left < right ) 00622 double, double, // bottom != top (usually bottom < top ) 00623 double, double // near != far an bot are non-zero (usually 0 < near < far ) 00624 ); 00625 00626 // Computes transform that maps the clipping box 00627 // 00628 // -1<x<1,-1<y<1,-1<z<1 00629 // 00630 // to the screen box 00631 // 00632 // (left,right) X (bottom,top) X (near,far) 00633 bool ClipToScreen( 00634 double, // left 00635 double, // right 00636 double, // bottom 00637 double, // top 00638 double, // near_z 00639 double // far_z 00640 ); 00641 00642 // Computes transform that maps the screen box 00643 // 00644 // (left,right) X (bottom,top) X (near,far) 00645 // 00646 // to the clipping box 00647 // 00648 // -1<x<1,-1<y<1,-1<z<1 00649 bool ScreenToClip( 00650 double, // left 00651 double, // right 00652 double, // bottom 00653 double, // top 00654 double, // near_z 00655 double // far_z 00656 ); 00657 00658 // Description: Computes homogeneous point clipping flags and 00659 // returns an int with bits set to indicate if the point 00660 // is outside of the clipping box. 00661 // 00662 // Parameters: 00663 // point - [in] 4d homogeneous clipping coordinate point 00664 // 00665 // Returns: 00666 // @table 00667 // bit point location 00668 // 1 x/w < -1 00669 // 2 x/w > +1 00670 // 4 y/w < -1 00671 // 8 y/w > +1 00672 // 16 z/w < -1 00673 // 32 z/w > +1 00674 // 00675 int ClipFlag4d( 00676 const double* // point 00677 ) const; 00678 00679 // Parameters: 00680 // count - [in] number of 4d points 00681 // stride - [in] (>=4) 00682 // points - [in] 4d clipping coordinate points 00683 // (array of stride*count doubles) 00684 // bTestZ - [in] (default=true) if false, do not test "z" coordinate 00685 // 00686 int ClipFlag4d( 00687 int, // count 00688 int, // stride 00689 const double*, // points 00690 ON_BOOL32 = true // bTeztZ 00691 ) const; 00692 00693 // Description: 00694 // Computes 3d point clipping flags and 00695 // returns an int with bits set to indicate if the point 00696 // is outside of the clipping box. 00697 // 00698 // Parameters: 00699 // point - [in] 3d clipping coordinate point 00700 // 00701 // Returns: 00702 // @table 00703 // bit point location 00704 // 1 x < -1 00705 // 2 x > +1 00706 // 4 y < -1 00707 // 8 y > +1 00708 // 16 z < -1 00709 // 32 z > +1 00710 int ClipFlag3d( 00711 const double* // point 00712 ) const; 00713 00714 // Parameters: 00715 // count - [in] number of 3d points 00716 // stride - [in] (>=3) 00717 // points - [in] 3d clipping coordinate points (array of stride*count doubles) 00718 // bTestZ - [in] (default=true) if false, do not test "z" coordinate 00719 // 00720 int ClipFlag3d( 00721 int, // count 00722 int, // stride 00723 const double*, // points 00724 ON_BOOL32 = true // bTestZ 00725 ) const; 00726 00727 // Description: Computes 3d clipping flags for a 3d bounding 00728 // box and returns an int with bits set to indicate if 00729 // the bounding box is outside of the clipping box. 00730 // 00731 // Parameters: 00732 // boxmin - [in] 3d boxmin corner 00733 // boxmax - [in] 3d boxmax corner 00734 // 00735 // Returns: 00736 // @table 00737 // bit box location 00738 // 1 boxmax x < -1 00739 // 2 boxmin x > +1 00740 // 4 boxmax y < -1 00741 // 8 boxmin y > +1 00742 // 16 boxmax z < -1 00743 // 32 boxmin z > +1 00744 int ClipFlag3dBox( 00745 const double*, // boxmin 00746 const double* // boxmax 00747 ) const; 00748 00749 00750 /* 00751 Description: 00752 Calculates the transformation that linearly maps 00753 old_interval to new_interval. 00754 Parameters: 00755 dir - [in] 0 = x, 1 = y, 2= z; 00756 old_interval - [in] 00757 new_interval - [in] 00758 */ 00759 bool IntervalChange( 00760 int dir, 00761 ON_Interval old_interval, 00762 ON_Interval new_interval 00763 ); 00764 }; 00765 00766 class ON_CLASS ON_ClippingRegion 00767 { 00768 public: 00769 ON_ClippingRegion(); 00770 00771 // The transformation m_xform transforms the view frustum, 00772 // in object coordinates to the (-1,+1)^3 clipping 00773 // coordinate box. 00774 ON_Xform m_xform; 00775 00776 /* 00777 Parameters: 00778 clip_plane_tolerance - [in] 00779 3d world coordinates tolerance to use when testing 00780 objects to see if the planes in m_clip_plane[] hide 00781 the objects. 00782 Remarks: 00783 The constructor sets this value to zero. Rhino uses 00784 values around 1e-5. 00785 */ 00786 void SetClipPlaneTolerance( double clip_plane_tolerance ); 00787 00788 /* 00789 Returns: 00790 3d world coordinates tolerance to use when testing 00791 objects to see if the planes in m_clip_plane[] hide 00792 the objects. 00793 Remarks: 00794 The constructor sets this value to zero. Rhino uses 00795 values around 1e-5. 00796 */ 00797 double ClipPlaneTolerance() const; 00798 00799 enum 00800 { 00801 max_clip_plane_count = 16, // must be <= 25 00802 frustum_bitmask = 0x0000003F, 00803 near_plane_bitmask = 0x00000020, 00804 far_plane_bitmask = 0x00000010, 00805 clip_plane_bitmask = 0x7FFFFFC0, 00806 negw_bitmask = 0x80000000 00807 }; 00808 00809 // Up to 25 additional clipping planes in object coordinates. 00810 // The convex region that is the intersection of the positive 00811 // side of these planes is the active region. 00812 int m_clip_plane_count; // (0 <= m_clip_plane_count <= max_clip_plane_count) 00813 00814 private: 00815 // The "float" should be a double, but that can't happen 00816 // until V6 because it will brake the SDK. Use the 00817 // SetClipPlaneTolerance() and ClipPlaneTolerance() 00818 // functions to set and get this value. 00819 float m_clip_plane_tolerance; 00820 00821 public: 00822 ON_PlaneEquation m_clip_plane[max_clip_plane_count]; 00823 00824 /* 00825 Description: 00826 The "view frustum" is the frustum the m_xform transformation 00827 maps to clipping coordinate box (-1,+1)^3. These functions 00828 determine if some portion of the convex hull of the test points 00829 is inside the view frustum. 00830 Parameters: 00831 P - [in] point 00832 box - [in] bounding box 00833 count - [in] number of points 00834 p - [in] array of points 00835 bEnableClippingPlanes - [in] 00836 If true, then the additional clipping planes are tested. 00837 If false, then the additional clipping planes are ignored. 00838 Returns: 00839 0 = No part of the of the convex hull of the tested points 00840 is in the view frustum. 00841 1 = A portion of the convex hull of the otested points may 00842 be in the view frustum. 00843 2 = The entire convex hull of the tested points is in the 00844 view frustum. 00845 */ 00846 int InViewFrustum( 00847 ON_3dPoint P 00848 ) const; 00849 int InViewFrustum( 00850 const ON_BoundingBox& bbox 00851 ) const; 00852 int InViewFrustum( 00853 int count, 00854 const ON_3fPoint* p 00855 ) const; 00856 int InViewFrustum( 00857 int count, 00858 const ON_3dPoint* p 00859 ) const; 00860 int InViewFrustum( 00861 int count, 00862 const ON_4dPoint* p 00863 ) const; 00864 00865 /* 00866 Description: 00867 The "clip plane region" is the convex hull of the planes in 00868 the m_clip_plane[] array. These functions determine if 00869 some portion of the convex hull of the test points is inside 00870 the clip plane region. 00871 Parameters: 00872 P - [in] point 00873 box - [in] bounding box 00874 count - [in] number of points 00875 p - [in] array of points 00876 bEnableClippingPlanes - [in] 00877 If true, then the additional clipping planes are tested. 00878 If false, then the additional clipping planes are ignored. 00879 Returns: 00880 0 = No part of the of the convex hull of the tested points 00881 is in the clip plane region. 00882 1 = A portion of the convex hull of the tested points may 00883 be in the clip plane region. 00884 2 = The entire convex hull of the tested points is in the 00885 clip plane region. 00886 */ 00887 int InClipPlaneRegion( 00888 ON_3dPoint P 00889 ) const; 00890 int InClipPlaneRegion( 00891 const ON_BoundingBox& bbox 00892 ) const; 00893 int InClipPlaneRegion( 00894 int count, 00895 const ON_3fPoint* p 00896 ) const; 00897 int InClipPlaneRegion( 00898 int count, 00899 const ON_3dPoint* p 00900 ) const; 00901 int InClipPlaneRegion( 00902 int count, 00903 const ON_4dPoint* p 00904 ) const; 00905 00906 00907 /* 00908 Description: 00909 The "visible area" is the intersection of the view frustum, 00910 defined by m_xform, and the clipping region, defined by the 00911 m_clip_plane[] array. These functions determing if some 00912 portion of the convex hull of the test points is visible. 00913 Parameters: 00914 P - [in] point 00915 box - [in] bounding box 00916 count - [in] number of points 00917 p - [in] array of points 00918 Returns: 00919 0 = no part of the object is in the region. 00920 1 = a portion of the object is in the region 00921 2 = entire object is in clipping region 00922 */ 00923 int IsVisible( 00924 ON_3dPoint P 00925 ) const; 00926 int IsVisible( 00927 const ON_BoundingBox& bbox 00928 ) const; 00929 int IsVisible( 00930 int count, 00931 const ON_3fPoint* p 00932 ) const; 00933 int IsVisible( 00934 int count, 00935 const ON_3dPoint* p 00936 ) const; 00937 int IsVisible( 00938 int count, 00939 const ON_4dPoint* p 00940 ) const; 00941 00942 /* 00943 Description: 00944 Transform a list of 4d homogenous points while testing 00945 for visibility. 00946 Parameters: 00947 count - [in] number of points 00948 p - [in/out] array of points to test and transform 00949 If 0 is returned, some of the points may not 00950 be transformed. In all other cases, the output 00951 points are transformed by m_xform. 00952 pflags - [out] 00953 0 when the point is in the visible region. 00954 Otherwise the bits are set to indicate which planes clip the 00955 intput point. 00956 0x01 left of the view frusturm 00957 0x02 right of the view frustum 00958 0x04 below the view frustum 00959 0x08 above the view frustum 00960 0x10 behind the view frustum (too far) 00961 0x20 in front of the view frustum (too near) 00962 00963 0x10 below m_clip_plane[0] 00964 0x20 below m_clip_plane[1] 00965 ... 00966 0x40000000 below m_clip_plane[24] 00967 00968 0x80000000 transformation created a non-positive weight 00969 Returns: 00970 0 = convex hull of the points is not in the region. 00971 The m_cull_bits field reports which plane or planes 00972 culled the point set. 00973 1 = a portion of the convex hull is in the region. 00974 The m_cull_bits field reports which plane or planes 00975 culled the point set. 00976 2 = all points are in the region. 00977 The m_cull_bits field will be zero. 00978 */ 00979 int TransformPoints( int count, ON_4dPoint* p ) const; 00980 int TransformPoints( int count, ON_4dPoint* p, unsigned int* pflags ) const; 00981 00982 00983 /* 00984 Description: 00985 Transform a pont and return the clipping information. 00986 Parameters: 00987 P - [in] point ot transform 00988 Q - [out] transformed point 00989 Returns: 00990 0 when the point is in the visible region. 00991 Otherwise the bits are set to indicate which planes clip the 00992 intput point. 00993 0x01 left of the view frusturm 00994 0x02 right of the view frustum 00995 0x04 below the view frustum 00996 0x08 above the view frustum 00997 0x10 behind the view frustum (too far) 00998 0x20 in front of the view frustum (too near) 00999 01000 0x10 below m_clip_plane[0] 01001 0x20 below m_clip_plane[1] 01002 ... 01003 0x40000000 below m_clip_plane[24] 01004 01005 0x80000000 transformation created a non-positive weight 01006 */ 01007 unsigned int TransformPoint( 01008 const ON_4dPoint& P, 01009 ON_4dPoint& Q 01010 ) const; 01011 unsigned int TransformPoint( 01012 const ON_3dPoint& P, 01013 ON_3dPoint& Q 01014 ) const; 01015 unsigned int TransformPoint( 01016 const ON_3fPoint& P, 01017 ON_3dPoint& Q 01018 ) const; 01019 01020 /* 01021 Description: 01022 Calculate the interval for the segment of a line that 01023 is in the clip plane region. 01024 Parameters: 01025 P0 - [in] start point 01026 P1 - [in] end point 01027 t0 - [out] start parameter 01028 t1 - [out] end parameter 01029 Returns: 01030 True if some portion of the line is visible and 01031 0.0 <= *t0 <= *t1 <= 1.0. 01032 */ 01033 bool GetLineClipPlaneParamters( 01034 ON_4dPoint P0, 01035 ON_4dPoint P1, 01036 double* t0, 01037 double* t1 01038 ) const; 01039 01040 }; 01041 01042 01043 class ON_CLASS ON_Localizer 01044 { 01045 public: 01046 ON_Localizer(); 01047 ~ON_Localizer(); 01048 01049 ON_Localizer(const ON_Localizer&); 01050 ON_Localizer& operator=(const ON_Localizer&); 01051 01052 void Destroy(); 01053 bool Read(ON_BinaryArchive&); 01054 bool Write(ON_BinaryArchive&) const; 01055 01056 /* 01057 Descrption: 01058 Creates a cylindrical localizer. 01059 If d = distance from the point to the line, 01060 then the localizer has the following behavior: 01061 01062 point distance localizer value 01063 d <= r0 < r1 or d >= r0 > r1 0 01064 d >= r1 > r0 or d <= r1 < r0 1 01065 01066 For values of d between r0 and r1, the localizer 01067 smoothly transitions between 0 to 1. 01068 01069 Parameters: 01070 P - [in] cylinder axis point 01071 D - [in] cylinder axis direction 01072 r0 - [in] 01073 r1 - [in] 01074 r0 and r1 are radii that control where the localizer is nonzero. 01075 Both r0 and r1 must be postive and the cannot be equal. 01076 If 0 < r0 < r1, then the localizer is zero for points 01077 inside the cylinder of radius r0 and one for points outside 01078 the cylinder of radius r1. 01079 If 0 < r1 < r0, then the localizer is one for points 01080 inside the cylinder of radius r1 and zero for points outside 01081 the cylinder of radius r0. 01082 01083 Returns: 01084 True if the input is value and the localizer is initialized. 01085 */ 01086 bool CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector D, double r0, double r1 ); 01087 01088 /* 01089 Descrption: 01090 Creates a planar localizer. 01091 If d = signed distance from the point to the plane, 01092 then the localizer has the following behavior: 01093 01094 point distance localizer value 01095 d <= h0 < h1 or d >= h0 > h1 0 01096 d >= h1 > h0 or d <= h1 < h0 1 01097 01098 For values of d between h0 and h1, the localizer 01099 smoothly transitions between 0 to 1. 01100 01101 Parameters: 01102 P - [in] point on plane 01103 N - [in] normal to plane 01104 h0 - [in] 01105 h1 - [in] 01106 h0 and h1 are signed distances that control where the 01107 localizer is nonzero. 01108 01109 Returns: 01110 True if the input is value and the localizer is initialized. 01111 */ 01112 bool CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 ); 01113 01114 /* 01115 Descrption: 01116 Creates a spherical localizer. 01117 If d = distance from the point to the center of the sphere, 01118 then the localizer has the following behavior: 01119 01120 point distance localizer value 01121 d <= r0 < r1 or d >= r0 > r1 0 01122 d >= r1 > r0 or d <= r1 < r0 1 01123 01124 For values of d between r0 and r1, the localizer 01125 smoothly transitions between 0 to 1. 01126 01127 Parameters: 01128 P - [in] center of sphere 01129 r0 - [in] 01130 r1 - [in] 01131 r0 and r1 are radii that control where the localizer is nonzero. 01132 Both r0 and r1 must be postive and the cannot be equal. 01133 If 0 < r0 < r1, then the localizer is zero for points 01134 inside the cylinder of radius r0 and one for points outside 01135 the cylinder of radius r1. 01136 If 0 < r1 < r0, then the localizer is one for points 01137 inside the cylinder of radius r1 and zero for points outside 01138 the cylinder of radius r0. 01139 01140 Returns: 01141 True if the input is value and the localizer is initialized. 01142 */ 01143 bool CreateSphereLocalizer( ON_3dPoint P, double r0, double r1 ); 01144 01145 /* 01146 Description: 01147 Evaluators. 01148 Parameters: 01149 P - [in] 01150 Evaluation point 01151 distance - [in] 01152 Evaluation distance 01153 Returns: 01154 Value of the localizer. 01155 */ 01156 double Value(ON_3dPoint P) const; 01157 double Value(double distance) const; 01158 01159 /* 01160 Parameters: 01161 bbox - [in] 01162 Returns: 01163 True if localizer is identically zero inside bbox. 01164 */ 01165 bool IsZero( const ON_BoundingBox& bbox ) const; 01166 01167 enum TYPE 01168 { 01169 no_type = 0, 01170 sphere_type = 1, 01171 plane_type = 2, 01172 cylinder_type = 3, 01173 curve_type = 4, 01174 surface_type = 5, 01175 distance_type = 6, 01176 force_32bit_localizer_type = 0xFFFFFFFF 01177 }; 01178 01179 TYPE m_type; 01180 01181 ON_Interval m_d; 01182 ON_3dPoint m_P; 01183 ON_3dVector m_V; 01184 class ON_NurbsCurve* m_nurbs_curve; 01185 class ON_NurbsSurface* m_nurbs_surface; 01186 }; 01187 01188 01189 class ON_CLASS ON_SpaceMorph 01190 { 01191 public: 01192 ON_SpaceMorph(); 01193 virtual ~ON_SpaceMorph(); 01194 01195 /* 01196 Description: 01197 Provides a quick way to determine if a morph function 01198 is the identity (doesn't move the points) on a region 01199 of space. 01200 Parameters: 01201 bbox - [in] region of space to test. 01202 Returns: 01203 The default always returns false. If you override 01204 this function, then return true when every point 01205 in the bounding box is fixed by the morph. 01206 */ 01207 virtual 01208 bool IsIdentity( const ON_BoundingBox& bbox ) const; 01209 01210 /* 01211 Description: 01212 Returns the desired accuracy of the morph. 01213 This value is primarily used for deforming 01214 surfaces and breps. 01215 Returns: 01216 3d fitting tolerance. 01217 Remarks: 01218 The default is 0.0 and any value <= 0.0 is 01219 ignored by morphing functions. 01220 The value returned by Tolerance() does not 01221 affect the way meshes and points are morphed. 01222 */ 01223 double Tolerance() const; 01224 01225 /* 01226 Description: 01227 Set the 3d fitting tolerance used when morphing 01228 surfaces and breps. 01229 Parameters: 01230 tolerance - [in] values < 0.0 are treated as 0.0. 01231 */ 01232 void SetTolerance( 01233 double tolerance 01234 ); 01235 01236 /* 01237 Returns: 01238 True if the morph should be done as quickly as 01239 possible because the result is being used for 01240 some type of dynamic preview. If QuickPreview 01241 is true, the tolerance may be ignored. 01242 Remarks: 01243 The value returned by QuickPreview() does not 01244 affect the way meshes and points are morphed. 01245 The default is false. 01246 */ 01247 bool QuickPreview() const; 01248 01249 /* 01250 Description: 01251 Set the quick preview value. 01252 Parameters: 01253 bQuickPreview - [in] 01254 */ 01255 void SetQuickPreview( 01256 bool bQuickPreview 01257 ); 01258 01259 /* 01260 Returns: 01261 True if the morph should be done in a way that 01262 preserves the structure of the geometry. 01263 In particular, for NURBS objects, true 01264 means that only the control points are moved. 01265 Remarks: 01266 The value returned by PreserveStructure() does not 01267 affect the way meshes and points are morphed. 01268 The default is false. 01269 */ 01270 bool PreserveStructure() const; 01271 01272 /* 01273 Description: 01274 Set the preserve structure value. 01275 Parameters: 01276 bPreserveStructure - [in] 01277 */ 01278 void SetPreserveStructure( 01279 bool bPreserveStructure 01280 ); 01281 01282 private: 01283 double m_tolerance; 01284 bool m_bQuickPreview; 01285 bool m_bPreserveStructure; 01286 }; 01287 01288 #if defined(ON_DLL_TEMPLATE) 01289 01290 // This stuff is here because of a limitation in the way Microsoft 01291 // handles templates and DLLs. See Microsoft's knowledge base 01292 // article ID Q168958 for details. 01293 #pragma warning( push ) 01294 #pragma warning( disable : 4231 ) 01295 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Xform>; 01296 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_Localizer>; 01297 #pragma warning( pop ) 01298 #endif 01299 01300 #endif