Python Matrix Transformations on FreeCAD Objects
Performing matrix transformations on FreeCAD objects using Python allows you to precisely manipulate geometry through 4x4 transformation matrices, enabling translation, rotation, scaling, and shearing. This guide covers how to construct transformation matrices using the FreeCAD API, apply them to an object's spatial placement, and transform underlying geometric shapes directly for advanced modeling tasks.
Understanding FreeCAD Matrix Basics
FreeCAD provides the FreeCAD.Matrix class to represent
4x4 affine transformation matrices. A 4x4 matrix can represent 3D
translation, rotation, scaling, and shear in homogeneous
coordinates.
To initialize an identity matrix:
import FreeCAD as App
import FreeCADGui as Gui
# Create a 4x4 identity matrix
mat = App.Matrix()You can define matrix elements manually or use built-in manipulation methods:
mat.move(App.Vector(x, y, z))applies a translation.mat.rotateX(angle_in_radians),mat.rotateY(angle),mat.rotateZ(angle)apply rotations around global axes.mat.scale(App.Vector(sx, sy, sz))applies scaling along each axis.
Method 1: Transforming Object Placement
FreeCAD objects have a Placement property defining their
location and orientation in the 3D scene. This method is ideal for
rigid-body transformations (translations and rotations) because it
updates the object's position without altering its underlying topology
or geometry.
import FreeCAD as App
doc = App.ActiveDocument
obj = doc.ActiveObject
# Create and define the transformation matrix
mat = App.Matrix()
mat.move(App.Vector(10, 0, 5)) # Translate 10 mm in X, 5 mm in Z
mat.rotateZ(1.5708) # Rotate ~90 degrees around Z axis (in radians)
# Convert the matrix into a Placement and apply it
new_placement = App.Placement(mat)
# Option A: Replace current placement entirely
obj.Placement = new_placement
# Option B: Multiply with current placement to apply relatively
# obj.Placement = new_placement.multiply(obj.Placement)
doc.recompute()Note: Object Placement only supports rigid
transformations. If your matrix includes non-uniform scaling or
shearing, converting it to a Placement will discard those
non-rigid components.
Method 2: Transforming Geometry Directly
To apply non-uniform scaling, reflection, or shearing, you must apply
the matrix directly to the object's Shape using
OpenCASCADE-level transformations.
FreeCAD's Part.Shape provides two primary methods:
transformShape(Matrix): Alters the shape geometry in-place.transformGeometry(Matrix): Creates and returns a transformed copy of the geometry.
import FreeCAD as App
import Part
doc = App.ActiveDocument
obj = doc.ActiveObject
# Define a transformation matrix with non-uniform scaling
mat = App.Matrix(
2.0, 0.0, 0.0, 10.0, # Row 1: X-scale = 2, X-translation = 10
0.0, 1.0, 0.0, 0.0, # Row 2: Y-scale = 1
0.0, 0.0, 0.5, 0.0, # Row 3: Z-scale = 0.5
0.0, 0.0, 0.0, 1.0 # Row 4: Homogeneous coordinate
)
# Apply transformation directly to the shape
transformed_shape = obj.Shape.transformGeometry(mat)
# Assign the transformed shape back to the object
obj.Shape = transformed_shape
doc.recompute()Combining Matrix Transformations
Matrix multiplication is associative, allowing you to combine several
discrete transformations into a single operation. In FreeCAD, operations
are executed in order using the multVec() or matrix
multiplication methods.
import FreeCAD as App
# Matrix A: Translation
mat_trans = App.Matrix()
mat_trans.move(App.Vector(50, 0, 0))
# Matrix B: Rotation
mat_rot = App.Matrix()
mat_rot.rotateY(0.7854) # 45 degrees
# Combined transformation: mat_trans * mat_rot
combined_mat = mat_trans.multiply(mat_rot)
# Apply to active object
obj = App.ActiveDocument.ActiveObject
obj.Placement = App.Placement(combined_mat)
App.ActiveDocument.recompute()Always call doc.recompute() after altering an object's
Placement or Shape to refresh the graphical
viewport and dependency graph.