当我尝试从 .mat 文件加载顶点、面和法线时,为什么我的缓冲区几何体会失败?

问题描述 投票:0回答:1

我想将我的 matlab 几何图形加载到我的 Three.js 场景中。我的 3D 数据保存在 struct .mat 文件中,其中包含 .vertices、.faces、.VertexNormals 和 .VertexColorData 数组。我能够将其加载到 JavaScript 中并使用缓冲区几何体并设置属性将数据存储到网格几何体中。

                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();
   

顶点着色效果很好。但是,我最终得到的网格具有索引面或法线,未连接到法线表面。

mesh with index faces or normal not connecting up into a normal surface.

我不确定我做错了什么。我将非常感谢所提供的任何帮助。

编辑-- 我做了一个 jsfiddle 来帮忙。 https://jsfiddle.net/marieO/5zdhsk78/68/

但是需要先下载.mat文件,然后上传到场景。

matlab three.js mesh buffer-geometry
1个回答
0
投票

感谢您发布一个工作示例,其中包含重现错误所需的步骤。这使得提供帮助变得更加容易。

Matlab 几何中有 652 个顶点。使用

.setIndex()
时,这些索引必须在
[0, 651]
范围内,因为 JavaScript 数组从索引
0
开始。但是,您的
faces
数据范围为
[1, 652]
,这意味着所有三角形都偏离 1 个顶点。

这可以通过在分配索引时添加

-1
轻松解决:

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);

结果:

© www.soinside.com 2019 - 2024. All rights reserved.