1

I have a mesh (image 1) and a parallelepipede, I add the intersection result of this 2 objects in a scene and I move the parallelepipede along my mesh repeating the same process to "cut" my mesh and get an exploded view of my mesh (image 2).

Problem is that the process time is more than 2 mins... I have tryed to reduce the mesh with meshmixxer but it's not enough... Does someone has another idea ?

image 1 image 2

function FirstCut() {

    var scene, camera, renderer, controls;

    //stl loader from https://threejs.org/examples/webgl_loader_stl.html
    // cf example https://stemkoski.github.io/Three.js/CSG.html

    //with obj

    init();
    animate();

    function init() {

        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xeeeeee);

        camera = new THREE.PerspectiveCamera(75, 800 / 500, 1, 2000);

        //camera.position.set(50, 500, 0);
        camera.position.x = 50;
        camera.position.y = 500;
        camera.position.z = 0;

        //var axeX = new THREE.Vector3(1, 0, 0);
        //camera.rotateOnAxis(axeX, -1);
        camera.lookAt(new THREE.Vector3(0, 500, 0));

        controls = new THREE.OrbitControls(camera);
        //les valeurs de min and max distance sont choisies pour que le filet ne disparaisse pas quand on le fait tourner
        controls.minDistance = 0;
        controls.maxDistance = 1000;
        //scene
        //var ambient = new THREE.AmbientLight(0x101030);
        //scene.add(ambient);
        //scene.add(new THREE.GridHelper(1000, 20));
        //var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        //directionalLight.position.set(0, 1, 0);
        //scene.add(directionalLight);

        var widthH = parseInt(document.getElementById("wdthH").value) || 0; // H for Head
        var widthT = parseInt(document.getElementById("wdthT").value) || 0; // T for tail
        var height = parseInt(document.getElementById("hght").value) || 0;  // flank

        //création du pavé
        var EmportePieceH = new THREE.BoxGeometry(300, 60, widthH);
        var EmportePieceT = new THREE.BoxGeometry(300, 60, widthT);
        var EmportePieceB = new THREE.BoxGeometry(height, 60, 520);

        var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });

        // création du meshage et material
        var EmportePieceMeshH = new THREE.Mesh(EmportePieceH, paveMaterial);
        var EmportePieceMeshT = new THREE.Mesh(EmportePieceT, paveMaterial);
        var paveMeshB = new THREE.Mesh(EmportePieceB, paveMaterial);

        var zH = 247 - widthH / 2;
        var zT = -247 + widthT / 2;
        EmportePieceMeshH.position.set(0, 30, zH);
        EmportePieceMeshT.position.set(0, 30, zT);
        paveMeshB.position.set(-95 + height / 2, 30, 0);
        var EmportePieceBSPH = new ThreeBSP(EmportePieceMeshH);
        var EmportePieceBSPT = new ThreeBSP(EmportePieceMeshT);
        var paveBSPB = new ThreeBSP(paveMeshB);

        //scene.add(EmportePieceMeshH);
        //scene.add(EmportePieceMeshT);
        //scene.add(paveMeshB);


        // texture
        var manager = new THREE.LoadingManager();
        manager.onProgress = function (item, loaded, total) {
            console.log(item, loaded, total);
        };
        var texture = new THREE.Texture();
        var onProgress = function (xhr) {
            if (xhr.lengthComputable) {
                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log(Math.round(percentComplete, 2) + '% downloaded');
            }
        };
        var onError = function (xhr) {
        };

        var loader = new THREE.ImageLoader(manager);
        loader.load('/Scan/filet_1kg500-reposition-reduit_material_0.jpg', function (image) {
            texture.image = image;
            texture.needsUpdate = true;
        });

        var width = parseInt(document.getElementById("wdth").value) || 0;

        //création du pavé
        var paveGeom = new THREE.BoxGeometry(250, 250, width);
        var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });

        // création du meshage parallélépipède avec material
        var paveMesh = new THREE.Mesh(paveGeom, paveMaterial);

        var z0 = -247 + widthH;
        paveMesh.position.set(0, 0, z0);

        var paveBSP = new ThreeBSP(paveMesh);
        //scene.add(paveMesh);

        //tableau des volumes
        var tabVolumes = new Array();

        // model
        var loader = new THREE.OBJLoader(manager);
        loader.load('/Scan/filet_1kg500-reposition-reduit.obj', function (object) {
            object.traverse(function (child) {
                if (child instanceof THREE.Mesh) {
                    child.material.map = texture;

                    var geo = new THREE.Geometry().fromBufferGeometry(child.geometry);
                    var filetMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
                    var filetMesh = new THREE.Mesh(geo, filetMaterial);
                    //scene.add(filetMesh);
                    var newBSPH, newBSPT, newBSPB, newBSP2, newBSP1, filletBSP
                    var filetBSP = new ThreeBSP(filetMesh);

                    newBSPH = filetBSP.intersect(EmportePieceBSPH);
                    newBSPT = filetBSP.intersect(EmportePieceBSPT);
                    newBSPB = filetBSP.intersect(paveBSPB);
                    newBSP2 = filetBSP.subtract(EmportePieceBSPH);
                    newBSP1 = newBSP2.subtract(paveBSPB);
                    filletBSP = newBSP1.subtract(EmportePieceBSPT);

                    ////////////////////subtract//////////////////////////////

                    var newFilet = new THREE.Geometry();
                    newFilet = filletBSP.toGeometry();
                    var newFilletMesh = new THREE.Mesh(newFilet, new THREE.MeshBasicMaterial({ map: texture }));
                    newFilletMesh.position.set(0, 0, 0);

                    ///////////////////////////////////création morceaux découpés///////////////////////////////////////////

                    var HeadFillet = new THREE.Geometry();
                    var TailFillet = new THREE.Geometry();
                    var degraissageFillet = new THREE.Geometry();
                    HeadFillet = newBSPH.toGeometry();
                    TailFillet = newBSPT.toGeometry();
                    degraissageFillet = newBSPB.toGeometry();


                    /////////////////////////////////calcul des volumes des 1ers morceaux/////////////////////////////////////////

                    if (widthH != 0) {
                        tabVolumes[0] = calculateVolume2(HeadFillet);
                    } else { tabVolumes[0] = 0;}

                    if (widthT != 0) {
                        //alert(tabVolumes[0]);
                        tabVolumes[1] = calculateVolume2(TailFillet);
                    } else { tabVolumes[1] = 0; }

                    if (height != 0) {
                        tabVolumes[2] = calculateVolume2(degraissageFillet);
                    } else { tabVolumes[2] = 0; }

                    var ind = 3;

                    var HeadFilletMesh = new THREE.Mesh(HeadFillet, new THREE.MeshBasicMaterial({ map: texture }));
                    var TailFilletMesh = new THREE.Mesh(TailFillet, new THREE.MeshBasicMaterial({ map: texture }));
                    var degraissageFilletMesh = new THREE.Mesh(degraissageFillet, new THREE.MeshBasicMaterial({ map: texture }));

                    HeadFilletMesh.position.set(0, 0, 20);
                    degraissageFilletMesh.position.set(-20, 0, 0);
                    TailFilletMesh.position.set(0, 0, -20);
                    scene.add(HeadFilletMesh);
                    scene.add(TailFilletMesh);
                    scene.add(degraissageFilletMesh);

                    //scene.add(newFilletMesh);
                    var cloneHeadFilletMesh = HeadFilletMesh.clone();
                    var cloneTailFilletMesh = TailFilletMesh.clone();
                    var clonedegraissageFilletMesh = degraissageFilletMesh.clone();

                    var mesh_decoupe = new THREE.Object3D;
                    mesh_decoupe.add(cloneHeadFilletMesh);
                    mesh_decoupe.add(cloneTailFilletMesh);
                    mesh_decoupe.add(clonedegraissageFilletMesh);

                    if (width != 0) {
                        var paveGeom = new THREE.BoxGeometry(300, 300, width);
                        var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });


                        var fillet2BSP = new ThreeBSP(newFilletMesh);

                        var intersectionPave = new THREE.Geometry();
                        intersectionPave = fillet2BSP.intersect(paveBSP);

                        var geometryPave = new THREE.Geometry();
                        geometryPave = intersectionPave.toGeometry();
                        var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));


                        //alert(geometryPave.faces.length);

                        while (geometryPave.faces.length != 0) {


                            var z = paveMesh.position.z + width + 5;

                            paveMesh.position.set(0, 0, z);
                            paveBSP = new ThreeBSP(paveMesh);
                            //scene.add(paveMesh);

                            fillet2BSP = new ThreeBSP(newFilletMesh);

                            intersectionPave = filletBSP.intersect(paveBSP);
                            geometryPave = intersectionPave.toGeometry();

                            tabVolumes[ind] = calculateVolume2(geometryPave);
                            ind = ind + 1;

                            var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));
                            newMesh.position.set(0, 0, newMesh.position.z);
                            scene.add(newMesh);

                            var meshSave = newMesh.clone();
                            mesh_decoupe.add(meshSave);
                        }

                        document.body.style.cursor = '';

                    } else {
                        scene.add(newFilletMesh);
                        document.body.style.cursor = '';


                        tabVolumes[3] = 0;
                        tabVolumes[4] = calculateVolume2(newFilet);
                    }



                    //    }
                    //}
                    //else {
                    //    scene.add(newFilletMesh);

                    //    tabVolumes[ind] = calculateVolume2(newFilet);
                    //}


                    //alert(calculateVolume2(newBSP.toGeometry()));

                    //afficher les volumes dans la textarea


                    var txtVolume = document.getElementById("txtVolume");
                    txtVolume.value = tabVolumes.join("\n");

                    //var exporter = new THREE.OBJExporter();
                    //var result = exporter.parse(mesh_decoupe);
                    //var blob = new Blob([result], { type: 'text/plain' });
                    //saveAs(blob, 'dechets.obj');

                }
            });
            //scene.add(object);

        }, onProgress, onError);

        renderer = new THREE.WebGLRenderer();
        renderer.setSize(800, 500, false);

        document.getElementById('canvas3D').innerHTML = "";
        document.getElementById('canvas3D').appendChild(renderer.domElement);
    }
        function animate() {

            requestAnimationFrame(animate);
            camin();
            renderer.render(scene, camera);


        }

        function camin() {
            camera.position.y -= .1;
        }


            function volumeOfT(p1, p2, p3) {
            var v321 = p3.x * p2.y * p1.z;
            var v231 = p2.x * p3.y * p1.z;
            var v312 = p3.x * p1.y * p2.z;
            var v132 = p1.x * p3.y * p2.z;
            var v213 = p2.x * p1.y * p3.z;
            var v123 = p1.x * p2.y * p3.z;
            return (-v321 + v231 + v312 - v132 - v213 + v123) / 6.0;
        }

        function calculateVolume2(object) {
            var volumes = 0.0;

            for (var i = 0; i < object.faces.length; i++) {
                var Pi = object.faces[i].a;
                var Qi = object.faces[i].b;
                var Ri = object.faces[i].c;
                //alert (Pi);

                var P = new THREE.Vector3(object.vertices[Pi].x, object.vertices[Pi].y, object.vertices[Pi].z);
                //alert(object.vertices[Pi].x);
                var Q = new THREE.Vector3(object.vertices[Qi].x, object.vertices[Qi].y, object.vertices[Qi].z);
                var R = new THREE.Vector3(object.vertices[Ri].x, object.vertices[Ri].y, object.vertices[Ri].z);
                volumes += volumeOfT(P, Q, R);
            }

            return Math.abs(volumes);

      }
}



function FirstCut() {

    var scene, camera, renderer, controls;

    //stl loader from https://threejs.org/examples/webgl_loader_stl.html
    // cf example https://stemkoski.github.io/Three.js/CSG.html

    //with obj

    init();
    animate();

    function init() {

        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xeeeeee);

        camera = new THREE.PerspectiveCamera(75, 800 / 500, 1, 2000);

        //camera.position.set(50, 500, 0);
        camera.position.x = 50;
        camera.position.y = 500;
        camera.position.z = 0;

        //var axeX = new THREE.Vector3(1, 0, 0);
        //camera.rotateOnAxis(axeX, -1);
        camera.lookAt(new THREE.Vector3(0, 500, 0));

        controls = new THREE.OrbitControls(camera);
        //les valeurs de min and max distance sont choisies pour que le filet ne disparaisse pas quand on le fait tourner
        controls.minDistance = 0;
        controls.maxDistance = 1000;
        //scene
        //var ambient = new THREE.AmbientLight(0x101030);
        //scene.add(ambient);
        //scene.add(new THREE.GridHelper(1000, 20));
        //var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        //directionalLight.position.set(0, 1, 0);
        //scene.add(directionalLight);

        var widthH = parseInt(document.getElementById("wdthH").value) || 0; // H for Head
        var widthT = parseInt(document.getElementById("wdthT").value) || 0; // T for tail
        var height = parseInt(document.getElementById("hght").value) || 0;  // flank

        //création du pavé
        var EmportePieceH = new THREE.BoxGeometry(300, 60, widthH);
        var EmportePieceT = new THREE.BoxGeometry(300, 60, widthT);
        var EmportePieceB = new THREE.BoxGeometry(height, 60, 520);

        var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });

        // création du meshage et material
        var EmportePieceMeshH = new THREE.Mesh(EmportePieceH, paveMaterial);
        var EmportePieceMeshT = new THREE.Mesh(EmportePieceT, paveMaterial);
        var paveMeshB = new THREE.Mesh(EmportePieceB, paveMaterial);

        var zH = 247 - widthH / 2;
        var zT = -247 + widthT / 2;
        EmportePieceMeshH.position.set(0, 30, zH);
        EmportePieceMeshT.position.set(0, 30, zT);
        paveMeshB.position.set(-95 + height / 2, 30, 0);
        var EmportePieceBSPH = new ThreeBSP(EmportePieceMeshH);
        var EmportePieceBSPT = new ThreeBSP(EmportePieceMeshT);
        var paveBSPB = new ThreeBSP(paveMeshB);

        //scene.add(EmportePieceMeshH);
        //scene.add(EmportePieceMeshT);
        //scene.add(paveMeshB);


        // texture
        var manager = new THREE.LoadingManager();
        manager.onProgress = function (item, loaded, total) {
            console.log(item, loaded, total);
        };
        var texture = new THREE.Texture();
        var onProgress = function (xhr) {
            if (xhr.lengthComputable) {
                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log(Math.round(percentComplete, 2) + '% downloaded');
            }
        };
        var onError = function (xhr) {
        };

        var loader = new THREE.ImageLoader(manager);
        loader.load('/Scan/filet_1kg500-reposition-reduit_material_0.jpg', function (image) {
            texture.image = image;
            texture.needsUpdate = true;
        });

        var width = parseInt(document.getElementById("wdth").value) || 0;

        //création du pavé
        var paveGeom = new THREE.BoxGeometry(250, 250, width);
        var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });

        // création du meshage parallélépipède avec material
        var paveMesh = new THREE.Mesh(paveGeom, paveMaterial);

        var z0 = -247 + widthH;
        paveMesh.position.set(0, 0, z0);

        var paveBSP = new ThreeBSP(paveMesh);
        //scene.add(paveMesh);

        //tableau des volumes
        var tabVolumes = new Array();

        // model
        var loader = new THREE.OBJLoader(manager);
        loader.load('/Scan/filet_1kg500-reposition-reduit.obj', function (object) {
            object.traverse(function (child) {
                if (child instanceof THREE.Mesh) {
                    child.material.map = texture;

                    var geo = new THREE.Geometry().fromBufferGeometry(child.geometry);
                    var filetMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
                    var filetMesh = new THREE.Mesh(geo, filetMaterial);
                    //scene.add(filetMesh);
                    var newBSPH, newBSPT, newBSPB, newBSP2, newBSP1, filletBSP
                    var filetBSP = new ThreeBSP(filetMesh);

                    newBSPH = filetBSP.intersect(EmportePieceBSPH);
                    newBSPT = filetBSP.intersect(EmportePieceBSPT);
                    newBSPB = filetBSP.intersect(paveBSPB);
                    newBSP2 = filetBSP.subtract(EmportePieceBSPH);
                    newBSP1 = newBSP2.subtract(paveBSPB);
                    filletBSP = newBSP1.subtract(EmportePieceBSPT);

                    ////////////////////subtract//////////////////////////////

                    var newFilet = new THREE.Geometry();
                    newFilet = filletBSP.toGeometry();
                    var newFilletMesh = new THREE.Mesh(newFilet, new THREE.MeshBasicMaterial({ map: texture }));
                    newFilletMesh.position.set(0, 0, 0);

                    ///////////////////////////////////création morceaux découpés///////////////////////////////////////////

                    var HeadFillet = new THREE.Geometry();
                    var TailFillet = new THREE.Geometry();
                    var degraissageFillet = new THREE.Geometry();
                    HeadFillet = newBSPH.toGeometry();
                    TailFillet = newBSPT.toGeometry();
                    degraissageFillet = newBSPB.toGeometry();


                    /////////////////////////////////calcul des volumes des 1ers morceaux/////////////////////////////////////////

                    if (widthH != 0) {
                        tabVolumes[0] = calculateVolume2(HeadFillet);
                    } else { tabVolumes[0] = 0;}

                    if (widthT != 0) {
                        //alert(tabVolumes[0]);
                        tabVolumes[1] = calculateVolume2(TailFillet);
                    } else { tabVolumes[1] = 0; }

                    if (height != 0) {
                        tabVolumes[2] = calculateVolume2(degraissageFillet);
                    } else { tabVolumes[2] = 0; }

                    var ind = 3;

                    var HeadFilletMesh = new THREE.Mesh(HeadFillet, new THREE.MeshBasicMaterial({ map: texture }));
                    var TailFilletMesh = new THREE.Mesh(TailFillet, new THREE.MeshBasicMaterial({ map: texture }));
                    var degraissageFilletMesh = new THREE.Mesh(degraissageFillet, new THREE.MeshBasicMaterial({ map: texture }));

                    HeadFilletMesh.position.set(0, 0, 20);
                    degraissageFilletMesh.position.set(-20, 0, 0);
                    TailFilletMesh.position.set(0, 0, -20);
                    scene.add(HeadFilletMesh);
                    scene.add(TailFilletMesh);
                    scene.add(degraissageFilletMesh);

                    //scene.add(newFilletMesh);
                    var cloneHeadFilletMesh = HeadFilletMesh.clone();
                    var cloneTailFilletMesh = TailFilletMesh.clone();
                    var clonedegraissageFilletMesh = degraissageFilletMesh.clone();

                    var mesh_decoupe = new THREE.Object3D;
                    mesh_decoupe.add(cloneHeadFilletMesh);
                    mesh_decoupe.add(cloneTailFilletMesh);
                    mesh_decoupe.add(clonedegraissageFilletMesh);

                    if (width != 0) {
                        var paveGeom = new THREE.BoxGeometry(300, 300, width);
                        var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });


                        var fillet2BSP = new ThreeBSP(newFilletMesh);

                        var intersectionPave = new THREE.Geometry();
                        intersectionPave = fillet2BSP.intersect(paveBSP);

                        var geometryPave = new THREE.Geometry();
                        geometryPave = intersectionPave.toGeometry();
                        var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));


                        //alert(geometryPave.faces.length);

                        while (geometryPave.faces.length != 0) {


                            var z = paveMesh.position.z + width + 5;

                            paveMesh.position.set(0, 0, z);
                            paveBSP = new ThreeBSP(paveMesh);
                            //scene.add(paveMesh);

                            fillet2BSP = new ThreeBSP(newFilletMesh);

                            intersectionPave = filletBSP.intersect(paveBSP);
                            geometryPave = intersectionPave.toGeometry();

                            tabVolumes[ind] = calculateVolume2(geometryPave);
                            ind = ind + 1;

                            var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));
                            newMesh.position.set(0, 0, newMesh.position.z);
                            scene.add(newMesh);

                            var meshSave = newMesh.clone();
                            mesh_decoupe.add(meshSave);
                        }

                        document.body.style.cursor = '';

                    } else {
                        scene.add(newFilletMesh);
                        document.body.style.cursor = '';


                        tabVolumes[3] = 0;
                        tabVolumes[4] = calculateVolume2(newFilet);
                    }



                    //    }
                    //}
                    //else {
                    //    scene.add(newFilletMesh);

                    //    tabVolumes[ind] = calculateVolume2(newFilet);
                    //}


                    //alert(calculateVolume2(newBSP.toGeometry()));

                    //afficher les volumes dans la textarea


                    var txtVolume = document.getElementById("txtVolume");
                    txtVolume.value = tabVolumes.join("\n");

                    //var exporter = new THREE.OBJExporter();
                    //var result = exporter.parse(mesh_decoupe);
                    //var blob = new Blob([result], { type: 'text/plain' });
                    //saveAs(blob, 'dechets.obj');

                }
            });
            //scene.add(object);

        }, onProgress, onError);

        renderer = new THREE.WebGLRenderer();
        renderer.setSize(800, 500, false);

        document.getElementById('canvas3D').innerHTML = "";
        document.getElementById('canvas3D').appendChild(renderer.domElement);
    }
        function animate() {

            requestAnimationFrame(animate);
            camin();
            renderer.render(scene, camera);


        }

        function camin() {
            camera.position.y -= .1;
        }


            function volumeOfT(p1, p2, p3) {
            var v321 = p3.x * p2.y * p1.z;
            var v231 = p2.x * p3.y * p1.z;
            var v312 = p3.x * p1.y * p2.z;
            var v132 = p1.x * p3.y * p2.z;
            var v213 = p2.x * p1.y * p3.z;
            var v123 = p1.x * p2.y * p3.z;
            return (-v321 + v231 + v312 - v132 - v213 + v123) / 6.0;
        }

        function calculateVolume2(object) {
            var volumes = 0.0;

            for (var i = 0; i < object.faces.length; i++) {
                var Pi = object.faces[i].a;
                var Qi = object.faces[i].b;
                var Ri = object.faces[i].c;
                //alert (Pi);

                var P = new THREE.Vector3(object.vertices[Pi].x, object.vertices[Pi].y, object.vertices[Pi].z);
                //alert(object.vertices[Pi].x);
                var Q = new THREE.Vector3(object.vertices[Qi].x, object.vertices[Qi].y, object.vertices[Qi].z);
                var R = new THREE.Vector3(object.vertices[Ri].x, object.vertices[Ri].y, object.vertices[Ri].z);
                volumes += volumeOfT(P, Q, R);
            }

            return Math.abs(volumes);

      }
}
Ben
  • 37
  • 11
  • Is removing only one slice at a time OK? If so, it is easy using clipping. See [this answer](http://stackoverflow.com/questions/36557486/three-js-object-clipping/36558152#36558152). – WestLangley May 15 '17 at 15:51
  • How many vertices/polygons are there in your initial mesh ? – VB_overflow May 15 '17 at 17:54
  • Does this need to be done at run-time (dynamic or user-defined cuts)? It seems like you could perform the cutting externally, and simply load the pre-cut meshes butted against each other until you wanted to move them into the exploded view. – TheJim01 May 15 '17 at 18:43
  • Hello, thanks for answers, yes I am removing one slice at a time through the while loop. There is about 3000 vertices, I already tried to simplify the mesh from 300 000 triangles to 6000 but I think I reached the limit. It's user-defined cut, actually they enter a mass for one filet and another script cut the mesh into very small slices (2mm) and when the volume is reached the loop stops. – Ben May 16 '17 at 07:20
  • @WestLangley I need to record the volume of my slices, but I am not sure I can do this with a clipping plane. – Ben May 16 '17 at 12:41
  • 1
    Maybe use raycasting over a tight grid to get the distance between the front and back faces. BSP is not the solution to your problem. – WestLangley May 16 '17 at 17:01
  • See http://daign.github.io/clipping-with-caps/. If you use an orthographic camera, and view perpendicularly to the slice, the number of red pixels will be proportional to the area of the slice. – WestLangley May 19 '17 at 16:46

0 Answers0