Working with Transformation Matrices and Placement Objects

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Working with Transformation Matrices and Placement Objects

Post by shoogen »

Hi,
is there a way to analyse if a given transformation matrix can be represented using a placement object?
So if this is the case i can apply the transformation on the Placement object.
In the (rare) case when there are operations like shearing and scaling involved I'd like to chave a PythonFeature that applies the Transformation to the Shape.

Version: 0.13.0681 (32bit) on Win7 (64bit)
wmayer
Founder
Posts: 20310
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Working with Transformation Matrices and Placement Objects

Post by wmayer »

A placement is described by a translation and a rotation. The first three elements of the 4th column of the 4x4 matrix is the translation part and the 3x3 sub-matrix is the rotation part. The 4th row is always 0, 0, 0, 1.

A rotation matrix is always a so called orthonormal matrix which means that if you consider the three columns or rows as vectors that they have a length of 1 and that the vectors are orthogonal to each other.
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Working with Transformation Matrices and Placement Objects

Post by shoogen »

wmayer wrote:A rotation matrix is always a so called orthonormal matrix.
Thank You

I found out that i also have to check for a determinant of +1.
The question is, whether it makes any difference in testing the 4x4 or the 3x3 matrix?
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Working with Transformation Matrices and Placement Objects

Post by shoogen »

I tried to implement a python feature to applay a transformation matrix. But unfortunately it breaks boolean operations.

Code: Select all

>>> [(f.Shape.check(), f.Shape.ShapeType) for f in App.ActiveDocument.union.Shapes]
[(None, 'Solid'), (None, 'Solid'), (None, 'Solid')]
>>> App.ActiveDocument.union.Shape.check()
StandardError
Image

Code: Select all

class MatrixTransform:
    def __init__(self, obj,matrix=None,child=None):
        obj.Proxy = self
        self.matrix = matrix
        self.child = child

    def execute(self, fp):
        if self.matrix and self.child:
            sh=self.child.Shape#.copy()
            m=self.child.Placement.toMatrix().multiply(self.matrix)
            fp.Shape = sh.transformGeometry(m)
            #fp.Shape = sh.transformShape(m)
transformShape doesn't work at all in 0.13.0681 (This object is immutable, ...)
Please do not expect the Feature in the attached file to do recomputation as I got 'PropertyPythonObject::toString: can't pickle Matrix objects' errors.
To recreate the file execute

Code: Select all

import csgparser
csgparser.parsenode(csgparser.csgstr)[0].flattengroups().addtofreecad(App.ActiveDocument)
https://raw.github.com/gist/1967104/csgparser.py
Attachments
bool1.FCStd
(10.84 KiB) Downloaded 176 times
wmayer
Founder
Posts: 20310
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Working with Transformation Matrices and Placement Objects

Post by wmayer »

Do not use transformGeometry() because this changes the underlying geometry to b-spline and the boolean ops have problems with that. Instead assign the matrix directly to the placement.

Code: Select all

            sh=self.child.Shape.copy()
            m=self.child.Placement.toMatrix().multiply(self.matrix)
            fp.Shape.Placement = m
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Working with Transformation Matrices and Placement Objects

Post by shoogen »

wmayer wrote:Instead assign the matrix directly to the placement.
Thanks You,
but is doesn't work in Version: 0.13.0681
And will an assignment of an Matrix to a Placement keep scaling, and mirroring?

Code: Select all

>>> App.ActiveDocument.multmatrix.Shape.Placement=FreeCAD.Matrix()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ReferenceError: This object is immutable, you can not set any attribute or call a method
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Working with Transformation Matrices and Placement Objects

Post by shoogen »

Hi Werner,
Thank you very much.
I found a way (for orthonormal matrices)

Code: Select all

obj.Placement=FreeCAD.Placement(m1).multiply(obj.Placement)
for non orthonormal matrices I have to stick with transformGeometry for the moment.
And that's it
Image
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Working with Transformation Matrices and Placement Objects

Post by shoogen »

wmayer wrote:A placement is described by a translation and a rotation. The first three elements of the 4th column of the 4x4 matrix is the translation part and the 3x3 sub-matrix is the rotation part. The 4th row is always 0, 0, 0, 1.

A rotation matrix is always a so called orthonormal matrix which means that if you consider the three columns or rows as vectors that they have a length of 1 and that the vectors are orthogonal to each other.
I've added the code to check if a "Placement object can represent a given transformation matrix" <==> 3x3 Submatrix is in Rotation group SO(3) <==> 3x3 Submatrix is special orthogonal

Code: Select all

>>> fcmatrix=FreeCAD.Matrix(); csgparser.isspecialorthogonal(csgparser.fcsubmatrix(fcmatrix))
True
>>> fcmatrix.rotateX(2); csgparser.isspecialorthogonal(csgparser.fcsubmatrix(fcmatrix))
True
>>> fcmatrix.move((1,2,3)); csgparser.isspecialorthogonal(csgparser.fcsubmatrix(fcmatrix))
True
>>> fcmatrix.scale(2,2,2); csgparser.isspecialorthogonal(csgparser.fcsubmatrix(fcmatrix))
False
https://raw.github.com/gist/1967104/csgparser.py
Post Reply