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. // clipping plane nor obscured by the mesh.
for (const unsigned int i : selected_idxs) { for (const unsigned int i : selected_idxs) {
const sla::SupportPoint &support_point = m_editing_cache[i].support_point; 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; bool is_obscured = false;
// Cast a ray in the direction of the camera and look for intersection with the mesh: // Cast a ray in the direction of the camera and look for intersection with the mesh:
std::vector<igl::Hit> hits; 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; typedef Eigen::Map<const Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor | Eigen::DontAlign>> MapMatrixXiUnaligned;
igl::AABB<MapMatrixXfUnaligned, 3> m_AABB; 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) MeshRaycaster::AABBWrapper::AABBWrapper(const TriangleMesh* mesh)
: m_mesh(mesh)
{ {
const indexed_triangle_set* its = &mesh->its;
m_AABB.init( m_AABB.init(
MapMatrixXfUnaligned(its->vertices.front().data(), its->vertices.size(), 3), MapMatrixXfUnaligned(m_mesh->its.vertices.front().data(), m_mesh->its.vertices.size(), 3),
MapMatrixXiUnaligned(its->indices.front().data(), its->indices.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; 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, bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo,
const Camera& camera, std::vector<Vec3f>* positions, std::vector<Vec3f>* normals) const 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 pt1;
Vec3d pt2; 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), 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.f, model_mat.data(), proj_mat.data(), viewport.data(), &pt2(0), &pt2(1), &pt2(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; std::vector<igl::Hit> hits;
@ -162,19 +184,11 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
positions->clear(); positions->clear();
if (normals != nullptr) if (normals != nullptr)
normals->clear(); normals->clear();
Vec3f bc;
Vec3f a;
Vec3f b;
int fid = 0;
for (const igl::Hit& hit : hits) { for (const igl::Hit& hit : hits) {
fid = hit.id; positions->push_back(m_AABB_wrapper->get_hit_pos(hit));
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)]);
if (normals != nullptr) 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 GUI
} // namespace Slic3r } // namespace Slic3r

View file

@ -100,14 +100,14 @@ public:
bool unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, 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<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: private:
// PIMPL wrapper around igl::AABB so I don't have to include the header-only IGL here // PIMPL wrapper around igl::AABB so I don't have to include the header-only IGL here
class AABBWrapper; class AABBWrapper;
AABBWrapper* m_AABB_wrapper; AABBWrapper* m_AABB_wrapper;
const TriangleMesh* m_mesh = nullptr; const TriangleMesh* m_mesh = nullptr;
}; };