Blender has a command to move an object’s origin ([0,0,0] point) to its center of mass. There’s a corresponding function call in in the Blender Python package bpy:
bpy.ops.object.origin_set(type=’ORIGIN_CENTER_OF_MASS’)
I wondered how it calculates the center of mass when the object is a triangular mesh (i.e. a bunch of triangles joined at their edges).
The API documentation for Blender 2.74 (the version I’m using) says the following about the above function call: “Move object origin to the object center of mass (assuming uniform density).” Also, bpy.ops.object.origin_set() can take an optional second argument; it can be center=’MEDIAN’ or center=’BOUNDS’. The default value is center=’MEDIAN’. After reading that, I still had many questions:
- Does it calculate the center of mass of the vertices? Does it weight them somehow? (Center of mass is a physical property of the object; it shouldn’t depend on the mesh used. We don’t want a dense mesh on one side of the object to outweigh a sparse mesh on the opposite side.)
- Does it calculate the center of mass of the faces? Does it weight them somehow (presumably by their area)?
- Does it construct some sort of 3D tesselation of the object and calculate the center of mass of that? Are we assuming the object is a solid or a hollow shell?
- And what’s that business about center=’MEDIAN’ being the default? Surely it doesn’t calculate the “center” as being the median of some distribution? Surely it calculates the average or weighted average, but DOES it?
I went digging in the Blender 2.74 source code (available at http://download.blender.org/source/ ) for some answers. The function in question is implemented in:
/blender-2.74/source/blender/editors/object/object_transform.c
and it has a call to the function BKE_mesh_center_centroid(), which is implemented in:
/blender-2.74/source/blender/blenkernel/intern/mesh_evaluate.c
and it calls the function mesh_calc_poly_planar_area_centroid(), which is also implemented in mesh_evaluate.c. Reading those source files answered my questions:
- Blender calculates a weighted average of face centroids, with the weights being the face areas. (The center of mass of a uniform-density object is the same as its centroid, so it’s fine to calculate centroids.)
- In other words, it assumes the object is a hollow shell (not solid).
- There is no “median” calculation. It’s an average.
We’d get much the same result if we randomly generated points uniformly on the mesh faces, with the probability of a point being generated somewhere on a particular face being proportional to the area of that face.
That’s the right way to calculate the center of mass of a hollow shell, because the center of mass is a physical property of the object; it shouldn’t depend on the mesh used to describe it.
If you’re using Blender to design a 3D model to be printed by a 3D printer, then you should know that the center of mass of a solid object is not the same as the center of mass of a hollow object of the same shape (which is what Blender calculates).
Image Credit: Light Bike 2.0″ by Bruno Alberto on Flickr is licensed under a Creative Commons Attribution 2.0 license