You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[GetGlobalPlacement] Issue with the scale computation #159
The macro return the wrong result for an object with rotation 0.45642222410108496, 0.49809724456331667, 0.5849212871934979, -0.4488262203714842. The returned scale factor is -1, -1, 1 but should be 1, 1, 1. According to this, the scale computation involves the eigenvalue decomposition.
I already fixed the issue for objects that are not scaled in 47dbb41. The issue subsists for scaled objects but a warning is printed.
I added a test for this.
@Jolbas do you have the capacity to have a look at this?
Maybe a solution, given a Matrixm with rotation and scaling, Rotation(m).toMatrix().inverse() * m returns a matrix whose diagonal elements are the scaling factors. The method is not very accurate though (+/- 0.0003) and I don't know how generic it is.
I don't know how to do the polar decomposition yet. But I know for sure there is no way to distinguish between a matrix representing no scaling at all and one that is a combination of scale(-1,-1,1) and a rotation of 180 degrees. Only option is to assume that all scale factors have the same sign. There is work going on to fix related issues in the creation of a rotation from a matrix. Maybe following code will work for now.
return_type_link_matrix = 6 # Cf. DocumentObjectPyImp.cpp::getSubObject (l.417).
matrix = object.getSubObject(subobject_fullpath, return_type_link_matrix,
transform=True)
if matrix is None:
return
scale_type = matrix.hasScale(1e-7)
if scale_type == ScaleType.Other:
app.Console.PrintWarning('Too complex transformation to find rotation\n')
return
if scale_type == app.ScaleType.NoScaling:
return app.Placement(matrix), app.Vector(1.0, 1.0, 1.0)
position = matrix.col(3)
matrix.setCol(3, app.Vector())
scale_type = matrix.hasScale(1e-5)
if scale_type == ScaleType.NonUniformRight:
matrix.transpose()
scale_vec = App.Vector(*(m.row(i).Length for i in range(3)))
matrix.scale(*(1 / s for s in scale_vec))
if scale_type == ScaleType.NonUniformRight:
matrix.transpose()
if matrix.determinant() < 0:
matrix.scale(-1)
scale_vec *= -1
matrix.setCol(3, position)
return app.Placement(matrix), scale_vec
Activity
galou commentedon Feb 27, 2023
Maybe a solution, given a
Matrixmwith rotation and scaling,Rotation(m).toMatrix().inverse() * mreturns a matrix whose diagonal elements are the scaling factors. The method is not very accurate though (+/- 0.0003) and I don't know how generic it is.Jolbas commentedon Feb 27, 2023
I don't know how to do the polar decomposition yet. But I know for sure there is no way to distinguish between a matrix representing no scaling at all and one that is a combination of scale(-1,-1,1) and a rotation of 180 degrees. Only option is to assume that all scale factors have the same sign. There is work going on to fix related issues in the creation of a rotation from a matrix. Maybe following code will work for now.