I want to load in my matlab geometry into my three.js scene. My 3D data is saved in a struct .mat file which contains .vertices, .faces, .VertexNormals and .VertexColorData arrays. I am able to load it into JavaScript and use buffer geometry and set attributes to store the data into a mesh geometry.
var keyName = keysArray[0];
meshGeometry = new THREE.BufferGeometry();
var index = 0;
var positions = new Float32Array(bfjson.data[keyName].vertices.length * 3);
for (let i = 0; i < bfjson.data[keyName].vertices.length; i++) {
positions[index++] = bfjson.data[keyName].vertices[i][0];
positions[index++] = bfjson.data[keyName].vertices[i][1];
positions[index++] = bfjson.data[keyName].vertices[i][2];
}
meshGeometry.setAttribute(
'position',
new THREE.BufferAttribute(positions, 3));
var index = 0;
var vectornormals = new Float32Array(bfjson.data[keyName].VertexNormals.length * 3);
for (let i = 0; i < bfjson.data[keyName].VertexNormals.length; i++) {
vectornormals[index++] = bfjson.data[keyName].VertexNormals[i][0];
vectornormals[index++] = bfjson.data[keyName].VertexNormals[i][1];
vectornormals[index++] = bfjson.data[keyName].VertexNormals[i][2];
}
meshGeometry.setAttribute(
'normal',
new THREE.BufferAttribute(vectornormals, 3));
var index = 0;
//var faces = new Uint16Array(bfjson.data[keyName].faces.length * 3);
var faces = [];
for (let i = 0; i < bfjson.data[keyName].faces.length; i++) {
faces[index++] = bfjson.data[keyName].faces[i][0];
faces[index++] = bfjson.data[keyName].faces[i][1];
faces[index++] = bfjson.data[keyName].faces[i][2];
}
meshGeometry.setIndex(faces);
// default color attribute
const colors = [];
for (let i = 0, n = meshGeometry.attributes.position.count; i < n; ++i) {
colors.push(1, 1, 1);
}
meshGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
for (let i = 0; i < bfjson.data[keyName].CData.length; i++) {
CData[i] = (bfjson.data[keyName].CData[i]);
}
meshGeometry.setAttribute('perfusion', new THREE.Float32BufferAttribute(CData, 1));
mesh.geometry = meshGeometry;
updateColors();
The vertex coloring works fine. However, I end up with mesh with index faces or normal not connecting into a normal surface.
mesh with index faces or normal not connecting up into a normal surface.
I am not sure what I am doing wrong. I will be extremely grateful for any help provided.
Edit-- I have made a jsfiddle to help. https://jsfiddle.net/marieO/5zdhsk78/68/
But you need to download the .mat file first then upload it to the scene.
Thanks for posting a working example with the steps needed to reproduce the error. It makes it much easier to help.
You have 652 vertices in your Matlab geometry. When using .setIndex()
, these indices have to be in the [0, 651]
range, because JavaScript arrays start at index 0
. However, your faces
data ranges from [1, 652]
, which means all your triangles are off by 1 vertex.
This is easily solvable by adding a -1
when assigning the index:
var index = 0;
var faces = [];
for (let i = 1; i < bfjson.data[keyName].faces.length; i++) {
faces[index++] = bfjson.data[keyName].faces[i][0] - 1;
faces[index++] = bfjson.data[keyName].faces[i][1] - 1;
faces[index++] = bfjson.data[keyName].faces[i][2] - 1;
}
meshGeometry.setIndex(faces);