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)