<div class="container" id="container"></div> 
    <div class="butns">
        <button class="but" id="but">boolean</button>  
        <button class="but" id="but1">detect/remove faces</button> 
        <div id="orig">
            <input id="original" type="checkbox" name="original" checked='true'> original Mesh visible
        </div>
        <div id="booler">
            <input id="boolean" type="checkbox" name="original" checked='true'> boolean Mesh visible
        </div>
        <div id="rays">
            <input id="rays1" type="checkbox" name="original" checked='true'> rays visible
        </div>
    </div>
html, body{
    width: 100vw;
    padding: 0;
    margin: 0;
    background-color: #ffffff;
    overflow-x: hidden !important;
    overflow-y: scroll;
}

.container{
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 100%;
    padding: 0;
    margin: 0;
    z-index: -1;    
}

.butns{
    position: fixed;
    color: #ffffff;
}

.but{
    position: relative;
    display: block;
    color: #ffffff;
    background-color: rgb(87, 87, 87);
    z-index: 3;
    font-size: 40px;
}

#but1{
    display: none;
}

#orig{
    display: block;
}

#booler{
    display: none;
}

#rays{
    display: none;
}
import * as THREE from 'https://3dpk.co.uk/R127/build/three.module.js';
import { BufferGeometryUtils } from 'https://3dpk.co.uk/R127/examples/jsm/utils/BufferGeometryUtils.js'
import {OrbitControls} from 'https://3dpk.co.uk/R127/examples/jsm/controls/OrbitControls.js';
import {GLTFLoader} from 'https://3dpk.co.uk/R127/examples/jsm/loaders/GLTFLoader.js';
import { CSG } from "https://3dpk.co.uk/unionboolean/CSG.js";

let scene, camera, renderer, manager, loader, controls;

var container = document.getElementById( 'container');
var widdi = container.offsetWidth;
var hiddi = container.offsetHeight;

var objsgeo = [];
var objs = [];
var objsMerge;
var objsFinal;

var unionMesh;

var cont = [];
var faceindex = [];
var result = [];
var FIresult = [];
var intersects = [];

var button = document.getElementById('but');
var button1 = document.getElementById('but1');

const ogmeshcheck = document.getElementById('original');
const boolmeshcheck = document.getElementById('boolean');
const booler = document.getElementById('booler');
const rays1 = document.getElementById('rays1');
const rays = document.getElementById('rays');
const fin = document.getElementById('fin');
const final = document.getElementById('final');



var raycaster = new THREE.Raycaster();

var rayhelper;

var raygroup = new THREE.Group();

const csg = new CSG();

const mat = new THREE.MeshStandardMaterial({ transparent: true, opacity: 0.5, side: THREE.BackSide });
const mat1 = new THREE.MeshStandardMaterial({ wireframe: true });

var csgMesh;

gogo(); 

function gogo(){

    // LOADING MANAGER --------------------

    manager = new THREE.LoadingManager();

    manager.onStart = function ( url, itemsLoaded, itemsTotal ) {
        //console.log( 'hiya');
    };

    manager.onProgress = function ( url, itemsLoaded, itemsTotal ) {

    //console.log(url);
    };

    manager.onLoad = function ( ) {
    //console.log( 'Loading complete!');
    init();
    
    }; 

    manager.onError = function ( url ) {
    //console.log( 'There was an error loading ' + url ); 
    //location.reload();       
    };

    loader = new GLTFLoader( manager );
    loader.setPath( 'https://3dpk.co.uk/unionboolean/' );
    loader.load( 'component1a.glb', function ( obj1 ) { 
        obj1.scene.traverse( function ( child ) {
            if ( child.isMesh ) {   
                objsgeo.push(child.geometry);
                objs.push(child);
                child.material.wireframe = true
                child.updateMatrix();  
            }               
        } );
        objsMerge = BufferGeometryUtils.mergeBufferGeometries(objsgeo);
        objsMerge.toNonIndexed();

    } );

}


function init() {

    scene = new THREE.Scene();
    //scene.add(firstobject)
    objsFinal = new THREE.Mesh( objsMerge , mat );
    //console.log(objsFinal);
    scene.add(objsFinal)

    renderer = new THREE.WebGLRenderer( { antialias: true, gammaOutput: true, alpha: true } );
    camera = new THREE.PerspectiveCamera( 60, widdi / hiddi, 0.1, 900 );
    camera.position.set(0,0,100)
    camera.aspect = widdi / hiddi;
   
    renderer.setSize( widdi , hiddi );
    renderer.setClearColor( 0x000000, 1); 
    renderer.setPixelRatio( window.devicePixelRatio );
    container.appendChild( renderer.domElement );

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

    const ambientLight = new THREE.AmbientLight( 0xffffff, 0.5 );
    scene.add( ambientLight );
    ambientLight.position.set( 0, 0, -20)

    const directionalLight = new THREE.DirectionalLight( "#f00505", 0.5 );
    scene.add( directionalLight );
    directionalLight.position.set( 40, 40, 40 )

    animate();

    // end init //
};

button.addEventListener('click', function(){

    csg.union(objs);
    csgMesh = csg.toGeometry();

    var uunionMesh = BufferGeometryUtils.mergeVertices(csgMesh);
    unionMesh = new THREE.Mesh( uunionMesh , mat1 );
    scene.add(unionMesh)

    button1.style.display = 'block';
    button.style.display = 'none';
    booler.style.display = 'block';

    console.log(unionMesh);

})



button1.addEventListener('click', function(){

    rays.style.display = 'block';

    var pos = unionMesh.geometry.attributes.position; 
    console.log(objsFinal.geometry.attributes.position.array);
    var ori = new THREE.Vector3();
    var dir = new THREE.Vector3();
    var a = new THREE.Vector3(),
    b = new THREE.Vector3(),
    c = new THREE.Vector3(),
    tri = new THREE.Triangle();


    var index = unionMesh.geometry.index;    
    var faces = index.count / 3;
    //scene.updateMatrixWorld()
    for (let i = 0; i < faces; i++) {

        a.fromBufferAttribute(pos, index.array[i * 3 + 0]);
        b.fromBufferAttribute(pos, index.array[i * 3 + 1]);
        c.fromBufferAttribute(pos, index.array[i * 3 + 2]);
        a.set(a.x + unionMesh.position.x, a.y + unionMesh.position.y, a.z + unionMesh.position.z);
        b.set(b.x + unionMesh.position.x, b.y + unionMesh.position.y, b.z + unionMesh.position.z);
        c.set(c.x + unionMesh.position.x, c.y + unionMesh.position.y, c.z + unionMesh.position.z);
        tri.set(a, b, c);
        tri.getMidpoint(ori);
        tri.getNormal(dir);
        ori.x = ori.x - dir.x * 0.1;
        ori.z = ori.z - dir.z * 0.1;
        ori.y = ori.y - dir.y * 0.1;
        raycaster.set(ori, dir);    
        intersects = raycaster.intersectObject(objsFinal, false);

        if ( intersects.length > 0 ) {
            if(intersects[ 0 ].face){            
                cont.push(intersects[ 0 ].face)
                faceindex.push(intersects[ 0 ].faceIndex)            
            }        
        }

        rayhelper = new THREE.ArrowHelper( raycaster.ray.direction, raycaster.ray.origin, 5, Math.random() * 0xffffff )
        raygroup.add(rayhelper);

    }
    scene.add(raygroup)
    removeDuplicates(cont)
    console.log(cont);
})

var j;
function removeDuplicates(array) {    
    for (let i = 0; i < array.length; i++) {
        let exists = false;
        for (j = 0; j < result.length; j++) {
            if (array[i].a === result[j].a && array[i].b === result[j].b &&array[i].c === result[j].c) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            result.push(array[i]);
        }
    }   
    removeDuplicatesFI(faceindex); 
    return result;
        
}

function removeDuplicatesFI(array) {    
    for (let i = 0; i < array.length; i++) {
        let exists = false;
        for (j = 0; j < FIresult.length; j++) {
            if (array[i] === FIresult[j]) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            FIresult.push(array[i]);
        }
    }    
    next();
    return FIresult;
}

var newF = [];
var newN = [];
var newnewF =[];

function next(){
    for (let nf = 0; nf < FIresult.length; nf++) {
        newnewF.push({"index": FIresult[nf], "a": result[nf].a, "b": result[nf].b, "c": result[nf].c})
    }
    next1();
    console.log(newnewF); 
}
    
function next1(){
    newnewF.sort(function(a, b) {
        return parseFloat(a.index) - parseFloat(b.index);
    });
    console.log(newnewF); 
    next2();
}

function next2(){
for (let f = 0; f < result.length; f++) {
    newF.push(newnewF[f].a)
    newF.push(newnewF[f].b)
    newF.push(newnewF[f].c)
    newN.push(newnewF[f].normal)
    }
    console.log(newF);
    next3();
}
        
var newV = [];

function next3(){
    for (let v = 0; v < newF.length; v++) {      
        newV.push( 
            objsFinal.geometry.attributes.position.array[newF[v]]        
        )
    }
    removeDuplicatesV(newV)
}

var newnewV = []

function removeDuplicatesV(array) {    
    for (let i = 0; i < array.length; i++) {
        let exists = false;
        for (j = 0; j < newnewV.length; j++) {
            if (array[i] === newnewV[j]) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            newnewV.push(array[i]);
        }
    }    
    next4();
    return newnewV;
}

function next4(){
    console.log(newnewV);
    var newGeo = new THREE.BufferGeometry();

    newGeo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(objsFinal.geometry.attributes.position.array), 3));
    newGeo.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(newN), 3));
    newGeo.index = new THREE.Uint16BufferAttribute(new Uint16Array (newF), 1);

    var newMesh = new THREE.Mesh(BufferGeometryUtils.mergeVertices(newGeo), mat1)
    newMesh.geometry.computeVertexNormals();

    scene.add(newMesh)
    console.log(newMesh);

    console.log(objsFinal.geometry);
}

ogmeshcheck.addEventListener('change', function(){
    if (ogmeshcheck.checked === true){
        objsFinal.visible = true;
    }
    else{
        objsFinal.visible = false;
    }
})
boolmeshcheck.addEventListener('change', function(){
    if (boolmeshcheck.checked === true){
        unionMesh.visible = true;
    }
    else{
        unionMesh.visible = false;
    }
})
rays1.addEventListener('change', function(){
    if (rays1.checked === true){
        raygroup.visible = true;
    }
    else{
        raygroup.visible = false;
    }
})



function render(){
    renderer.render(scene, camera)
    controls.update();
};



function animate(){
    requestAnimationFrame( animate );

        render();
};

Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.