merge master via cli

This commit is contained in:
AgCaliva
2023-10-04 13:28:48 -03:00
1111 changed files with 84224 additions and 65531 deletions

View File

@@ -26,6 +26,7 @@
# include <cstring>
# include <sstream>
#endif
# include <array>
#include "Matrix.h"
#include "Converter.h"
@@ -897,3 +898,94 @@ ScaleType Matrix4D::hasScale(double tol) const
return ScaleType::NoScaling;
}
std::array<Matrix4D, 4> Matrix4D::decompose() const {
// decompose the matrix to shear, scale, rotation and move
// so that matrix = move * rotation * scale * shear
// return an array of matrices
Matrix4D moveMatrix;
Matrix4D rotationMatrix;
Matrix4D scaleMatrix;
Matrix4D residualMatrix(*this);
// extract transform
moveMatrix.move(residualMatrix.getCol(3));
residualMatrix.setCol(3, Vector3d());
// find and extract rotation
int prim_dir = -1;
std::array<Vector3d, 3> dirs = {
Vector3d(1., 0., 0.),Vector3d(0., 1., 0.),Vector3d(0., 0., 1.)
};
int i;
for (i = 0; i < 3; i++) {
if (residualMatrix.getCol(i).IsNull()) {
continue;
}
if (prim_dir < 0) {
dirs[i] = residualMatrix.getCol(i);
dirs[i].Normalize();
prim_dir = i;
continue;
} else {
Vector3d cross = dirs[prim_dir].Cross(residualMatrix.getCol(i));
if (cross.IsNull()) {
continue;
}
cross.Normalize();
int last_dir = 3-i-prim_dir;
if (i - prim_dir == 1) {
dirs[last_dir] = cross;
dirs[i] = cross.Cross(dirs[prim_dir]);
} else {
dirs[last_dir] = -cross;
dirs[i] = dirs[prim_dir].Cross(-cross);
}
prim_dir = -2; // done
break;
}
}
if (prim_dir >= 0) {
// handle case with only one valid direction
Vector3d cross = dirs[prim_dir].Cross(Vector3d(0., 0., 1.));
if (cross.IsNull()) {
cross = dirs[prim_dir].Cross(Vector3d(0., 1., 0.));
}
dirs[(prim_dir+1)%3] = cross;
dirs[(prim_dir+2)%3] = dirs[prim_dir].Cross(cross);
}
rotationMatrix.setCol(0, dirs[0]);
rotationMatrix.setCol(1, dirs[1]);
rotationMatrix.setCol(2, dirs[2]);
rotationMatrix.inverseGauss();
residualMatrix = rotationMatrix * residualMatrix;
// To keep signs of the scale factors equal
if (residualMatrix.determinant() < 0) {
rotationMatrix.rotZ(D_PI);
residualMatrix.rotZ(D_PI);
}
rotationMatrix.inverseGauss();
// extract scale
double xScale = residualMatrix.dMtrx4D[0][0];
double yScale = residualMatrix.dMtrx4D[1][1];
double zScale = residualMatrix.dMtrx4D[2][2];
scaleMatrix.dMtrx4D[0][0] = xScale;
scaleMatrix.dMtrx4D[1][1] = yScale;
scaleMatrix.dMtrx4D[2][2] = zScale;
// The remaining shear
residualMatrix.scale(xScale ? 1.0 / xScale : 1.0, yScale ? 1.0 / yScale : 1.0, zScale ? 1.0 / zScale : 1.0);
// Restore trace in shear matrix
residualMatrix.setDiagonal(Vector3d(1.0, 1.0, 1.0));
// Remove values close to zero
for (i = 0; i < 3; i++) {
if (std::abs(scaleMatrix.dMtrx4D[i][i]) < 1e-15)
scaleMatrix.dMtrx4D[i][i] = 0.0;
for (int j = 0; j < 3; j++) {
if (std::abs(residualMatrix.dMtrx4D[i][j]) < 1e-15)
residualMatrix.dMtrx4D[i][j] = 0.0;
if (std::abs(rotationMatrix.dMtrx4D[i][j]) < 1e-15)
rotationMatrix.dMtrx4D[i][j] = 0.0;
}
}
return std::array<Matrix4D, 4>{
residualMatrix, scaleMatrix, rotationMatrix, moveMatrix
};
}

View File

@@ -25,6 +25,7 @@
#define BASE_MATRIX_H
#include <string>
#include <array>
#include "Vector3D.h"
#ifndef FC_GLOBAL_H
@@ -175,6 +176,8 @@ public:
{ scale(Vector3d(scalexyz, scalexyz, scalexyz)); }
/// Check for scaling factor
ScaleType hasScale(double tol=0.0) const;
/// Decompose matrix into pure shear, scale, rotation and move
std::array<Matrix4D, 4> decompose() const;
/// Rotate around the X axis (in transformed space) for the given value in radians
void rotX (double fAngle);
/// Rotate around the Y axis (in transformed space) for the given value in radians

View File

@@ -97,28 +97,35 @@ if it's not a scale matrix.
tol : float</UserDocu>
</Documentation>
</Methode>
<Methode Name="nullify">
<Methode Name="decompose" Const="true">
<Documentation>
<UserDocu>decompose() -> Base.Matrix, Base.Matrix, Base.Matrix, Base.Matrix\n
Return a tuple of matrices representing shear, scale, rotation and move.
So that matrix = move * rotation * scale * shear.</UserDocu>
</Documentation>
</Methode>
<Methode Name="nullify" NoArgs="true">
<Documentation>
<UserDocu>nullify() -> None
Make this the null matrix.</UserDocu>
</Documentation>
</Methode>
<Methode Name="isNull" Const="true">
<Methode Name="isNull" Const="true" NoArgs="true">
<Documentation>
<UserDocu>isNull() -> bool
Check if this is the null matrix.</UserDocu>
</Documentation>
</Methode>
<Methode Name="unity">
<Methode Name="unity" NoArgs="true">
<Documentation>
<UserDocu>unity() -> None
Make this matrix to unity (4D identity matrix).</UserDocu>
</Documentation>
</Methode>
<Methode Name="isUnity" Const="true">
<Methode Name="isUnity" Const="true" NoArgs="true">
<Documentation>
<UserDocu>isUnity() -> bool
@@ -185,7 +192,7 @@ index : int
vector : Base.Vector</UserDocu>
</Documentation>
</Methode>
<Methode Name="diagonal" Const="true">
<Methode Name="diagonal" Const="true" NoArgs="true">
<Documentation>
<UserDocu>diagonal() -> Base.Vector
@@ -252,34 +259,34 @@ Compute the transformed vector using the matrix.
vector : Base.Vector</UserDocu>
</Documentation>
</Methode>
<Methode Name="invert">
<Methode Name="invert" NoArgs="true">
<Documentation>
<UserDocu>invert() -> None
Compute the inverse matrix in-place, if possible.</UserDocu>
</Documentation>
</Methode>
<Methode Name="inverse" Const="true">
<Methode Name="inverse" Const="true" NoArgs="true">
<Documentation><UserDocu>inverse() -> Base.Matrix
Compute the inverse matrix, if possible.</UserDocu>
</Documentation>
</Methode>
<Methode Name="transpose">
<Methode Name="transpose" NoArgs="true">
<Documentation>
<UserDocu>transpose() -> None
Transpose the matrix in-place.</UserDocu>
</Documentation>
</Methode>
<Methode Name="transposed" Const="true">
<Methode Name="transposed" Const="true" NoArgs="true">
<Documentation>
<UserDocu>transposed() -> Base.Matrix
Returns a transposed copy of this matrix.</UserDocu>
</Documentation>
</Methode>
<Methode Name="determinant" Const="true">
<Methode Name="determinant" Const="true" NoArgs="true">
<Documentation>
<UserDocu>determinant() -> float
@@ -309,7 +316,7 @@ dim : int
Dimension parameter must be in the range [1,4].</UserDocu>
</Documentation>
</Methode>
<Methode Name="analyze" Const="true">
<Methode Name="analyze" Const="true" NoArgs="true">
<Documentation>
<UserDocu>analyze() -> str

View File

@@ -22,6 +22,7 @@
#include "PreCompiled.h"
//#include <array>
// inclusion of the generated files (generated out of MatrixPy.xml)
#include "RotationPy.h"
@@ -351,12 +352,21 @@ PyObject* MatrixPy::hasScale(PyObject * args)
Py::Module mod("FreeCAD");
return Py::new_reference_to(mod.callMemberFunction("ScaleType", Py::TupleN(Py::Int(static_cast<int>(type)))));
}
PyObject* MatrixPy::nullify(PyObject * args)
PyObject* MatrixPy::decompose(PyObject * args)
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
auto ms = getMatrixPtr()->decompose();
Py::Tuple tuple(4);
for (int i=0; i<4; i++) {
tuple.setItem(i, Py::Matrix(ms[i]));
}
return Py::new_reference_to(tuple);
}
PyObject* MatrixPy::nullify()
{
PY_TRY {
getMatrixPtr()->nullify();
Py_Return;
@@ -364,11 +374,8 @@ PyObject* MatrixPy::nullify(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::isNull(PyObject * args)
PyObject* MatrixPy::isNull()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
bool ok = getMatrixPtr()->isNull();
return Py::new_reference_to(Py::Boolean(ok));
@@ -376,11 +383,8 @@ PyObject* MatrixPy::isNull(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::unity(PyObject * args)
PyObject* MatrixPy::unity()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
getMatrixPtr()->setToUnity();
Py_Return;
@@ -388,11 +392,8 @@ PyObject* MatrixPy::unity(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::isUnity(PyObject * args)
PyObject* MatrixPy::isUnity()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
bool ok = getMatrixPtr()->isUnity();
return Py::new_reference_to(Py::Boolean(ok));
@@ -487,11 +488,8 @@ PyObject* MatrixPy::setRow(PyObject * args)
Py_Return;
}
PyObject* MatrixPy::diagonal(PyObject * args)
PyObject* MatrixPy::diagonal()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
Matrix4D* mat = getMatrixPtr();
Base::Vector3d v = mat->diagonal();
return Py::new_reference_to(Py::Vector(v));
@@ -628,11 +626,8 @@ PyObject* MatrixPy::multVec(PyObject * args)
return new VectorPy(new Vector3d(vec));
}
PyObject* MatrixPy::invert(PyObject * args)
PyObject* MatrixPy::invert()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
if (fabs(getMatrixPtr()->determinant()) > DBL_EPSILON) {
getMatrixPtr()->inverseGauss();
@@ -646,11 +641,8 @@ PyObject* MatrixPy::invert(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::inverse(PyObject * args)
PyObject* MatrixPy::inverse()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
if (fabs(getMatrixPtr()->determinant()) > DBL_EPSILON) {
Base::Matrix4D m = *getMatrixPtr();
@@ -665,11 +657,8 @@ PyObject* MatrixPy::inverse(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::determinant(PyObject * args)
PyObject* MatrixPy::determinant()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
return PyFloat_FromDouble(getMatrixPtr()->determinant());
}
@@ -741,11 +730,8 @@ PyObject* MatrixPy::isOrthogonal(PyObject * args)
return Py::new_reference_to(Py::Float(ok ? mult : 0.0));
}
PyObject* MatrixPy::transposed(PyObject * args)
PyObject* MatrixPy::transposed()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
Base::Matrix4D m = *getMatrixPtr();
m.transpose();
@@ -754,11 +740,8 @@ PyObject* MatrixPy::transposed(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::transpose(PyObject * args)
PyObject* MatrixPy::transpose()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
getMatrixPtr()->transpose();
Py_Return;
@@ -766,11 +749,8 @@ PyObject* MatrixPy::transpose(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::analyze(PyObject * args)
PyObject* MatrixPy::analyze()
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
PY_TRY {
std::string type = getMatrixPtr()->analyse();
return PyUnicode_FromString(type.c_str());

View File

@@ -22,6 +22,7 @@
#include "PreCompiled.h"
#include <array>
#include <boost/algorithm/string/predicate.hpp>
#include "Base/Exception.h"
@@ -220,28 +221,8 @@ void Rotation::setValue(const double q[4])
void Rotation::setValue(const Matrix4D & m)
{
auto type = m.hasScale();
if (type == Base::ScaleType::Other) {
THROWM(Base::ValueError, "setValue(matrix): Could not determine the rotation.");
}
Matrix4D mc(m);
if (type != Base::ScaleType::NoScaling) {
mc.setCol(3, Vector3d(0.0, 0.0, 0.0));
if (type == Base::ScaleType::NonUniformRight) {
mc.transpose();
}
double sx = 1.0 / mc.getRow(0).Length();
double sy = 1.0 / mc.getRow(1).Length();
double sz = 1.0 / mc.getRow(2).Length();
mc.scale(sx, sy, sz);
if (type == Base::ScaleType::NonUniformRight) {
mc.transpose();
}
if (mc.determinant3() < 0.0) {
mc.scale(-1.0, -1.0, -1.0);
}
}
// Get the rotation part matrix
Matrix4D mc = m.decompose()[2];
// Extract quaternion
double trace = (mc[0][0] + mc[1][1] + mc[2][2]);
if (trace > 0.0) {