【发布时间】: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);
}
【问题讨论】: