WIP: First working implementation of the triangle selector for the FDM support gizmo

This commit is contained in:
Lukas Matena 2019-09-26 13:30:22 +02:00
parent 7afe7326b6
commit 08daddb5de
7 changed files with 108 additions and 28 deletions

View file

@ -105,13 +105,40 @@ void GLGizmoFdmSupports::on_render() const
glsafe(::glEnable(GL_BLEND));
glsafe(::glEnable(GL_DEPTH_TEST));
render_triangles(selection);
render_clipping_plane(selection);
glsafe(::glDisable(GL_BLEND));
}
void GLGizmoFdmSupports::render_triangles(const Selection& selection) const
{
if (! m_mesh)
return;
// Get transformation of the instance
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
Transform3d trafo = vol->get_instance_transformation().get_matrix();
::glColor3f(0.0f, 0.37f, 1.0f);
for (size_t facet_idx : m_selected_facets) {
stl_normal normal = 0.01f * MeshRaycaster::get_triangle_normal(m_mesh->its, facet_idx);
::glPushMatrix();
::glTranslatef(normal(0), normal(1), normal(2));
::glMultMatrixd(trafo.data());
::glBegin(GL_TRIANGLES);
::glVertex3f(m_mesh->its.vertices[m_mesh->its.indices[facet_idx](0)](0), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](0)](1), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](0)](2));
::glVertex3f(m_mesh->its.vertices[m_mesh->its.indices[facet_idx](1)](0), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](1)](1), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](1)](2));
::glVertex3f(m_mesh->its.vertices[m_mesh->its.indices[facet_idx](2)](0), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](2)](1), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](2)](2));
::glEnd();
::glPopMatrix();
}
}
void GLGizmoFdmSupports::render_clipping_plane(const Selection& selection) const
{
@ -193,7 +220,7 @@ void GLGizmoFdmSupports::update_mesh()
// Unprojects the mouse position on the mesh and saves hit point and normal of the facet into pos_and_normal
// Return false if no intersection was found, true otherwise.
bool GLGizmoFdmSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal)
bool GLGizmoFdmSupports::unproject_on_mesh(const Vec2d& mouse_pos, size_t& facet_idx)
{
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
if (! m_mesh_raycaster)
@ -208,11 +235,8 @@ bool GLGizmoFdmSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
// The raycaster query
Vec3f hit;
Vec3f normal;
if (m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) {
// Return both the point and the facet normal.
pos_and_normal = std::make_pair(hit, normal);
if (m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get(), &facet_idx))
return true;
}
else
return false;
}
@ -240,6 +264,22 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
return true;
}
if (action == SLAGizmoEventType::LeftDown || (action == SLAGizmoEventType::Dragging && m_wait_for_up_event)) {
size_t facet_idx = 0;
if (unproject_on_mesh(mouse_position, facet_idx)) {
m_selected_facets.push_back(facet_idx);
m_wait_for_up_event = true;
return true;
}
if (action == SLAGizmoEventType::Dragging && m_wait_for_up_event)
return true;
}
if (action == SLAGizmoEventType::LeftUp && m_wait_for_up_event) {
m_wait_for_up_event = false;
return true;
}
return false;
}
@ -332,11 +372,9 @@ std::string GLGizmoFdmSupports::on_get_name() const
void GLGizmoFdmSupports::on_set_state()
{
if (m_state == On)
std::cout << "zapinam se..." << std::endl;
else
std::cout << "vypinam se..." << std::endl;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
return;
// m_model_object pointer can be invalid (for instance because of undo/redo action),
// we should recover it from the object id
m_model_object = nullptr;
@ -351,7 +389,7 @@ void GLGizmoFdmSupports::on_set_state()
return;
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on")));
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned on")));
if (is_mesh_update_necessary())
update_mesh();

View file

@ -3,9 +3,6 @@
#include "GLGizmoBase.hpp"
//#include "libslic3r/SLA/SLACommon.hpp"
//#include <wx/dialog.h>
#include <cereal/types/vector.hpp>
@ -24,7 +21,7 @@ private:
ObjectID m_model_object_id = 0;
int m_active_instance = -1;
float m_active_instance_bb_radius; // to cache the bb
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
bool unproject_on_mesh(const Vec2d& mouse_pos, size_t& facet_idx);
GLUquadricObj* m_quadric;
@ -34,6 +31,8 @@ private:
const indexed_triangle_set* m_its;
mutable std::vector<Vec2f> m_triangles;
std::vector<size_t> m_selected_facets;
public:
GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
@ -48,6 +47,7 @@ private:
void on_render() const override;
void on_render_for_picking() const override;
void render_triangles(const Selection& selection) const;
void render_clipping_plane(const Selection& selection) const;
bool is_mesh_update_necessary() const;
void update_mesh();

View file

@ -388,9 +388,12 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
if (m_current == SlaSupports)
return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
if (m_current == Hollow)
else if (m_current == Hollow)
return dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
return false;
else if (m_current == FdmSupports)
return dynamic_cast<GLGizmoFdmSupports*>(m_gizmos[FdmSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
else
return false;
}
ClippingPlane GLGizmosManager::get_clipping_plane() const
@ -444,7 +447,7 @@ bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt)
{
bool processed = false;
if (m_current == SlaSupports || m_current == Hollow) {
if (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) {
float rot = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
processed = true;
@ -502,7 +505,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
if (evt.LeftDown())
{
if ((m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports)
&& gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
// the gizmo got the event and took some action, there is no need to do anything more
processed = true;
else if (!selection.is_empty() && grabber_contains_mouse()) {
@ -530,7 +534,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
else if (evt.Dragging() && (m_parent.get_move_volume_id() != -1) && (m_current == SlaSupports || m_current == Hollow))
// don't allow dragging objects with the Sla gizmo on
processed = true;
else if (evt.Dragging() && (m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
else if (evt.Dragging() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports )
&& gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
{
// the gizmo got the event and took some action, no need to do anything more here
m_parent.set_as_dirty();
@ -603,9 +608,9 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
processed = true;
}
else if (evt.LeftUp() && (m_current == SlaSupports || m_current == Hollow) && !m_parent.is_mouse_dragging())
else if (evt.LeftUp() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) && !m_parent.is_mouse_dragging())
{
// in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither
// in case SLA/FDM gizmo is selected, we just pass the LeftUp event and stop processing - neither
// object moving or selecting is suppressed in that case
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
processed = true;
@ -702,7 +707,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)
case 'r' :
case 'R' :
{
if ((m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::ResetClippingPlane))
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) && gizmo_event(SLAGizmoEventType::ResetClippingPlane))
processed = true;
break;