# Volume of THREE.BufferGeometry()

**URL:** <https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109>\
**Category:** Resources\
**Tags:** buffergeometry, volume\
**Created:** [November 25, 2018, 10:55pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109 "2018-11-25T22:55:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [November 25, 2018, 10:55pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/1 "2018-11-25T22:55:39Z")

</div>

Hi, community!  
There were several similar questions on SO about how to compute the volume of a geometry.  
I wrote a function, that computes the volume of an buffer geometry (both indexed and non-indexed):

```javascript
  function getVolume(geometry) {
    if (!geometry.isBufferGeometry) {
      console.log("'geometry' must be an indexed or non-indexed buffer geometry");
      return 0;
    }
    var isIndexed = geometry.index !== null;
    let position = geometry.attributes.position;
    let sum = 0;
    let p1 = new THREE.Vector3(),
      p2 = new THREE.Vector3(),
      p3 = new THREE.Vector3();
    if (!isIndexed) {
      let faces = position.count / 3;
      for (let i = 0; i < faces; i++) {
        p1.fromBufferAttribute(position, i * 3 + 0);
        p2.fromBufferAttribute(position, i * 3 + 1);
        p3.fromBufferAttribute(position, i * 3 + 2);
        sum += signedVolumeOfTriangle(p1, p2, p3);
      }
    }
    else {
      let index = geometry.index;
      let faces = index.count / 3;
      for (let i = 0; i < faces; i++){
        p1.fromBufferAttribute(position, index.array[i * 3 + 0]);
        p2.fromBufferAttribute(position, index.array[i * 3 + 1]);
        p3.fromBufferAttribute(position, index.array[i * 3 + 2]);
        sum += signedVolumeOfTriangle(p1, p2, p3);
      }
    }
    return sum;
  }

  function signedVolumeOfTriangle(p1, p2, p3) {
    return p1.dot(p2.cross(p3)) / 6.0;
  }

```

Here is a codepen (have a look at the browser console):  
https://codepen.io/prisoner849/embed/preview/QJxgjb?height=300&slug-hash=QJxgjb&default-tabs=js,result&host=https://codepen.io

Related SO topics:

> <https://stackoverflow.com/questions/1406029/how-to-calculate-the-volume-of-a-3d-mesh-object-the-surface-of-which-is-made-up>

> <https://stackoverflow.com/questions/53459241/three-js-calculate-stl-file-mesh-volume>

PS I hope I didn’t re-invent a bicycle. If I did, just let me know 🙂

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [April 25, 2019, 8:55am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/2 "2019-04-25T08:55:21Z")

</div>

I like it. The method is well-known, but I believe having clear and usable code for it available will be helpful. Have you considered doing a PR to three.js, making it a `BufferGeometry` method?

If I remember right, the method requires the surface to be closed. Would you be able to detect whether or not the surface is closed, perhaps spitting out a warning if it is not?

---

<div class="post-metadata">

**Author:** ![kubinho1032](https://avatars.discourse-cdn.com/v4/letter/k/77aa72/32.png) [@kubinho1032](https://discourse.threejs.org/u/kubinho1032)\
**Post date:** [September 23, 2019, 11:48am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/3 "2019-09-23T11:48:43Z")

</div>

Hello.  
How to calculate volume of TextGeometry? Because this method checks for BufferGeometry.  
Thanks

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 23, 2019, 11:50am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/4 "2019-09-23T11:50:55Z")

</div>

@kubinho1032  
Hi!  
Use `THREE.TextBufferGeometry()` instead.  
Or you can adapt this code to work with usual geometry.

In general, you need to get vertices of each face, something like that:

```auto
geometry.faces.forEach( face => {
    p1.copy(geometry.vertices[face.a]);
    p2.copy(geometry.vertices[face.b]);
    p3.copy(geometry.vertices[face.c]);
    sum += signedVolumeOfTriangle(p1, p2, p3);
})

```

---

<div class="post-metadata">

**Author:** ![kubinho1032](https://avatars.discourse-cdn.com/v4/letter/k/77aa72/32.png) [@kubinho1032](https://discourse.threejs.org/u/kubinho1032)\
**Post date:** [September 23, 2019, 12:12pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/5 "2019-09-23T12:12:54Z")

</div>

Great!  
Thanks!

---

<div class="post-metadata">

**Author:** ![kubinho1032](https://avatars.discourse-cdn.com/v4/letter/k/77aa72/32.png) [@kubinho1032](https://discourse.threejs.org/u/kubinho1032)\
**Post date:** [September 23, 2019, 1:24pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/6 "2019-09-23T13:24:12Z")

</div>

Does scale of mesh affect volume calculating of BufferGeometry?  
I have calculated volume, then changed scale of mesh, finally recalculate the volume and numbers were the same.  
Should I do something special to recalculate it after scale change?  
Thanks

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 23, 2019, 1:33pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/7 "2019-09-23T13:33:04Z")

</div>

No, it doesn’t.  
Scaling doesn’t change original coordinates of vertices.

Maybe this will help:

```auto
geometry.faces.forEach( face => {
    p1.copy(geometry.vertices[face.a]).multiply(mesh.scale);
    p2.copy(geometry.vertices[face.b]).multiply(mesh.scale);
    p3.copy(geometry.vertices[face.c]).multiply(mesh.scale);
    sum += signedVolumeOfTriangle(p1, p2, p3);
})

```

where `mesh` is your text mesh.

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [September 23, 2019, 1:37pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/8 "2019-09-23T13:37:18Z")

</div>

If the scale is uniform you can just multiply the result by that factor.

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 23, 2019, 1:39pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/9 "2019-09-23T13:39:23Z")

</div>

@Fyrestar  
Yeah, also true. We just don’t know what scaling was applied (uniform or non-uniform) 🙂

---

<div class="post-metadata">

**Author:** ![kubinho1032](https://avatars.discourse-cdn.com/v4/letter/k/77aa72/32.png) [@kubinho1032](https://discourse.threejs.org/u/kubinho1032)\
**Post date:** [September 23, 2019, 1:43pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/10 "2019-09-23T13:43:11Z")

</div>

Working fine with TextGeometry and scaling.  
But what about BufferGeometry?  
Im using method provided in first post in this thread to calculate volume.  
Im using three.js for the first time, so sorry if my questions are obvious.

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 23, 2019, 2:27pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/11 "2019-09-23T14:27:40Z")

</div>

> [@kubinho1032](#):
>
> But what about BufferGeometry?

And what about it?  
Feel free to modify the code, provided in the main post. You can multiply `p1`, `p2`, `p3` with scaling vector (if you scale the mesh non-uniformly), or simply multiply the result with the scaling factor (in the case of uniform scaling), like @Fyrestar said before.

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [September 27, 2019, 9:28pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/12 "2019-09-27T21:28:26Z")

</div>

> [@kubinho1032](#):
>
> Should I do something special to recalculate it after scale change?

> [@Fyrestar](#):
>
> If the scale is uniform you can just multiply the result by that factor.

In fact, to scale a volume, just multiply the unscaled volume by the _product_ of the three scale dimensions, regardless of whether the scaling is uniform or not (so `scale**3` for uniform scale). There is no need to recalculate per face.

---

<div class="post-metadata">

**Author:** ![patrikx3](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/patrikx3/32/9606_2.png) [@patrikx3](https://discourse.threejs.org/u/patrikx3)\
**Post date:** [March 2, 2020, 10:13am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/13 "2020-03-02T10:13:57Z")

</div>

could you tell me what the volume type it is? is it cubic meter? or what is this calculated volume?

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [March 2, 2020, 11:21am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/14 "2020-03-02T11:21:56Z")

</div>

@patrikx3 Cubic units.  
About units, take a look at this topic: [Units in Three.js](https://discourse.threejs.org/t/units-in-three-js/1174)

---

<div class="post-metadata">

**Author:** ![looeee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/looeee/32/59_2.png) [@looeee](https://discourse.threejs.org/u/looeee)\
**Post date:** [March 2, 2020, 11:25am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/15 "2020-03-02T11:25:54Z")

</div>

> [@patrikx3](#):
>
> About units, take a look at this topic: [Units in Three.js](https://discourse.threejs.org/t/units-in-three-js/1174)

TL;DR: if you assume 1unit=1metre, then the answer will be in cubic meters. If you assume 1unit=1inch, you’ll get cubic inches, and so on.

---

<div class="post-metadata">

**Author:** ![minichua](https://avatars.discourse-cdn.com/v4/letter/m/919ad9/32.png) [@minichua](https://discourse.threejs.org/u/minichua)\
**Post date:** [November 1, 2021, 3:31pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/16 "2021-11-01T15:31:35Z")

</div>

Is there a way to update the volume for an animated mesh? It seems to compute the volume of the rest position only.

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [January 3, 2022, 11:38pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/17 "2022-01-03T23:38:04Z")

</div>

Apparently, it works on pure geometry, i.e. ignoring all transformations that occur in the vertex shader. If you can afford to apply all the transformations/animation to the geometry itself, the method may work as it is. Otherwise, you may have to try a different approach. Hm, it may perhaps be possible to “trick” a fragment shader into generating similar measurements…

---

<div class="post-metadata">

**Author:** ![oldman](https://avatars.discourse-cdn.com/v4/letter/o/b2d939/32.png) [@oldman](https://discourse.threejs.org/u/oldman)\
**Post date:** [November 11, 2022, 12:09am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/18 "2022-11-11T00:09:12Z")

</div>

What assumptions do you make on the geometry “goodness”?

- closure, water-tightness
- properly oriented faces

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [November 11, 2022, 7:58am UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/19 "2022-11-11T07:58:37Z")

</div>

@oldman I don’t, but the one, who uses it, will do 🤔

---

<div class="post-metadata">

**Author:** ![isalgadof](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/isalgadof/32/36361_2.png) [@isalgadof](https://discourse.threejs.org/u/isalgadof)\
**Post date:** [May 17, 2023, 5:19pm UTC](https://discourse.threejs.org/t/volume-of-three-buffergeometry/5109/20 "2023-05-17T17:19:12Z")

</div>

Just for you: [three-volume - npm](https://www.npmjs.com/package/three-volume)
