Hi
does anybody know of a script that can calculate the volume or mass of a closed mesh object?
Hi
does anybody know of a script that can calculate the volume or mass of a closed mesh object?
Hi,
based on http://stackoverflow.com/questions/1406029/how-to-calculate-the-volume-of-a-3d-mesh-object-the-surface-of-which-is-made-up, I created the following script:
import bpy
def SignedTriangleVolume(v1, v2, v3):
return v1.dot(v2.cross(v3)) / 6.0
def TriangleMeshVolume():
polygons = bpy.context.active_object.data.polygons
vertices = bpy.context.active_object.data.vertices
volume = 0
for polygon in polygons:
volume += SignedTriangleVolume(vertices[polygon.vertices[0]].co, vertices[polygon.vertices[1]].co, vertices[polygon.vertices[2]].co)
return abs(volume)
if __name__ == "__main__":
print(TriangleMeshVolume())
It’s very rough and has several restrictions:
these restrictions could easily be overcome, but with a little more time (which I am lacking at the moment)
best regards
blackno666
I copy the text into the note editor and run the script while having the object selected?
Here you go, works on tessfaces (so no matter if tris, quads or ngons), takes object scale into account and prints to info area. Paste code in text editor, run, then hit Spacebar over 3d view and type “Mesh Volume”
import bpy
class MeshVolume(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.mesh_volume"
bl_label = "Mesh Volume"
@classmethod
def poll(cls, context):
return (context.active_object is not None and
context.active_object.type == 'MESH')
def execute(self, context):
volume = 0
ob = context.active_object
ob_mat = ob.matrix_world
me = ob.data
me.calc_tessface()
for tf in me.tessfaces:
tfv = tf.vertices
if len(tf.vertices) == 3:
tf_tris = (me.vertices[tfv[0]], me.vertices[tfv[1]], me.vertices[tfv[2]]),
else:
tf_tris = (me.vertices[tfv[0]], me.vertices[tfv[1]], me.vertices[tfv[2]]),\
(me.vertices[tfv[2]], me.vertices[tfv[3]], me.vertices[tfv[0]])
for tf_iter in tf_tris:
v1 = ob_mat * tf_iter[0].co
v2 = ob_mat * tf_iter[1].co
v3 = ob_mat * tf_iter[2].co
volume += v1.dot(v2.cross(v3)) / 6.0
self.report({'INFO'}, "Volume: %2.f" % volume)
return {'FINISHED'}
def register():
bpy.utils.register_class(MeshVolume)
def unregister():
bpy.utils.unregister_class(MeshVolume)
if __name__ == "__main__":
register()
This isn’t optimized in any way and did not change the way of calculation
Oddly it only says that the volume is “0” ???
the Volume has been output with no significant digits: so change the line:
self.report({'INFO'}, "Volume: %2.f" % volume)
to
self.report({'INFO'}, "Volume: %.2f" % volume)
(the %.2f) means to print two significant digits (change to your liking, e.g. %.4f for a more precise output)
There’s a Volume option in the Measure Panel addon. Other than not accepting ngons, it seems to be in working order.
ENCN
the script works well. Really too bad that I googled for a measure tool but nothing came up in Google besides scripts from 2005.
COD and Blackno
thanks for the effort as well. The script works, just needed to adjust the decimale steps after the dot because I measure a small object.
Nice script !
Thanks
Included 3d print toolbox addon has volume calculation.
Thanks, It works well
I am using Blender 2.9 , somehow I cannot see any outcome of this script, could it be because of Blender version is not suitable ? After I run the script, in the search box (F3 shortcut in ver.2.9) there is no such thing “Mesh Volume” appears. Thanks.