C++ 布尔几何的光线到八叉树相交
我试图做布尔几何,我有两个网格,想计算它们之间的交集 所以我从网格A构造一个八叉树,然后我检查网格B的顶点和八分之一点,如果有交集,检查八分之一点三角形的交集,然后我添加三角形,构造一个网格C++ 布尔几何的光线到八叉树相交,c++,algorithm,3d,octree,C++,Algorithm,3d,Octree,我试图做布尔几何,我有两个网格,想计算它们之间的交集 所以我从网格A构造一个八叉树,然后我检查网格B的顶点和八分之一点,如果有交集,检查八分之一点三角形的交集,然后我添加三角形,构造一个网格 auto intersected_octant_faces = mn::buf_new<musa::Triangle>(); std::stack < cg::Octant *> stack; stack.push(octree_sphere.root); f
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);
}
}
}
auto-intersected_octant_faces=mn::buf_new();
std::stackstack;
stack.push(八叉树\球面根);
对于(大小i=0;i区域);
如果(pts.count>=1)
{
musa::交点t={};
自动顶点=节点->面;
对于(大小j=0;joctants)
{
堆栈推送(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);
}
auto tri\u mesh\u a=cg::trimesh\u来自索引网格(球体索引网格);
自动tri_mesh_b=cg::trimesh_来自索引网格(立方体索引网格);
自动八叉树=cg::八叉树网格(三重网格);
std::stackstack;
对于(大小i=0;i区域))
{
自动顶点=节点->面;
对于(大小a=0;a模型交点,v1);
mn::buf_推送(self->modelcrossion.points,v2);
mn::buf_push(self->modelcrossion.points,v3);
}
}
用于(自动&n:node->octants)
{
如果(n==nullptr)
继续;
堆栈推送(n);
}
}
}
}
对于(int i=0;imodelcrossion.points.count;i++)
{
mn::buf_push(self->modelcrossion.index,i);
}
假设:球体是对象
A
,八叉树o
中填充了它。立方体是objectB
,两个对象都仅由三角形构成
B的每个三角形
因此,循环遍历B
的所有三角形,并一次测试一个,让我们称之为tb
。让我们调用三角形点:tb.p0,tb.p1,t.p2
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)
然而,如果您需要完整的测试,您很可能需要以艰难的方式实现它(三角形与立方体相交)
tb测试其所有三角形
因此,现在您可以使用A
中的三角形与三角形tb
测试并存储A
中相交的所有三角形
以下是完整测试的示例:
结果中可能会有许多重复的三角形,因此您可以在向结果中添加新三角形之前添加重复性测试
它现在确实相交良好,但有一些三角形不包括在内,另一个则被排除在外。