0

我是 Three.js 的新手,并被分配了尝试修复偶尔出现的看起来很糟糕的文件的法线的任务。我们不知道它们是否是错误的扫描或可能是错误的上传。我们正在研究上传功能,但如果可能的话也想尝试修复它们。谁能提供任何想法或提示来修复文件或找到正确的法线?

下面是我们获取法线以及如何获取它们的代码。注意:此代码通常可以正常工作,只有当法线不好时才会出现问题。我还附上了其中一个文件,这样您就可以看到我正在处理的法线类型和“坏文件”。在此处获取文件

我们还在后端使用 C++ 使用 VTK,因此使用其中任何一个的解决方案或想法都会很有帮助。

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;
  }
}
4

2 回答 2

0

VTK 有一个名为vtkPolyDataNormals的过滤器,您可以在文件上运行它来计算法线。您可能想在运行它之前调用ConsistencyOn(), NonManifoldTraversalOn(), and 。AutoOrientNormalsOn()

如果您想要点法线(而不是每个单元的法线)并且您的形状有尖角,您可能需要提供一个特征角度SetFeatureAngle()并调用SplittingOn().

于 2017-07-04T15:41:47.557 回答
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;
于 2017-07-04T11:04:54.880 回答