Threejs给物体最外圈加线框(被挖洞或者被切的物体都可以)

// 物体最外圈加线框(被挖洞或者被切的物体都可以)

    addEdge(mesh: THREE.Mesh) {

        let allVertices = [];

        let vertices: THREE.Vector3[] = [];

        // 物体最高点

        let height = GlobalApi.mDangQianLouCeng.mCabinetClass.mCurUnit.H / 10;

        for (let i = 0; i < mesh.geometry.attributes.position.array.length; i += 3) {

            allVertices.push(new THREE.Vector3(mesh.geometry.attributes.position.array[i], mesh.geometry.attributes.position.array[i + 1], mesh.geometry.attributes.position.array[i + 2]));

        }

        // 此处每次提一个面的三个点,判断这三个点的y值是否等于最高点,如果是,就把这三个点放到vertices数组中(取mesh的最高面)

        for (let i = 0; i < allVertices.length; i += 3) {

            if (allVertices[i].y == height && allVertices[i + 1].y == height && allVertices[i + 2].y == height) {

                vertices.push(allVertices[i], allVertices[i + 1], allVertices[i + 2]);

            }

        }

        //转换成polybool需要的数据

        let polyPos = [];

        for (let i = 0; i < vertices.length; i += 3) {

            polyPos.push([

                [vertices[i].x, vertices[i].z],

                [vertices[i + 1].x, vertices[i + 1].z],

                [vertices[i + 2].x, vertices[i + 2].z]

            ])

        }

        let polyBool = require('polybooljs');

        let resultPolyPos = polyPos[0];

        //计算,并将结果保存到resultPolyPos中

        //得到结果为外轮廓的点位

        //TODO:当墙面被完全截断为两个或多个区域时,该方法会死循环

        for (let i = 1; i < polyPos.length; i++) {

            let result: any = polyBool.union({

                regions: [resultPolyPos],

                inverted: false

            }, {

                regions: [polyPos[i]],

                inverted: false

            });

            // console.log(result.regions)

            resultPolyPos = result.regions[0];

            //当regions的长度大于1时,说明有多个区域,需要将多余的区域重新存储到polyPos中

            if (result.regions.length > 1) {

                polyPos.push(...(result.regions.splice(1)));

            }

        }


 

        let resultVectors = [];

        for (let i = 0; i < resultPolyPos.length; i++) {

            resultVectors.push(new THREE.Vector3(resultPolyPos[i][0], height, resultPolyPos[i][1]));

        }


 

        let geoVertices = [];

        for (let i = 0; i < resultVectors.length; i++) {

            geoVertices.push(resultVectors[i].x, resultVectors[i].y, resultVectors[i].z);

        }

        geoVertices.push(geoVertices[0], geoVertices[1], geoVertices[2])

        let edgeLineGeo = new THREE.BufferGeometry();

        edgeLineGeo.setAttribute('position', new THREE.Float32BufferAttribute(geoVertices, 3));

        let edgeLine = new THREE.Line(edgeLineGeo,

            new THREE.LineBasicMaterial({

                color: 0x00000,

                opacity: 1,

            }));

        return edgeLine;

    }