Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GetGlobalPlacement] Issue with the scale computation #159

Open
galou opened this issue Feb 27, 2023 · 2 comments
Open

[GetGlobalPlacement] Issue with the scale computation #159

galou opened this issue Feb 27, 2023 · 2 comments

Comments

@galou
Copy link
Collaborator

galou commented Feb 27, 2023

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?

@galou
Copy link
Collaborator Author

galou commented Feb 27, 2023

Maybe a solution, given a Matrix m 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.

@Jolbas
Copy link
Contributor

Jolbas commented 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.

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants