SLA gizmo now respects the clipping plane when rendering points and raycasting mouse onto mesh
This commit is contained in:
parent
fd1f9d65fb
commit
bc9164e40c
@ -2582,27 +2582,7 @@ void GLCanvas3D::render()
|
||||
if (early_bed_render)
|
||||
_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();
|
||||
//////////////////////////////////
|
||||
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_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
|
||||
{
|
||||
if (m_volumes.empty())
|
||||
@ -4728,6 +4730,8 @@ void GLCanvas3D::_render_objects() const
|
||||
::glEnable(GL_LIGHTING);
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
|
||||
set_sla_clipping(true);
|
||||
|
||||
if (m_use_VBOs)
|
||||
{
|
||||
if (m_picking_enabled)
|
||||
@ -4789,6 +4793,8 @@ void GLCanvas3D::_render_objects() const
|
||||
}
|
||||
}
|
||||
|
||||
set_sla_clipping(false);
|
||||
|
||||
::glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
@ -4831,6 +4837,8 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||
if (!fake_colors)
|
||||
::glEnable(GL_LIGHTING);
|
||||
|
||||
set_sla_clipping(true);
|
||||
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
::glDisable(GL_CULL_FACE);
|
||||
|
||||
@ -4869,6 +4877,8 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||
|
||||
::glEnable(GL_CULL_FACE);
|
||||
|
||||
set_sla_clipping(false);
|
||||
|
||||
if (!fake_colors)
|
||||
::glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
@ -778,6 +778,9 @@ private:
|
||||
// Sets current projection matrix to ortho, accounting for current camera zoom.
|
||||
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 _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_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();
|
||||
::glTranslated(0.0, 0.0, z_shift);
|
||||
::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 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.
|
||||
if (picking) {
|
||||
std::array<float, 3> color = picking_color_component(i);
|
||||
@ -285,6 +293,8 @@ void GLGizmoSlaSupports::update_mesh()
|
||||
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)
|
||||
{
|
||||
// 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), 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 GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
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;
|
||||
point2(2) -= z_offset;
|
||||
|
||||
@ -317,17 +330,37 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse
|
||||
point1 = inv * point1;
|
||||
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.");
|
||||
|
||||
int fid = hit.id; // facet id
|
||||
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)));
|
||||
Vec3f b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0)));
|
||||
std::sort(hits.begin(), hits.end(), [](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; });
|
||||
|
||||
// Now let's iterate through the points and find the first that is not clipped:
|
||||
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.
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ private:
|
||||
int m_canvas_height;
|
||||
|
||||
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,
|
||||
// editing mode selection, etc:
|
||||
|
Loading…
Reference in New Issue
Block a user