Page MenuHome

BMesh calc_volume() reports an incorrect volume, off by a significant factor
Closed, ResolvedPublic

Description

System Information
Operating system: Gentoo Linux
Graphics card:

Blender Version
Broken: 2.83.1

I have a funny pipe shaped object. The following script produces a volume of 0.124:

>>> bm = bmesh.new()
>>> bm.from_mesh(bpy.context.active_object.data) # Ensure funny pipe shaped object is selected
>>> bm.calc_volume() # returns 0.124

The actual volume should be approximately 0.521.

The attached file has the script and object ready for you to run :)

Event Timeline

Philipp Oeser (lichtwerk) changed the task status from Needs Triage to Confirmed.Jul 29 2020, 5:35 PM

Can confirm the difference.

Note: still works correctly when you triangulate prior (same as 3D printing does by default)

import bmesh
import bpy
bm = bmesh.new()
bm.from_mesh(bpy.data.objects['IfcActuator/BezierCurve'].data)

# triangulate prior makes the difference
bmesh.ops.triangulate(bm, faces=bm.faces)

print(bm.calc_volume()) # Will return 0.124, correct value should be ~0.52.
# You can confirm this using the 3D print add-on which gives the correct result ias ~0.521m3

Without prior triangulation:

  • normals are already consistent here (would asume this would have caused errors as well)
  • calc_volume code then uses BM_face_calc_tessellation (this seems to be different from BM_face_triangulate which the bmesh.ops.triangulate uses)

For your mesh it already improves splitting non planar faces:

  • Mesh > Clean Up > Split Non-Planar Faces (up to a reported volume of ~0.332)

Then if you move all of the geometry in the quadrant of only positive vertex coordinates it improves further

  • up to a reported volume of ~0.445

This might all be a limitation of the algorithm used, but I would like to ask @Campbell Barton (campbellbarton) if this is to be expected? Could this be more robust?
Tempted to call this a bug, but there might be reasons to do it the way it is now...

If it helps, this is the algorithm I use in Python (which I think I stole from the 3D print add-on), which also gets the correct result of 0.521:

https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.6.0/src/ifcblenderexport/blenderbim/bim/qto.py#L100