3d three.js如何分割包含未连接零件的几何图形
有没有办法确定几何体是否包含多个未连接的“对象”? 然后把它分成几个几何体 (我使用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
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)