Determining the volume of a mesh

Although Blender is not really a CAD program, many people use it for CAD-like issues such as architectural visualization. Blender is capable of importing many types of files including those of major CAD programs, so including technical models drawn to precise measurements is never a problem.

These CAD programs often offer all kinds of tools to measure the dimensions of (parts of) your model, yet Blender, by its nature, provides very few of those tools. It is possible to inspect the size and location of an object by pressing the N key in the 3D view window. In edit mode you may enable the display of edge lengths, edge angles, and face areas (see the panel Mesh tools more in the editing context (F9) of the Buttons window) but that is about as far as it gets.

Python may overcome those limitations in situations where we need some specific measurement and exporting our model to a CAD tool is not an option. A practical example is the calculation of the volume of a mesh. Nowadays, a number of companies offer possibilities to re-create your digital model as real world objects by way of 3D printing techniques. I have to say it is a rather special feeling to hold a plastic or even metal replica of your Blender model in your hands, it really adds a whole new dimension to 3D.

Now a major component of the price of 3D-printing a model is the amount of material that will be used. Often, it will be possible to design your model as a hollow object that takes less material to produce, but it is quite inconvenient to upload intermediate versions of your model again and again to let the manufacturer's software calculate the volume and give you a price quote. So what we would like to have is a script that can calculate the volume of a mesh in a fairly accurate manner.

A common method to calculate the volume of a mesh is sometimes referred to as the Surveyor's Formula as it is related to the way surveyors may calculate the volume of a hill or mountain by triangulating its surface.

The central idea is to split a triangulated mesh into many columns that have their base on the xy-plane.

The surface area of the triangle projected onto the xy-plane times the average z-position of the three vertices then gives the volume of such a column. Summing these volumes finally gives the volume of the complete mesh (see the next figure).

Determining the volume of a mesh

There are a couple of things that have to be taken into account. First, a mesh may extend below the xy-plane. If we construct a column from a face that lies below the xy-plane, the product of the projected area and the average of the z-coordinates will be a negative number, so we have to negate its value to get a volume.

Determining the volume of a mesh

Second, a mesh may lie completely or partially above the xy-plane. If we take a look at the example in the previous diagram we see that the object has two triangles that contribute to the volume of the object, the top and bottom ones (the vertical triangles have a projected area of zero, so will contribute nothing). As the top and bottom faces both lie above the xy-plane, we have to subtract the volume of the column constructed from the bottom face from the one constructed from the top face. If the object was completely below the xy-plane it would be the other way around, and we would have to subtract the volume of the top column from the volume of the bottom column.

How we can tell what to do is determined by the direction of the face normal of our triangles. If, for example, a triangle is above the xy-plane but its face normal is pointing downward (it has a negative z-component), then we have to subtract the calculated volume. It is therefore vital that all face normals point consistently outward (in edit mode, select all faces and press Ctrl + N).

If we take into account all four possibilities (face normal up or down, face above or below the xy-plane) we can write the following outline for our function:

  1. Make sure all face normals consistently point outward.
  2. For all faces:
    • Calculate the z-component of face normal vector Nz
    • Calculate the product P of the average z-coordinates and the projected surface area.
    • If Nz is positive: add P
    • If Nz is negative: subtract P

This nifty algorithm works for simple objects without holes and just as well for objects containing holes (such as a torus), or even hollow ones (that is, containing an object completely enclosed in another object) like the examples shown in the following screenshot:

Determining the volume of a mesh

Because we allow the product of area and z-coordinates to be negative, we have to check only for the direction of the face normal to cover all situations.

Note

Note that it is necessary for the mesh to be closed and manifold: There shouldn't be any missing faces nor should there be any edges that do not share exactly two faces, such as interior faces.

Determining the volume of a mesh

The important part of the code is shown here (the complete script is called volume.py):

def meshvolume(me):
volume = 0.0
for f in me.faces:

xy_area = Mathutils.TriangleArea(vec(f.v[0].co[:2]), vec(f.v[1].co[:2]),vec(f.v[2].co[:2]))
Nz = f.no[2]
avg_z = sum([f.v[i].co[2] for i in range(3)])/3.0
partial_volume = avg_z * xy_area
if Nz < 0: volume -= partial_volume
if Nz > 0: volume += partial_volume
return volume

The highlighted code shows how we calculate the area of the triangle projected on the xy-plane. TriangleArea() will calculate the area of a two-dimensional triangle when given two dimensional points (points in the xy-plane). So we pass not the full coordinate vectors of the vertices, but truncate them (that is, we drop the z-coordinate) into two component vectors.

After running the script from the text editor, or from the Scripts menu when in object mode, a pop up is displayed showing the volume in Blender units. Before running the script make sure that all modifiers are applied, scale and rotation are applied (Ctrl + A in object mode), the mesh is fully triangulated (Ctrl + T in edit mode), and that the mesh is manifold (closed or water-tight) by checking for non-manifold edges (Ctrl + Alt + Shift +M in edge selection mode). Manifold edges are edges that are shared by exactly two faces. Also make sure that all normals are pointing in the right direction. The application of modifiers is necessary to make the mesh closed (if it is a mirror modifier) and to make the calculation of the volume accurate (if it is a subsurface modifier).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.134.133