three.js calculate STL file mesh volume





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







-1















I have to calculate the volume of an STL file, I successfully got the sizes of the model with



var box = new THREE.Box3().setFromObject( mesh );
var sizes = box.getSize();


but I just can't wrap my head around the concept of calculating it. I load the model with



var loader = new THREE.STLLoader();
loader.load(stlFileURL, function ( geometry ) {});


Can someone help me out and point me in the right direction? I'm doing it with javascript.










share|improve this question























  • Are you trying to estimate how much filament for 3d printing?

    – manthrax
    Nov 24 '18 at 17:03











  • Have a look at this SO thread.

    – prisoner849
    Nov 24 '18 at 17:58











  • @manthrax exactly

    – John
    Nov 24 '18 at 20:22


















-1















I have to calculate the volume of an STL file, I successfully got the sizes of the model with



var box = new THREE.Box3().setFromObject( mesh );
var sizes = box.getSize();


but I just can't wrap my head around the concept of calculating it. I load the model with



var loader = new THREE.STLLoader();
loader.load(stlFileURL, function ( geometry ) {});


Can someone help me out and point me in the right direction? I'm doing it with javascript.










share|improve this question























  • Are you trying to estimate how much filament for 3d printing?

    – manthrax
    Nov 24 '18 at 17:03











  • Have a look at this SO thread.

    – prisoner849
    Nov 24 '18 at 17:58











  • @manthrax exactly

    – John
    Nov 24 '18 at 20:22














-1












-1








-1








I have to calculate the volume of an STL file, I successfully got the sizes of the model with



var box = new THREE.Box3().setFromObject( mesh );
var sizes = box.getSize();


but I just can't wrap my head around the concept of calculating it. I load the model with



var loader = new THREE.STLLoader();
loader.load(stlFileURL, function ( geometry ) {});


Can someone help me out and point me in the right direction? I'm doing it with javascript.










share|improve this question














I have to calculate the volume of an STL file, I successfully got the sizes of the model with



var box = new THREE.Box3().setFromObject( mesh );
var sizes = box.getSize();


but I just can't wrap my head around the concept of calculating it. I load the model with



var loader = new THREE.STLLoader();
loader.load(stlFileURL, function ( geometry ) {});


Can someone help me out and point me in the right direction? I'm doing it with javascript.







javascript three.js






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 '18 at 14:37









JohnJohn

269




269













  • Are you trying to estimate how much filament for 3d printing?

    – manthrax
    Nov 24 '18 at 17:03











  • Have a look at this SO thread.

    – prisoner849
    Nov 24 '18 at 17:58











  • @manthrax exactly

    – John
    Nov 24 '18 at 20:22



















  • Are you trying to estimate how much filament for 3d printing?

    – manthrax
    Nov 24 '18 at 17:03











  • Have a look at this SO thread.

    – prisoner849
    Nov 24 '18 at 17:58











  • @manthrax exactly

    – John
    Nov 24 '18 at 20:22

















Are you trying to estimate how much filament for 3d printing?

– manthrax
Nov 24 '18 at 17:03





Are you trying to estimate how much filament for 3d printing?

– manthrax
Nov 24 '18 at 17:03













Have a look at this SO thread.

– prisoner849
Nov 24 '18 at 17:58





Have a look at this SO thread.

– prisoner849
Nov 24 '18 at 17:58













@manthrax exactly

– John
Nov 24 '18 at 20:22





@manthrax exactly

– John
Nov 24 '18 at 20:22












2 Answers
2






active

oldest

votes


















1














You can find it with the algorithm from my comment.



In the code snippet, the volume is computed without scaling.



Also, I've added a simple check that the algorithm calculates correctly by finding the volume of a hollow cylinder. As THREE.STLLoader() returns a non-indexed geometry, I've casted the geometry of the cylinder to non-indexed too.



Related forum topic






var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.setScalar(20);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x404040);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var loader = new THREE.STLLoader();
loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
color: 0xff00ff,
wireframe: true
}));
mesh.rotation.set(-Math.PI / 2, 0, 0);
mesh.scale.setScalar(100);
scene.add(mesh);

console.log("stl volume is " + getVolume(geometry));
});

// check with known volume:
var hollowCylinderGeom = new THREE.LatheBufferGeometry([
new THREE.Vector2(1, 0),
new THREE.Vector2(2, 0),
new THREE.Vector2(2, 2),
new THREE.Vector2(1, 2),
new THREE.Vector2(1, 0)
], 90).toNonIndexed();
console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


function getVolume(geometry) {

let position = geometry.attributes.position;
let faces = position.count / 3;
let sum = 0;
let p1 = new THREE.Vector3(),
p2 = new THREE.Vector3(),
p3 = new THREE.Vector3();
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);
}
return sum;

}

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

renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});

body {
overflow: hidden;
margin: 0;
}

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>








share|improve this answer


























  • This calculates the sum of the areas of the triangles?

    – manthrax
    Nov 26 '18 at 13:51











  • Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

    – manthrax
    Nov 26 '18 at 13:52






  • 1





    @manthrax Works for those geometries that have no self-intersections/overlapping.

    – prisoner849
    Nov 26 '18 at 13:56











  • so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

    – manthrax
    Nov 26 '18 at 14:06






  • 1





    @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

    – prisoner849
    Nov 27 '18 at 9:07



















-1














This is a pretty tricky problem. One way is to decompose the object into a bunch of convex polyhedra and sum the volumes of those...



Another way is to voxelize it, and add up the voxels on the inside to get an estimate whos accuracy is limited by the resolution of your voxelization.



Edit: prisoner849 has a rad solution!






share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459241%2fthree-js-calculate-stl-file-mesh-volume%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    You can find it with the algorithm from my comment.



    In the code snippet, the volume is computed without scaling.



    Also, I've added a simple check that the algorithm calculates correctly by finding the volume of a hollow cylinder. As THREE.STLLoader() returns a non-indexed geometry, I've casted the geometry of the cylinder to non-indexed too.



    Related forum topic






    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.setScalar(20);
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x404040);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.STLLoader();
    loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

    var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
    }));
    mesh.rotation.set(-Math.PI / 2, 0, 0);
    mesh.scale.setScalar(100);
    scene.add(mesh);

    console.log("stl volume is " + getVolume(geometry));
    });

    // check with known volume:
    var hollowCylinderGeom = new THREE.LatheBufferGeometry([
    new THREE.Vector2(1, 0),
    new THREE.Vector2(2, 0),
    new THREE.Vector2(2, 2),
    new THREE.Vector2(1, 2),
    new THREE.Vector2(1, 0)
    ], 90).toNonIndexed();
    console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
    console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


    function getVolume(geometry) {

    let position = geometry.attributes.position;
    let faces = position.count / 3;
    let sum = 0;
    let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
    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);
    }
    return sum;

    }

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

    renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    });

    body {
    overflow: hidden;
    margin: 0;
    }

    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>








    share|improve this answer


























    • This calculates the sum of the areas of the triangles?

      – manthrax
      Nov 26 '18 at 13:51











    • Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

      – manthrax
      Nov 26 '18 at 13:52






    • 1





      @manthrax Works for those geometries that have no self-intersections/overlapping.

      – prisoner849
      Nov 26 '18 at 13:56











    • so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

      – manthrax
      Nov 26 '18 at 14:06






    • 1





      @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

      – prisoner849
      Nov 27 '18 at 9:07
















    1














    You can find it with the algorithm from my comment.



    In the code snippet, the volume is computed without scaling.



    Also, I've added a simple check that the algorithm calculates correctly by finding the volume of a hollow cylinder. As THREE.STLLoader() returns a non-indexed geometry, I've casted the geometry of the cylinder to non-indexed too.



    Related forum topic






    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.setScalar(20);
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x404040);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.STLLoader();
    loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

    var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
    }));
    mesh.rotation.set(-Math.PI / 2, 0, 0);
    mesh.scale.setScalar(100);
    scene.add(mesh);

    console.log("stl volume is " + getVolume(geometry));
    });

    // check with known volume:
    var hollowCylinderGeom = new THREE.LatheBufferGeometry([
    new THREE.Vector2(1, 0),
    new THREE.Vector2(2, 0),
    new THREE.Vector2(2, 2),
    new THREE.Vector2(1, 2),
    new THREE.Vector2(1, 0)
    ], 90).toNonIndexed();
    console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
    console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


    function getVolume(geometry) {

    let position = geometry.attributes.position;
    let faces = position.count / 3;
    let sum = 0;
    let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
    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);
    }
    return sum;

    }

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

    renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    });

    body {
    overflow: hidden;
    margin: 0;
    }

    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>








    share|improve this answer


























    • This calculates the sum of the areas of the triangles?

      – manthrax
      Nov 26 '18 at 13:51











    • Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

      – manthrax
      Nov 26 '18 at 13:52






    • 1





      @manthrax Works for those geometries that have no self-intersections/overlapping.

      – prisoner849
      Nov 26 '18 at 13:56











    • so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

      – manthrax
      Nov 26 '18 at 14:06






    • 1





      @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

      – prisoner849
      Nov 27 '18 at 9:07














    1












    1








    1







    You can find it with the algorithm from my comment.



    In the code snippet, the volume is computed without scaling.



    Also, I've added a simple check that the algorithm calculates correctly by finding the volume of a hollow cylinder. As THREE.STLLoader() returns a non-indexed geometry, I've casted the geometry of the cylinder to non-indexed too.



    Related forum topic






    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.setScalar(20);
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x404040);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.STLLoader();
    loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

    var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
    }));
    mesh.rotation.set(-Math.PI / 2, 0, 0);
    mesh.scale.setScalar(100);
    scene.add(mesh);

    console.log("stl volume is " + getVolume(geometry));
    });

    // check with known volume:
    var hollowCylinderGeom = new THREE.LatheBufferGeometry([
    new THREE.Vector2(1, 0),
    new THREE.Vector2(2, 0),
    new THREE.Vector2(2, 2),
    new THREE.Vector2(1, 2),
    new THREE.Vector2(1, 0)
    ], 90).toNonIndexed();
    console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
    console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


    function getVolume(geometry) {

    let position = geometry.attributes.position;
    let faces = position.count / 3;
    let sum = 0;
    let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
    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);
    }
    return sum;

    }

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

    renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    });

    body {
    overflow: hidden;
    margin: 0;
    }

    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>








    share|improve this answer















    You can find it with the algorithm from my comment.



    In the code snippet, the volume is computed without scaling.



    Also, I've added a simple check that the algorithm calculates correctly by finding the volume of a hollow cylinder. As THREE.STLLoader() returns a non-indexed geometry, I've casted the geometry of the cylinder to non-indexed too.



    Related forum topic






    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.setScalar(20);
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x404040);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.STLLoader();
    loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

    var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
    }));
    mesh.rotation.set(-Math.PI / 2, 0, 0);
    mesh.scale.setScalar(100);
    scene.add(mesh);

    console.log("stl volume is " + getVolume(geometry));
    });

    // check with known volume:
    var hollowCylinderGeom = new THREE.LatheBufferGeometry([
    new THREE.Vector2(1, 0),
    new THREE.Vector2(2, 0),
    new THREE.Vector2(2, 2),
    new THREE.Vector2(1, 2),
    new THREE.Vector2(1, 0)
    ], 90).toNonIndexed();
    console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
    console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


    function getVolume(geometry) {

    let position = geometry.attributes.position;
    let faces = position.count / 3;
    let sum = 0;
    let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
    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);
    }
    return sum;

    }

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

    renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    });

    body {
    overflow: hidden;
    margin: 0;
    }

    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>








    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.setScalar(20);
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x404040);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.STLLoader();
    loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

    var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
    }));
    mesh.rotation.set(-Math.PI / 2, 0, 0);
    mesh.scale.setScalar(100);
    scene.add(mesh);

    console.log("stl volume is " + getVolume(geometry));
    });

    // check with known volume:
    var hollowCylinderGeom = new THREE.LatheBufferGeometry([
    new THREE.Vector2(1, 0),
    new THREE.Vector2(2, 0),
    new THREE.Vector2(2, 2),
    new THREE.Vector2(1, 2),
    new THREE.Vector2(1, 0)
    ], 90).toNonIndexed();
    console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
    console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


    function getVolume(geometry) {

    let position = geometry.attributes.position;
    let faces = position.count / 3;
    let sum = 0;
    let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
    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);
    }
    return sum;

    }

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

    renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    });

    body {
    overflow: hidden;
    margin: 0;
    }

    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>





    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.setScalar(20);
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x404040);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.STLLoader();
    loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

    var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
    }));
    mesh.rotation.set(-Math.PI / 2, 0, 0);
    mesh.scale.setScalar(100);
    scene.add(mesh);

    console.log("stl volume is " + getVolume(geometry));
    });

    // check with known volume:
    var hollowCylinderGeom = new THREE.LatheBufferGeometry([
    new THREE.Vector2(1, 0),
    new THREE.Vector2(2, 0),
    new THREE.Vector2(2, 2),
    new THREE.Vector2(1, 2),
    new THREE.Vector2(1, 0)
    ], 90).toNonIndexed();
    console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
    console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


    function getVolume(geometry) {

    let position = geometry.attributes.position;
    let faces = position.count / 3;
    let sum = 0;
    let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
    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);
    }
    return sum;

    }

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

    renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    });

    body {
    overflow: hidden;
    margin: 0;
    }

    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 27 '18 at 9:12

























    answered Nov 25 '18 at 22:02









    prisoner849prisoner849

    7,87821430




    7,87821430













    • This calculates the sum of the areas of the triangles?

      – manthrax
      Nov 26 '18 at 13:51











    • Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

      – manthrax
      Nov 26 '18 at 13:52






    • 1





      @manthrax Works for those geometries that have no self-intersections/overlapping.

      – prisoner849
      Nov 26 '18 at 13:56











    • so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

      – manthrax
      Nov 26 '18 at 14:06






    • 1





      @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

      – prisoner849
      Nov 27 '18 at 9:07



















    • This calculates the sum of the areas of the triangles?

      – manthrax
      Nov 26 '18 at 13:51











    • Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

      – manthrax
      Nov 26 '18 at 13:52






    • 1





      @manthrax Works for those geometries that have no self-intersections/overlapping.

      – prisoner849
      Nov 26 '18 at 13:56











    • so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

      – manthrax
      Nov 26 '18 at 14:06






    • 1





      @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

      – prisoner849
      Nov 27 '18 at 9:07

















    This calculates the sum of the areas of the triangles?

    – manthrax
    Nov 26 '18 at 13:51





    This calculates the sum of the areas of the triangles?

    – manthrax
    Nov 26 '18 at 13:51













    Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

    – manthrax
    Nov 26 '18 at 13:52





    Whoa. Never mind. This is pretty slick. but only works for convex objects, yeah?

    – manthrax
    Nov 26 '18 at 13:52




    1




    1





    @manthrax Works for those geometries that have no self-intersections/overlapping.

    – prisoner849
    Nov 26 '18 at 13:56





    @manthrax Works for those geometries that have no self-intersections/overlapping.

    – prisoner849
    Nov 26 '18 at 13:56













    so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

    – manthrax
    Nov 26 '18 at 14:06





    so for 3d printing filament estimation, it would overestimate on objects with those features. Might be an acceptable tradeoff. But imagine printing a flowerpot.. the overestimation would be huuuge.

    – manthrax
    Nov 26 '18 at 14:06




    1




    1





    @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

    – prisoner849
    Nov 27 '18 at 9:07





    @manthrax Yes, it's not mandatory for the model's geometry to be positioned in the center of coordinates, the algorithm will calculate its volume.

    – prisoner849
    Nov 27 '18 at 9:07













    -1














    This is a pretty tricky problem. One way is to decompose the object into a bunch of convex polyhedra and sum the volumes of those...



    Another way is to voxelize it, and add up the voxels on the inside to get an estimate whos accuracy is limited by the resolution of your voxelization.



    Edit: prisoner849 has a rad solution!






    share|improve this answer






























      -1














      This is a pretty tricky problem. One way is to decompose the object into a bunch of convex polyhedra and sum the volumes of those...



      Another way is to voxelize it, and add up the voxels on the inside to get an estimate whos accuracy is limited by the resolution of your voxelization.



      Edit: prisoner849 has a rad solution!






      share|improve this answer




























        -1












        -1








        -1







        This is a pretty tricky problem. One way is to decompose the object into a bunch of convex polyhedra and sum the volumes of those...



        Another way is to voxelize it, and add up the voxels on the inside to get an estimate whos accuracy is limited by the resolution of your voxelization.



        Edit: prisoner849 has a rad solution!






        share|improve this answer















        This is a pretty tricky problem. One way is to decompose the object into a bunch of convex polyhedra and sum the volumes of those...



        Another way is to voxelize it, and add up the voxels on the inside to get an estimate whos accuracy is limited by the resolution of your voxelization.



        Edit: prisoner849 has a rad solution!







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 27 '18 at 6:59

























        answered Nov 24 '18 at 17:01









        manthraxmanthrax

        2,52211010




        2,52211010






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459241%2fthree-js-calculate-stl-file-mesh-volume%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()