1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00
occt/src/gp/gp_Trsf.cxx
nds 6b63dc83c3 0031326: Foundation Classes - Init from Json for base OCCT classes
InitFromJson method implementation for some simple classes.
OCCT_INIT_* defines introduction to do automatic parsing of the stream into values.
Inspector is extended to visualize objects created on the dump stream if it might be created.
2020-09-09 19:36:06 +03:00

954 lines
27 KiB
C++

// 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.
// JCV 30/08/90 Modif passage version C++ 2.0 sur Sun
// JCV 1/10/90 Changement de nom du package vgeom -> gp
// JCV 4/10/90 codage sur la forme de la transformation shape,Scaling,negative
// JCV 10/12/90 Modif introduction des classes Mat et XYZ dans gp
#define No_Standard_OutOfRange
#include <gp.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_GTrsf.hxx>
#include <gp_Mat.hxx>
#include <gp_Pnt.hxx>
#include <gp_Quaternion.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_Dump.hxx>
//=======================================================================
//function : gp_Trsf
//purpose : Constructor from 2d
//=======================================================================
gp_Trsf::gp_Trsf (const gp_Trsf2d& T) :
scale(T.ScaleFactor()),
shape(T.Form()),
loc(T.TranslationPart().X(),T.TranslationPart().Y(), 0.0)
{
const gp_Mat2d& M = T.HVectorialPart();
matrix(1,1) = M(1,1);
matrix(1,2) = M(1,2);
matrix(2,1) = M(2,1);
matrix(2,2) = M(2,2);
matrix(3,3) = 1.;
if (shape == gp_Ax1Mirror)
{
scale = 1;
matrix.Multiply(-1);
}
}
//=======================================================================
//function : SetMirror
//purpose :
//=======================================================================
void gp_Trsf::SetMirror (const gp_Ax1& A1)
{
shape = gp_Ax1Mirror;
scale = 1;
loc = A1.Location().XYZ();
matrix.SetDot(A1.Direction().XYZ());
matrix.Multiply(-2);
matrix.SetDiagonal (matrix.Value (1,1) + 1,
matrix.Value (2,2) + 1,
matrix.Value (3,3) + 1);
loc.Multiply (matrix);
loc.Add (A1.Location().XYZ());
matrix.Multiply(-1);
}
//=======================================================================
//function : SetMirror
//purpose :
//=======================================================================
void gp_Trsf::SetMirror (const gp_Ax2& A2)
{
shape = gp_Ax2Mirror;
scale = -1;
loc = A2.Location().XYZ();
matrix.SetDot(A2.Direction().XYZ());
matrix.Multiply(2);
matrix.SetDiagonal (matrix.Value (1,1) - 1,
matrix.Value (2,2) - 1,
matrix.Value (3,3) - 1);
loc.Multiply (matrix);
loc.Add (A2.Location().XYZ());
}
//=======================================================================
//function : SetRotation
//purpose :
//=======================================================================
void gp_Trsf::SetRotation (const gp_Ax1& A1,
const Standard_Real Ang)
{
shape = gp_Rotation;
scale = 1.;
loc = A1.Location().XYZ();
matrix.SetRotation (A1.Direction().XYZ(), Ang);
loc.Reverse ();
loc.Multiply (matrix);
loc.Add (A1.Location().XYZ());
}
//=======================================================================
//function : SetRotation
//purpose :
//=======================================================================
void gp_Trsf::SetRotation (const gp_Quaternion& R)
{
shape = gp_Rotation;
scale = 1.;
loc.SetCoord (0., 0., 0.);
matrix = R.GetMatrix();
}
//=======================================================================
//function : SetRotationPart
//purpose :
//=======================================================================
void gp_Trsf::SetRotationPart (const gp_Quaternion& theR)
{
const bool hasRotation = !theR.IsEqual (gp_Quaternion());
if (hasRotation)
{
matrix = theR.GetMatrix();
}
else
{
matrix.SetIdentity();
}
switch (shape)
{
case gp_Identity:
{
if (hasRotation)
{
shape = gp_Rotation;
}
break;
}
case gp_Rotation:
{
if (!hasRotation)
{
shape = gp_Identity;
}
break;
}
case gp_Translation:
case gp_PntMirror:
case gp_Ax1Mirror:
case gp_Ax2Mirror:
case gp_Scale:
case gp_CompoundTrsf:
case gp_Other:
{
if (hasRotation)
{
shape = gp_CompoundTrsf;
}
break;
}
}
}
//=======================================================================
//function : SetScale
//purpose :
//=======================================================================
void gp_Trsf::SetScale (const gp_Pnt& P, const Standard_Real S)
{
shape = gp_Scale;
scale = S;
loc = P.XYZ();
Standard_Real As = scale;
if (As < 0) As = - As;
Standard_ConstructionError_Raise_if
(As <= gp::Resolution(),"gp_Trsf::SetScaleFactor");
matrix.SetIdentity ();
loc.Multiply (1-S);
}
//=======================================================================
//function : SetTransformation
//purpose :
//=======================================================================
void gp_Trsf::SetTransformation (const gp_Ax3& FromA1,
const gp_Ax3& ToA2)
{
shape = gp_CompoundTrsf;
scale = 1.0;
// matrix from XOY ToA2 :
matrix.SetRows (ToA2.XDirection().XYZ(),
ToA2.YDirection().XYZ(),
ToA2. Direction().XYZ());
loc = ToA2.Location().XYZ();
loc.Multiply (matrix);
loc.Reverse ();
// matrix FromA1 to XOY :
const gp_XYZ& xDir = FromA1.XDirection().XYZ();
const gp_XYZ& yDir = FromA1.YDirection().XYZ();
const gp_XYZ& zDir = FromA1.Direction().XYZ();
gp_Mat MA1 (xDir, yDir, zDir);
gp_XYZ MA1loc = FromA1.Location().XYZ();
// matrix * MA1 => FromA1 ToA2 :
MA1loc.Multiply (matrix);
loc.Add (MA1loc);
matrix.Multiply (MA1);
}
void gp_Trsf::SetTransformation (const gp_Ax3& A3)
{
shape = gp_CompoundTrsf;
scale = 1.0;
matrix.SetRows (A3.XDirection().XYZ(),
A3.YDirection().XYZ(),
A3. Direction().XYZ());
loc = A3.Location().XYZ();
loc.Multiply (matrix);
loc.Reverse ();
}
//=======================================================================
//function : SetTransformation
//purpose :
//=======================================================================
void gp_Trsf::SetTransformation (const gp_Quaternion& R, const gp_Vec& T)
{
shape = gp_CompoundTrsf;
scale = 1.;
loc = T.XYZ();
matrix = R.GetMatrix();
}
//=======================================================================
//function : SetDisplacement
//purpose :
//=======================================================================
void gp_Trsf::SetDisplacement (const gp_Ax3& FromA1,
const gp_Ax3& ToA2)
{
shape = gp_CompoundTrsf;
scale = 1.0;
// matrix from ToA2 to XOY :
matrix.SetCol (1, ToA2.XDirection().XYZ());
matrix.SetCol (2, ToA2.YDirection().XYZ());
matrix.SetCol (3, ToA2.Direction().XYZ());
loc = ToA2.Location().XYZ();
// matrix XOY to FromA1 :
const gp_XYZ& xDir = FromA1.XDirection().XYZ();
const gp_XYZ& yDir = FromA1.YDirection().XYZ();
const gp_XYZ& zDir = FromA1.Direction().XYZ();
gp_Mat MA1 (xDir, yDir, zDir);
MA1.Transpose();
gp_XYZ MA1loc = FromA1.Location().XYZ();
MA1loc.Multiply (MA1);
MA1loc.Reverse();
// matrix * MA1
MA1loc.Multiply (matrix);
loc.Add (MA1loc);
matrix.Multiply (MA1);
}
//=======================================================================
//function : SetTranslationPart
//purpose :
//=======================================================================
void gp_Trsf::SetTranslationPart (const gp_Vec& V) {
loc = V.XYZ();
const Standard_Boolean locnull = (loc.SquareModulus() < gp::Resolution());
switch (shape) {
case gp_Identity :
if (!locnull) shape = gp_Translation;
break;
case gp_Translation :
if (locnull) shape = gp_Identity;
break;
case gp_Rotation :
case gp_PntMirror :
case gp_Ax1Mirror :
case gp_Ax2Mirror :
case gp_Scale :
case gp_CompoundTrsf :
case gp_Other :
if (!locnull) {
shape = gp_CompoundTrsf;
}
break;
}
}
//=======================================================================
//function : SetScaleFactor
//purpose :
//=======================================================================
void gp_Trsf::SetScaleFactor (const Standard_Real S)
{
Standard_Real As = S;
if (As < 0) As = - As;
Standard_ConstructionError_Raise_if
(As <= gp::Resolution(),"gp_Trsf::SetScaleFactor");
scale = S;
As = scale - 1.;
if (As < 0) As = - As;
Standard_Boolean unit = As <= gp::Resolution(); // = (scale == 1)
As = scale + 1.;
if (As < 0) As = - As;
Standard_Boolean munit = As <= gp::Resolution(); // = (scale == -1)
switch (shape) {
case gp_Identity :
case gp_Translation :
if (!unit) shape = gp_Scale;
if (munit) shape = gp_PntMirror;
break;
case gp_Rotation :
if (!unit) shape = gp_CompoundTrsf;
break;
case gp_PntMirror :
case gp_Ax1Mirror :
case gp_Ax2Mirror :
if (!munit) shape = gp_Scale;
if (unit) shape = gp_Identity;
break;
case gp_Scale :
if (unit) shape = gp_Identity;
if (munit) shape = gp_PntMirror;
break;
case gp_CompoundTrsf :
break;
case gp_Other :
break;
}
}
//=======================================================================
//function : SetValues
//purpose :
// 06-01-1998 modified by PMN : On utilise TolDist pour evaluer si les coeffs
// sont nuls : c'est toujours mieux que gp::Resolution !
//=======================================================================
void gp_Trsf::SetValues(const Standard_Real a11,
const Standard_Real a12,
const Standard_Real a13,
const Standard_Real a14,
const Standard_Real a21,
const Standard_Real a22,
const Standard_Real a23,
const Standard_Real a24,
const Standard_Real a31,
const Standard_Real a32,
const Standard_Real a33,
const Standard_Real a34)
{
gp_XYZ col1(a11,a21,a31);
gp_XYZ col2(a12,a22,a32);
gp_XYZ col3(a13,a23,a33);
gp_XYZ col4(a14,a24,a34);
// compute the determinant
gp_Mat M(col1,col2,col3);
Standard_Real s = M.Determinant();
Standard_Real As = s;
if (As < 0) As = - As;
Standard_ConstructionError_Raise_if
(As < gp::Resolution(),"gp_Trsf::SetValues, null determinant");
if (s > 0)
s = Pow(s,1./3.);
else
s = -Pow(-s,1./3.);
M.Divide(s);
scale = s;
shape = gp_CompoundTrsf;
matrix = M;
Orthogonalize();
loc = col4;
}
//=======================================================================
//function : GetRotation
//purpose :
//=======================================================================
gp_Quaternion gp_Trsf::GetRotation () const
{
return gp_Quaternion (matrix);
}
//=======================================================================
//function : VectorialPart
//purpose :
//=======================================================================
gp_Mat gp_Trsf::VectorialPart () const
{
if (scale == 1.0) return matrix;
gp_Mat M = matrix;
if (shape == gp_Scale || shape == gp_PntMirror)
M.SetDiagonal(scale*M.Value(1,1),
scale*M.Value(2,2),
scale*M.Value(3,3));
else
M.Multiply (scale);
return M;
}
//=======================================================================
//function : Invert
//purpose :
//=======================================================================
void gp_Trsf::Invert()
{
// -1
// X' = scale * R * X + T => X = (R / scale) * ( X' - T)
//
// Pour les gp_Trsf puisque le scale est extrait de la gp_Matrice R
// on a toujours determinant (R) = 1 et R-1 = R transposee.
if (shape == gp_Identity) { }
else if (shape == gp_Translation || shape == gp_PntMirror) loc.Reverse();
else if (shape == gp_Scale) {
Standard_ConstructionError_Raise_if (Abs(scale) <= gp::Resolution(), "gp_Trsf::Invert() - transformation has zero scale");
scale = 1.0 / scale;
loc.Multiply (-scale);
}
else {
Standard_ConstructionError_Raise_if (Abs(scale) <= gp::Resolution(), "gp_Trsf::Invert() - transformation has zero scale");
scale = 1.0 / scale;
matrix.Transpose ();
loc.Multiply (matrix);
loc.Multiply (-scale);
}
}
//=======================================================================
//function : Multiply
//purpose :
//=======================================================================
void gp_Trsf::Multiply(const gp_Trsf& T)
{
if (T.shape == gp_Identity) { }
else if (shape == gp_Identity) {
shape = T.shape;
scale = T.scale;
loc = T.loc;
matrix = T.matrix;
}
else if (shape == gp_Rotation && T.shape == gp_Rotation) {
if (T.loc.X() != 0.0 || T.loc.Y() != 0.0 || T.loc.Z() != 0.0) {
loc.Add (T.loc.Multiplied (matrix));
}
matrix.Multiply(T.matrix);
}
else if (shape == gp_Translation && T.shape == gp_Translation) {
loc.Add (T.loc);
}
else if (shape == gp_Scale && T.shape == gp_Scale) {
loc.Add (T.loc.Multiplied(scale));
scale = scale * T.scale;
}
else if (shape == gp_PntMirror && T.shape == gp_PntMirror) {
scale = 1.0;
shape = gp_Translation;
loc.Add (T.loc.Reversed());
}
else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) {
shape = gp_Rotation;
loc.Add (T.loc.Multiplied (matrix));
matrix.Multiply(T.matrix);
}
else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
&& T.shape == gp_Translation) {
gp_XYZ Tloc(T.loc);
Tloc.Multiply(matrix);
if (scale != 1.0) { Tloc.Multiply(scale); }
loc.Add (Tloc);
}
else if ((shape == gp_Scale || shape == gp_PntMirror)
&& T.shape == gp_Translation) {
gp_XYZ Tloc(T.loc);
Tloc.Multiply (scale);
loc.Add (Tloc);
}
else if (shape == gp_Translation &&
(T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)) {
shape = gp_CompoundTrsf;
scale = T.scale;
loc.Add (T.loc);
matrix = T.matrix;
}
else if (shape == gp_Translation &&
(T.shape == gp_Scale || T.shape == gp_PntMirror)) {
shape = T.shape;
loc.Add (T.loc);
scale = T.scale;
}
else if ((shape == gp_PntMirror || shape == gp_Scale) &&
(T.shape == gp_PntMirror || T.shape == gp_Scale)) {
shape = gp_CompoundTrsf;
gp_XYZ Tloc(T.loc);
Tloc.Multiply (scale);
loc.Add (Tloc);
scale = scale * T.scale;
}
else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
&& (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
shape = gp_CompoundTrsf;
gp_XYZ Tloc(T.loc);
if (scale == 1.0) {
scale = T.scale;
Tloc.Multiply(matrix);
}
else {
Tloc.Multiply (matrix);
Tloc.Multiply (scale);
scale = scale * T.scale;
}
loc.Add (Tloc);
}
else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)
&& (shape == gp_Scale || shape == gp_PntMirror)) {
shape = gp_CompoundTrsf;
gp_XYZ Tloc(T.loc);
Tloc.Multiply(scale);
loc.Add (Tloc);
scale = scale * T.scale;
matrix = T.matrix;
}
else {
shape = gp_CompoundTrsf;
gp_XYZ Tloc(T.loc);
Tloc.Multiply (matrix);
if (scale != 1.0) {
Tloc.Multiply (scale);
scale = scale * T.scale;
}
else { scale = T.scale; }
loc.Add (Tloc);
matrix.Multiply(T.matrix);
}
}
//=======================================================================
//function : Power
//purpose :
//=======================================================================
void gp_Trsf::Power (const Standard_Integer N)
{
if (shape == gp_Identity) { }
else {
if (N == 0) {
scale = 1.0;
shape = gp_Identity;
matrix.SetIdentity();
loc = gp_XYZ (0.0, 0.0, 0.0);
}
else if (N == 1) { }
else if (N == -1) { Invert(); }
else {
if (N < 0) { Invert(); }
if (shape == gp_Translation) {
Standard_Integer Npower = N;
if (Npower < 0) Npower = - Npower;
Npower--;
gp_XYZ Temploc = loc;
for(;;) {
if (IsOdd(Npower)) loc.Add (Temploc);
if (Npower == 1) break;
Temploc.Add (Temploc);
Npower = Npower/2;
}
}
else if (shape == gp_Scale) {
Standard_Integer Npower = N;
if (Npower < 0) Npower = - Npower;
Npower--;
gp_XYZ Temploc = loc;
Standard_Real Tempscale = scale;
for(;;) {
if (IsOdd(Npower)) {
loc.Add (Temploc.Multiplied(scale));
scale = scale * Tempscale;
}
if (Npower == 1) break;
Temploc.Add (Temploc.Multiplied(Tempscale));
Tempscale = Tempscale * Tempscale;
Npower = Npower/2;
}
}
else if (shape == gp_Rotation) {
Standard_Integer Npower = N;
if (Npower < 0) Npower = - Npower;
Npower--;
gp_Mat Tempmatrix (matrix);
if (loc.X() == 0.0 && loc.Y() == 0.0 && loc.Z() == 0.0) {
for(;;) {
if (IsOdd(Npower)) matrix.Multiply (Tempmatrix);
if (Npower == 1) break;
Tempmatrix.Multiply (Tempmatrix);
Npower = Npower/2;
}
}
else {
gp_XYZ Temploc = loc;
for(;;) {
if (IsOdd(Npower)) {
loc.Add (Temploc.Multiplied (matrix));
matrix.Multiply (Tempmatrix);
}
if (Npower == 1) break;
Temploc.Add (Temploc.Multiplied (Tempmatrix));
Tempmatrix.Multiply (Tempmatrix);
Npower = Npower/2;
}
}
}
else if (shape == gp_PntMirror || shape == gp_Ax1Mirror ||
shape == gp_Ax2Mirror) {
if (IsEven (N)) {
shape = gp_Identity;
scale = 1.0;
matrix.SetIdentity ();
loc.SetX(0);
loc.SetY(0);
loc.SetZ(0);
}
}
else {
shape = gp_CompoundTrsf;
Standard_Integer Npower = N;
if (Npower < 0) Npower = - Npower;
Npower--;
gp_XYZ Temploc = loc;
Standard_Real Tempscale = scale;
gp_Mat Tempmatrix (matrix);
for(;;) {
if (IsOdd(Npower)) {
loc.Add ((Temploc.Multiplied (matrix)).Multiplied (scale));
scale = scale * Tempscale;
matrix.Multiply (Tempmatrix);
}
if (Npower == 1) break;
Tempscale = Tempscale * Tempscale;
Temploc.Add ( (Temploc.Multiplied (Tempmatrix)).Multiplied
(Tempscale)
);
Tempmatrix.Multiply (Tempmatrix);
Npower = Npower/2;
}
}
}
}
}
//=======================================================================
//function : PreMultiply
//purpose :
//=======================================================================
void gp_Trsf::PreMultiply (const gp_Trsf& T)
{
if (T.shape == gp_Identity) { }
else if (shape == gp_Identity) {
shape = T.shape;
scale = T.scale;
loc = T.loc;
matrix = T.matrix;
}
else if (shape == gp_Rotation && T.shape == gp_Rotation) {
loc.Multiply (T.matrix);
loc.Add (T.loc);
matrix.PreMultiply(T.matrix);
}
else if (shape == gp_Translation && T.shape == gp_Translation) {
loc.Add (T.loc);
}
else if (shape == gp_Scale && T.shape == gp_Scale) {
loc.Multiply (T.scale);
loc.Add (T.loc);
scale = scale * T.scale;
}
else if (shape == gp_PntMirror && T.shape == gp_PntMirror) {
scale = 1.0;
shape = gp_Translation;
loc.Reverse();
loc.Add (T.loc);
}
else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) {
shape = gp_Rotation;
loc.Multiply (T.matrix);
loc.Add (T.loc);
matrix.PreMultiply(T.matrix);
}
else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
&& T.shape == gp_Translation) {
loc.Add (T.loc);
}
else if ((shape == gp_Scale || shape == gp_PntMirror)
&& T.shape == gp_Translation) {
loc.Add (T.loc);
}
else if (shape == gp_Translation &&
(T.shape == gp_CompoundTrsf || T.shape == gp_Rotation
|| T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)) {
shape = gp_CompoundTrsf;
matrix = T.matrix;
if (T.scale == 1.0) loc.Multiply (T.matrix);
else {
scale = T.scale;
loc.Multiply (matrix);
loc.Multiply (scale);
}
loc.Add (T.loc);
}
else if ((T.shape == gp_Scale || T.shape == gp_PntMirror)
&& shape == gp_Translation) {
loc.Multiply (T.scale);
loc.Add (T.loc);
scale = T.scale;
shape = T.shape;
}
else if ((shape == gp_PntMirror || shape == gp_Scale) &&
(T.shape == gp_PntMirror || T.shape == gp_Scale)) {
shape = gp_CompoundTrsf;
loc.Multiply (T.scale);
loc.Add (T.loc);
scale = scale * T.scale;
}
else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
&& (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
shape = gp_CompoundTrsf;
loc.Multiply (T.scale);
loc.Add (T.loc);
scale = scale * T.scale;
}
else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)
&& (shape == gp_Scale || shape == gp_PntMirror)) {
shape = gp_CompoundTrsf;
matrix = T.matrix;
if (T.scale == 1.0) loc.Multiply (T.matrix);
else {
loc.Multiply (matrix);
loc.Multiply (T.scale);
scale = T.scale * scale;
}
loc.Add (T.loc);
}
else {
shape = gp_CompoundTrsf;
loc.Multiply (T.matrix);
if (T.scale != 1.0) {
loc.Multiply (T.scale); scale = scale * T.scale;
}
loc.Add (T.loc);
matrix.PreMultiply(T.matrix);
}
}
//=======================================================================
//function : GetRotation
//purpose : algorithm from A.Korn, M.Korn, "Mathematical Handbook for
// scientists and Engineers" McGraw-Hill, 1961, ch.14.10-2.
//=======================================================================
Standard_Boolean gp_Trsf::GetRotation (gp_XYZ& theAxis,
Standard_Real& theAngle) const
{
gp_Quaternion Q = GetRotation();
gp_Vec aVec;
Q.GetVectorAndAngle (aVec, theAngle);
theAxis = aVec.XYZ();
return Standard_True;
}
//=======================================================================
//function : Orthogonalize
//purpose :
//ATTENTION!!!
// Orthogonalization is not equivalent transformation. Therefore,
// transformation with source matrix and with orthogonalized matrix can
// lead to different results for one shape. Consequently, source matrix must
// be close to orthogonalized matrix for reducing these differences.
//=======================================================================
void gp_Trsf::Orthogonalize()
{
//Matrix M is called orthogonal if and only if
// M*Transpose(M) == E
//where E is identity matrix.
//Set of all rows (as of all columns) of matrix M (for gp_Trsf class) is
//orthonormal basis. If this condition is not satisfied then the basis can be
//orthonormalized in accordance with below described algorithm.
//In 3D-space, we have the linear span of three basis vectors: V1, V2 and V3.
//Correspond orthonormalized basis is formed by vectors Vn1, Vn2 and Vn3.
//In this case,
// Vn_{i}*Vn_{j} = (i == j)? 1 : 0.
//The algorithm includes following steps:
//1. Normalize V1 vector:
// V1n=V1/|V1|;
//
//2. Let
// V2n=V2-m*V1n.
//
//After multiplication two parts of this equation by V1n,
//we will have following equation:
// 0=V2*V1n-m <==> m=V2*V1n.
//
//Consequently,
// V2n=V2-(V2*V1n)*V1n.
//3. Let
// V3n=V3-m1*V1n-m2*V2n.
//
//After multiplication two parts of this equation by V1n,
//we will have following equation:
// 0=V3*V1n-m1 <==> m1=V3*V1n.
//
//After multiplication two parts of main equation by V2n,
//we will have following equation:
// 0=V3*V2n-m2 <==> m2=V3*V2n.
//
//In conclusion,
// V3n=V3-(V3*V1n)*V1n-(V3*V2n)*V2n.
gp_Mat aTM(matrix);
gp_XYZ aV1 = aTM.Column(1);
gp_XYZ aV2 = aTM.Column(2);
gp_XYZ aV3 = aTM.Column(3);
aV1.Normalize();
aV2 -= aV1*(aV2.Dot(aV1));
aV2.Normalize();
aV3 -= aV1*(aV3.Dot(aV1)) + aV2*(aV3.Dot(aV2));
aV3.Normalize();
aTM.SetCols(aV1, aV2, aV3);
aV1 = aTM.Row(1);
aV2 = aTM.Row(2);
aV3 = aTM.Row(3);
aV1.Normalize();
aV2 -= aV1*(aV2.Dot(aV1));
aV2.Normalize();
aV3 -= aV1*(aV3.Dot(aV1)) + aV2*(aV3.Dot(aV2));
aV3.Normalize();
aTM.SetRows(aV1, aV2, aV3);
matrix = aTM;
}
//=======================================================================
//function : DumpJson
//purpose :
//=======================================================================
void gp_Trsf::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
{
OCCT_DUMP_VECTOR_CLASS (theOStream, "Location", 3, loc.X(), loc.Y(), loc.Z())
OCCT_DUMP_VECTOR_CLASS (theOStream, "Matrix", 9, matrix.Value(1, 1), matrix.Value(1, 2), matrix.Value(1, 3),
matrix.Value(2, 1), matrix.Value(2, 2), matrix.Value(2, 3),
matrix.Value(3, 1), matrix.Value(3, 2), matrix.Value(3, 3))
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, shape)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, scale)
}
//=======================================================================
//function : InitFromJson
//purpose :
//=======================================================================
Standard_Boolean gp_Trsf::InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos)
{
Standard_Integer aPos = theStreamPos;
TCollection_AsciiString aStreamStr = Standard_Dump::Text (theSStream);
gp_XYZ anXYZLoc;
OCCT_INIT_VECTOR_CLASS (aStreamStr, "Location", aPos, 3,
&anXYZLoc.ChangeCoord (1), &anXYZLoc.ChangeCoord (2), &anXYZLoc.ChangeCoord (3))
SetTranslation (anXYZLoc);
Standard_Real mymatrix[3][3];
OCCT_INIT_VECTOR_CLASS (aStreamStr, "Matrix", aPos, 9, &mymatrix[0][0], &mymatrix[0][1], &mymatrix[0][2],
&mymatrix[1][0], &mymatrix[1][1], &mymatrix[1][2],
&mymatrix[2][0], &mymatrix[2][1], &mymatrix[2][2])
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
matrix.SetValue (i + 1, j + 1, mymatrix[i][j]);
}
}
Standard_Real ashape;
OCCT_INIT_FIELD_VALUE_INTEGER (aStreamStr, aPos, ashape);
shape = (gp_TrsfForm)((Standard_Integer)ashape);
OCCT_INIT_FIELD_VALUE_REAL (aStreamStr, aPos, scale);
theStreamPos = aPos;
return Standard_True;
}