【问题标题】:Ray to Octree Intersection for boolean geometry布尔几何的射线到八叉树交点
【发布时间】:2021-02-20 04:50:19
【问题描述】:

我正在尝试做布尔几何,我有两个网格并想计算它们之间的交集。

所以我从网格 A 构造一个八叉树,然后检查网格 B 的顶点与八分圆,如果有交集,检查八分圆三角形是否相交,然后添加三角形,构造一个网格。

auto intersected_octant_faces = mn::buf_new<musa::Triangle>();
    std::stack < cg::Octant *> stack;
    stack.push(octree_sphere.root);
    for (size_t i = 0; i < tri_mesh_cube.vertices.count; i++)
    {
        while (!stack.empty())
        {
            cg::Octant* node = stack.top();
            if (!node)
                break;
            stack.pop();

            musa::Ray ray;
            ray.origin = { tri_mesh_cube.vertices[i] };
            ray.dir = { 1,0,0 };

            musa::Intersection_Points pts = {};
            pts = musa::ray_box_intersection(ray, node->region);
            if (pts.count >= 1)
            {
                musa::Intersection_Points t = {};
                auto vertices = node->faces;
                for (size_t j = 0; j < vertices.count; j += 3)
                {
                    musa::Triangle tri{ vertices[j], vertices[j + 1], vertices[j + 2] };
                    t = musa::ray_triangle_intersection(ray, tri);
                    if (t.count == 1)
                    {
                        mn::buf_push(intersected_octant_faces, tri);
                    }
                }

            }
            for (auto& n : node->octants)
            {
                stack.push(n);
            }
        }
    }

现在我只得到如图所示的两张脸,不确定问题出在哪里。

更新:

我遵循了 Spektre 所说的算法,结果如下:

auto tri_mesh_a = cg::trimesh_from_indexed_mesh(sphere_indexed_mesh);
    auto tri_mesh_b = cg::trimesh_from_indexed_mesh(cube_indexed_mesh);
    auto octree_a = cg::octree_from_mesh(tri_mesh_a);
    
        std::stack < cg::Octant*> stack;

        for (size_t i = 0; i < tri_mesh_b.vertices.count; i += 3)
        {
            musa::Triangle triB{ tri_mesh_b.vertices[i], tri_mesh_b.vertices[i + 1], tri_mesh_b.vertices[i + 2] };
            stack.push(octree_a.root);

            while (!stack.empty())
            {
                cg::Octant* node = stack.top();
                stack.pop();

                if (box_box_intersect(musa::triangle_bounding_box(triB), node->region))
                {
                    auto vertices = node->faces;

                    for (size_t a = 0; a < vertices.count; a += 3)
                    {
                        musa::Triangle triA{ vertices[a], vertices[a + 1], vertices[a + 2] };

                        if (triangle_triangle_intersection_check(triB, triA))
                        {
                            vec3 v1 = { vertices[a] };
                            vec3 v2 = { vertices[a + 1] };
                            vec3 v3 = { vertices[a + 2] };

                            mn::buf_push(self->modelIntersection.points, v1);
                            mn::buf_push(self->modelIntersection.points, v2);
                            mn::buf_push(self->modelIntersection.points, v3);


                        }



                    }

                    for (auto& n : node->octants)
                    {
                        if (n == nullptr)
                            continue;
                        stack.push(n);
                    }
                }
            }
        }

 
    for (int i = 0; i < self->modelIntersection.points.count; i++)
    {
        mn::buf_push(self->modelIntersection.indices, i);
    }

【问题讨论】:

    标签: c++ algorithm 3d octree


    【解决方案1】:

    假设:球体是对象A,八叉树o 填充了它。立方体是对象B,两个对象都仅由三角形构成。

    1. 对于B的每个三角形

      所以循环遍历B 的所有三角形并一次测试一个,我们称之为tb。让我们调用三角形点:tb.p0, tb.p1, t.p2

    2. 获取所有与tb三角形相交的o节点

      如果您的八叉树没有三角形测试,您可以通过测试线来简化:

      line(tb.p0,tb.p1)
      line(tb.p1,tb.p2)
      line(tb.p2,tb.p0)
      

      它不是完整的测试,但在大多数情况下已经足够了。如果需要,您还可以测试几条内部线以覆盖一些内部:

      pp = (tb.p0 + tb.p1 + tb.p2) / 3
      line(tb.pp,tb.p0)
      line(tb.pp,tb.p1)
      line(tb.pp,tb.p2)
      

      但是,如果您需要完整的测试,您很可能需要以困难的方式实现它(三角形与立方体相交)。

    3. 针对每个找到的相交节点测试其所有三角形与tb

      因此,现在您对来自A 的三角形与三角形tb 进行测试并存储所有相交的来自A 的三角形。

      此处为完整测试示例:line closest(triangle t0,triangle t1)

      结果中可能会有很多重复的三角形,因此您可以在向结果中添加新三角形之前添加重复性测试。

    【讨论】:

    • 它现在相交很好,但有些三角形不包括在内,另一个则被排除在外。
    猜你喜欢
    • 2015-08-20
    • 2012-05-01
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多