SLA gizmo now uses glClipPlane instead of touching projection matrix

Messing with the projection matrix invalidates the z-buffer
This currently only works in OpenGL legacy mode
This commit is contained in:
Lukas Matena 2019-03-25 10:47:23 +01:00
parent bc9164e40c
commit 273fcf68a1
4 changed files with 30 additions and 36 deletions

View File

@ -1319,16 +1319,16 @@ bool GLCanvas3D::Gizmos::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
std::pair<float, float> GLCanvas3D::Gizmos::get_sla_clipping_plane() const
GLCanvas3D::ClippingPlane GLCanvas3D::Gizmos::get_sla_clipping_plane() const
{
if (!m_enabled)
return std::make_pair(0.f, 0.f);
return ClippingPlane();
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
if (it != m_gizmos.end())
return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->get_sla_clipping_plane();
return std::make_pair(0.f, 0.f);;
return ClippingPlane();
}
@ -4706,19 +4706,17 @@ void GLCanvas3D::set_sla_clipping(bool enable) const
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);
ClippingPlane gizmo_clipping_plane;
try {
gizmo_clipping_plane = m_gizmos.get_sla_clipping_plane();
}
catch (...) { return; }
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)gizmo_clipping_plane.get_data());
::glEnable(GL_CLIP_PLANE0);
}
else
::glDisable(GL_CLIP_PLANE0);
}
@ -4774,10 +4772,10 @@ void GLCanvas3D::_render_objects() const
{
if (m_use_clipping_planes)
{
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_clipping_planes[0].get_data());
::glEnable(GL_CLIP_PLANE0);
::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[1].get_data());
::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data());
::glEnable(GL_CLIP_PLANE1);
::glClipPlane(GL_CLIP_PLANE2, (GLdouble*)m_clipping_planes[1].get_data());
::glEnable(GL_CLIP_PLANE2);
}
// do not cull backfaces to show broken geometry, if any
@ -4788,8 +4786,8 @@ void GLCanvas3D::_render_objects() const
if (m_use_clipping_planes)
{
::glDisable(GL_CLIP_PLANE0);
::glDisable(GL_CLIP_PLANE1);
::glDisable(GL_CLIP_PLANE2);
}
}

View File

@ -448,7 +448,7 @@ private:
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false);
std::pair<float, float> get_sla_clipping_plane() const;
ClippingPlane get_sla_clipping_plane() const;
void render_current_gizmo(const Selection& selection) const;
void render_current_gizmo_for_picking_pass(const Selection& selection) const;

View File

@ -612,47 +612,42 @@ void GLGizmoSlaSupports::update_cache_entry_normal(unsigned int i) const
std::pair<float, float> GLGizmoSlaSupports::get_sla_clipping_plane() const
GLCanvas3D::ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
{
if (!m_model_object)
return std::make_pair(0.f, 0.f);;
throw std::invalid_argument("GLGizmoSlaSupports::get_sla_clipping_plane() has no model object pointer.");
Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> modelview_matrix;
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
// clipping space origin transformed to world coords:
Vec3d clipping_origin = (modelview_matrix.inverse() * Eigen::Matrix<GLdouble, 4, 1, Eigen::DontAlign>{0, 0, 0, 1}).block<3,1>(0,0);
// 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]);
float dist = direction_to_camera.dot(clipping_origin) - direction_to_camera.dot(m_active_instance_bb.center());
float dist = direction_to_camera.dot(m_active_instance_bb.center());
return std::make_pair((dist - m_active_instance_bb.radius()) + m_clipping_plane_distance * 2*m_active_instance_bb.radius(), dist + 5.f*m_active_instance_bb.radius());
return GLCanvas3D::ClippingPlane(-direction_to_camera.normalized(),(dist - (-m_active_instance_bb.radius()) - m_clipping_plane_distance * 2*m_active_instance_bb.radius()));
}
/*
void GLGizmoSlaSupports::find_intersections(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<IntersectionLine>& idxs) const
void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& idxs) const
{
if (aabb->is_leaf()) { // this is a facet
// corner.dot(normal) - offset
unsigned int facet_idx = aabb->m_primitive;
Vec3f a = m_V.row(m_F(facet_idx, 0));
Vec3f b = m_V.row(m_F(facet_idx, 1));
Vec3f c = m_V.row(m_F(facet_idx, 2));
idxs.push_back(aabb->m_primitive);
}
else { // not a leaf
using CornerType = Eigen::AlignedBox<float, 3>::CornerType;
bool sign = std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(0))));
for (unsigned int i=1; i<8; ++i)
if (std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(i)))) != sign) {
find_intersections(aabb->m_left, normal, offset, idxs);
find_intersections(aabb->m_right, normal, offset, idxs);
find_intersecting_facets(aabb->m_left, normal, offset, idxs);
find_intersecting_facets(aabb->m_right, normal, offset, idxs);
}
}
}
void GLGizmoSlaSupports::make_line_segments() const
{
TriangleMeshSlicer tms(&m_model_object->volumes.front()->mesh);

View File

@ -52,7 +52,7 @@ public:
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down);
void delete_selected_points(bool force = false);
std::pair<float, float> get_sla_clipping_plane() const;
GLCanvas3D::ClippingPlane get_sla_clipping_plane() const;
private:
bool on_init();
@ -87,6 +87,7 @@ private:
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;
void find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& out) const;
// Methods that do the model_object and editing cache synchronization,
// editing mode selection, etc: