Fixed a raycaster problem with handling duplicate hits from igl
The duplicate hits confused winding number calculations in the raycaster, which in turn returned incorrect hit.
This commit is contained in:
parent
e9d340c87f
commit
f22961edae
@ -297,7 +297,14 @@ EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
|
|||||||
// The sort is necessary, the hits are not always sorted.
|
// The sort is necessary, the hits are not always sorted.
|
||||||
std::sort(hits.begin(), hits.end(),
|
std::sort(hits.begin(), hits.end(),
|
||||||
[](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; });
|
[](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; });
|
||||||
|
|
||||||
|
// Remove duplicates. They sometimes appear, for example when the ray is cast
|
||||||
|
// along an axis of a cube due to floating-point approximations in igl (?)
|
||||||
|
hits.erase(std::unique(hits.begin(), hits.end(),
|
||||||
|
[](const igl::Hit& a, const igl::Hit& b)
|
||||||
|
{ return a.t == b.t; }),
|
||||||
|
hits.end());
|
||||||
|
|
||||||
// Convert the igl::Hit into hit_result
|
// Convert the igl::Hit into hit_result
|
||||||
outs.reserve(hits.size());
|
outs.reserve(hits.size());
|
||||||
for (const igl::Hit& hit : hits) {
|
for (const igl::Hit& hit : hits) {
|
||||||
@ -342,14 +349,11 @@ EigenMesh3D::hit_result EigenMesh3D::filter_hits(
|
|||||||
for (const sla::DrainHole& hole : m_holes) {
|
for (const sla::DrainHole& hole : m_holes) {
|
||||||
std::array<std::pair<float, Vec3d>, 2> isects;
|
std::array<std::pair<float, Vec3d>, 2> isects;
|
||||||
if (hole.get_intersections(sf, dirf, isects)) {
|
if (hole.get_intersections(sf, dirf, isects)) {
|
||||||
|
// Ignore hole hits behind the source
|
||||||
if (isects[0].first > 0.f) hole_isects.emplace_back(isects[0].first, isects[0].second, true);
|
if (isects[0].first > 0.f) hole_isects.emplace_back(isects[0].first, isects[0].second, true);
|
||||||
if (isects[1].first > 0.f) hole_isects.emplace_back(isects[1].first, isects[1].second, false);
|
if (isects[1].first > 0.f) hole_isects.emplace_back(isects[1].first, isects[1].second, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// // Remove hole hits behind the source
|
|
||||||
// for (int i=0; i<int(hole_isects.size()); ++i)
|
|
||||||
// if (hole_isects[i].t < 0.f)
|
|
||||||
// hole_isects.erase(hole_isects.begin() + (i--));
|
|
||||||
|
|
||||||
// Holes can intersect each other, sort the hits by t
|
// Holes can intersect each other, sort the hits by t
|
||||||
std::sort(hole_isects.begin(), hole_isects.end(),
|
std::sort(hole_isects.begin(), hole_isects.end(),
|
||||||
|
@ -48,11 +48,10 @@ TEST_CASE("Raycaster with loaded drillholes", "[sla_raycast]")
|
|||||||
REQUIRE(hit.distance() == Approx(radius));
|
REQUIRE(hit.distance() == Approx(radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shouldn't this hit the inside wall through the hole?
|
|
||||||
SECTION("Fire from outside, hit the back side of the hole cylinder.") {
|
SECTION("Fire from outside, hit the back side of the hole cylinder.") {
|
||||||
s.y() = -1.;
|
s.y() = -1.;
|
||||||
auto hit = emesh.query_ray_hit(s, {0, 1., 0.});
|
auto hit = emesh.query_ray_hit(s, {0, 1., 0.});
|
||||||
REQUIRE(hit.distance() == Approx(hole_length + 1.f));
|
REQUIRE(hit.distance() == Approx(boxbb.size().y() - hcfg.min_thickness + 1.));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Check for support tree correctness") {
|
SECTION("Check for support tree correctness") {
|
||||||
|
Loading…
Reference in New Issue
Block a user