I know I can manually set my origin point but I would like to know why Blender keeps setting the origin of my mesh to the front of my model instead of in the body where it should be when I set Origin to Center of Mass. Why does this happen?
This is based on just a hunch but assuming by in front you mean to the left (-y global axis) blender is not wrong about that center of mass.
from the screenshot you have more faces to the left than to the right.
the more faces you have the more mass it will weight.
as an example two cubes joined together ; one with faces and the other without faces ,
when calculating the origin from the center of mass, blender will place it at the center of the cube with faces.
if you calculate the origin from the geometry, it will be placed exactly in-between the two cubes.
What Blender's "origin to center of mass" does is compute the center of mass of the faces, i.e. it treats the object as a hollow shell with infinitely thin faces.
This is not the same as the center of mass of a solid object with constant density, as this example illustrates:
Blender's CM is the yellow dot, closest to the broad faces of the base
"solid" CM is at cursor's location, closest to the massive cube on top.
Unfortunately, I don't think there is a simple builtin way to compute the "solid" center of mass.
I have written a Python script that does the actual computation, but it will only give a correct result on meshes that define enclosed volumes (possibly with holes, but the outer boundaries must be continuous). It works by summing signed volumes of tetrahedrons defined by all the mesh triangles.
import bpy import mathutils from mathutils import Vector def triangles (verts): """enumerate triangles in a face""" for i in range (1, len(verts)-1): yield (verts, verts[i], verts[i+1]) def cg_mesh (obj): """center of mass (and volume) of a mesh""" center = Vector() volume = 0 mesh = obj.to_mesh (bpy.context.scene, True, 'PREVIEW') for face in mesh.polygons: f = face.vertices for t in triangles (f): a,b,c = (mesh.vertices[v].co for v in t) v = a.cross(b).dot(c) / 6 center += v * (a+b+c) / 4 volume += v bpy.data.meshes.remove(mesh) if volume == 0: print ("ZERO VOLUME", obj.name) else : center /= volume return obj.matrix_world * center # puts the cursor at the active object's center of mass bpy.context.scene.cursor_location = cg_mesh (bpy.context.scene.objects.active)
This example will put the 3D cursor at the "solid" CM location, but you can adapt the script to do whatever you want.
The script applies all modifiers to the object, converting it to a mesh. If you want the CM of your primitive object, disable the modifiers first.
On the other hand, you can use it on a flat object by adding a "solidify" modifier first.
Again, no checks are made to insure the mesh defines a valid volume. If not, the result will be wrong.
I did a couple of tests and I find using "origin to geometry" works better as it finds the center of the object whereas the "origin to center of mass" finds the center of the weight. Thus "origin to mass" is best for physics but I usually work with "origin to geometry". So if your model won't be used for physics use "origin to geometry". I don't know what this could be but it would be helpful to see if your mesh has depth,though this could be a bug but I don't want to jump to conclusions staight away. Hope I was helful.