diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index fb1facf14..815cc8685 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1196,6 +1196,17 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); + gizmo = new GLGizmoSlaSupports(parent); + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) { + _reset(); + return false; + } + + m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo)); + return true; } @@ -1457,6 +1468,26 @@ void GLCanvas3D::Gizmos::set_flattening_data(const ModelObject* model_object) reinterpret_cast(it->second)->set_flattening_data(model_object); } +void GLCanvas3D::Gizmos::set_model_object_ptr(const ModelObject* model_object) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); + if (it != m_gizmos.end()) + reinterpret_cast(it->second)->set_model_object_ptr(model_object); +} + +void GLCanvas3D::Gizmos::move_current_point(const Vec2d& mouse_position) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); + if (it != m_gizmos.end()) + reinterpret_cast(it->second)->move_current_point(mouse_position); +} + void GLCanvas3D::Gizmos::render_current_gizmo(const BoundingBoxf3& box) const { if (!m_enabled) @@ -1519,6 +1550,8 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas) const float scaled_gap_y = OverlayGapY * inv_zoom; for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { + /*if (dynamic_cast(it->second)) // don't render sla gizmo overlay for FDM + continue;*/ float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale * inv_zoom; GLTexture::render_texture(it->second->get_texture_id(), top_x, top_x + tex_size, top_y - tex_size, top_y); top_y -= (tex_size + scaled_gap_y); @@ -2381,6 +2414,7 @@ void GLCanvas3D::update_gizmos_data() m_gizmos.set_scale(model_instance->scaling_factor); m_gizmos.set_angle_z(model_instance->rotation); m_gizmos.set_flattening_data(model_object); + m_gizmos.set_model_object_ptr(model_object); } } } @@ -2432,8 +2466,6 @@ void GLCanvas3D::render() } _render_objects(); - _render_sla_support_points(); - if (!is_custom_bed) // textured bed needs to be rendered after objects { _render_axes(true); @@ -3129,48 +3161,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) Vec3d pos3d = (volume_idx == -1) ? Vec3d(DBL_MAX, DBL_MAX, DBL_MAX) : _mouse_to_3d(pos); - //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - int id = _get_first_selected_object_id(); - if ((id != -1) && (m_model != nullptr)) - { - ModelObject* model_object = m_model->objects[id]; - stl_file stl = model_object->mesh().stl; - - Eigen::MatrixXf V; // vertices - Eigen::MatrixXi F;// facets indices - V.resize(3*stl.stats.number_of_facets, 3); - F.resize(stl.stats.number_of_facets, 3); - for (unsigned int i=0; ivertex[0](0); V(3*i+0, 1) = facet->vertex[0](1); V(3*i+0, 2) = facet->vertex[0](2); - V(3*i+1, 0) = facet->vertex[1](0); V(3*i+1, 1) = facet->vertex[1](1); V(3*i+1, 2) = facet->vertex[1](2); - V(3*i+2, 0) = facet->vertex[2](0); V(3*i+2, 1) = facet->vertex[2](1); V(3*i+2, 2) = facet->vertex[2](2); - F(i, 0) = 3*i+0; - F(i, 1) = 3*i+1; - F(i, 2) = 3*i+2; - } - - Eigen::Matrix viewport; - ::glGetIntegerv(GL_VIEWPORT, viewport.data()); - Eigen::Matrix modelview_matrix; - ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); - Eigen::Matrix projection_matrix; - ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data()); - - int fid = 0; - Vec3f bc(0, 0, 0); - - if (igl::unproject_onto_mesh(Vec2f(pos(0), viewport(3)-pos(1)), modelview_matrix.cast(), projection_matrix.cast(), viewport.cast(), V, F, fid, bc) - && (stl.facet_start + fid)->normal(2) < 0.f) { - const Vec3f& a = (stl.facet_start+fid)->vertex[0]; - const Vec3f& b = (stl.facet_start+fid)->vertex[1]; - const Vec3f& c = (stl.facet_start+fid)->vertex[2]; - model_object->sla_support_points.emplace_back(bc(0)*a + bc(1)*b + bc(2)*c); - } - } - //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - - // Only accept the initial position, if it is inside the volume bounding box. BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box(); volume_bbox.offset(1.0); @@ -3314,6 +3304,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) update_rotation_value((double)angle_z, Z); break; } + case Gizmos::SlaSupports: + { + m_gizmos.move_current_point(Vec2d(pos(0), pos(1))); + break; + } default: break; } @@ -3407,6 +3402,44 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if ((volume_idxs.size() == 1) && m_volumes.volumes[volume_idxs[0]]->is_wipe_tower) select_volume(volume_idxs[0]); } + else if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_hover_volume_id != -1) + { + int id = _get_first_selected_object_id(); + if ((id != -1) && (m_model != nullptr)) { + ModelObject* model_object = m_model->objects[id]; + const stl_file& stl = model_object->mesh().stl; + Eigen::MatrixXf V; // vertices + Eigen::MatrixXi F;// facets indices + V.resize(3*stl.stats.number_of_facets, 3); + F.resize(stl.stats.number_of_facets, 3); + for (unsigned int i=0; ivertex[0](0); V(3*i+0, 1) = facet->vertex[0](1); V(3*i+0, 2) = facet->vertex[0](2); + V(3*i+1, 0) = facet->vertex[1](0); V(3*i+1, 1) = facet->vertex[1](1); V(3*i+1, 2) = facet->vertex[1](2); + V(3*i+2, 0) = facet->vertex[2](0); V(3*i+2, 1) = facet->vertex[2](1); V(3*i+2, 2) = facet->vertex[2](2); + F(i, 0) = 3*i+0; + F(i, 1) = 3*i+1; + F(i, 2) = 3*i+2; + } + + Eigen::Matrix viewport; + ::glGetIntegerv(GL_VIEWPORT, viewport.data()); + Eigen::Matrix modelview_matrix; + ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); + Eigen::Matrix projection_matrix; + ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data()); + + int fid = 0; + Vec3f bc(0, 0, 0); + if (igl::unproject_onto_mesh(Vec2f(pos(0), viewport(3)-pos(1)), modelview_matrix.cast(), projection_matrix.cast(), viewport.cast(), V, F, fid, bc) + && (stl.facet_start + fid)->normal(2) < 0.f) { + const Vec3f& a = (stl.facet_start+fid)->vertex[0]; + const Vec3f& b = (stl.facet_start+fid)->vertex[1]; + const Vec3f& c = (stl.facet_start+fid)->vertex[2]; + model_object->sla_support_points.emplace_back(bc(0)*a + bc(1)*b + bc(2)*c); + } + } + } else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() && !is_layers_editing_enabled()) { // deselect and propagate event through callback diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 358ee21e3..3eefb46a4 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -340,6 +340,7 @@ public: Scale, Rotate, Flatten, + SlaSupports, Num_Types }; @@ -388,6 +389,9 @@ public: void set_flattening_data(const ModelObject* model_object); Vec3d get_flattening_normal() const; + void set_model_object_ptr(const ModelObject* model_object); + void move_current_point(const Vec2d& mouse_position); + void render_current_gizmo(const BoundingBoxf3& box) const; void render_current_gizmo_for_picking_pass(const BoundingBoxf3& box) const; diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index 50c93d72c..10c917580 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -6,6 +6,7 @@ #include #include "../../libslic3r/Geometry.hpp" +#include #include #include @@ -1476,5 +1477,127 @@ Vec3d GLGizmoFlatten::get_flattening_normal() const { return normal.normalized(); } + + + +GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent) + : GLGizmoBase(parent) +{ +} + +bool GLGizmoSlaSupports::on_init() +{ + std::string path = resources_dir() + "/icons/overlay/"; + + std::string filename = path + "layflat_off.png"; + if (!m_textures[Off].load_from_file(filename, false)) + return false; + + filename = path + "layflat_hover.png"; + if (!m_textures[Hover].load_from_file(filename, false)) + return false; + + filename = path + "layflat_on.png"; + if (!m_textures[On].load_from_file(filename, false)) + return false; + + return true; +} + + + +void GLGizmoSlaSupports::on_start_dragging() +{ + if (m_hover_id != -1) + ;//m_normal = m_planes[m_hover_id].normal; +} + +void GLGizmoSlaSupports::on_render(const BoundingBoxf3& box) const +{ + ::glEnable(GL_BLEND); + ::glEnable(GL_DEPTH_TEST); + + if (m_model_object && !m_model_object->instances.empty()) { + for (int i=0; i<(int)m_model_object->sla_support_points.size(); ++i) { + const auto& point = m_model_object->sla_support_points[i]; + if (i == m_hover_id) + ::glColor4f(0.9f, 0.f, 0.f, 0.75f); + else + ::glColor4f(0.5f, 0.f, 0.f, 0.75f); + + ::glPushMatrix(); + ::glTranslatef(point(0), point(1), point(2)); + GLUquadricObj *quadric; + quadric = ::gluNewQuadric(); + ::gluQuadricDrawStyle(quadric, GLU_FILL ); + ::gluSphere( quadric , 0.5 , 36 , 18 ); + ::gluDeleteQuadric(quadric); + ::glPopMatrix(); + } + } + + ::glDisable(GL_BLEND); +} + +void GLGizmoSlaSupports::on_render_for_picking(const BoundingBoxf3& box) const +{ + ::glEnable(GL_DEPTH_TEST); + + if (m_model_object && !m_model_object->instances.empty()) { + for (unsigned int i=0; isla_support_points.size(); ++i) { + const auto& point = m_model_object->sla_support_points[i]; + ::glColor3f(1.0f, 1.0f, picking_color_component(i)); + ::glPushMatrix(); + ::glTranslatef(point(0), point(1), point(2)); + GLUquadricObj *quadric; + quadric = ::gluNewQuadric(); + + ::gluQuadricDrawStyle(quadric, GLU_FILL ); + ::gluSphere( quadric , 0.5 , 36 , 18 ); + ::gluDeleteQuadric(quadric); + ::glPopMatrix(); + } + } +} + +void GLGizmoSlaSupports::move_current_point(const Vec2d& mouse_position) +{ + const stl_file& stl = m_model_object->mesh().stl; + Eigen::MatrixXf V; // vertices + Eigen::MatrixXi F;// facets indices + V.resize(3*stl.stats.number_of_facets, 3); + F.resize(stl.stats.number_of_facets, 3); + for (unsigned int i=0; ivertex[0](0); V(3*i+0, 1) = facet->vertex[0](1); V(3*i+0, 2) = facet->vertex[0](2); + V(3*i+1, 0) = facet->vertex[1](0); V(3*i+1, 1) = facet->vertex[1](1); V(3*i+1, 2) = facet->vertex[1](2); + V(3*i+2, 0) = facet->vertex[2](0); V(3*i+2, 1) = facet->vertex[2](1); V(3*i+2, 2) = facet->vertex[2](2); + F(i, 0) = 3*i+0; + F(i, 1) = 3*i+1; + F(i, 2) = 3*i+2; + } + + Eigen::Matrix viewport; + ::glGetIntegerv(GL_VIEWPORT, viewport.data()); + Eigen::Matrix modelview_matrix; + ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); + Eigen::Matrix projection_matrix; + ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data()); + + int fid = 0; + Vec3f bc(0, 0, 0); + Vec3f final_pos; + if (igl::unproject_onto_mesh(Vec2f(mouse_position(0), viewport(3)-mouse_position(1)), modelview_matrix.cast(), projection_matrix.cast(), viewport.cast(), V, F, fid, bc) + && (stl.facet_start + fid)->normal(2) < 0.f) { + const Vec3f& a = (stl.facet_start+fid)->vertex[0]; + const Vec3f& b = (stl.facet_start+fid)->vertex[1]; + const Vec3f& c = (stl.facet_start+fid)->vertex[2]; + final_pos = bc(0)*a + bc(1)*b + bc(2)*c; + const_cast(m_model_object)->sla_support_points[m_hover_id] = final_pos; + } +} + + + } // namespace GUI } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp index d3cad05c6..b97339754 100644 --- a/xs/src/slic3r/GUI/GLGizmo.hpp +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -353,6 +353,25 @@ protected: } }; +class GLGizmoSlaSupports : public GLGizmoBase +{ +// This gizmo does not use grabbers. The m_hover_id relates to shape managed by the class itself. +private: + const ModelObject* m_model_object = nullptr; + +public: + explicit GLGizmoSlaSupports(GLCanvas3D& parent); + void set_model_object_ptr(const ModelObject* model_object) { m_model_object = model_object; } + void move_current_point(const Vec2d& mouse_position); + +protected: + virtual bool on_init(); + virtual void on_start_dragging(); + virtual void on_update(const Linef3& mouse_ray) {} + virtual void on_render(const BoundingBoxf3& box) const; + virtual void on_render_for_picking(const BoundingBoxf3& box) const; +}; + } // namespace GUI } // namespace Slic3r