I tried with a function but still is not accurate, it produce more geometries than non connected geometries:
If somebody could have a look on it, it would be grate.
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];
}
let count = 0;
let currentCount = 0;
let geometryStructureArray = [];
for (let strIdx=0; strIdx<structure.length; strIdx++) {
if (structure[strIdx].parent == null) {
currentCount = count;
geometryStructureArray[currentCount] = {
name: "G_" + currentCount,
indexMap: {},
currentIndex: 0,
indexArray: [],
positionArray: [],
colorArray: []
};
count += 1;
}
if (structure[strIdx].child.length > 0) {
const childLen = structure[strIdx].child.length / 2;
for (let childIdx=0; childIdx<childLen; childIdx++) {
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].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].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].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;
}
Best regards