Calculate Center of Mass in FreeCAD with Python
This guide explains how to determine the center of mass of any 3D object in FreeCAD using its built-in Python API. By accessing an object's underlying topological shape, you can query its geometric properties directly and extract the precise X, Y, and Z coordinates of its center of mass, whether you are running scripts in FreeCAD's integrated Python console or executing standalone headless macros.
Accessing the Center of Mass for Solid Objects
For objects created in workbenches like Part or Part Design, geometry
is evaluated as a boundary representation (BRep) solid. The
Part.Shape class provides a direct property named
CenterOfMass that calculates this point based on
volume.
Open the Python console in FreeCAD (View > Panels > Python console) and run the following script:
import FreeCAD as App
# Get the active document and select your target object by its name
doc = App.ActiveDocument
obj = doc.getObject("Body") # Replace 'Body' with your object's label/name
# Verify the object has a Shape property
if hasattr(obj, "Shape"):
com = obj.Shape.CenterOfMass
print(f"Center of Mass Vector: {com}")
print(f"X: {com.x:.4f}")
print(f"Y: {com.y:.4f}")
print(f"Z: {com.z:.4f}")
else:
print("The selected object does not have a Part.Shape geometry.")The returned CenterOfMass is a
FreeCAD.Vector representing the coordinates in millimeters
according to the global coordinate system, factoring in the object's
current placement.
Calculating Center of Mass for Multiple Objects
If your model consists of multiple separate solids or an assembly, calculating the total center of mass requires a weighted average based on the volume of each individual solid (assuming uniform material density).
import FreeCAD as App
doc = App.ActiveDocument
total_volume = 0.0
weighted_com = App.Vector(0, 0, 0)
# List of object names to include
object_names = ["Pad", "Pocket", "Cylinder"]
for name in object_names:
obj = doc.getObject(name)
if obj and hasattr(obj, "Shape"):
shape = obj.Shape
vol = shape.Volume
com = shape.CenterOfMass
weighted_com += com * vol
total_volume += vol
if total_volume > 0:
combined_com = weighted_com / total_volume
print(f"Combined Center of Mass: {combined_com}")
else:
print("Total volume is zero; cannot calculate center of mass.")Adding a Visual Marker at the Center of Mass
To visually verify the calculated coordinates within the FreeCAD 3D view, create a datum point or a small vertex at the coordinate location:
import FreeCAD as App
import Part
doc = App.ActiveDocument
obj = doc.ActiveObject
if obj and hasattr(obj, "Shape"):
com = obj.Shape.CenterOfMass
# Create a visual point feature
point_shape = Part.Vertex(com)
com_marker = doc.addObject("Part::Feature", "CenterOfMassMarker")
com_marker.Shape = point_shape
doc.recompute()Handling Mesh Objects
If your object is an imported mesh (STL, OBJ) rather than a solid
feature, it will not have a Shape attribute. You must first
convert it to a shape or calculate the center of mass using the mesh
facets:
import FreeCAD as App
doc = App.ActiveDocument
mesh_obj = doc.getObject("Mesh")
if hasattr(mesh_obj, "Mesh"):
# Calculate geometric center from the mesh boundary box as an approximation
bbox = mesh_obj.Mesh.BoundBox
print(f"Bounding Box Center: {bbox.Center}")
# For an exact mass center, convert mesh to a solid via Part workbench tools:
# Part.Shape().makeShapeFromMesh(mesh_obj.Mesh.Topology, tolerance)