javascript — исправление нормалей на возможно плохих файлах .stl

Я новичок в Three.js, и мне было поручено попытаться восстановить нормали в файлах, которые время от времени появлялись, которые кажутся плохими. Мы не знаем, являются ли они плохими сканированиями или, возможно, плохими загрузками. Мы рассматриваем функцию загрузки, но также хотели бы попытаться восстановить их, если это возможно. Может ли кто-нибудь предоставить какие-либо идеи или советы по восстановлению файла или найти правильные нормали?

Ниже приведен код, где мы берем нормали и как мы их получаем. ПРИМЕЧАНИЕ: этот код работает нормально, это проблема, только если нормальные значения плохие. Я также прикрепляю один из файлов, чтобы вы могли видеть типы нормалей и «плохих файлов», с которыми я имею дело. Получить файл здесь

Мы также используем VTK в бэкэнде с C ++, поэтому решение или идея, использующая любой из них, полезна.

my.geometry = geometry;

var front = new THREE.MeshPhongMaterial(
{color: 0xe2e4dc, shininess: 50, side: THREE.DoubleSide});

var mesh = [new THREE.Mesh(geometry, front)];

my.scene.add(mesh[0]);
my.objects.push(mesh[0]);

var rc = new THREE.Raycaster();

var modelData = {'objects': [mesh[0].id], 'id': mesh[0].id};

var normalFound = false;
for (var dy = 80; dy >= -80; dy = dy - 10) {
console.log('finding a normal on', 0, dy, -200);
rc.set(new THREE.Vector3(0, dy, -200), new THREE.Vector3(0, 0, 1));

var hit = rc.intersectObjects([mesh[0]]);

if (hit.length) {
my.normal = hit[0].face.normal.normalize();
console.log('normal', my.normal.z);

modelData['normal'] = my.normal;

if ((my.normal.z > 0.9 && my.normal.z < 1.1)) {
my.requireOrienteering = true;
modelData['arch'] = 'lower';
normalFound = true;
console.log('we have a lower arch');
} else if ((my.normal.z < -0.9 && my.normal.z > -1.1)) {
modelData['arch'] = 'upper';
normalFound = true;
console.log('we have an upper arch');
}

break;
}
}

0

Решение

Вычисление норм является простым шагом. Если вы вычислите перекрестное произведение двух векторов (геометрического), вы получите вектор, который ортогонален двум введенным вами значениям. Все, что вам нужно сделать сейчас, это нормализовать его, так как нормали должны быть нормализованы, чтобы не испортить молниеносные вычисления.

Для гладких поверхностей вы должны вычислить все нормали на точке и усреднить их. Для плоских поверхностей каждая вершина имеет несколько нормалей (по одной на каждую поверхность).

В псевдокоде это будет выглядеть для четырехугольников:

foreach quad : mesh
foreach vertex : quad
vector1 = neighborVertex.pos - vertex.pos;
vector2 = otherNeighborVertex.pos - vertex.pos;
vertex.normal = normalize(cross(vector1, vector2));
end foreach;
end foreach;
0

Другие решения

ВТК имеет фильтр с именем vtkPolyDataNormals что вы можете запустить свой файл для вычисления нормалей. Вы, вероятно, хотите позвонить ConsistencyOn(), NonManifoldTraversalOn(), а также AutoOrientNormalsOn() перед запуском.

Если вам нужны точечные нормали (вместо нормалей на ячейку) и ваша фигура имеет острые углы, вы, вероятно, захотите задать угол элемента с помощью SetFeatureAngle() и позвонить SplittingOn(),

0

По вопросам рекламы [email protected]