[Bug]: [freecad] measure center-of-mass wrong for sphere/cylinder/cone/torus

Author: Surya-koushikCreated Aug 25, 2026Updated Aug 25, 2026

Affected Software/Harness

freecad (cli-anything-freecad)

Version / Commit

cli-anything-freecad 1.1.0 (via cli-hub info freecad), cli-anything-hub 0.4.1

Operating System

Windows

Python Version

3.13.13

Steps to Reproduce

cli-anything-freecad document new -o doc.json
cli-anything-freecad --project doc.json part add sphere -pos 0,0,0 -P radius=10
cli-anything-freecad --project doc.json measure position 0
cli-anything-freecad --project doc.json measure center-of-mass 0

# control case, same origin
cli-anything-freecad --project doc.json part add box -pos 0,0,0 -P length=10 -P width=10 -P height=10
cli-anything-freecad --project doc.json measure center-of-mass 1

Expected Behavior

For a sphere, measure center-of-mass should return the same point as measure position (a sphere is centrally symmetric about its own placement — its center of mass is its placement position, by definition, independent of any external convention). This is self-consistent within the harness's own data model, not an assumption about FreeCAD internals.

Actual Behavior

measure position 0        -> position: [0.0, 0.0, 0.0]
measure center-of-mass 0  -> center_of_mass: [10.0, 10.0, 10.0]

The reported center of mass is ~17.3 units from the origin — outside the sphere's own surface (radius 10) — for a sphere the harness's own measure position says is placed exactly at the origin. The box control at the same origin correctly returns [5.0, 5.0, 5.0] (its true geometric center, since a FreeCAD box's placement is its min corner), confirming the harness's box-center math is fine and the bug is specific to the other primitive types.

Relevant Logs / Tracebacks

$ cli-anything-freecad --project doc.json measure center-of-mass 0
Center of mass: [10.0, 10.0, 10.0]
  id: 1
  kind: center_of_mass
  part_index: 0
  center_of_mass: [10.0, 10.0, 10.0]

No exception — this is a silent, wrong-value bug, not a crash.

Root cause

cli_anything/freecad/core/measure.py, function _bbox_center() (called by measure_center_of_mass()), computes every primitive's bounding-box center by adding a min-corner offset to Placement.position:

elif t == "sphere":
    r = p["radius"]
    return [pos[0] + r, pos[1] + r, pos[2] + r]

and the analogous pos[i] + r/pos[2] + height/2 pattern for cylinder, cone, and torus. This is only correct for box and wedge, whose placement really is their bounding-box min corner. For sphere, cylinder, cone, and torus, the harness's own measure position / part add -pos treats the placement as the shape's own center (sphere, cylinder, cone) or torus center — so adding the radius again double-counts the offset and produces a point that is wrong (and, as in the sphere case above, physically outside the solid).

Affects: sphere, cylinder, cone, torus. Confirmed box is correct; did not test wedge.

Suggested Fix

In _bbox_center(), for sphere/cylinder/cone/torus, return pos (or pos with only the z-offset already used for height, where applicable) directly rather than adding the radius — matching what measure_position() already reports for the same part. box/wedge can keep their current min-corner-based math.