3d three.js如何分割包含未连接零件的几何图形

3d three.js如何分割包含未连接零件的几何图形,3d,split,three.js,3d,Split,Three.js,有没有办法确定几何体是否包含多个未连接的“对象”? 然后把它分成几个几何体 (我使用three.js,但实际上可以使用任何接受顶点和面列表的东西)我想我终于得到了它。 但是如果有其他人来测试,那就太好了 新代码如下: function groupGeometryIntoNonConnectedGeometries(geometry) { const material = new THREE.MeshBasicMaterial({ side: THREE.D

有没有办法确定几何体是否包含多个未连接的“对象”? 然后把它分成几个几何体

(我使用three.js,但实际上可以使用任何接受顶点和面列表的东西)

我想我终于得到了它。 但是如果有其他人来测试,那就太好了

新代码如下:

function groupGeometryIntoNonConnectedGeometries(geometry) {
        const material = new THREE.MeshBasicMaterial({
            side: THREE.DoubleSide,
            vertexColors: THREE.VertexColors
        });
        let geometryArray = [];
        const indexArray = geometry.index.array;
        const positionArray = geometry.attributes.position.array;
        const positionCount = geometry.attributes.position.count;
        const color = new THREE.Vector3(geometry.attributes.color.array[0], geometry.attributes.color.array[1], geometry.attributes.color.array[2]);
        const totalTriangles = indexArray.length / 3;
        let geometryCount = 0;
        let indexValueAlreadyVisited = new Uint8Array(indexArray.length);   
        let structure = [];
            /*
             * indexValue: {
             *  child: [ [indexval0, indexval1], [] ],
             *  parent: null
             * }
             */
        // Initialize Structure:
        for (var vextexIdx=0; vextexIdx<positionCount; vextexIdx++) {
            structure[vextexIdx] = {
                child: [],
                parent: null
            }
        }   
        
        for (idx=0; idx<totalTriangles; idx++) {
            const geoIndex1 = indexArray[idx*3];
            const geoIndex2 = indexArray[idx*3+1];
            const geoIndex3 = indexArray[idx*3+2];
            const triangleIndexVertexArray = [ geoIndex1, geoIndex2, geoIndex3 ].sort(function(a, b) { 
                return a - b; 
            });
            //structure[ triangleIndexVertexArray[0] ].child.push(triangleIndexVertexArray[1], triangleIndexVertexArray[2]);
            //structure[ triangleIndexVertexArray[1] ].parent = triangleIndexVertexArray[0];
            //structure[ triangleIndexVertexArray[2] ].parent = triangleIndexVertexArray[0];
            structure[ triangleIndexVertexArray[0] ].child.push(triangleIndexVertexArray[1], triangleIndexVertexArray[2]);
            if (structure[ triangleIndexVertexArray[1] ].parent == null) {
                structure[ triangleIndexVertexArray[1] ].parent = triangleIndexVertexArray[0];
            }
            if (structure[ triangleIndexVertexArray[2] ].parent == null) {
                structure[ triangleIndexVertexArray[2] ].parent = triangleIndexVertexArray[0];          
            }
            //if structure[ triangleIndexVertexArray[0] ].parent == null --> check children which parent is not itself
            if (structure[ triangleIndexVertexArray[0] ].parent == null) {
                for (var childIdx=0; childIdx<structure[ triangleIndexVertexArray[0] ].child.length; childIdx++) {
                    let childIndex = structure[ triangleIndexVertexArray[0] ].child[childIdx];
                    if (structure[childIndex].parent != triangleIndexVertexArray[0]) {
                        structure[ triangleIndexVertexArray[0] ].parent = structure[childIndex].parent;
                        break;
                    }
                }
            }       
        }
        
        console.log(structure);
        
        let count = 0;
        let currentCount = 0;
        let geometryStructureArray = [];
        
        for (let strIdx=0; strIdx<structure.length; strIdx++) {
            if (structure[strIdx].parent == null || geometryStructureArray[currentCount] == undefined) {
                currentCount = count;
                geometryStructureArray[currentCount] = {
                    name: "G_" + currentCount,
                    indexMap: {},
                    currentIndex: 0,
                    indexArray: [],
                    positionArray: [],
                    colorArray: [],
                    geoColor: [Math.random(), Math.random(), Math.random()]
                };
                count += 1;
            }
            if (structure[strIdx].child.length > 0) {
                const childLen = structure[strIdx].child.length / 2;
                for (let childIdx=0; childIdx<childLen; childIdx++) {
                    if (structure[strIdx] != undefined) {
                        const vertexIndex0 = strIdx;
                        const vertexIndex1 = structure[strIdx].child[childIdx*2];
                        const vertexIndex2 = structure[strIdx].child[childIdx*2+1];
                        const v0 = new THREE.Vector3( positionArray[strIdx*3], positionArray[strIdx*3+1], positionArray[strIdx*3+2] );
                        const v1 = new THREE.Vector3( positionArray[vertexIndex1*3], positionArray[vertexIndex1*3+1], positionArray[vertexIndex1*3+2] );
                        const v2 = new THREE.Vector3( positionArray[vertexIndex2*3], positionArray[vertexIndex2*3+1], positionArray[vertexIndex2*3+2] );
                        
                        
                        // check vertex0
                        if (geometryStructureArray[currentCount].indexMap[vertexIndex0] == undefined) {
                            geometryStructureArray[currentCount].indexMap[vertexIndex0] = geometryStructureArray[currentCount].currentIndex;
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
                            geometryStructureArray[currentCount].positionArray.push(v0.x, v0.y, v0.z);
                            //geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
                            geometryStructureArray[currentCount].colorArray.push(
                                geometryStructureArray[currentCount].geoColor[0],
                                geometryStructureArray[currentCount].geoColor[1],
                                geometryStructureArray[currentCount].geoColor[2]
                            )
                            geometryStructureArray[currentCount].currentIndex += 1;
                        } else {
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex0]);
                        }
                        
                        // check vertex1
                        if (geometryStructureArray[currentCount].indexMap[vertexIndex1] == undefined) {
                            geometryStructureArray[currentCount].indexMap[vertexIndex1] = geometryStructureArray[currentCount].currentIndex;
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
                            geometryStructureArray[currentCount].positionArray.push(v1.x, v1.y, v1.z);
                            //geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
                            geometryStructureArray[currentCount].colorArray.push(
                                geometryStructureArray[currentCount].geoColor[0],
                                geometryStructureArray[currentCount].geoColor[1],
                                geometryStructureArray[currentCount].geoColor[2]
                            )
                            geometryStructureArray[currentCount].currentIndex += 1;
                        } else {
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex1]);
                        }
                        
                        // check vertex1
                        if (geometryStructureArray[currentCount].indexMap[vertexIndex2] == undefined) {
                            geometryStructureArray[currentCount].indexMap[vertexIndex2] = geometryStructureArray[currentCount].currentIndex;
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
                            geometryStructureArray[currentCount].positionArray.push(v2.x, v2.y, v2.z);
                            //geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
                            geometryStructureArray[currentCount].colorArray.push(
                                geometryStructureArray[currentCount].geoColor[0],
                                geometryStructureArray[currentCount].geoColor[1],
                                geometryStructureArray[currentCount].geoColor[2]
                            )
                            geometryStructureArray[currentCount].currentIndex += 1;
                        } else {
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex2]);
                        }
                    }
                }
            }   
        }
        
        // Convert to geometryArray:
        const geometryStructureArrayLen = geometryStructureArray.length;
        const object3d = new THREE.Object3D();
        
        for (let geoIdx=0; geoIdx<geometryStructureArrayLen; geoIdx++) {
            const geo = new THREE.BufferGeometry();
            geo.name = "G_" + geoIdx;
            const geoPositions = new Float32Array(geometryStructureArray[geoIdx].positionArray);
            const geoColors = new Float32Array(geometryStructureArray[geoIdx].colorArray);
            const geoIndices = new Uint32Array(geometryStructureArray[geoIdx].indexArray);
            //console.log(geoIdx, "geoPositions: ", geoPositions);
            //console.log(geoIdx, "geoColors: ", geoColors);
            //console.log(geoIdx, "geoIndices: ", geoIndices);
            geo.index = new THREE.BufferAttribute(geoIndices, 1, false);
            
            geo.attributes.position = new THREE.BufferAttribute(geoPositions, 3, false);
            geo.attributes.color = new THREE.BufferAttribute(geoColors, 3, true);
            geo.computeBoundingSphere();
            geo.computeBoundingBox();
            
            const mesh = new THREE.Mesh(geo, material);
            mesh.name = "M_" + geoIdx;
            object3d.add(mesh);
        }
        return [structure, geometryStructureArray, object3d, count];
        //return object3d;
    }
function groupGeometryIntoNonConnectedGeometries(geometry) {
        const material = new THREE.MeshBasicMaterial({
            side: THREE.DoubleSide,
            vertexColors: THREE.VertexColors
        });
        let geometryArray = [];
        const indexArray = geometry.index.array;
        const positionArray = geometry.attributes.position.array;
        const positionCount = geometry.attributes.position.count;
        const color = new THREE.Vector3(geometry.attributes.color.array[0], geometry.attributes.color.array[1], geometry.attributes.color.array[2]);
        const totalTriangles = indexArray.length / 3;
        let geometryCount = 0;
        let indexValueAlreadyVisited = new Uint8Array(indexArray.length);   
        let structure = [];
            /*
             * indexValue: {
             *  child: [ [indexval0, indexval1], [] ],
             *  parent: null
             * }
             */
        // Initialize Structure:
        for (var vextexIdx=0; vextexIdx<positionCount; vextexIdx++) {
            structure[vextexIdx] = {
                child: [],
                parent: null
            }
        }   
        
        for (idx=0; idx<totalTriangles; idx++) {
            const geoIndex1 = indexArray[idx*3];
            const geoIndex2 = indexArray[idx*3+1];
            const geoIndex3 = indexArray[idx*3+2];
            const triangleIndexVertexArray = [ geoIndex1, geoIndex2, geoIndex3 ].sort(function(a, b) { 
                return a - b; 
            });
            //structure[ triangleIndexVertexArray[0] ].child.push(triangleIndexVertexArray[1], triangleIndexVertexArray[2]);
            //structure[ triangleIndexVertexArray[1] ].parent = triangleIndexVertexArray[0];
            //structure[ triangleIndexVertexArray[2] ].parent = triangleIndexVertexArray[0];
            structure[ triangleIndexVertexArray[0] ].child.push(triangleIndexVertexArray[1], triangleIndexVertexArray[2]);
            if (structure[ triangleIndexVertexArray[1] ].parent == null) {
                structure[ triangleIndexVertexArray[1] ].parent = triangleIndexVertexArray[0];
            }
            if (structure[ triangleIndexVertexArray[2] ].parent == null) {
                structure[ triangleIndexVertexArray[2] ].parent = triangleIndexVertexArray[0];          
            }
            //if structure[ triangleIndexVertexArray[0] ].parent == null --> check children which parent is not itself
            if (structure[ triangleIndexVertexArray[0] ].parent == null) {
                for (var childIdx=0; childIdx<structure[ triangleIndexVertexArray[0] ].child.length; childIdx++) {
                    let childIndex = structure[ triangleIndexVertexArray[0] ].child[childIdx];
                    if (structure[childIndex].parent != triangleIndexVertexArray[0]) {
                        structure[ triangleIndexVertexArray[0] ].parent = structure[childIndex].parent;
                        break;
                    }
                }
            }       
        }
        
        console.log(structure);
        
        let count = 0;
        let currentCount = 0;
        let geometryStructureArray = [];
        
        for (let strIdx=0; strIdx<structure.length; strIdx++) {
            if (structure[strIdx].parent == null || geometryStructureArray[currentCount] == undefined) {
                currentCount = count;
                geometryStructureArray[currentCount] = {
                    name: "G_" + currentCount,
                    indexMap: {},
                    currentIndex: 0,
                    indexArray: [],
                    positionArray: [],
                    colorArray: [],
                    geoColor: [Math.random(), Math.random(), Math.random()]
                };
                count += 1;
            }
            if (structure[strIdx].child.length > 0) {
                const childLen = structure[strIdx].child.length / 2;
                for (let childIdx=0; childIdx<childLen; childIdx++) {
                    if (structure[strIdx] != undefined) {
                        const vertexIndex0 = strIdx;
                        const vertexIndex1 = structure[strIdx].child[childIdx*2];
                        const vertexIndex2 = structure[strIdx].child[childIdx*2+1];
                        const v0 = new THREE.Vector3( positionArray[strIdx*3], positionArray[strIdx*3+1], positionArray[strIdx*3+2] );
                        const v1 = new THREE.Vector3( positionArray[vertexIndex1*3], positionArray[vertexIndex1*3+1], positionArray[vertexIndex1*3+2] );
                        const v2 = new THREE.Vector3( positionArray[vertexIndex2*3], positionArray[vertexIndex2*3+1], positionArray[vertexIndex2*3+2] );
                        
                        
                        // check vertex0
                        if (geometryStructureArray[currentCount].indexMap[vertexIndex0] == undefined) {
                            geometryStructureArray[currentCount].indexMap[vertexIndex0] = geometryStructureArray[currentCount].currentIndex;
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
                            geometryStructureArray[currentCount].positionArray.push(v0.x, v0.y, v0.z);
                            //geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
                            geometryStructureArray[currentCount].colorArray.push(
                                geometryStructureArray[currentCount].geoColor[0],
                                geometryStructureArray[currentCount].geoColor[1],
                                geometryStructureArray[currentCount].geoColor[2]
                            )
                            geometryStructureArray[currentCount].currentIndex += 1;
                        } else {
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex0]);
                        }
                        
                        // check vertex1
                        if (geometryStructureArray[currentCount].indexMap[vertexIndex1] == undefined) {
                            geometryStructureArray[currentCount].indexMap[vertexIndex1] = geometryStructureArray[currentCount].currentIndex;
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
                            geometryStructureArray[currentCount].positionArray.push(v1.x, v1.y, v1.z);
                            //geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
                            geometryStructureArray[currentCount].colorArray.push(
                                geometryStructureArray[currentCount].geoColor[0],
                                geometryStructureArray[currentCount].geoColor[1],
                                geometryStructureArray[currentCount].geoColor[2]
                            )
                            geometryStructureArray[currentCount].currentIndex += 1;
                        } else {
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex1]);
                        }
                        
                        // check vertex1
                        if (geometryStructureArray[currentCount].indexMap[vertexIndex2] == undefined) {
                            geometryStructureArray[currentCount].indexMap[vertexIndex2] = geometryStructureArray[currentCount].currentIndex;
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
                            geometryStructureArray[currentCount].positionArray.push(v2.x, v2.y, v2.z);
                            //geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
                            geometryStructureArray[currentCount].colorArray.push(
                                geometryStructureArray[currentCount].geoColor[0],
                                geometryStructureArray[currentCount].geoColor[1],
                                geometryStructureArray[currentCount].geoColor[2]
                            )
                            geometryStructureArray[currentCount].currentIndex += 1;
                        } else {
                            geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex2]);
                        }
                    }
                }
            }   
        }
        
        // Convert to geometryArray:
        const geometryStructureArrayLen = geometryStructureArray.length;
        const object3d = new THREE.Object3D();
        
        for (let geoIdx=0; geoIdx<geometryStructureArrayLen; geoIdx++) {
            const geo = new THREE.BufferGeometry();
            geo.name = "G_" + geoIdx;
            const geoPositions = new Float32Array(geometryStructureArray[geoIdx].positionArray);
            const geoColors = new Float32Array(geometryStructureArray[geoIdx].colorArray);
            const geoIndices = new Uint32Array(geometryStructureArray[geoIdx].indexArray);
            //console.log(geoIdx, "geoPositions: ", geoPositions);
            //console.log(geoIdx, "geoColors: ", geoColors);
            //console.log(geoIdx, "geoIndices: ", geoIndices);
            geo.index = new THREE.BufferAttribute(geoIndices, 1, false);
            
            geo.attributes.position = new THREE.BufferAttribute(geoPositions, 3, false);
            geo.attributes.color = new THREE.BufferAttribute(geoColors, 3, true);
            geo.computeBoundingSphere();
            geo.computeBoundingBox();
            
            const mesh = new THREE.Mesh(geo, material);
            mesh.name = "M_" + geoIdx;
            object3d.add(mesh);
        }
        return [structure, geometryStructureArray, object3d, count];
        //return object3d;
    }
功能组GeometryIntonConnectedGeometries(几何){
常量材质=新的三网格基本材质({
三面,双面,
顶点颜色:三。顶点颜色
});
设geometryArray=[];
const indexArray=geometry.index.array;
const positionArray=geometry.attributes.position.array;
const positionCount=geometry.attributes.position.count;
const color=new THREE.Vector3(geometry.attributes.color.array[0],geometry.attributes.color.array[1],geometry.attributes.color.array[2]);
const totalTriangles=indexArray.length/3;
设geometryCount=0;
让indexValueAlreadyVisited=新的UINT8数组(indexArray.length);
让结构=[];
/*
*索引值:{
*子项:[[indexval0,indexval1],],
*父项:null
* }
*/
//初始化结构:

对于(var-vextexix=0;vextexix我认为fowwing代码可以工作,但是如果有人能够检查并提供反馈,那就太好了

功能组GeometryIntonConnectedGeometries(几何){
常量材质=新的三网格基本材质({
三面,双面,
顶点颜色:三。顶点颜色
});
设geometryArray=[];
const indexArray=geometry.index.array;
const positionArray=geometry.attributes.position.array;
const positionCount=geometry.attributes.position.count;
const color=new THREE.Vector3(geometry.attributes.color.array[0],geometry.attributes.color.array[1],geometry.attributes.color.array[2]);
const totalTriangles=indexArray.length/3;
设geometryCount=0;
让indexValueAlreadyVisited=新的UINT8数组(indexArray.length);
让结构=[];
/*
*索引值:{
*子项:[[indexval0,indexval1],],
*父项:null
* }
*/
//初始化结构:
对于(var VEXTEXIXIX=0;VEXTEXIXIX)