立体光刻 (STL) 文件中的三角形顶点缠绕顺序(三角对象)

发布于 2024-12-25 02:02:05 字数 2144 浏览 2 评论 0原文

我正在开发一个 STL 文件导入器,并认为我应该利用给定的法线来确定三角形缠绕顺序。下面包含 4 个三角形的示例数据(原始数据有超过 70k 个三角形)。我的代码的逻辑计算法线,假设顶点是逆时针指定的,然后将计算出的法线与提供的法线进行点积。如果结果是正的,那么我假设逆时针,否则顺时针。

        tm.SetCCW(Dot(Cross(facet.getVertex2() - facet.getVertex1(),facet.getVertex3() - facet.getVertex1()),facet.getNormal()) > 0.0);

此逻辑在来自特定 3D 扫描仪的一组文件上失败。当我将这些文件加载​​到Rhino3D中,并发出“Dir”来查看法线方向时,Rhino的方向是正确的!与我尝试过的其他几个 STL 查看器相同。

我的代码推断出样本数据上的顶点是按顺时针顺序提供的,但是当使用该缠绕顺序时,模型是由内而外的,这意味着提供的法线是错误的。

这让我得出这样的结论:STL 导入器通常会忽略提供的法线,并采用逆时针缠绕顺序。我正在寻找对 STL 文件格式有更多经验的人来衡量我的假设是否正确。

solid object_name
    facet normal -0.651094 0.733745 -0.194150
        outer loop
            vertex 30.335684 -40.893806 -68.126500
            vertex 31.155055 -39.911656 -67.162500
            vertex 30.263726 -40.702583 -67.162500
        endloop
    endfacet
    facet normal -0.654292 0.732059 -0.189714
        outer loop
            vertex 30.335684 -40.893806 -68.126500
            vertex 31.225185 -40.098797 -68.126500
            vertex 31.155055 -39.911656 -67.162500
        endloop
    endfacet
    facet normal -0.711866 0.677947 -0.183397
        outer loop
            vertex 31.225185 -40.098797 -68.126500
            vertex 31.980540 -39.044870 -67.162500
            vertex 31.155055 -39.911656 -67.162500
        endloop
    endfacet
    facet normal -0.714326 0.676343 -0.179716
        outer loop
            vertex 31.225185 -40.098797 -68.126500
            vertex 32.048799 -39.228928 -68.126500
            vertex 31.980540 -39.044870 -67.162500
        endloop
    endfacet
endsolid

编辑:我对第一个方面的计算:

p1 = {30.335684, -40.893806, -68.126500}
p2 = {31.155055, -39.911656, -67.162500}
p3 = {30.263726, -40.702583, -67.162500}

u = p2 - p1 = {0.819371, 0.98215, 0.964}
w = p3 - p1 = {-0.071958, 0.191223, 0.964}

u x w = {0.762454, -0.859241, 0.227356}   (calculated normal)

given normal = {-0.651094, 0.733745, -0.194150}

calculated_normal <dot> given_normal = -1.17103

verdict: 90 < theta < 270 where theta is the angle between the calculated and given normals

I'm working on an STL file importer and thought I'd make use of the normal given to determine the triangle winding order. Sample data with 4 triangles is included below (original data has over 70k triangles). My code's logic computes the normal assuming the vertices are specified anticlockwise, then does a dot product of this calculated normal with the supplied normal. If the result is positive, then I assume anticlockwise, else clockwise.

        tm.SetCCW(Dot(Cross(facet.getVertex2() - facet.getVertex1(),facet.getVertex3() - facet.getVertex1()),facet.getNormal()) > 0.0);

This logic fails on a set of files from a particular 3D scanner. When I load these files into Rhino3D though, and issue "Dir" to look at the normal direction, Rhino has the direction correct! Same with a couple of other STL viewers I've tried.

My code deduces that the vertices are supplied in clockwise order on the sample data, but when using that winding order, the model is inside-out, implying the supplied normals are wrong.

This leads me to the conclusion that it is convention for STL importers to ignore the supplied normal, and assume anticlockwise winding order. I'm looking for people with more experience in the STL file format to weigh in on whether my assumption is correct.

solid object_name
    facet normal -0.651094 0.733745 -0.194150
        outer loop
            vertex 30.335684 -40.893806 -68.126500
            vertex 31.155055 -39.911656 -67.162500
            vertex 30.263726 -40.702583 -67.162500
        endloop
    endfacet
    facet normal -0.654292 0.732059 -0.189714
        outer loop
            vertex 30.335684 -40.893806 -68.126500
            vertex 31.225185 -40.098797 -68.126500
            vertex 31.155055 -39.911656 -67.162500
        endloop
    endfacet
    facet normal -0.711866 0.677947 -0.183397
        outer loop
            vertex 31.225185 -40.098797 -68.126500
            vertex 31.980540 -39.044870 -67.162500
            vertex 31.155055 -39.911656 -67.162500
        endloop
    endfacet
    facet normal -0.714326 0.676343 -0.179716
        outer loop
            vertex 31.225185 -40.098797 -68.126500
            vertex 32.048799 -39.228928 -68.126500
            vertex 31.980540 -39.044870 -67.162500
        endloop
    endfacet
endsolid

EDIT: My calculations for the first facet:

p1 = {30.335684, -40.893806, -68.126500}
p2 = {31.155055, -39.911656, -67.162500}
p3 = {30.263726, -40.702583, -67.162500}

u = p2 - p1 = {0.819371, 0.98215, 0.964}
w = p3 - p1 = {-0.071958, 0.191223, 0.964}

u x w = {0.762454, -0.859241, 0.227356}   (calculated normal)

given normal = {-0.651094, 0.733745, -0.194150}

calculated_normal <dot> given_normal = -1.17103

verdict: 90 < theta < 270 where theta is the angle between the calculated and given normals

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

盛装女皇 2025-01-01 02:02:05

当从对象外部观察顶点时,顶点应按逆时针顺序排列。 (显然,从物体内部观察,它们按顺时针顺序排列)。

法线应指向外侧。

我读过一些程序忽略法线,只按照顶点顺序进行,我什至读过将法线设置为 {0.0, 0.0, 0.0} 的建议,尽管规范规定法线和顶点顺序应该两者都可以使用。

虽然正常是多余的。对于许多程序来说,顶点顺序就足够了。我不知道这是否适用于所有程序。我建议两者都正确。

The vertices should be in counter-clockwise order when the vertices are viewed from outside of the object. (Obviously, viewing from inside the object they are then in clockwise order).

The normal should point outward.

I have read that some programs ignore the normal and only go by the vertex ordering, and I've even read a recommendation to set the normal to {0.0, 0.0, 0.0}, although the specification states that the normal and the vertex order should both be used.

The normal is redundant though. For many programs, the vertex order is all that is necessary. I don't know if that is generally true for all programs. I recommend making both be correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文