Как сгладить треугольники сетки в STL загруженной Буфергеометрии
Im пытается загрузить некоторые файлы STL, используя три.js. Модели загружены правильно, но слишком много треугольников, которые я хотел бы объединить/сгладить.
Я успешно применил гладкие области загрузки в других форматах 3D, но я не могу сделать это с помощью BufferGeometry, которая возникает при загрузке файла STL с помощью STLLoader.
var material = new THREE.MeshLambertMaterial( { ... } );
var path = "./models/budah.stl";
var loader = new THREE.STLLoader();
loader.load( path, function ( object ) {
object.computeBoundingBox();
object.computeBoundingSphere();
object.computeFaceNormals();
object.computeVertexNormals();
object.normalizeNormals();
object.center();
// Apply smooth
var modifier = new THREE.SubdivisionModifier( 1);
var smooth = smooth = object.clone();
smooth.mergeVertices();
smooth.computeFaceNormals();
smooth.computeVertexNormals();
modifier.modify( smooth );
scene.add( smooth );
});
Это то, что я пробовал, он выдает ошибку: Uncaught TypeError: гладкий.mergeVertices не является функцией
если я прокомментирую строку" mergeVertices ()", я получу другую ошибку: Uncaught TypeError: не удается прочитать свойство "length" неопределенного в SubdivisionsModifier, строка 156.
Кажется, что примеры кодов, которые я пытаюсь, устарели (это происходит в последнее время из-за массовых изменений в трех.JS library). Или, может быть, я что-то забыл. Дело в том, что вершины кажутся ноль..?
спасибо заранее!
3 ответов
Кажется, я смотрел в неправильном направлении: сглаживание треугольников не имеет ничего общего с SubdivisionsModifier... То, что мне было нужно, было проще, просто вычислите вершину перед применением материала, чтобы она могла использовать SmoothShading вместо FlatShading (я правильно понял?).
проблема здесь заключалась в том, что BufferGeometry, возвращаемая STLLoader, не вычисляла вершины/вершину, поэтому мне пришлось сделать это вручную. После этого примените mergeVertices () непосредственно перед computeVertexNormals () и вуаля! Треугольники исчезают, и все становится гладким:
var material = new THREE.MeshLambertMaterial( { ... } );
var path = "./models/budah.stl";
var loader = new THREE.STLLoader();
loader.load( path, function ( object ) {
object.computeBoundingBox();
object.computeVertexNormals();
object.center();
///////////////////////////////////////////////////////////////
var attrib = object.getAttribute('position');
if(attrib === undefined) {
throw new Error('a given BufferGeometry object must have a position attribute.');
}
var positions = attrib.array;
var vertices = [];
for(var i = 0, n = positions.length; i < n; i += 3) {
var x = positions[i];
var y = positions[i + 1];
var z = positions[i + 2];
vertices.push(new THREE.Vector3(x, y, z));
}
var faces = [];
for(var i = 0, n = vertices.length; i < n; i += 3) {
faces.push(new THREE.Face3(i, i + 1, i + 2));
}
var geometry = new THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeFaceNormals();
geometry.mergeVertices()
geometry.computeVertexNormals();
///////////////////////////////////////////////////////////////
var mesh = new THREE.Mesh(geometry, material);
scene.add( mesh );
});
чем, вы можете преобразовать его обратно в BufferGeometry, потому что он более эффективен GPU/CPU для более сложных моделей:
var geometry = new THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeFaceNormals();
geometry.mergeVertices();
geometry.computeVertexNormals();
var buffer_g = new THREE.BufferGeometry();
buffer_g.fromGeometry(geometry);
var mesh = new THREE.Mesh(buffer_g, material);
scene.add( mesh )
произошла эта проблема для меня при загрузке файла obj. Если у вас есть программное обеспечение 3d, как 3dsmax:
- откройте файл obj,
- перейдите в режим выбора полигонов и выберите все полигоны.
- на панели "свойства поверхности" нажмите кнопку "Auto Smooth".
- экспорт модели обратно в формат obj
теперь вам не придется вызывать геометрию функций.mergeVertices () и геометрия.computeVertexNormals ();. Просто загрузите obj и добавьте к сцене, сетка будет гладкой.
изменить: Мои obj-файлы по умолчанию имели meshphongmaterial, и при изменении свойства затенения на значение 2 сетка стала гладкой.
child.material.shading = 2