如何处理输出:trim_with_solid
How to process output: trim_with_solid
trim_with_solid
被称为:
// Trim mesh A (m_VA and m_FA) with solid B (m_VB and m_FB)
igl::copyleft::cgal::trim_with_solid(
m_VA, m_FA // input: mesh A
, m_VB, m_FB // input: solid B
, m_V, m_F, m_D, m_J // output
);
处理输出:
// Loop over output vertex data
for (int i = 0; i < m_V.rows(); ++i) {
// Access all the vertex data
}
// Loop over output triangle (face) data
for (int i = 0; i < m_F.rows(); ++i) {
// Condition to decide if facet is inside or outside the solid B
if (m_D.coeff(i)) {
// The output face is outside the solid B
} else {
// The output face is inside the solid B
}
}
很好的结果
有时 trim 结果很好。就像这个 trimming 一个带有实心圆柱体的茶壶模型:
不好的结果
但有时 trim 结果与预期不符:
如上面的线框视图所示,正确识别了茶壶和圆柱体的交点。但出于某种原因,此循环无法检测到圆柱体外部的三角形:
// Loop over output triangle (face) data
for (int i = 0; i < m_F.rows(); ++i) {
// Condition to decide if facet is inside or outside the solid B
if (m_D.coeff(i)) {
// Face is outside the solid B
} else {
// Face is inside the solid B
}
}
有人知道我可能遗漏了什么吗?
以前,我使用 Qt3DExtras::QCylinderMesh 作为实体 B
(VB
和 FB
)。但它不是无懈可击。我将其替换为以下创建防水圆柱体的代码。
Header:
// Create a cylinder mesh which is exactly solid
// without any open boundary
// Down facing cylinder in Z direction with arguments:
// r: radius
// h: Height
// ssteps: how many edges will create the base circle
// sp: starting point
static void cylinder(
std::vector<QVector3D>& points
, std::vector<std::array<int, 3>>& indices
, const float r
, const float h
, const size_t ssteps = 45
, const QVector3D &sp = QVector3D()
);
来源:
void EditorUtils::cylinder(
std::vector<QVector3D> &points
, std::vector<std::array<int, 3>> &indices
, const float r
, const float h
, const size_t ssteps
, const QVector3D &sp
)
{
assert(ssteps > 0);
auto PI = M_PI;
auto steps = int(ssteps);
points.reserve(2*ssteps);
double a = 2*PI/steps;
QVector3D jp = sp;
QVector3D endp = {sp.x(), sp.y(), sp.z() + h};
// Upper circle points
for(int i = 0; i < steps; ++i) {
double phi = i*a;
double ex = endp.x() + r*std::cos(phi);
double ey = endp.y() + r*std::sin(phi);
points.emplace_back(ex, ey, endp.z());
}
// Lower circle points
for(int i = 0; i < steps; ++i) {
double phi = i*a;
double x = jp.x() + r*std::cos(phi);
double y = jp.y() + r*std::sin(phi);
points.emplace_back(x, y, jp.z());
}
// Now create long triangles connecting upper and lower circles
indices.reserve(2*ssteps);
auto offs = steps;
for(int i = 0; i < steps - 1; ++i) {
indices.emplace_back(std::array<int, 3>{i, i + offs, offs + i + 1});
indices.emplace_back(std::array<int, 3>{i, offs + i + 1, i + 1});
}
// Last triangle connecting the first and last vertices
auto last = steps - 1;
indices.emplace_back(std::array<int, 3>{0, last, offs});
indices.emplace_back(std::array<int, 3>{last, offs + last, offs});
// Try generating a watertight body.
// So we create a triangle fan for the upper and lower
// ending of the cylinder to close the geometry.
points.emplace_back(jp); int ci = int(points.size() - 1);
for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(std::array<int, 3>{i + offs + 1, i + offs, ci});
indices.emplace_back(std::array<int, 3>{offs, steps + offs - 1, ci});
points.emplace_back(endp); ci = int(points.size() - 1);
for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(std::array<int, 3>{ci, i, i + 1});
indices.emplace_back(std::array<int, 3>{steps - 1, 0, ci});
return;
}
现在正确创建了孔:
trim_with_solid
被称为:
// Trim mesh A (m_VA and m_FA) with solid B (m_VB and m_FB)
igl::copyleft::cgal::trim_with_solid(
m_VA, m_FA // input: mesh A
, m_VB, m_FB // input: solid B
, m_V, m_F, m_D, m_J // output
);
处理输出:
// Loop over output vertex data
for (int i = 0; i < m_V.rows(); ++i) {
// Access all the vertex data
}
// Loop over output triangle (face) data
for (int i = 0; i < m_F.rows(); ++i) {
// Condition to decide if facet is inside or outside the solid B
if (m_D.coeff(i)) {
// The output face is outside the solid B
} else {
// The output face is inside the solid B
}
}
很好的结果
有时 trim 结果很好。就像这个 trimming 一个带有实心圆柱体的茶壶模型:
不好的结果
但有时 trim 结果与预期不符:
如上面的线框视图所示,正确识别了茶壶和圆柱体的交点。但出于某种原因,此循环无法检测到圆柱体外部的三角形:
// Loop over output triangle (face) data
for (int i = 0; i < m_F.rows(); ++i) {
// Condition to decide if facet is inside or outside the solid B
if (m_D.coeff(i)) {
// Face is outside the solid B
} else {
// Face is inside the solid B
}
}
有人知道我可能遗漏了什么吗?
以前,我使用 Qt3DExtras::QCylinderMesh 作为实体 B
(VB
和 FB
)。但它不是无懈可击。我将其替换为以下创建防水圆柱体的代码。
// Create a cylinder mesh which is exactly solid
// without any open boundary
// Down facing cylinder in Z direction with arguments:
// r: radius
// h: Height
// ssteps: how many edges will create the base circle
// sp: starting point
static void cylinder(
std::vector<QVector3D>& points
, std::vector<std::array<int, 3>>& indices
, const float r
, const float h
, const size_t ssteps = 45
, const QVector3D &sp = QVector3D()
);
来源:
void EditorUtils::cylinder(
std::vector<QVector3D> &points
, std::vector<std::array<int, 3>> &indices
, const float r
, const float h
, const size_t ssteps
, const QVector3D &sp
)
{
assert(ssteps > 0);
auto PI = M_PI;
auto steps = int(ssteps);
points.reserve(2*ssteps);
double a = 2*PI/steps;
QVector3D jp = sp;
QVector3D endp = {sp.x(), sp.y(), sp.z() + h};
// Upper circle points
for(int i = 0; i < steps; ++i) {
double phi = i*a;
double ex = endp.x() + r*std::cos(phi);
double ey = endp.y() + r*std::sin(phi);
points.emplace_back(ex, ey, endp.z());
}
// Lower circle points
for(int i = 0; i < steps; ++i) {
double phi = i*a;
double x = jp.x() + r*std::cos(phi);
double y = jp.y() + r*std::sin(phi);
points.emplace_back(x, y, jp.z());
}
// Now create long triangles connecting upper and lower circles
indices.reserve(2*ssteps);
auto offs = steps;
for(int i = 0; i < steps - 1; ++i) {
indices.emplace_back(std::array<int, 3>{i, i + offs, offs + i + 1});
indices.emplace_back(std::array<int, 3>{i, offs + i + 1, i + 1});
}
// Last triangle connecting the first and last vertices
auto last = steps - 1;
indices.emplace_back(std::array<int, 3>{0, last, offs});
indices.emplace_back(std::array<int, 3>{last, offs + last, offs});
// Try generating a watertight body.
// So we create a triangle fan for the upper and lower
// ending of the cylinder to close the geometry.
points.emplace_back(jp); int ci = int(points.size() - 1);
for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(std::array<int, 3>{i + offs + 1, i + offs, ci});
indices.emplace_back(std::array<int, 3>{offs, steps + offs - 1, ci});
points.emplace_back(endp); ci = int(points.size() - 1);
for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(std::array<int, 3>{ci, i, i + 1});
indices.emplace_back(std::array<int, 3>{steps - 1, 0, ci});
return;
}
现在正确创建了孔: