mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-21 10:13:43 +03:00
On Apple with XCode 9.4.1 and onwards, the compiler optimization is disabled for method gp_Mat::Transpose() as optimizer generates invalid code when that method is used. Some refactoring of the code affected by this bug.
356 lines
9.0 KiB
Plaintext
356 lines
9.0 KiB
Plaintext
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <gp.hxx>
|
|
#include <Standard_OutOfRange.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
|
|
#define Mat00 matrix[0][0]
|
|
#define Mat01 matrix[0][1]
|
|
#define Mat02 matrix[0][2]
|
|
#define Mat10 matrix[1][0]
|
|
#define Mat11 matrix[1][1]
|
|
#define Mat12 matrix[1][2]
|
|
#define Mat20 matrix[2][0]
|
|
#define Mat21 matrix[2][1]
|
|
#define Mat22 matrix[2][2]
|
|
|
|
#define Nat00 NewMat.matrix[0][0]
|
|
#define Nat01 NewMat.matrix[0][1]
|
|
#define Nat02 NewMat.matrix[0][2]
|
|
#define Nat10 NewMat.matrix[1][0]
|
|
#define Nat11 NewMat.matrix[1][1]
|
|
#define Nat12 NewMat.matrix[1][2]
|
|
#define Nat20 NewMat.matrix[2][0]
|
|
#define Nat21 NewMat.matrix[2][1]
|
|
#define Nat22 NewMat.matrix[2][2]
|
|
|
|
#define Oat00 Other.matrix[0][0]
|
|
#define Oat01 Other.matrix[0][1]
|
|
#define Oat02 Other.matrix[0][2]
|
|
#define Oat10 Other.matrix[1][0]
|
|
#define Oat11 Other.matrix[1][1]
|
|
#define Oat12 Other.matrix[1][2]
|
|
#define Oat20 Other.matrix[2][0]
|
|
#define Oat21 Other.matrix[2][1]
|
|
#define Oat22 Other.matrix[2][2]
|
|
|
|
inline gp_Mat::gp_Mat () {
|
|
Mat00 =
|
|
Mat01 =
|
|
Mat02 =
|
|
Mat10 =
|
|
Mat11 =
|
|
Mat12 =
|
|
Mat20 =
|
|
Mat21 =
|
|
Mat22 = 0.0;
|
|
}
|
|
|
|
inline gp_Mat::gp_Mat (const Standard_Real a11,
|
|
const Standard_Real a12,
|
|
const Standard_Real a13,
|
|
const Standard_Real a21,
|
|
const Standard_Real a22,
|
|
const Standard_Real a23,
|
|
const Standard_Real a31,
|
|
const Standard_Real a32,
|
|
const Standard_Real a33) {
|
|
|
|
Mat00 = a11;
|
|
Mat01 = a12;
|
|
Mat02 = a13;
|
|
Mat10 = a21;
|
|
Mat11 = a22;
|
|
Mat12 = a23;
|
|
Mat20 = a31;
|
|
Mat21 = a32;
|
|
Mat22 = a33;
|
|
}
|
|
|
|
inline void gp_Mat::SetDiagonal (const Standard_Real X1,
|
|
const Standard_Real X2,
|
|
const Standard_Real X3)
|
|
{
|
|
Mat00 = X1; Mat11 = X2; Mat22 = X3;
|
|
}
|
|
|
|
inline void gp_Mat::SetIdentity ()
|
|
{
|
|
Mat00 = Mat11 = Mat22 = 1.0;
|
|
Mat01 = Mat02 = Mat10 = Mat12 = Mat20 = Mat21 = 0.0;
|
|
}
|
|
|
|
inline void gp_Mat::SetScale (const Standard_Real S)
|
|
{
|
|
Mat00 = Mat11 = Mat22 = S;
|
|
Mat01 = Mat02 = Mat10 = Mat12 = Mat20 = Mat21 = 0.0;
|
|
}
|
|
|
|
inline void gp_Mat::SetValue (const Standard_Integer Row,
|
|
const Standard_Integer Col,
|
|
const Standard_Real Value)
|
|
{
|
|
Standard_OutOfRange_Raise_if
|
|
(Row < 1 || Row > 3 || Col < 1 || Col > 3, " ");
|
|
matrix[Row-1][Col-1] = Value;
|
|
}
|
|
|
|
inline Standard_Real gp_Mat::Determinant () const
|
|
{
|
|
return
|
|
Mat00 * (Mat11 * Mat22 - Mat21 * Mat12) -
|
|
Mat01 * (Mat10 * Mat22 - Mat20 * Mat12) +
|
|
Mat02 * (Mat10 * Mat21 - Mat20 * Mat11);
|
|
}
|
|
|
|
inline const Standard_Real& gp_Mat::Value (const Standard_Integer Row,
|
|
const Standard_Integer Col) const
|
|
{
|
|
Standard_OutOfRange_Raise_if
|
|
(Row < 1 || Row > 3 || Col < 1 || Col > 3, " ");
|
|
return matrix[Row-1][Col-1];
|
|
}
|
|
|
|
inline Standard_Real& gp_Mat::ChangeValue (const Standard_Integer Row,
|
|
const Standard_Integer Col)
|
|
{
|
|
Standard_OutOfRange_Raise_if
|
|
(Row < 1 || Row > 3 || Col < 1 || Col > 3, " ");
|
|
return matrix[Row-1][Col-1];
|
|
}
|
|
|
|
inline Standard_Boolean gp_Mat::IsSingular () const
|
|
{
|
|
// Pour etre sur que Gauss va fonctionner, il faut faire Gauss ...
|
|
Standard_Real val = Determinant();
|
|
if (val < 0) val = - val;
|
|
return val <= gp::Resolution();
|
|
}
|
|
|
|
inline void gp_Mat::Add (const gp_Mat& Other)
|
|
{
|
|
Mat00 = Mat00 + Oat00;
|
|
Mat01 = Mat01 + Oat01;
|
|
Mat02 = Mat02 + Oat02;
|
|
Mat10 = Mat10 + Oat10;
|
|
Mat11 = Mat11 + Oat11;
|
|
Mat12 = Mat12 + Oat12;
|
|
Mat20 = Mat20 + Oat20;
|
|
Mat21 = Mat21 + Oat21;
|
|
Mat22 = Mat22 + Oat22;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Added (const gp_Mat& Other) const
|
|
{
|
|
gp_Mat NewMat;
|
|
Nat00 = Mat00 + Oat00;
|
|
Nat01 = Mat01 + Oat01;
|
|
Nat02 = Mat02 + Oat02;
|
|
Nat10 = Mat10 + Oat10;
|
|
Nat11 = Mat11 + Oat11;
|
|
Nat12 = Mat12 + Oat12;
|
|
Nat20 = Mat20 + Oat20;
|
|
Nat21 = Mat21 + Oat21;
|
|
Nat22 = Mat22 + Oat22;
|
|
return NewMat;
|
|
}
|
|
|
|
inline void gp_Mat::Divide (const Standard_Real Scalar)
|
|
{
|
|
Standard_Real val = Scalar;
|
|
if (val < 0) val = - val;
|
|
Standard_ConstructionError_Raise_if
|
|
(val <= gp::Resolution(),"gp_Mat : Divide by 0");
|
|
Standard_Real UnSurScalar = 1.0 / Scalar;
|
|
Mat00 *= UnSurScalar;
|
|
Mat01 *= UnSurScalar;
|
|
Mat02 *= UnSurScalar;
|
|
Mat10 *= UnSurScalar;
|
|
Mat11 *= UnSurScalar;
|
|
Mat12 *= UnSurScalar;
|
|
Mat20 *= UnSurScalar;
|
|
Mat21 *= UnSurScalar;
|
|
Mat22 *= UnSurScalar;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Divided (const Standard_Real Scalar) const
|
|
{
|
|
Standard_Real val = Scalar;
|
|
if (val < 0) val = - val;
|
|
Standard_ConstructionError_Raise_if
|
|
(val <= gp::Resolution(),"gp_Mat : Divide by 0");
|
|
gp_Mat NewMat;
|
|
Standard_Real UnSurScalar = 1.0 / Scalar;
|
|
Nat00 = Mat00 * UnSurScalar;
|
|
Nat01 = Mat01 * UnSurScalar;
|
|
Nat02 = Mat02 * UnSurScalar;
|
|
Nat10 = Mat10 * UnSurScalar;
|
|
Nat11 = Mat11 * UnSurScalar;
|
|
Nat12 = Mat12 * UnSurScalar;
|
|
Nat20 = Mat20 * UnSurScalar;
|
|
Nat21 = Mat21 * UnSurScalar;
|
|
Nat22 = Mat22 * UnSurScalar;
|
|
return NewMat;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Multiplied (const gp_Mat& Other) const
|
|
{
|
|
gp_Mat NewMat = *this;
|
|
NewMat.Multiply(Other);
|
|
return NewMat;
|
|
}
|
|
|
|
inline void gp_Mat::Multiply (const gp_Mat& Other)
|
|
{
|
|
Standard_Real T00,T01,T02,T10,T11,T12,T20,T21,T22;
|
|
T00 = Mat00 * Oat00 + Mat01 * Oat10 + Mat02 * Oat20;
|
|
T01 = Mat00 * Oat01 + Mat01 * Oat11 + Mat02 * Oat21;
|
|
T02 = Mat00 * Oat02 + Mat01 * Oat12 + Mat02 * Oat22;
|
|
T10 = Mat10 * Oat00 + Mat11 * Oat10 + Mat12 * Oat20;
|
|
T11 = Mat10 * Oat01 + Mat11 * Oat11 + Mat12 * Oat21;
|
|
T12 = Mat10 * Oat02 + Mat11 * Oat12 + Mat12 * Oat22;
|
|
T20 = Mat20 * Oat00 + Mat21 * Oat10 + Mat22 * Oat20;
|
|
T21 = Mat20 * Oat01 + Mat21 * Oat11 + Mat22 * Oat21;
|
|
T22 = Mat20 * Oat02 + Mat21 * Oat12 + Mat22 * Oat22;
|
|
Mat00 = T00;
|
|
Mat01 = T01;
|
|
Mat02 = T02;
|
|
Mat10 = T10;
|
|
Mat11 = T11;
|
|
Mat12 = T12;
|
|
Mat20 = T20;
|
|
Mat21 = T21;
|
|
Mat22 = T22;
|
|
}
|
|
|
|
inline void gp_Mat::PreMultiply (const gp_Mat& Other)
|
|
{
|
|
Standard_Real T00,T01,T02,T10,T11,T12,T20,T21,T22;
|
|
T00 = Oat00 * Mat00 + Oat01 * Mat10 + Oat02 * Mat20;
|
|
T01 = Oat00 * Mat01 + Oat01 * Mat11 + Oat02 * Mat21;
|
|
T02 = Oat00 * Mat02 + Oat01 * Mat12 + Oat02 * Mat22;
|
|
T10 = Oat10 * Mat00 + Oat11 * Mat10 + Oat12 * Mat20;
|
|
T11 = Oat10 * Mat01 + Oat11 * Mat11 + Oat12 * Mat21;
|
|
T12 = Oat10 * Mat02 + Oat11 * Mat12 + Oat12 * Mat22;
|
|
T20 = Oat20 * Mat00 + Oat21 * Mat10 + Oat22 * Mat20;
|
|
T21 = Oat20 * Mat01 + Oat21 * Mat11 + Oat22 * Mat21;
|
|
T22 = Oat20 * Mat02 + Oat21 * Mat12 + Oat22 * Mat22;
|
|
Mat00 = T00;
|
|
Mat01 = T01;
|
|
Mat02 = T02;
|
|
Mat10 = T10;
|
|
Mat11 = T11;
|
|
Mat12 = T12;
|
|
Mat20 = T20;
|
|
Mat21 = T21;
|
|
Mat22 = T22;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Multiplied (const Standard_Real Scalar) const
|
|
{
|
|
gp_Mat NewMat;
|
|
Nat00 = Scalar * Mat00;
|
|
Nat01 = Scalar * Mat01;
|
|
Nat02 = Scalar * Mat02;
|
|
Nat10 = Scalar * Mat10;
|
|
Nat11 = Scalar * Mat11;
|
|
Nat12 = Scalar * Mat12;
|
|
Nat20 = Scalar * Mat20;
|
|
Nat21 = Scalar * Mat21;
|
|
Nat22 = Scalar * Mat22;
|
|
return NewMat;
|
|
}
|
|
|
|
inline void gp_Mat::Multiply (const Standard_Real Scalar)
|
|
{
|
|
Mat00 *= Scalar;
|
|
Mat01 *= Scalar;
|
|
Mat02 *= Scalar;
|
|
Mat10 *= Scalar;
|
|
Mat11 *= Scalar;
|
|
Mat12 *= Scalar;
|
|
Mat20 *= Scalar;
|
|
Mat21 *= Scalar;
|
|
Mat22 *= Scalar;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Powered (const Standard_Integer N) const
|
|
{
|
|
gp_Mat MatN = *this;
|
|
MatN.Power (N);
|
|
return MatN;
|
|
}
|
|
|
|
inline void gp_Mat::Subtract (const gp_Mat& Other)
|
|
{
|
|
Mat00 -= Oat00;
|
|
Mat01 -= Oat01;
|
|
Mat02 -= Oat02;
|
|
Mat10 -= Oat10;
|
|
Mat11 -= Oat11;
|
|
Mat12 -= Oat12;
|
|
Mat20 -= Oat20;
|
|
Mat21 -= Oat21;
|
|
Mat22 -= Oat22;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Subtracted (const gp_Mat& Other) const
|
|
{
|
|
gp_Mat NewMat;
|
|
Nat00 = Mat00 - Oat00;
|
|
Nat01 = Mat01 - Oat01;
|
|
Nat02 = Mat02 - Oat02;
|
|
Nat10 = Mat10 - Oat10;
|
|
Nat11 = Mat11 - Oat11;
|
|
Nat12 = Mat12 - Oat12;
|
|
Nat20 = Mat20 - Oat20;
|
|
Nat21 = Mat21 - Oat21;
|
|
Nat22 = Mat22 - Oat22;
|
|
return NewMat;
|
|
}
|
|
|
|
// On macOS 10.13.6 with XCode 9.4.1 the compiler has a bug leading to
|
|
// generation of invalid code when method gp_Mat::Transpose() is called
|
|
// for a matrix which is when applied to vector; it looks like vector
|
|
// is transformed before the matrix is actually transposed; see #29978.
|
|
// To avoid this, we disable compiler optimization here.
|
|
#if defined(__APPLE__) && (__apple_build_version__ > 9020000)
|
|
__attribute__((optnone))
|
|
#endif
|
|
inline void gp_Mat::Transpose ()
|
|
{
|
|
Standard_Real Temp;
|
|
Temp = Mat01;
|
|
Mat01 = Mat10;
|
|
Mat10 = Temp;
|
|
Temp = Mat02;
|
|
Mat02 = Mat20;
|
|
Mat20 = Temp;
|
|
Temp = Mat12;
|
|
Mat12 = Mat21;
|
|
Mat21 = Temp;
|
|
}
|
|
|
|
inline gp_Mat gp_Mat::Transposed () const
|
|
{
|
|
gp_Mat NewMat = *this;
|
|
NewMat.Transpose();
|
|
return NewMat;
|
|
}
|
|
|
|
inline gp_Mat operator* (const Standard_Real Scalar, const gp_Mat& Mat3D)
|
|
{ return Mat3D.Multiplied (Scalar); }
|
|
|