Added functions get_hit_pos, get_hit_normal, ready to implement intersect_ray

This commit is contained in:
Lukas Matena 2019-09-17 10:47:01 +02:00
parent b6292247e8
commit 3694bf3da9
3 changed files with 41 additions and 19 deletions

View file

@ -503,7 +503,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
// clipping plane nor obscured by the mesh.
for (const unsigned int i : selected_idxs) {
const sla::SupportPoint &support_point = m_editing_cache[i].support_point;
if (!is_point_clipped(support_point.pos.cast<double>())) {
if (! is_point_clipped(support_point.pos.cast<double>())) {
bool is_obscured = false;
// Cast a ray in the direction of the camera and look for intersection with the mesh:
std::vector<igl::Hit> hits;

View file

@ -108,14 +108,19 @@ public:
typedef Eigen::Map<const Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor | Eigen::DontAlign>> MapMatrixXiUnaligned;
igl::AABB<MapMatrixXfUnaligned, 3> m_AABB;
Vec3f get_hit_pos(const igl::Hit& hit) const;
Vec3f get_hit_normal(const igl::Hit& hit) const;
private:
const TriangleMesh* m_mesh;
};
MeshRaycaster::AABBWrapper::AABBWrapper(const TriangleMesh* mesh)
: m_mesh(mesh)
{
const indexed_triangle_set* its = &mesh->its;
m_AABB.init(
MapMatrixXfUnaligned(its->vertices.front().data(), its->vertices.size(), 3),
MapMatrixXiUnaligned(its->indices.front().data(), its->indices.size(), 3));
MapMatrixXfUnaligned(m_mesh->its.vertices.front().data(), m_mesh->its.vertices.size(), 3),
MapMatrixXiUnaligned(m_mesh->its.indices.front().data(), m_mesh->its.indices.size(), 3));
}
@ -129,6 +134,23 @@ MeshRaycaster::~MeshRaycaster()
delete m_AABB_wrapper;
}
Vec3f MeshRaycaster::AABBWrapper::get_hit_pos(const igl::Hit& hit) const
{
const stl_triangle_vertex_indices& indices = m_mesh->its.indices[hit.id];
return Vec3f((1-hit.u-hit.v) * m_mesh->its.vertices[indices(0)]
+ hit.u * m_mesh->its.vertices[indices(1)]
+ hit.v * m_mesh->its.vertices[indices(2)]);
}
Vec3f MeshRaycaster::AABBWrapper::get_hit_normal(const igl::Hit& hit) const
{
const stl_triangle_vertex_indices& indices = m_mesh->its.indices[hit.id];
Vec3f a(m_mesh->its.vertices[indices(1)] - m_mesh->its.vertices[indices(0)]);
Vec3f b(m_mesh->its.vertices[indices(2)] - m_mesh->its.vertices[indices(0)]);
return Vec3f(a.cross(b));
}
bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo,
const Camera& camera, std::vector<Vec3f>* positions, std::vector<Vec3f>* normals) const
@ -139,8 +161,8 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
Vec3d pt1;
Vec3d pt2;
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0.f, model_mat.data(), proj_mat.data(), viewport.data(), &pt1(0), &pt1(1), &pt1(2));
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1.f, model_mat.data(), proj_mat.data(), viewport.data(), &pt2(0), &pt2(1), &pt2(2));
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0., model_mat.data(), proj_mat.data(), viewport.data(), &pt1(0), &pt1(1), &pt1(2));
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1., model_mat.data(), proj_mat.data(), viewport.data(), &pt2(0), &pt2(1), &pt2(2));
std::vector<igl::Hit> hits;
@ -162,19 +184,11 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
positions->clear();
if (normals != nullptr)
normals->clear();
Vec3f bc;
Vec3f a;
Vec3f b;
int fid = 0;
for (const igl::Hit& hit : hits) {
fid = hit.id;
bc = Vec3f(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
a = (m_mesh->its.vertices[m_mesh->its.indices[fid](1)] - m_mesh->its.vertices[m_mesh->its.indices[fid](0)]);
b = (m_mesh->its.vertices[m_mesh->its.indices[fid](2)] - m_mesh->its.vertices[m_mesh->its.indices[fid](0)]);
positions->push_back(bc(0) * m_mesh->its.vertices[m_mesh->its.indices[fid](0)] + bc(1) * m_mesh->its.vertices[m_mesh->its.indices[fid](1)] + bc(2) * m_mesh->its.vertices[m_mesh->its.indices[fid](2)]);
positions->push_back(m_AABB_wrapper->get_hit_pos(hit));
if (normals != nullptr)
normals->push_back(a.cross(b));
normals->push_back(m_AABB_wrapper->get_hit_normal(hit));
}
}
@ -182,6 +196,14 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
}
std::vector<size_t> MeshRaycaster::get_unobscured_idxs(const Transform3d& trafo, const Camera& camera, const std::vector<Vec3f>& points) const
{
return std::vector<size_t>();
}
} // namespace GUI
} // namespace Slic3r

View file

@ -100,14 +100,14 @@ public:
bool unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
std::vector<Vec3f>* positions = nullptr, std::vector<Vec3f>* normals = nullptr) const;
std::vector<size_t> get_unobscured_idxs(const Transform3d& trafo, const Camera& camera,
const std::vector<Vec3f>& points) const;
private:
// PIMPL wrapper around igl::AABB so I don't have to include the header-only IGL here
class AABBWrapper;
AABBWrapper* m_AABB_wrapper;
const TriangleMesh* m_mesh = nullptr;
};