mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-04 14:09:41 +08:00
2152 lines
66 KiB
C++
2152 lines
66 KiB
C++
//
|
|
// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved.
|
|
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
|
// McNeel & Associates.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
|
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
|
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
|
//
|
|
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// defines ON_Xform (4 x 4 transformation matrix)
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
#if !defined(ON_XFORM_INC_)
|
|
#define ON_XFORM_INC_
|
|
|
|
class ON_Matrix;
|
|
class ON_Quaternion;
|
|
|
|
class ON_CLASS ON_Xform
|
|
{
|
|
public:
|
|
// ON_Xform IdentityTransformation diagonal = (1,1,1,1)
|
|
static const ON_Xform IdentityTransformation;
|
|
|
|
// ON_Xform ZeroTransformation diagonal = (0,0,0,1)
|
|
static const ON_Xform ZeroTransformation;
|
|
|
|
// ON_Xform::Zero4x4 - every coefficient is 0.0.
|
|
static const ON_Xform Zero4x4;
|
|
|
|
// ON_Xform::Unset - every coefficient is ON_UNSET_VALUE
|
|
static const ON_Xform Unset;
|
|
|
|
// ON_Xform::Nan - every coefficient is ON_DBL_QNAN
|
|
static const ON_Xform Nan;
|
|
|
|
double m_xform[4][4]; // [i][j] = row i, column j. I.e.,
|
|
//
|
|
// [0][0] [0][1] [0][2] [0][3]
|
|
// [1][0] [1][1] [1][2] [1][3]
|
|
// [2][0] [2][1] [2][2] [2][3]
|
|
// [3][0] [3][1] [3][2] [3][3]
|
|
|
|
// Default constructor transformation has diagonal (0,0,0,1)
|
|
ON_Xform();
|
|
~ON_Xform() = default;
|
|
ON_Xform(const ON_Xform&) = default;
|
|
ON_Xform& operator=(const ON_Xform&) = default;
|
|
|
|
bool operator==(const ON_Xform& rhs) const;
|
|
|
|
bool operator!=(const ON_Xform& rhs) const;
|
|
|
|
// Constructs transformation with diagonal (x,x,x,1)
|
|
explicit ON_Xform(
|
|
double x
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
Transformation with diagonal (d,d,d,1).
|
|
*/
|
|
static const ON_Xform DiagonalTransformation(
|
|
double d
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
Transformation with diagonal (d0,d1,d2,1.0).
|
|
*/
|
|
static const ON_Xform DiagonalTransformation(
|
|
double d0,
|
|
double d1,
|
|
double d2
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
Transformation with diagonal (d0,d1,d2,1.0).
|
|
*/
|
|
static const ON_Xform DiagonalTransformation(
|
|
const ON_3dVector& diagonal
|
|
);
|
|
|
|
#if defined(ON_COMPILER_MSC)
|
|
// Microsoft's compiler won't pass double m[4][4] as a const double[4][4] arg.
|
|
// Gnu's compiler handles this.
|
|
explicit ON_Xform( double[4][4] ); // from standard double m[4][4]
|
|
explicit ON_Xform( float[4][4] ); // from standard float m[4][4]
|
|
#endif
|
|
|
|
explicit ON_Xform( const double[4][4] ); // from standard double m[4][4]
|
|
explicit ON_Xform( const float[4][4] ); // from standard float m[4][4]
|
|
|
|
explicit ON_Xform( const double* ); // from array of 16 doubles (row0,row1,row2,row3)
|
|
explicit ON_Xform( const float* ); // from array of 16 floats (row0,row1,row2,row3)
|
|
|
|
explicit ON_Xform( const ON_Matrix& ); // from upper left 4x4 of an
|
|
// arbitrary matrix. Any missing
|
|
// rows/columns are set to identity.
|
|
ON_Xform(const ON_3dPoint& P, // as a frame.
|
|
const ON_3dVector& X,
|
|
const ON_3dVector& Y,
|
|
const ON_3dVector& Z);
|
|
|
|
double* operator[](int);
|
|
const double* operator[](int) const;
|
|
|
|
// xform = scalar results in a diagonal 3x3 with bottom row = 0,0,0,1
|
|
ON_Xform& operator=( const ON_Matrix& ); // from upper left 4x4 of an
|
|
// arbitrary matrix. Any missing
|
|
// rows/columns are set to identity.
|
|
|
|
// All non-commutative operations have "this" as left hand side and
|
|
// argument as right hand side.
|
|
|
|
// Note well: The right hand column and bottom row have an important effect
|
|
// when transforming a Euclidean point and have no effect when transforming a vector.
|
|
// Be sure you understand the differences between vectors and points when applying a 4x4 transformation.
|
|
ON_2dPoint operator*( const ON_2dPoint& ) const;
|
|
ON_3dPoint operator*( const ON_3dPoint& ) const;
|
|
ON_4dPoint operator*( const ON_4dPoint& ) const;
|
|
|
|
// Note well: The right hand column and bottom row have an important effect
|
|
// when transforming a Euclidean point and have no effect when transforming a vector.
|
|
// Be sure you understand the differences between vectors and points when applying a 4x4 transformation.
|
|
ON_2dVector operator*( const ON_2dVector& ) const;
|
|
ON_3dVector operator*( const ON_3dVector& ) const;
|
|
|
|
ON_Xform operator*( const ON_Xform& /*rhs*/ ) const;
|
|
ON_Xform operator+( const ON_Xform& ) const;
|
|
ON_Xform operator-( const ON_Xform& /*rhs*/ ) const;
|
|
|
|
const ON_SHA1_Hash Hash() const;
|
|
ON__UINT32 CRC32(ON__UINT32 current_remainder) const;
|
|
|
|
/*
|
|
Description:
|
|
Test the entries of the transformation matrix
|
|
to see if they are valid number.
|
|
Returns:
|
|
True if ON_IsValid() is true for every coefficient in the transformation matrix.
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Description:
|
|
Test the entries of the transformation matrix
|
|
to see if they are valid number.
|
|
Returns:
|
|
True if any coefficient in the transformation matrix is a nan.
|
|
*/
|
|
bool IsNan() const;
|
|
|
|
bool IsValidAndNotZeroAndNotIdentity(
|
|
double zero_tolerance = 0.0
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
true if matrix is the identity transformation
|
|
|
|
1 0 0 0
|
|
0 1 0 0
|
|
0 0 1 0
|
|
0 0 0 1
|
|
Remarks:
|
|
An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
|
|
An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance.
|
|
If the matrix contains a nan, false is returned.
|
|
*/
|
|
bool IsIdentity( double zero_tolerance = 0.0) const;
|
|
|
|
/*
|
|
Returns:
|
|
true if the matrix is valid and is not the identity transformation
|
|
Remarks:
|
|
An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
|
|
An element of the matrix is "one" if fabs(1.0-x) <= zero_tolerance.
|
|
If the matrix contains a nan, false is returned.
|
|
*/
|
|
bool IsNotIdentity( double zero_tolerance = 0.0) const;
|
|
|
|
/*
|
|
Returns:
|
|
true if matrix is a pure translation
|
|
|
|
1 0 0 dx
|
|
0 1 0 dy
|
|
0 0 1 dz
|
|
0 0 0 1
|
|
Remarks:
|
|
The test for zero is fabs(x) <= zero_tolerance.
|
|
The test for one is fabs(x-1) <= zero_tolerance.
|
|
*/
|
|
bool IsTranslation( double zero_tolerance = 0.0) const;
|
|
|
|
/*
|
|
Returns:
|
|
true if matrix is ON_Xform::Zero4x4, ON_Xform::ZeroTransformation,
|
|
or some other type of zero. The value xform[3][3] can be anything.
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 *
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if matrix is ON_Xform::Zero4x4
|
|
The value xform[3][3] must be zero.
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 0
|
|
*/
|
|
bool IsZero4x4() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if matrix is ON_Xform::Zero4x4
|
|
The value xform[3][3] must be zero.
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 0
|
|
*/
|
|
bool IsZero4x4(double zero_tolerance) const;
|
|
|
|
/*
|
|
Returns:
|
|
true if matrix is ON_Xform::ZeroTransformation
|
|
The value xform[3][3] must be 1.
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 0
|
|
0 0 0 1
|
|
An element of the matrix is "zero" if fabs(x) <= zero_tolerance.
|
|
IsZeroTransformation() is the same as IsZeroTransformation( 0.0 );
|
|
*/
|
|
bool IsZeroTransformation() const;
|
|
bool IsZeroTransformation(double zero_tolerance ) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
A similarity transformation can be broken into a sequence
|
|
of a dialation, translation, rotation, and a reflection.
|
|
Parameters:
|
|
*this - must be IsAffine().
|
|
Translation - [out] Translation vector
|
|
dilation - [out] dialation, (dilation <0 iff this is an orientation reversing similarity )
|
|
Rotation - [out] a proper rotation transformation ie. R*Transpose(R)=I and det(R)=1
|
|
Details:
|
|
If X.DecomposeSimilarity(T, d, R, tol) !=0 then X ~ TranslationTransformation(T)*DiagonalTransformation(d)*R
|
|
note when d>0 the transformation is orientation preserving.
|
|
Note:
|
|
If dilation<0 then DiagonalTransformation( dilation) is actually a reflection
|
|
combined with a "true" dialation, i.e.
|
|
DiagonalTransformation( dilation) = DiagonalTransformation(-1) * DiagonalTransformation( |diagonal| )
|
|
Returns:
|
|
+1: This transformation is an orientation preserving similarity.
|
|
-1: This transformation is an orientation reversing similarity.
|
|
0: This transformation is not a similarity.
|
|
*/
|
|
int IsSimilarity() const;
|
|
int IsSimilarity(double tolerance) const;
|
|
int DecomposeSimilarity(ON_3dVector& Translation, double& dilation, ON_Xform& Rotation, double tolerance) const;
|
|
|
|
/*
|
|
Description:
|
|
NOTE: A better name for this fuction would be IsIsometry().
|
|
|
|
An "isometry" transformation is an affine transformation that preserves
|
|
distances. Isometries include transformation like reflections
|
|
that reverse orientation.
|
|
|
|
A "rigid" transformation is an isometry that preserves orientation
|
|
and can be broken into a proper rotation and a translation.
|
|
Returns:
|
|
+1: This transformation is an orientation preserving isometry transformation ("rigid and determinant = 1).
|
|
-1: This transformation is an orientation reversing isometry (determinant = -1).
|
|
0 : This transformation is not an orthogonal transformation.
|
|
*/
|
|
int IsRigid(double tolerance = ON_ZERO_TOLERANCE) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
A rigid transformation preserves distances and orientation
|
|
and can be broken into a proper rotation and a translation.
|
|
An isometry transformation preserves distance and may include a reflection.
|
|
Parameters:
|
|
*this - must be IsAffine().
|
|
Translation - [out] Translation vector
|
|
Rotation - [out] Proper Rotation transformation, ie. R*Transpose(R)=I and det(R)=1
|
|
Details:
|
|
If X.DecomposeRigid(T, R) is 1 then X ~ TranslationTransformation(T)*R
|
|
-1 X ~ ON_Xform(-1) *TranslationTransformation(T)*R
|
|
where ~ means approximates to within tolerance.
|
|
DecomposeRigid will find the closest rotation to the linear part of this transformation.
|
|
Returns:
|
|
+1: This transformation is an rigid transformation.
|
|
-1: This transformation is an orientation reversing isometry.
|
|
0 : This transformation is not an orthogonal transformation.
|
|
*/
|
|
int DecomposeRigid(ON_3dVector& Translation, ON_Xform& Rotation, double tolerance = ON_ZERO_TOLERANCE) const;
|
|
|
|
/*
|
|
Description:
|
|
A transformation is affine if it is valid and its last row is
|
|
0 0 0 1
|
|
If in addition its last column is ( 0, 0, 0, 1)^T then it is linear.
|
|
An affine transformation can be broken into a linear transformation and a translation.
|
|
Parameters:
|
|
*this - IsAffine() must be true for DecomposeAffine(..) to succeed
|
|
Translation - [out] Translation vector
|
|
Linear - [out] Linear transformation
|
|
Example:
|
|
A perspective transformation is not affine.
|
|
Details:
|
|
If X.DecomposeAffine(T, L) is true then X == TranslationTransformation(T)*L
|
|
If X.DecomposeAffine(L, T) is true then X == L* TranslationTransformation(T).
|
|
Note:
|
|
DecomposeAffine(T,L) succeeds for all affine transformations and is a simple copying of values.
|
|
DecomposeAffine(L, T), on the otherhand, may fail for affine transformations if L is not invertible
|
|
and is more computationally expensive.
|
|
Returns:
|
|
True - if successful decomposition
|
|
*/
|
|
bool IsAffine() const;
|
|
bool IsLinear() const;
|
|
bool DecomposeAffine(ON_3dVector& Translation, ON_Xform& Linear) const;
|
|
bool DecomposeAffine(ON_Xform& Linear, ON_3dVector& Translation ) const;
|
|
|
|
// Convert an ON_Xform into the offset, repeat and rotation values used in ON_Texture and similar classes.
|
|
void DecomposeTextureMapping(ON_3dVector& offset, ON_3dVector& repeat, ON_3dVector& rotation) const;
|
|
|
|
// true if this is a proper rotation.
|
|
bool IsRotation() const;
|
|
|
|
/*
|
|
Description:
|
|
If *this is a proper rotation then find the equivalent quaternion.
|
|
Parameters:
|
|
Q - [out] Quaternion that represents this rotation transformation
|
|
Returns:
|
|
True - if *this is a proper rotation
|
|
*/
|
|
bool GetQuaternion(ON_Quaternion& Q) const;
|
|
|
|
/*
|
|
Description:
|
|
An affine transformation can be decomposed into a Symmetric, Rotation and Translation.
|
|
Then the Symmetric component may be further decomposed as non-uniform scale in an orthonormal
|
|
coordinate system.
|
|
Parameters:
|
|
*this - must be IsAffine().
|
|
Translation-[out] Translation vector
|
|
Rotation - [out] Proper Rotation transformation
|
|
OrthBasis - [out] Orthogonal Basis
|
|
Diagonal - [out] diagonal elements of a DiagonalTransformation
|
|
Details:
|
|
DecomposeAffine(T,R,Q,diag)
|
|
(*this) == TranslationTransformation(T) * R * Q * DiagonalTransformation(diag) * Q.Transpose()
|
|
Returns:
|
|
true if decomposition succeeds
|
|
*/
|
|
bool DecomposeAffine(ON_3dVector& Translation, ON_Xform& Rotation, ON_Xform& OrthBasis, ON_3dVector& Diagonal) const;
|
|
|
|
/*
|
|
Description:
|
|
Replace last row with 0 0 0 1 discarding any perspecive part of this transform
|
|
*/
|
|
void Affineize();
|
|
|
|
/*
|
|
Description:
|
|
Affineize() and replace last column with (0 0 0 1)^T
|
|
discarding any translation part of this transform.
|
|
*/
|
|
void Linearize();
|
|
|
|
/*
|
|
Description:
|
|
Force the linear part of this transformation to be a rotation (or a rotation with reflection).
|
|
This is probably best to perform minute tweeks.
|
|
Use DecomposeRigid(T,R) to find the nearest rotation
|
|
*/
|
|
bool Orthogonalize(double tol);
|
|
|
|
/*
|
|
Description:
|
|
A Symmetric linear transformation can be decomposed A = Q * Diag * Q^T where Diag is a diagonal
|
|
transformation. Diag[i][i] is an eigenvalue of A and the i-th coulmn of Q is a corresponding
|
|
unit length eigenvector.
|
|
Parameters:
|
|
This transformation must be Linear() and Symmetric, that is *this==Transpose().
|
|
Q -[out] is set to an orthonormal matrix of eigenvectors when true is returned.
|
|
diagonal -[out] is set to a vector of eigenvalues when true is returned.
|
|
Details:
|
|
If success then *this== Q*DiagonalTransformation(diagonal) * QT, where QT == Q.Transpose().
|
|
If L.IsLinear() and LT==L.Transpose() then LT*L is symmetric and is a common source of symmetric
|
|
transformations.
|
|
Return:
|
|
true if success.
|
|
*/
|
|
bool DecomposeSymmetric(ON_Xform& Q, ON_3dVector& diagonal) const;
|
|
|
|
/*
|
|
Description:
|
|
Well ordered dictionary compare that is nan aware.
|
|
*/
|
|
int Compare( const ON_Xform& other ) const;
|
|
|
|
// matrix operations
|
|
void Transpose(); // transposes 4x4 matrix
|
|
|
|
int
|
|
Rank( // returns 0 to 4
|
|
double* = nullptr // If not nullptr, returns minimum pivot
|
|
) const;
|
|
|
|
/// <summary>
|
|
/// If you need a slow and accurate determinant, this is the function to call.
|
|
/// If you need a fast sign check, used SignOfDeterminant(true).
|
|
/// </summary>
|
|
/// <param name=minimum_pivot>
|
|
/// If not nullptr, returns the minimum pivot
|
|
/// </param>
|
|
/// <returns>The determinant of 4x4 matrix</returns>
|
|
double
|
|
Determinant(
|
|
double* minimum_pivot = nullptr //
|
|
) const;
|
|
|
|
/// <summary>
|
|
/// Quickly determine the sign of the determinant.
|
|
/// Definitely good enough for graphics code.
|
|
/// </summary>
|
|
/// <param name=bFastTest>
|
|
/// When in double, pass true.
|
|
/// If you need a fast answer and can tolerate extremely rare wrong answers,
|
|
/// pass true. True definitely works for all common matrices used to transform
|
|
/// 3d objects and all common view projection matrices.
|
|
/// </param>
|
|
/// <returns>
|
|
/// +1, 0, or -1.
|
|
/// </returns>
|
|
int SignOfDeterminant(
|
|
bool bFastTest
|
|
) const;
|
|
|
|
bool
|
|
Invert( // If matrix is non-singular, returns true,
|
|
// otherwise returns false and sets matrix to
|
|
// pseudo inverse.
|
|
double* = nullptr // If not nullptr, returns minimum pivot
|
|
);
|
|
|
|
ON_Xform
|
|
Inverse( // If matrix is non-singular, returns inverse,
|
|
// otherwise returns pseudo inverse.
|
|
double* = nullptr // If not nullptr, returns minimum pivot
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
When transforming 3d point and surface or mesh normals
|
|
two different transforms must be used.
|
|
If P_xform transforms the point, then the inverse
|
|
transpose of P_xform must be used to transform normal
|
|
vectors.
|
|
Parameters:
|
|
N_xform - [out]
|
|
Returns:
|
|
The determinant of the transformation.
|
|
If non-zero, "this" is invertable and N_xform can be calculated.
|
|
False if "this" is not invertable, in which case
|
|
the returned N_xform = this with the right hand column
|
|
and bottom row zeroed out.
|
|
*/
|
|
double GetSurfaceNormalXform( ON_Xform& N_xform ) const;
|
|
|
|
/*
|
|
Description:
|
|
If a texture mapping is applied to an object, the object
|
|
is subsequently transformed by T, and the texture mapping
|
|
needs to be recalculated, then two transforms are required
|
|
to recalcalculate the texture mapping.
|
|
Parameters:
|
|
P_xform - [out]
|
|
Transform to apply to points before applying the
|
|
texture mapping transformation.
|
|
N_xform - [out]
|
|
Transform to apply to surface normals before applying
|
|
the texture mapping transformation.
|
|
Returns:
|
|
The determinant of the "this" transformation.
|
|
If non-zero, "this" is invertable and P_xform and N_xform
|
|
were calculated.
|
|
False if "this" is not invertable, in which case
|
|
the returned P_xform and N_xform are the identity.
|
|
*/
|
|
double GetMappingXforms( ON_Xform& P_xform, ON_Xform& N_xform ) const;
|
|
|
|
// Description:
|
|
// Computes matrix * transpose([x,y,z,w]).
|
|
//
|
|
// Parameters:
|
|
// x - [in]
|
|
// y - [in]
|
|
// z - [in]
|
|
// z - [in]
|
|
// ans - [out] = matrix * transpose([x,y,z,w])
|
|
void ActOnLeft(
|
|
double, // x
|
|
double, // y
|
|
double, // z
|
|
double, // w
|
|
double[4] // ans
|
|
) const;
|
|
|
|
// Description:
|
|
// Computes [x,y,z,w] * matrix.
|
|
//
|
|
// Parameters:
|
|
// x - [in]
|
|
// y - [in]
|
|
// z - [in]
|
|
// z - [in]
|
|
// ans - [out] = [x,y,z,w] * matrix
|
|
void ActOnRight(
|
|
double, // x
|
|
double, // y
|
|
double, // z
|
|
double, // w
|
|
double[4] // ans
|
|
) const;
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// standard transformations
|
|
|
|
|
|
// diagonal is (1,1,1,1)
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::IdentityTransformation;")
|
|
void Identity();
|
|
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::DiagonalTransformation(d);")
|
|
void Diagonal(double d);
|
|
|
|
/*
|
|
Description:
|
|
Create non-uniform scale transformation with the origin as
|
|
a fixed point.
|
|
Parameters:
|
|
fixed_point - [in]
|
|
x_scale_factor - [in]
|
|
y_scale_factor - [in]
|
|
z_scale_factor - [in]
|
|
Remarks:
|
|
The diagonal is (x_scale_factor, y_scale_factor, z_scale_factor, 1)
|
|
*/
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::DiagonalTransformation(x_scale_factor,z_scale_factor,z_scale_factor);")
|
|
void Scale(
|
|
double x_scale_factor,
|
|
double y_scale_factor,
|
|
double z_scale_factor
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create non-uniform scale transformation with the origin as the fixed point.
|
|
Parameters:
|
|
fixed_point - [in]
|
|
scale_vector - [in]
|
|
Remarks:
|
|
The diagonal is (scale_vector.x, scale_vector.y, scale_vector.z, 1)
|
|
*/
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::DiagonalTransformation(scale_vector);")
|
|
void Scale(
|
|
const ON_3dVector& scale_vector
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create uniform scale transformation with a specified
|
|
fixed point.
|
|
Parameters:
|
|
fixed_point - [in]
|
|
scale_factor - [in]
|
|
*/
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::ScaleTransformation(fixed_point,scale_factor)")
|
|
void Scale
|
|
(
|
|
ON_3dPoint fixed_point,
|
|
double scale_factor
|
|
);
|
|
|
|
static const ON_Xform ScaleTransformation(
|
|
const ON_3dPoint& fixed_point,
|
|
double scale_factor
|
|
);
|
|
|
|
static const ON_Xform ScaleTransformation(
|
|
const ON_3dPoint& fixed_point,
|
|
double x_scale_factor,
|
|
double y_scale_factor,
|
|
double z_scale_factor
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create non-uniform scale transformation with a specified
|
|
fixed point.
|
|
Parameters:
|
|
plane - [in] plane.origin is the fixed point
|
|
x_scale_factor - [in] plane.xaxis scale factor
|
|
y_scale_factor - [in] plane.yaxis scale factor
|
|
z_scale_factor - [in] plane.zaxis scale factor
|
|
*/
|
|
static const ON_Xform ScaleTransformation
|
|
(
|
|
const ON_Plane& plane,
|
|
double x_scale_factor,
|
|
double y_scale_factor,
|
|
double z_scale_factor
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create non-uniform scale transformation with a specified
|
|
fixed point.
|
|
Parameters:
|
|
plane - [in] plane.origin is the fixed point
|
|
x_scale_factor - [in] plane.xaxis scale factor
|
|
y_scale_factor - [in] plane.yaxis scale factor
|
|
z_scale_factor - [in] plane.zaxis scale factor
|
|
*/
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::ScaleTransformation(plane,x_scale_factor,y_scale_factor,z_scale_factor)")
|
|
void Scale
|
|
(
|
|
const ON_Plane& plane,
|
|
double x_scale_factor,
|
|
double y_scale_factor,
|
|
double z_scale_factor
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create shear transformation.
|
|
Parameters:
|
|
plane - [in] plane.origin is the fixed point
|
|
x1 - [in] plane.xaxis scale factor
|
|
y1 - [in] plane.yaxis scale factor
|
|
z1 - [in] plane.zaxis scale factor
|
|
*/
|
|
static const ON_Xform ShearTransformation(
|
|
const ON_Plane& plane,
|
|
const ON_3dVector& x1,
|
|
const ON_3dVector& y1,
|
|
const ON_3dVector& z1
|
|
);
|
|
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::ShearTransformation(plane,x1,y1,z1);")
|
|
void Shear
|
|
(
|
|
const ON_Plane& plane,
|
|
const ON_3dVector& x1,
|
|
const ON_3dVector& y1,
|
|
const ON_3dVector& z1
|
|
);
|
|
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::TranslationTransformation(delta);")
|
|
void Translation(
|
|
const ON_3dVector& delta
|
|
);
|
|
|
|
ON_DEPRECATED_MSG("Use xform = ON_Xform::TranslationTransformation(dx,dy,dz);")
|
|
void Translation(
|
|
double dx,
|
|
double dy,
|
|
double dz
|
|
);
|
|
|
|
// Right column is (delta.x, delta.y, 0, 1).
|
|
static const ON_Xform TranslationTransformation(
|
|
const ON_2dVector& delta
|
|
);
|
|
|
|
// Right column is (delta.x, delta.y, delta.z, 1).
|
|
static const ON_Xform TranslationTransformation(
|
|
const ON_3dVector& delta
|
|
);
|
|
|
|
// Right column is (dx, dy, dz, 1).
|
|
static const ON_Xform TranslationTransformation(
|
|
double dx,
|
|
double dy,
|
|
double dz
|
|
);
|
|
|
|
// Description:
|
|
// Get transformation that projects to a plane
|
|
// Parameters:
|
|
// plane - [in] plane to project to
|
|
// Remarks:
|
|
// This transformation maps a 3d point P to the
|
|
// point plane.ClosestPointTo(Q).
|
|
void PlanarProjection(
|
|
const ON_Plane& plane
|
|
);
|
|
|
|
// Description:
|
|
// The Rotation() function is overloaded and provides several
|
|
// ways to compute a rotation transformation. A positive
|
|
// rotation angle indicates a counter-clockwise (right hand rule)
|
|
// rotation about the axis of rotation.
|
|
//
|
|
// Parameters:
|
|
// sin_angle - sin(rotation angle)
|
|
// cos_angle - cos(rotation angle)
|
|
// rotation_axis - 3d unit axis of rotation
|
|
// rotation_center - 3d center of rotation
|
|
//
|
|
// Remarks:
|
|
// In the overloads that take frames, the frames should
|
|
// be right hand orthonormal frames
|
|
// (unit vectors with Z = X x Y).
|
|
// The resulting rotation fixes
|
|
// the origin (0,0,0), maps initial X to
|
|
// final X, initial Y to final Y, and initial Z to final Z.
|
|
//
|
|
// In the overload that takes frames with center points,
|
|
// if the initial and final center are equal, then that
|
|
// center point is the fixed point of the rotation. If
|
|
// the initial and final point differ, then the resulting
|
|
// transform is the composition of a rotation fixing P0
|
|
// and translation from P0 to P1. The resulting
|
|
// transformation maps P0 to P1, P0+X0 to P1+X1, ...
|
|
//
|
|
// The rotation transformations that map frames to frames
|
|
// are not the same as the change of basis transformations
|
|
// for those frames. See ON_Xform::ChangeBasis().
|
|
//
|
|
void Rotation(
|
|
double sin_angle,
|
|
double cos_angle,
|
|
ON_3dVector rotation_axis,
|
|
ON_3dPoint rotation_center
|
|
);
|
|
|
|
// Parameters:
|
|
// angle - rotation angle in radians
|
|
// rotation_axis - 3d unit axis of rotation
|
|
// rotation_center - 3d center of rotation
|
|
void Rotation(
|
|
double angle_radians,
|
|
ON_3dVector rotation_axis,
|
|
ON_3dPoint rotation_center
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Calculate the minimal transformation that rotates
|
|
start_dir to end_dir while fixing rotation_center.
|
|
*/
|
|
void Rotation(
|
|
ON_3dVector start_dir,
|
|
ON_3dVector end_dir,
|
|
ON_3dPoint rotation_center
|
|
);
|
|
|
|
// Parameters:
|
|
// X0 - initial frame X
|
|
// Y0 - initial frame Y
|
|
// Z0 - initial frame Z
|
|
// X1 - final frame X
|
|
// Y1 - final frame Y
|
|
// Z1 - final frame Z
|
|
//
|
|
void Rotation(
|
|
const ON_3dVector& X0,
|
|
const ON_3dVector& Y0,
|
|
const ON_3dVector& Z0,
|
|
const ON_3dVector& X1,
|
|
const ON_3dVector& Y1,
|
|
const ON_3dVector& Z1
|
|
);
|
|
|
|
// Parameters:
|
|
// P0 - initial frame center
|
|
// X0 - initial frame X
|
|
// Y0 - initial frame Y
|
|
// Z0 - initial frame Z
|
|
// P1 - initial frame center
|
|
// X1 - final frame X
|
|
// Y1 - final frame Y
|
|
// Z1 - final frame Z
|
|
void Rotation(
|
|
const ON_3dPoint& P0,
|
|
const ON_3dVector& X0,
|
|
const ON_3dVector& Y0,
|
|
const ON_3dVector& Z0,
|
|
const ON_3dPoint& P1,
|
|
const ON_3dVector& X1,
|
|
const ON_3dVector& Y1,
|
|
const ON_3dVector& Z1
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create rotation transformation that maps plane0 to plane1.
|
|
Parameters:
|
|
plane0 - [in]
|
|
plane1 - [in]
|
|
*/
|
|
void Rotation(
|
|
const ON_Plane& plane0,
|
|
const ON_Plane& plane1
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create rotation transformation From Tait-Byran angles (also loosely known as Euler angles).
|
|
Parameters:
|
|
yaw - angle (in radians) to rotate about the Z axis
|
|
pitch - angle (in radians) to rotate about the Y axis
|
|
roll - angle (in radians) to rotate about the X axis
|
|
Details:
|
|
RotationZYX(yaw, pitch, roll) = R_z( yaw) * R_y(pitch) * R_x(roll)
|
|
where R_*(angle) is rotation of angle radians about the corresponding world coordinate axis.
|
|
*/
|
|
void RotationZYX(double yaw, double pitch, double roll);
|
|
|
|
/*
|
|
Description:
|
|
Find the Tait-Byran angles (also loosely called Euler angles) for a rotation transformation.
|
|
Parameters:
|
|
yaw - angle (in radians) to rotate about the Z axis
|
|
pitch - angle (in radians) to rotate about the Y axis
|
|
roll - angle (in radians) to rotate about the X axis
|
|
Details:
|
|
When true is returned.
|
|
this = RotationZYX(yaw, pitch, roll) = R_z( yaw) * R_y(pitch) * R_x(roll)
|
|
where R_*(angle) is rotation of angle radians about the corresponding world coordinate axis.
|
|
Returns false if this is not a rotation.
|
|
Notes:
|
|
roll and yaw are in the range (-pi, pi] and pitch is in [-pi/2, pi/2]
|
|
|
|
*/
|
|
bool GetYawPitchRoll(double& yaw, double& pitch, double& roll)const;
|
|
|
|
/*
|
|
Description:
|
|
Find the Keyhole Markup Language (KML) orientation angles (in radians) of a rotation
|
|
transformation that maps model (east,north,up) to ((1,0,0),(0,1,0),(0,0,1)).
|
|
KML Earth Z axis = up, KML Earth X axis = east, KML Earth Y axis = north.
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
Parameters:
|
|
heading_radians - [out]
|
|
angle (in radians) of rotation around KML Earth Z axis (Earth up).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
tilt_radians - [out]
|
|
angle (in radians) of rotation around KML Earth X axis (Earth east).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
roll_radians - [out]
|
|
angle (in radians) of rotation around KML Earth Y axis (Earth north).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
Returns:
|
|
True if this transformation is a rotation and the KML angles are returned.
|
|
False if this transformation is not a rotation, in which case all returned
|
|
angle values are ON_DLB_QNAN.
|
|
See Also:
|
|
https://developers.google.com/kml/documentation/kmlreference#orientation
|
|
*/
|
|
bool GetKMLOrientationAnglesRadians(
|
|
double& heading_radians,
|
|
double& tilt_radians,
|
|
double& roll_radians
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Find the Keyhole Markup Language (KML) orientation angles (in degrees) of a rotation
|
|
transformation that maps model (east,north,up) to ((1,0,0),(0,1,0),(0,0,1)).
|
|
KML Earth Z axis = up, KML Earth X axis = east, KML Earth Y axis = north.
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
Parameters:
|
|
heading_degrees - [out]
|
|
angle (in degrees) of rotation around KML Earth Z axis (Earth up).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
tilt_degrees - [out]
|
|
angle (in degrees) of rotation around KML Earth X axis (Earth east).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
roll_degrees - [out]
|
|
angle (in degrees) of rotation around KML Earth Y axis (Earth north).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
Returns:
|
|
True if this transformation is a rotation and the KML angles are returned.
|
|
False if this transformation is not a rotation, in which case all returned
|
|
angle values are ON_DLB_QNAN.
|
|
See Also:
|
|
https://developers.google.com/kml/documentation/kmlreference#orientation
|
|
*/
|
|
bool GetKMLOrientationAnglesDegrees(
|
|
double& heading_degrees,
|
|
double& tilt_degrees,
|
|
double& roll_degrees
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Get a rotation transformation from the Keyhole Markup Language (KML) orientation angles in radians.
|
|
(KML Earth Z axis = up, KML Earth X axis = east, KML Earth Y axis = north).
|
|
KML rotations are applied in the following order: first roll, second tilt, third heading.
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
Parameters:
|
|
heading_radians - [in]
|
|
angle (in radians) of rotation around KML Earth Z axis (Earth up).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin.
|
|
If R = RotationTransformationFromKMLAnglesRadians(pi/2,0,0),
|
|
then R*(1,0,0) = (0,-1,0), R*(0,1,0) = (1,0,0), R*(0,0,1) = (0,0,1)
|
|
tilt_radians - [in]
|
|
angle (in radians) of rotation around KML Earth X axis (Earth east).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin.
|
|
If R = RotationTransformationFromKMLAnglesRadians(0,pi/2,0),
|
|
then R*(1,0,0) = (1,0,0), R*(0,1,0) = (0,0,-1), R*(0,0,1) = (0,1,0)
|
|
roll_radians - [in]
|
|
angle (in radians) of rotation around KML Earth Y axis (Earth north).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin.
|
|
If R = RotationTransformationFromKMLAnglesRadians(0,0,pi/2),
|
|
then R*(1,0,0) = (0,0,1), R*(0,1,0) = (0,1,0), R*(0,0,1) = (-1,0,0)
|
|
Returns:
|
|
If the input is valid, the rotation transformation is returned.
|
|
Otherwise the ON_Xform::Nan is returned.
|
|
See Also:
|
|
https://developers.google.com/kml/documentation/kmlreference#orientation
|
|
*/
|
|
static const ON_Xform RotationTransformationFromKMLAnglesRadians(
|
|
double heading_radians,
|
|
double tilt_radians,
|
|
double roll_radians
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Get a rotation transformation from the Keyhole Markup Language (KML) orientation angles in degrees.
|
|
(KML Earth Z axis = up, KML Earth X axis = east, KML Earth Y axis = north).
|
|
KML rotations are applied in the following order: first roll, second tilt, third heading.
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin. This is rotation direction
|
|
is opposite the conventional "right hand rule."
|
|
Parameters:
|
|
heading_degrees - [in]
|
|
angle (in degrees) of rotation around KML Earth Z axis (Earth up).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin.
|
|
If R = RotationTransformationFromKMLAnglesDegrees(90,0,0),
|
|
then R*(1,0,0) = (0,-1,0), R*(0,1,0) = (1,0,0), R*(0,0,1) = (0,0,1)
|
|
tilt_degrees - [in]
|
|
angle (in degrees) of rotation around KML Earth X axis (Earth east).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin.
|
|
If R = RotationTransformationFromKMLAnglesDegrees(0,90,0),
|
|
then R*(1,0,0) = (1,0,0), R*(0,1,0) = (0,0,-1), R*(0,0,1) = (0,1,0)
|
|
roll_degrees - [in]
|
|
angle (in degrees) of rotation around KML Earth Y axis (Earth north).
|
|
NOTE WELL: In KML, positive rotations are CLOCKWISE looking down
|
|
specified axis vector towards the origin.
|
|
If R = RotationTransformationFromKMLAnglesDegrees(0,0,90),
|
|
then R*(1,0,0) = (0,0,1), R*(0,1,0) = (0,1,0), R*(0,0,1) = (-1,0,0)
|
|
Returns:
|
|
If the input is valid, the rotation transformation is returned.
|
|
Otherwise the ON_Xform::Nan is returned.
|
|
See Also:
|
|
https://developers.google.com/kml/documentation/kmlreference#orientation
|
|
*/
|
|
static const ON_Xform RotationTransformationFromKMLAnglesDegrees(
|
|
double heading_degrees,
|
|
double tilt_degrees,
|
|
double roll_degrees
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Create rotation transformation From Euler angles.
|
|
Parameters:
|
|
alpha - angle (in radians) to rotate about the Z axis
|
|
beta - angle (in radians) to rotate about the Y axis
|
|
gamma - angle (in radians) to rotate about the Z axis
|
|
Details:
|
|
RotationZYZ(alpha, beta, gamma) = R_z( alpha) * R_y(beta) * R_z(gamma)
|
|
where R_*(angle) is rotation of angle radians about the corresponding *-world coordinate axis.
|
|
*/
|
|
void RotationZYZ(double alpha, double beta, double gamma);
|
|
|
|
/*
|
|
Description:
|
|
Find the Euler angles for a rotation transformation.
|
|
Parameters:
|
|
alpha - angle (in radians) to rotate about the Z axis
|
|
beta - angle (in radians) to rotate about the Y axis
|
|
gamma - angle (in radians) to rotate about the Z axis
|
|
Details:
|
|
When true is returned.
|
|
*this = RotationZYZ(alpha, beta, gamma) = R_z( alpha) * R_y(beta) * R_z(gamma)
|
|
where R_*(angle) is rotation of angle radians about the corresponding *-world coordinate axis.
|
|
Returns false if this is not a rotation.
|
|
Notes:
|
|
alpha and gamma are in the range (-pi, pi] while beta in in the range [0, pi]
|
|
*/
|
|
bool GetEulerZYZ(double& alpha, double& beta, double& gamma )const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Create mirror transformation matrix.
|
|
Parameters:
|
|
point_on_mirror_plane - [in] point on mirror plane
|
|
normal_to_mirror_plane - [in] normal to mirror plane
|
|
Remarks:
|
|
The mirror transform maps a point Q to
|
|
Q - (2*(Q-P)oN)*N, where
|
|
P = point_on_mirror_plane and N = normal_to_mirror_plane.
|
|
*/
|
|
void Mirror(
|
|
ON_3dPoint point_on_mirror_plane,
|
|
ON_3dVector normal_to_mirror_plane
|
|
);
|
|
|
|
static const ON_Xform MirrorTransformation(
|
|
ON_PlaneEquation mirror_plane
|
|
);
|
|
|
|
static const ON_Xform TextureMapping(const ON_3dVector& offset, const ON_3dVector& repeat, const ON_3dVector& rotation);
|
|
|
|
// Description: The ChangeBasis() function is overloaded
|
|
// and provides several
|
|
// ways to compute a change of basis transformation.
|
|
//
|
|
// Parameters:
|
|
// plane0 - initial plane
|
|
// plane1 - final plane
|
|
//
|
|
// Returns:
|
|
// @untitled table
|
|
// true success
|
|
// false vectors for initial frame are not a basis
|
|
//
|
|
// Remarks:
|
|
// If you have points defined with respect to planes, the
|
|
// version of ChangeBasis() that takes two planes computes
|
|
// the transformation to change coordinates from one plane to
|
|
// another. The predefined world plane ON_world_plane can
|
|
// be used as an argument.
|
|
//
|
|
// If P = plane0.Evaluate( a0,b0,c0 ) and
|
|
//
|
|
// (a1,b1,c1) = ChangeBasis(plane0,plane1)*ON_3dPoint(a0,b0,c0),
|
|
//
|
|
// then P = plane1.Evaluate( a1, b1, c1 )
|
|
//
|
|
// The version of ChangeBasis() that takes six vectors
|
|
// maps (a0,b0,c0) to (a1,b1,c1) where
|
|
// a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1
|
|
//
|
|
// The version of ChangeBasis() that takes six vectors
|
|
// with center points
|
|
// maps (a0,b0,c0) to (a1,b1,c1) where
|
|
// P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1
|
|
//
|
|
// The change of basis transformation is not the same as
|
|
// the rotation transformation that rotates one orthonormal
|
|
// frame to another. See ON_Xform::Rotation().
|
|
bool ChangeBasis(
|
|
const ON_Plane& plane0,
|
|
const ON_Plane& plane1
|
|
);
|
|
|
|
// Description:
|
|
// Get a change of basis transformation.
|
|
// Parameters:
|
|
// X0 - initial basis X (X0,Y0,Z0 can be any 3d basis)
|
|
// Y0 - initial basis Y
|
|
// Z0 - initial basis Z
|
|
// X1 - final basis X (X1,Y1,Z1 can be any 3d basis)
|
|
// Y1 - final basis Y
|
|
// Z1 - final basis Z
|
|
// Remarks:
|
|
// Change of basis transformations and rotation transformations
|
|
// are often confused. This is a change of basis transformation.
|
|
// If Q = a0*X0 + b0*Y0 + c0*Z0 = a1*X1 + b1*Y1 + c1*Z1
|
|
// then this transform will map the point (a0,b0,c0) to (a1,b1,c1)
|
|
bool ChangeBasis(
|
|
const ON_3dVector& X0,
|
|
const ON_3dVector& Y0,
|
|
const ON_3dVector& Z0,
|
|
const ON_3dVector& X1,
|
|
const ON_3dVector& Y1,
|
|
const ON_3dVector& Z1
|
|
);
|
|
|
|
// Parameters:
|
|
// P0 - initial center
|
|
// X0 - initial basis X (X0,Y0,Z0 can be any 3d basis)
|
|
// Y0 - initial basis Y
|
|
// Z0 - initial basis Z
|
|
// P1 - final center
|
|
// X1 - final basis X (X1,Y1,Z1 can be any 3d basis)
|
|
// Y1 - final basis Y
|
|
// Z1 - final basis Z
|
|
// Remarks:
|
|
// Change of basis transformations and rotation transformations
|
|
// are often confused. This is a change of basis transformation.
|
|
// If Q = P0 + a0*X0 + b0*Y0 + c0*Z0 = P1 + a1*X1 + b1*Y1 + c1*Z1
|
|
// then this transform will map the point (a0,b0,c0) to (a1,b1,c1)
|
|
bool ChangeBasis(
|
|
const ON_3dPoint& P0,
|
|
const ON_3dVector& X0,
|
|
const ON_3dVector& Y0,
|
|
const ON_3dVector& Z0,
|
|
const ON_3dPoint& P1,
|
|
const ON_3dVector& X1,
|
|
const ON_3dVector& Y1,
|
|
const ON_3dVector& Z1
|
|
);
|
|
|
|
// standard viewing transformations
|
|
void WorldToCamera(
|
|
const ON_3dPoint&, // CameraLocation
|
|
const ON_3dVector&, // unit CameraX vector (right)
|
|
const ON_3dVector&, // unit CameraY vector (up)
|
|
const ON_3dVector& // unit CameraZ vector (from screen to camera)
|
|
);
|
|
void CameraToWorld(
|
|
const ON_3dPoint&, // CameraLocation
|
|
const ON_3dVector&, // unit CameraX vector (right)
|
|
const ON_3dVector&, // unit CameraY vector (up)
|
|
const ON_3dVector& // unit CameraZ vector (from screen to camera)
|
|
);
|
|
bool CameraToClip( // maps viewport frustum to -1 <= x,y,z <= 1 box
|
|
bool bIsPerspective, // true for perspective, false for orthographic
|
|
double, double, // left != right (usually left < right )
|
|
double, double, // bottom != top (usually bottom < top )
|
|
double, double // near != far (usually 0 < near < far )
|
|
);
|
|
|
|
// maps -1 <= x,y,z <= 1 box to viewport frustum
|
|
bool ClipToCamera(
|
|
bool bIsPerspective, // true for perspective, false for orthographic
|
|
double, double, // left != right (usually left < right )
|
|
double, double, // bottom != top (usually bottom < top )
|
|
double, double // near != far an bot are non-zero (usually 0 < near < far )
|
|
);
|
|
|
|
// Computes transform that maps the clipping box
|
|
//
|
|
// -1<x<1,-1<y<1,-1<z<1
|
|
//
|
|
// to the screen box
|
|
//
|
|
// (left,right) X (bottom,top) X (near,far)
|
|
bool ClipToScreen(
|
|
double, // left
|
|
double, // right
|
|
double, // bottom
|
|
double, // top
|
|
double, // near_z
|
|
double // far_z
|
|
);
|
|
|
|
// Computes transform that maps the screen box
|
|
//
|
|
// (left,right) X (bottom,top) X (near,far)
|
|
//
|
|
// to the clipping box
|
|
//
|
|
// -1<x<1,-1<y<1,-1<z<1
|
|
bool ScreenToClip(
|
|
double, // left
|
|
double, // right
|
|
double, // bottom
|
|
double, // top
|
|
double, // near_z
|
|
double // far_z
|
|
);
|
|
|
|
// Description: Computes homogeneous point clipping flags and
|
|
// returns an int with bits set to indicate if the point
|
|
// is outside of the clipping box.
|
|
//
|
|
// Parameters:
|
|
// point - [in] 4d homogeneous clipping coordinate point
|
|
//
|
|
// Returns:
|
|
// @table
|
|
// bit point location
|
|
// 1 x/w < -1
|
|
// 2 x/w > +1
|
|
// 4 y/w < -1
|
|
// 8 y/w > +1
|
|
// 16 z/w < -1
|
|
// 32 z/w > +1
|
|
//
|
|
int ClipFlag4d(
|
|
const double* // point
|
|
) const;
|
|
|
|
// Parameters:
|
|
// count - [in] number of 4d points
|
|
// stride - [in] (>=4)
|
|
// points - [in] 4d clipping coordinate points
|
|
// (array of stride*count doubles)
|
|
// bTestZ - [in] (default=true) if false, do not test "z" coordinate
|
|
//
|
|
int ClipFlag4d(
|
|
int, // count
|
|
int, // stride
|
|
const double*, // points
|
|
bool bTestZ = true // bTeztZ
|
|
) const;
|
|
|
|
// Description:
|
|
// Computes 3d point clipping flags and
|
|
// returns an int with bits set to indicate if the point
|
|
// is outside of the clipping box.
|
|
//
|
|
// Parameters:
|
|
// point - [in] 3d clipping coordinate point
|
|
//
|
|
// Returns:
|
|
// @table
|
|
// bit point location
|
|
// 1 x < -1
|
|
// 2 x > +1
|
|
// 4 y < -1
|
|
// 8 y > +1
|
|
// 16 z < -1
|
|
// 32 z > +1
|
|
int ClipFlag3d(
|
|
const double* // point
|
|
) const;
|
|
|
|
// Parameters:
|
|
// count - [in] number of 3d points
|
|
// stride - [in] (>=3)
|
|
// points - [in] 3d clipping coordinate points (array of stride*count doubles)
|
|
// bTestZ - [in] (default=true) if false, do not test "z" coordinate
|
|
//
|
|
int ClipFlag3d(
|
|
int, // count
|
|
int, // stride
|
|
const double*, // points
|
|
bool bTestZ = true // bTestZ
|
|
) const;
|
|
|
|
// Description: Computes 3d clipping flags for a 3d bounding
|
|
// box and returns an int with bits set to indicate if
|
|
// the bounding box is outside of the clipping box.
|
|
//
|
|
// Parameters:
|
|
// boxmin - [in] 3d boxmin corner
|
|
// boxmax - [in] 3d boxmax corner
|
|
//
|
|
// Returns:
|
|
// @table
|
|
// bit box location
|
|
// 1 boxmax x < -1
|
|
// 2 boxmin x > +1
|
|
// 4 boxmax y < -1
|
|
// 8 boxmin y > +1
|
|
// 16 boxmax z < -1
|
|
// 32 boxmin z > +1
|
|
int ClipFlag3dBox(
|
|
const double*, // boxmin
|
|
const double* // boxmax
|
|
) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Calculates the transformation that linearly maps
|
|
old_interval to new_interval.
|
|
Parameters:
|
|
dir - [in] 0 = x, 1 = y, 2= z;
|
|
old_interval - [in]
|
|
new_interval - [in]
|
|
*/
|
|
bool IntervalChange(
|
|
int dir,
|
|
ON_Interval old_interval,
|
|
ON_Interval new_interval
|
|
);
|
|
};
|
|
|
|
ON_DECL
|
|
const ON_Xform operator*(double c, const ON_Xform& xform);
|
|
|
|
ON_DECL
|
|
const ON_Xform operator*(const ON_Xform& xform, double c);
|
|
|
|
class ON_CLASS ON_ClippingRegion
|
|
{
|
|
public:
|
|
ON_ClippingRegion();
|
|
|
|
/*
|
|
Description:
|
|
Sets the object to clip transformation to
|
|
the viewport's workd to clip transformation.
|
|
*/
|
|
bool SetObjectToClipTransformation(
|
|
const class ON_Viewport& viewport
|
|
);
|
|
|
|
bool SetObjectToClipTransformation(
|
|
const ON_Xform object_to_clip_transformation
|
|
);
|
|
|
|
ON_Xform ObjectToClipTransformation() const;
|
|
ON_Xform InverseObjectToClipTransformation() const;
|
|
|
|
private:
|
|
// The transformation m_xform transforms the view frustum,
|
|
// in object coordinates to the (-1,+1)^3 clipping
|
|
// coordinate box.
|
|
ON_Xform m_xform;
|
|
mutable ON_Xform m_inverse_xform; // = m_xform.Inverse().
|
|
|
|
public:
|
|
/*
|
|
Parameters:
|
|
clip_plane_tolerance - [in]
|
|
3d world coordinates tolerance to use when testing
|
|
objects to see if the planes in m_clip_plane[] hide
|
|
the objects.
|
|
Remarks:
|
|
The constructor sets this value to zero. Rhino uses
|
|
values around 1e-5.
|
|
*/
|
|
void SetClipPlaneTolerance( double clip_plane_tolerance );
|
|
|
|
/*
|
|
Returns:
|
|
3d world coordinates tolerance to use when testing
|
|
objects to see if the planes in m_clip_plane[] hide
|
|
the objects.
|
|
Remarks:
|
|
The constructor sets this value to zero. Rhino uses
|
|
values around 1e-5.
|
|
*/
|
|
double ClipPlaneTolerance() const;
|
|
|
|
enum
|
|
{
|
|
max_clip_plane_count = 16, // must be <= 25
|
|
frustum_bitmask = 0x0000003F,
|
|
near_plane_bitmask = 0x00000020,
|
|
far_plane_bitmask = 0x00000010,
|
|
clip_plane_bitmask = 0x7FFFFFC0,
|
|
negw_bitmask = 0x80000000
|
|
};
|
|
|
|
// Up to 25 additional clipping planes in object coordinates.
|
|
// The convex region that is the intersection of the positive
|
|
// side of these planes is the active region.
|
|
int m_clip_plane_count; // (0 <= m_clip_plane_count <= max_clip_plane_count)
|
|
|
|
private:
|
|
double m_clip_plane_tolerance;
|
|
|
|
public:
|
|
ON_PlaneEquation m_clip_plane[max_clip_plane_count];
|
|
|
|
/*
|
|
Description:
|
|
The "view frustum" is the frustum the m_xform transformation
|
|
maps to clipping coordinate box (-1,+1)^3. These functions
|
|
determine if some portion of the convex hull of the test points
|
|
is inside the view frustum.
|
|
Parameters:
|
|
P - [in] point
|
|
box - [in] bounding box
|
|
count - [in] number of points
|
|
p - [in] array of points
|
|
bEnableClippingPlanes - [in]
|
|
If true, then the additional clipping planes are tested.
|
|
If false, then the additional clipping planes are ignored.
|
|
Returns:
|
|
0 = No part of the of the convex hull of the tested points
|
|
is in the view frustum.
|
|
1 = A portion of the convex hull of the otested points may
|
|
be in the view frustum.
|
|
2 = The entire convex hull of the tested points is in the
|
|
view frustum.
|
|
*/
|
|
int InViewFrustum(
|
|
ON_3dPoint P
|
|
) const;
|
|
int InViewFrustum(
|
|
const ON_BoundingBox& bbox
|
|
) const;
|
|
int InViewFrustum(
|
|
int count,
|
|
const ON_3fPoint* p
|
|
) const;
|
|
int InViewFrustum(
|
|
int count,
|
|
const ON_3dPoint* p
|
|
) const;
|
|
int InViewFrustum(
|
|
int count,
|
|
const ON_4dPoint* p
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
The "clip plane region" is the convex hull of the planes in
|
|
the m_clip_plane[] array. These functions determine if
|
|
some portion of the convex hull of the test points is inside
|
|
the clip plane region.
|
|
Parameters:
|
|
P - [in] point
|
|
box - [in] bounding box
|
|
count - [in] number of points
|
|
p - [in] array of points
|
|
bEnableClippingPlanes - [in]
|
|
If true, then the additional clipping planes are tested.
|
|
If false, then the additional clipping planes are ignored.
|
|
Returns:
|
|
0 = No part of the of the convex hull of the tested points
|
|
is in the clip plane region.
|
|
1 = A portion of the convex hull of the tested points may
|
|
be in the clip plane region.
|
|
2 = The entire convex hull of the tested points is in the
|
|
clip plane region.
|
|
*/
|
|
int InClipPlaneRegion(
|
|
ON_3dPoint P
|
|
) const;
|
|
int InClipPlaneRegion(
|
|
const ON_BoundingBox& bbox
|
|
) const;
|
|
int InClipPlaneRegion(
|
|
int count,
|
|
const ON_3fPoint* p
|
|
) const;
|
|
int InClipPlaneRegion(
|
|
int count,
|
|
const ON_3dPoint* p
|
|
) const;
|
|
int InClipPlaneRegion(
|
|
int count,
|
|
const ON_4dPoint* p
|
|
) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
The "visible area" is the intersection of the view frustum,
|
|
defined by m_xform, and the clipping region, defined by the
|
|
m_clip_plane[] array. These functions determing if some
|
|
portion of the convex hull of the test points is visible.
|
|
Parameters:
|
|
P - [in] point
|
|
box - [in] bounding box
|
|
count - [in] number of points
|
|
p - [in] array of points
|
|
Returns:
|
|
0 = no part of the object is in the region.
|
|
1 = a portion of the object is in the region
|
|
2 = entire object is in clipping region
|
|
*/
|
|
int IsVisible(
|
|
ON_3dPoint P
|
|
) const;
|
|
int IsVisible(
|
|
const ON_BoundingBox& bbox
|
|
) const;
|
|
int IsVisible(
|
|
int count,
|
|
const ON_3fPoint* p
|
|
) const;
|
|
int IsVisible(
|
|
int count,
|
|
const ON_3dPoint* p
|
|
) const;
|
|
int IsVisible(
|
|
int count,
|
|
const ON_4dPoint* p
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Transform a list of 4d homogeneous points while testing
|
|
for visibility.
|
|
Parameters:
|
|
count - [in] number of points
|
|
p - [in/out] array of points to test and transform
|
|
If 0 is returned, some of the points may not
|
|
be transformed. In all other cases, the output
|
|
points are transformed by m_xform.
|
|
pflags - [out]
|
|
0 when the point is in the visible region.
|
|
Otherwise the bits are set to indicate which planes clip the
|
|
input point.
|
|
0x01 left of the view frusturm
|
|
0x02 right of the view frustum
|
|
0x04 below the view frustum
|
|
0x08 above the view frustum
|
|
0x10 behind the view frustum (too far)
|
|
0x20 in front of the view frustum (too near)
|
|
|
|
0x10 below m_clip_plane[0]
|
|
0x20 below m_clip_plane[1]
|
|
...
|
|
0x40000000 below m_clip_plane[24]
|
|
|
|
0x80000000 transformation created a non-positive weight
|
|
Returns:
|
|
0 = convex hull of the points is not in the region.
|
|
The m_cull_bits field reports which plane or planes
|
|
culled the point set.
|
|
1 = a portion of the convex hull is in the region.
|
|
The m_cull_bits field reports which plane or planes
|
|
culled the point set.
|
|
2 = all points are in the region.
|
|
The m_cull_bits field will be zero.
|
|
*/
|
|
int TransformPoints( int count, ON_4dPoint* p ) const;
|
|
int TransformPoints( int count, ON_4dPoint* p, unsigned int* pflags ) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Transform a point and return the clipping information.
|
|
Parameters:
|
|
P - [in] point ot transform
|
|
Q - [out] transformed point
|
|
Returns:
|
|
0 when the point is in the visible region.
|
|
Otherwise the bits are set to indicate which planes clip the
|
|
input point.
|
|
0x01 left of the view frusturm
|
|
0x02 right of the view frustum
|
|
0x04 below the view frustum
|
|
0x08 above the view frustum
|
|
0x10 behind the view frustum (too far)
|
|
0x20 in front of the view frustum (too near)
|
|
|
|
0x10 below m_clip_plane[0]
|
|
0x20 below m_clip_plane[1]
|
|
...
|
|
0x40000000 below m_clip_plane[24]
|
|
|
|
0x80000000 transformation created a non-positive weight
|
|
*/
|
|
unsigned int TransformPoint(
|
|
const ON_4dPoint& P,
|
|
ON_4dPoint& Q
|
|
) const;
|
|
unsigned int TransformPoint(
|
|
const ON_3dPoint& P,
|
|
ON_3dPoint& Q
|
|
) const;
|
|
unsigned int TransformPoint(
|
|
const ON_3fPoint& P,
|
|
ON_3dPoint& Q
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Calculate the interval for the segment of a line that
|
|
is in the clip plane region.
|
|
Parameters:
|
|
P0 - [in] start point
|
|
P1 - [in] end point
|
|
t0 - [out] start parameter
|
|
t1 - [out] end parameter
|
|
Returns:
|
|
True if some portion of the line is visible and
|
|
0.0 <= *t0 <= *t1 <= 1.0.
|
|
*/
|
|
bool GetLineClipPlaneParamters(
|
|
ON_4dPoint P0,
|
|
ON_4dPoint P1,
|
|
double* t0,
|
|
double* t1
|
|
) const;
|
|
|
|
};
|
|
|
|
/*
|
|
Description:
|
|
ON_ClippingRegionPoints is a container for storing or referencing
|
|
clip points and clip flags.
|
|
The values are typically calculated by ON_ClippingRegion.TransformPoint().
|
|
*/
|
|
class ON_CLASS ON_ClippingRegionPoints
|
|
{
|
|
public:
|
|
static const ON_ClippingRegionPoints Empty;
|
|
|
|
ON_ClippingRegionPoints() = default;
|
|
~ON_ClippingRegionPoints();
|
|
ON_ClippingRegionPoints(const ON_ClippingRegionPoints& src);
|
|
ON_ClippingRegionPoints& operator=(const ON_ClippingRegionPoints& src);
|
|
|
|
#if defined(ON_HAS_RVALUEREF)
|
|
// rvalue copy constructor
|
|
ON_ClippingRegionPoints( ON_ClippingRegionPoints&& ) ON_NOEXCEPT;
|
|
|
|
// The rvalue assignment operator calls ON_Object::operator=(ON_Object&&)
|
|
// which could throw exceptions. See the implementation of
|
|
// ON_Object::operator=(ON_Object&&) for details.
|
|
ON_ClippingRegionPoints& operator=( ON_ClippingRegionPoints&& );
|
|
#endif
|
|
|
|
unsigned int PointCapacity() const;
|
|
|
|
unsigned int PointCout() const;
|
|
|
|
/*
|
|
Description:
|
|
Sets point count and aggregate flags falues to zero but does not
|
|
deallocate the memory buffer. When an ON_ClippingRegionPoints will be used
|
|
multiple times, it is more efficient to call Clear() between
|
|
uses than calling Destroy().
|
|
*/
|
|
void Clear();
|
|
|
|
/*
|
|
Description:
|
|
Clear() and deallocate the memory buffer.
|
|
*/
|
|
void Destroy();
|
|
|
|
/*
|
|
Returns:
|
|
Clip point location.
|
|
*/
|
|
ON_3dPoint ClipPoint(
|
|
unsigned int point_index
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Clip flag
|
|
*/
|
|
unsigned int ClipFlag(
|
|
unsigned int point_index
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Append the clipping point and clipping flag calculated by
|
|
clipping_region.TransformPoint(world_point,...).
|
|
*/
|
|
bool AppendClipPoint(
|
|
const class ON_ClippingRegion& clipping_region,
|
|
ON_3dPoint world_point
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Append the clipping points and clipping flags calculated by
|
|
clipping_region.TransformPoint(world_point,...) for every input
|
|
world point.
|
|
*/
|
|
bool AppendClipPoints(
|
|
const class ON_ClippingRegion& clipping_region,
|
|
const ON_SimpleArray<ON_3dPoint>& world_points
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Append the clipping points and clipping flags calculated by
|
|
clipping_region.TransformPoint(world_point,...) for every input
|
|
world point.
|
|
*/
|
|
bool AppendClipPoints(
|
|
const class ON_ClippingRegion& clipping_region,
|
|
size_t world_point_count,
|
|
const ON_3dPoint* world_points
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Append the clipping points and clipping flags calculated by
|
|
clipping_region.TransformPoint(world_point,...) for every input
|
|
world point.
|
|
*/
|
|
bool AppendClipPoints(
|
|
const class ON_ClippingRegion& clipping_region,
|
|
size_t world_point_count,
|
|
size_t world_point_stride,
|
|
const double* world_points
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Append the clipping point and clipping flag value.
|
|
*/
|
|
bool AppendClipPoint(
|
|
ON_3dPoint clip_point,
|
|
unsigned int clip_flag
|
|
);
|
|
|
|
public:
|
|
// These functions and data members are public so they can be used
|
|
// by experts to reference information that is managed by other entities.
|
|
// If you access or modify them, you are responsible for making
|
|
// sure you do it correctly. All the interface functions above
|
|
// assume the values below are correctly set.
|
|
|
|
/*
|
|
Reserve buffer capacity.
|
|
*/
|
|
bool ReserveBufferPointCapacity(
|
|
size_t buffer_point_capacity
|
|
);
|
|
|
|
// All the information below is automatically managed if you use
|
|
// the AppendClipPoint() or AppendClipPoints() functions to add
|
|
// clipping points.
|
|
unsigned int m_point_count = 0;
|
|
unsigned int m_point_capacity = 0;
|
|
ON_3dPoint* m_clip_points = nullptr;
|
|
unsigned int* m_clip_flags = nullptr;
|
|
|
|
unsigned int m_and_clip_flags = 0;
|
|
unsigned int m_or_clip_flags = 0;
|
|
|
|
private:
|
|
size_t m_buffer_point_capacity = 0;
|
|
void* m_buffer = nullptr;
|
|
};
|
|
|
|
#pragma region
|
|
/// <summary>
|
|
/// ON_PickType specifies what type of pick is occurring.
|
|
/// </summary>
|
|
enum class ON_PickType : unsigned char
|
|
{
|
|
///<summary>
|
|
/// Type has not been set.
|
|
///</summary>
|
|
Unset = 0,
|
|
|
|
///<summary>
|
|
/// A point pick is centered on a ray in the view frustum.
|
|
/// Often the pick region is a small frustum centered on the pick
|
|
/// ray defined by a mouse click in viewport. The size of the
|
|
/// frustum is typically a few pixels in diameter at the most
|
|
/// likely depth the user is focused on. An object must intersect
|
|
/// the pick region for it to be considered.
|
|
///</summary>
|
|
PointPick = 1,
|
|
|
|
///<summary>
|
|
/// The pick region for a window pick is a rectangular frustum inside
|
|
/// the view frustum. An object must be completely inside the frustum
|
|
/// for it to be considered.
|
|
/// The pick frustum is defined by a rectangle in the view plane.
|
|
/// The size of the rectangle has varies widely in aspect and size.
|
|
///</summary>
|
|
WindowPick = 2,
|
|
|
|
///<summary>
|
|
/// The pick region for a crossing pick is a rectangular frustum inside
|
|
/// the view frustum. An object must intersect the frustum
|
|
/// for it to be considered.
|
|
/// The pick frustum is defined by a rectangle in the view plane.
|
|
/// The size of the rectangle has varies widely in aspect and size.
|
|
///</summary>
|
|
CrossingPick = 3
|
|
};
|
|
#pragma endregion
|
|
|
|
class ON_CLASS ON_PickPoint
|
|
{
|
|
public:
|
|
static const ON_PickPoint Unset;
|
|
|
|
ON_PickPoint() = default;
|
|
~ON_PickPoint() = default;
|
|
ON_PickPoint(const ON_PickPoint&)= default;
|
|
ON_PickPoint& operator=(const ON_PickPoint&) = default;
|
|
|
|
/*
|
|
Returns:
|
|
+1: a is a better pick point than b.
|
|
-1: b is a better pick point than a.
|
|
0: a and b are the same.
|
|
*/
|
|
static int Compare(
|
|
const ON_PickPoint& a,
|
|
const ON_PickPoint& b
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
True if this is set.
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if this is not set.
|
|
*/
|
|
bool IsNotSet() const;
|
|
|
|
ON_3dPoint m_point = ON_3dPoint::UnsetPoint;
|
|
double m_t[4] = {}; // parameters (When m_point is set, unused values are set to ON_UNSET_VALUE.)
|
|
double m_depth = ON_UNSET_VALUE; // larger values are in front of smaller values.
|
|
double m_distance = 1.0e300; // smaller values are closer to pick ray.
|
|
};
|
|
|
|
class ON_CLASS ON_Localizer
|
|
{
|
|
public:
|
|
ON_Localizer();
|
|
~ON_Localizer();
|
|
|
|
ON_Localizer(const ON_Localizer&);
|
|
ON_Localizer& operator=(const ON_Localizer&);
|
|
|
|
void Destroy();
|
|
bool Read(ON_BinaryArchive&);
|
|
bool Write(ON_BinaryArchive&) const;
|
|
|
|
/*
|
|
Description:
|
|
Creates a cylindrical localizer.
|
|
If d = distance from the point to the line,
|
|
then the localizer has the following behavior:
|
|
|
|
point distance localizer value
|
|
d <= r0 < r1 or d >= r0 > r1 0
|
|
d >= r1 > r0 or d <= r1 < r0 1
|
|
|
|
For values of d between r0 and r1, the localizer
|
|
smoothly transitions between 0 to 1.
|
|
|
|
Parameters:
|
|
P - [in] cylinder axis point
|
|
D - [in] cylinder axis direction
|
|
r0 - [in]
|
|
r1 - [in]
|
|
r0 and r1 are radii that control where the localizer is nonzero.
|
|
Both r0 and r1 must be positive and the cannot be equal.
|
|
If 0 < r0 < r1, then the localizer is zero for points
|
|
inside the cylinder of radius r0 and one for points outside
|
|
the cylinder of radius r1.
|
|
If 0 < r1 < r0, then the localizer is one for points
|
|
inside the cylinder of radius r1 and zero for points outside
|
|
the cylinder of radius r0.
|
|
|
|
Returns:
|
|
True if the input is value and the localizer is initialized.
|
|
*/
|
|
bool CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector D, double r0, double r1 );
|
|
|
|
/*
|
|
Description:
|
|
Creates a planar localizer.
|
|
If d = signed distance from the point to the plane,
|
|
then the localizer has the following behavior:
|
|
|
|
point distance localizer value
|
|
d <= h0 < h1 or d >= h0 > h1 0
|
|
d >= h1 > h0 or d <= h1 < h0 1
|
|
|
|
For values of d between h0 and h1, the localizer
|
|
smoothly transitions between 0 to 1.
|
|
|
|
Parameters:
|
|
P - [in] point on plane
|
|
N - [in] normal to plane
|
|
h0 - [in]
|
|
h1 - [in]
|
|
h0 and h1 are signed distances that control where the
|
|
localizer is nonzero.
|
|
|
|
Returns:
|
|
True if the input is value and the localizer is initialized.
|
|
*/
|
|
bool CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 );
|
|
|
|
/*
|
|
Description:
|
|
Creates a spherical localizer.
|
|
If d = distance from the point to the center of the sphere,
|
|
then the localizer has the following behavior:
|
|
|
|
point distance localizer value
|
|
d <= r0 < r1 or d >= r0 > r1 0
|
|
d >= r1 > r0 or d <= r1 < r0 1
|
|
|
|
For values of d between r0 and r1, the localizer
|
|
smoothly transitions between 0 to 1.
|
|
|
|
Parameters:
|
|
P - [in] center of sphere
|
|
r0 - [in]
|
|
r1 - [in]
|
|
r0 and r1 are radii that control where the localizer is nonzero.
|
|
Both r0 and r1 must be positive and the cannot be equal.
|
|
If 0 < r0 < r1, then the localizer is zero for points
|
|
inside the cylinder of radius r0 and one for points outside
|
|
the cylinder of radius r1.
|
|
If 0 < r1 < r0, then the localizer is one for points
|
|
inside the cylinder of radius r1 and zero for points outside
|
|
the cylinder of radius r0.
|
|
|
|
Returns:
|
|
True if the input is value and the localizer is initialized.
|
|
*/
|
|
bool CreateSphereLocalizer( ON_3dPoint P, double r0, double r1 );
|
|
|
|
/*
|
|
Description:
|
|
Evaluators.
|
|
Parameters:
|
|
P - [in]
|
|
Evaluation point
|
|
distance - [in]
|
|
Evaluation distance
|
|
Returns:
|
|
Value of the localizer.
|
|
*/
|
|
double Value(ON_3dPoint P) const;
|
|
double Value(double distance) const;
|
|
|
|
/*
|
|
Parameters:
|
|
bbox - [in]
|
|
Returns:
|
|
True if localizer is identically zero inside bbox.
|
|
*/
|
|
bool IsZero( const ON_BoundingBox& bbox ) const;
|
|
|
|
enum TYPE
|
|
{
|
|
no_type = 0,
|
|
sphere_type = 1,
|
|
plane_type = 2,
|
|
cylinder_type = 3,
|
|
curve_type = 4,
|
|
surface_type = 5,
|
|
distance_type = 6,
|
|
force_32bit_localizer_type = 0xFFFFFFFF
|
|
};
|
|
|
|
TYPE m_type;
|
|
|
|
ON_Interval m_d;
|
|
ON_3dPoint m_P;
|
|
ON_3dVector m_V;
|
|
class ON_NurbsCurve* m_nurbs_curve;
|
|
class ON_NurbsSurface* m_nurbs_surface;
|
|
};
|
|
|
|
|
|
class ON_CLASS ON_SpaceMorph
|
|
{
|
|
public:
|
|
ON_SpaceMorph();
|
|
virtual ~ON_SpaceMorph();
|
|
|
|
|
|
/*
|
|
Description:
|
|
Provides a quick way to determine if a morph function
|
|
is the identity (doesn't move the points) on a region
|
|
of space.
|
|
Parameters:
|
|
bbox - [in] region of space to test.
|
|
Returns:
|
|
The default always returns false. If you override
|
|
this function, then return true when every point
|
|
in the bounding box is fixed by the morph.
|
|
*/
|
|
virtual
|
|
bool IsIdentity( const ON_BoundingBox& bbox ) const;
|
|
|
|
/*
|
|
Description:
|
|
A slower way to determine if a morph function
|
|
is the identity (doesn't move the points) on a set of points, to within a tolerance
|
|
Parameters:
|
|
Points - [in] Set of points to test.
|
|
tol - [in] Distance tolerance.
|
|
Returns:
|
|
True if none of the points move a distance of tol or more under the morph function.
|
|
Uses MorphPoint()
|
|
*/
|
|
bool IsIdentity(const ON_SimpleArray<ON_3dPoint>& Points, double tol) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
A slower way to determine if a morph function
|
|
is the identity (doesn't move the points) on a surface, to within a tolerance
|
|
Parameters:
|
|
Srf - [in] Surface to be tested.
|
|
tol - [in] Distance tolerance.
|
|
Returns:
|
|
Uses MorphPoint() on a dense sample of points.
|
|
True if none of the points move a distance of tol or more under the morph function.
|
|
Remark:
|
|
Call IsIdentity(Srf.BoundingBox()) first.
|
|
Use this on surfaces whose nurb form is rational or has a different parameterization.
|
|
*/
|
|
bool IsIdentity(const class ON_Surface& Srf, double tol) const;
|
|
|
|
/*
|
|
Description:
|
|
A slower way to determine if a morph function
|
|
is the identity (doesn't move the points) on a curve, to within a tolerance.
|
|
Parameters:
|
|
Crv - [in] Curve to be tested.
|
|
tol - [in] Distance tolerance.
|
|
Returns:
|
|
Uses MorphPoint() on a dense sample of points.
|
|
True if none of the points move a distance of tol or more under the morph function.
|
|
Remark:
|
|
Call IsIdentity(Crv.BoundingBox()) first.
|
|
Use this on curves whose nurb form is rational or has a different parameterization.
|
|
*/
|
|
bool IsIdentity(const class ON_Curve& Crv, double tol) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Returns the desired accuracy of the morph.
|
|
This value is primarily used for deforming
|
|
surfaces and breps.
|
|
Returns:
|
|
3d fitting tolerance.
|
|
Remarks:
|
|
The default is 0.0 and any value <= 0.0 is
|
|
ignored by morphing functions.
|
|
The value returned by Tolerance() does not
|
|
affect the way meshes and points are morphed.
|
|
*/
|
|
double Tolerance() const;
|
|
|
|
/*
|
|
Description:
|
|
Set the 3d fitting tolerance used when morphing
|
|
surfaces and breps.
|
|
Parameters:
|
|
tolerance - [in] values < 0.0 are treated as 0.0.
|
|
*/
|
|
void SetTolerance(
|
|
double tolerance
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
True if the morph should be done as quickly as
|
|
possible because the result is being used for
|
|
some type of dynamic preview. If QuickPreview
|
|
is true, the tolerance may be ignored.
|
|
Remarks:
|
|
The value returned by QuickPreview() does not
|
|
affect the way meshes and points are morphed.
|
|
The default is false.
|
|
*/
|
|
bool QuickPreview() const;
|
|
|
|
/*
|
|
Description:
|
|
Set the quick preview value.
|
|
Parameters:
|
|
bQuickPreview - [in]
|
|
*/
|
|
void SetQuickPreview(
|
|
bool bQuickPreview
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
True if the morph should be done in a way that
|
|
preserves the structure of the geometry.
|
|
In particular, for NURBS objects, true
|
|
means that only the control points are moved.
|
|
Remarks:
|
|
The value returned by PreserveStructure() does not
|
|
affect the way meshes and points are morphed.
|
|
The default is false.
|
|
*/
|
|
bool PreserveStructure() const;
|
|
|
|
/*
|
|
Description:
|
|
Set the preserve structure value.
|
|
Parameters:
|
|
bPreserveStructure - [in]
|
|
*/
|
|
void SetPreserveStructure(
|
|
bool bPreserveStructure
|
|
);
|
|
|
|
private:
|
|
double m_tolerance = 0.0;
|
|
ON__UINT_PTR m_reserved1 = 0; // Some reserved field could provide more Morph type information. RH-4091
|
|
unsigned int m_reserved2 = 0;
|
|
bool m_bQuickPreview = false;
|
|
bool m_bPreserveStructure = false;
|
|
char m_reserved3 = 0;
|
|
char m_reserved4 = 0;
|
|
};
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Xform>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_Localizer>;
|
|
#endif
|
|
|
|
#endif
|