SLA gizmo now respects the clipping plane when rendering points and raycasting mouse onto mesh
This commit is contained in:
parent
fd1f9d65fb
commit
bc9164e40c
4 changed files with 74 additions and 27 deletions
|
@ -2582,27 +2582,7 @@ void GLCanvas3D::render()
|
||||||
if (early_bed_render)
|
if (early_bed_render)
|
||||||
_render_bed(theta);
|
_render_bed(theta);
|
||||||
|
|
||||||
////////////////////////
|
|
||||||
//Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> stashed_projection_matrix;
|
|
||||||
//::glGetDoublev(GL_PROJECTION_MATRIX, stashed_projection_matrix.data());
|
|
||||||
const Size& cnv_size = get_canvas_size();
|
|
||||||
if (m_gizmos.get_current_type() == Gizmos::SlaSupports) {
|
|
||||||
std::pair<float, float> clipping_limits = m_gizmos.get_sla_clipping_plane();
|
|
||||||
set_ortho_projection((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height(), clipping_limits.first, clipping_limits.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////
|
|
||||||
_render_objects();
|
_render_objects();
|
||||||
//////////////////////////////////
|
|
||||||
if (m_gizmos.get_current_type() == Gizmos::SlaSupports) {
|
|
||||||
//::glMatrixMode(GL_PROJECTION);
|
|
||||||
//::glLoadIdentity();
|
|
||||||
//::glMultMatrixd(stashed_projection_matrix.data());
|
|
||||||
//::glMatrixMode(GL_MODELVIEW);
|
|
||||||
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
|
|
||||||
}
|
|
||||||
//////////////////////////////////
|
|
||||||
|
|
||||||
_render_sla_slices();
|
_render_sla_slices();
|
||||||
_render_selection();
|
_render_selection();
|
||||||
|
|
||||||
|
@ -4720,6 +4700,28 @@ void GLCanvas3D::set_ortho_projection(float w, float h, float near, float far) c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLCanvas3D::set_sla_clipping(bool enable) const
|
||||||
|
{
|
||||||
|
if (m_gizmos.get_current_type() != Gizmos::SlaSupports)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
::glMatrixMode(GL_PROJECTION);
|
||||||
|
::glPushMatrix();
|
||||||
|
::glMatrixMode(GL_MODELVIEW);
|
||||||
|
const Size& cnv_size = get_canvas_size();
|
||||||
|
std::pair<float, float> clipping_limits = m_gizmos.get_sla_clipping_plane();
|
||||||
|
set_ortho_projection((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height(), clipping_limits.first, clipping_limits.second);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
::glMatrixMode(GL_PROJECTION);
|
||||||
|
::glPopMatrix();
|
||||||
|
::glMatrixMode(GL_MODELVIEW);
|
||||||
|
::glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLCanvas3D::_render_objects() const
|
void GLCanvas3D::_render_objects() const
|
||||||
{
|
{
|
||||||
if (m_volumes.empty())
|
if (m_volumes.empty())
|
||||||
|
@ -4728,6 +4730,8 @@ void GLCanvas3D::_render_objects() const
|
||||||
::glEnable(GL_LIGHTING);
|
::glEnable(GL_LIGHTING);
|
||||||
::glEnable(GL_DEPTH_TEST);
|
::glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
set_sla_clipping(true);
|
||||||
|
|
||||||
if (m_use_VBOs)
|
if (m_use_VBOs)
|
||||||
{
|
{
|
||||||
if (m_picking_enabled)
|
if (m_picking_enabled)
|
||||||
|
@ -4789,6 +4793,8 @@ void GLCanvas3D::_render_objects() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_sla_clipping(false);
|
||||||
|
|
||||||
::glDisable(GL_LIGHTING);
|
::glDisable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4831,6 +4837,8 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||||
if (!fake_colors)
|
if (!fake_colors)
|
||||||
::glEnable(GL_LIGHTING);
|
::glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
set_sla_clipping(true);
|
||||||
|
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
::glDisable(GL_CULL_FACE);
|
::glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
@ -4869,6 +4877,8 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||||
|
|
||||||
::glEnable(GL_CULL_FACE);
|
::glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
set_sla_clipping(false);
|
||||||
|
|
||||||
if (!fake_colors)
|
if (!fake_colors)
|
||||||
::glDisable(GL_LIGHTING);
|
::glDisable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
|
@ -778,6 +778,9 @@ private:
|
||||||
// Sets current projection matrix to ortho, accounting for current camera zoom.
|
// Sets current projection matrix to ortho, accounting for current camera zoom.
|
||||||
void set_ortho_projection(float w, float h, float near, float far) const;
|
void set_ortho_projection(float w, float h, float near, float far) const;
|
||||||
|
|
||||||
|
// Set/unset near clipping plane according to SLA gizmo requirements.
|
||||||
|
void set_sla_clipping(bool enable) const;
|
||||||
|
|
||||||
void _start_timer();
|
void _start_timer();
|
||||||
void _stop_timer();
|
void _stop_timer();
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,11 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
||||||
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
||||||
|
|
||||||
|
// we'll recover current look direction from the modelview matrix (in world coords):
|
||||||
|
Eigen::Matrix<double, 4, 4, Eigen::DontAlign> modelview_matrix;
|
||||||
|
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
|
||||||
|
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
|
||||||
|
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glTranslated(0.0, 0.0, z_shift);
|
::glTranslated(0.0, 0.0, z_shift);
|
||||||
::glMultMatrixd(instance_matrix.data());
|
::glMultMatrixd(instance_matrix.data());
|
||||||
|
@ -167,6 +172,9 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
const sla::SupportPoint& support_point = m_editing_mode_cache[i].support_point;
|
const sla::SupportPoint& support_point = m_editing_mode_cache[i].support_point;
|
||||||
const bool& point_selected = m_editing_mode_cache[i].selected;
|
const bool& point_selected = m_editing_mode_cache[i].selected;
|
||||||
|
|
||||||
|
if (is_point_clipped(support_point.pos.cast<double>(), direction_to_camera, z_shift))
|
||||||
|
continue;
|
||||||
|
|
||||||
// First decide about the color of the point.
|
// First decide about the color of the point.
|
||||||
if (picking) {
|
if (picking) {
|
||||||
std::array<float, 3> color = picking_color_component(i);
|
std::array<float, 3> color = picking_color_component(i);
|
||||||
|
@ -285,6 +293,8 @@ void GLGizmoSlaSupports::update_mesh()
|
||||||
m_AABB.init(m_V, m_F);
|
m_AABB.init(m_V, m_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unprojects the mouse position on the mesh and return the hit point and normal of the facet.
|
||||||
|
// The function throws if no intersection if found.
|
||||||
std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
|
std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
|
||||||
{
|
{
|
||||||
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
||||||
|
@ -303,12 +313,15 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse
|
||||||
::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
|
::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
|
||||||
::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
|
::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
|
||||||
|
|
||||||
igl::Hit hit;
|
std::vector<igl::Hit> hits;
|
||||||
|
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
double z_offset = volume->get_sla_shift_z();
|
double z_offset = volume->get_sla_shift_z();
|
||||||
|
|
||||||
|
// we'll recover current look direction from the modelview matrix (in world coords):
|
||||||
|
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
|
||||||
|
|
||||||
point1(2) -= z_offset;
|
point1(2) -= z_offset;
|
||||||
point2(2) -= z_offset;
|
point2(2) -= z_offset;
|
||||||
|
|
||||||
|
@ -317,17 +330,37 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse
|
||||||
point1 = inv * point1;
|
point1 = inv * point1;
|
||||||
point2 = inv * point2;
|
point2 = inv * point2;
|
||||||
|
|
||||||
if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hit))
|
if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hits))
|
||||||
throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
|
throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
|
||||||
|
|
||||||
int fid = hit.id; // facet id
|
std::sort(hits.begin(), hits.end(), [](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; });
|
||||||
Vec3f bc(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
|
|
||||||
Vec3f a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0)));
|
// Now let's iterate through the points and find the first that is not clipped:
|
||||||
Vec3f b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0)));
|
unsigned int i=0;
|
||||||
|
Vec3f bc;
|
||||||
|
Vec3f a;
|
||||||
|
Vec3f b;
|
||||||
|
Vec3f result;
|
||||||
|
for (i=0; i<hits.size(); ++i) {
|
||||||
|
igl::Hit& hit = hits[i];
|
||||||
|
int fid = hit.id; // facet id
|
||||||
|
bc = Vec3f(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
|
||||||
|
a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0)));
|
||||||
|
b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0)));
|
||||||
|
result = bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2));
|
||||||
|
if (m_clipping_plane_distance == 0.f || !is_point_clipped(result.cast<double>(), direction_to_camera, z_offset))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i==hits.size() || (hits.size()-i) % 2 != 0) {
|
||||||
|
// All hits are either clipped, or there is an odd number of unclipped
|
||||||
|
// hits - meaning the nearest must be from inside the mesh.
|
||||||
|
throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate and return both the point and the facet normal.
|
// Calculate and return both the point and the facet normal.
|
||||||
return std::make_pair(
|
return std::make_pair(
|
||||||
bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2)),
|
result,
|
||||||
a.cross(b)
|
a.cross(b)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ private:
|
||||||
int m_canvas_height;
|
int m_canvas_height;
|
||||||
|
|
||||||
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
|
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
|
||||||
|
bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera, float z_shift) const;
|
||||||
|
|
||||||
// Methods that do the model_object and editing cache synchronization,
|
// Methods that do the model_object and editing cache synchronization,
|
||||||
// editing mode selection, etc:
|
// editing mode selection, etc:
|
||||||
|
|
Loading…
Reference in a new issue