From d28d4823e07f15c31e82490c86a328237c2743ef Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 26 Nov 2018 10:49:25 +0100 Subject: [PATCH] SLA support points gizmo - multiple instance support --- resources/icons/sla_support_points_reset.png | Bin 0 -> 1050 bytes .../icons/sla_support_points_tooltip.png | Bin 0 -> 4008 bytes src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GLGizmo.cpp | 141 ++++++++++-------- src/slic3r/GUI/GLGizmo.hpp | 6 +- 6 files changed, 84 insertions(+), 67 deletions(-) create mode 100644 resources/icons/sla_support_points_reset.png create mode 100644 resources/icons/sla_support_points_tooltip.png diff --git a/resources/icons/sla_support_points_reset.png b/resources/icons/sla_support_points_reset.png new file mode 100644 index 0000000000000000000000000000000000000000..6e051fe95104027f06f524c7e60e090dcdc05bce GIT binary patch literal 1050 zcmV+#1m*jQP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf1FuO$K~z{r?U>7J z6Hye#zf5A2rb(MV6k01dMRcY*JQ}3Bi`bxVCE#POqs!t-;76OIta?#Gyc|1#~*RY&!*OSs9OVC$B&p8 z9K_8JeTcG5ZvZy9LJW*zNqf=3qkmF1R|w3zxL?W%W}1K)uDdb&?Hi&aBM=JpQ0esu z9y*Mt`S}^wNL0$o`*$%Djq)sI>b~s*ELN(exYDaCwW6ezPsBoSB@(mc z#peA^Ghp{fu~0HeR^k%NTBlaC@#7~MyLg$g);7kDwK8`80vp-0muUqdV@|4VjBb+A zjirpK#1q$acvHs&LQG)vD2%AE5c4v6;6yy`oO$u_ytop}R!m$qblRu|YN}L0n4JY^ zn~7Fy)Tp7}qf}<6pRcMPjXkuj_I1YsHW#|=VYsjGF)7e_6+Uw#jwBY@j^^~8rzmgn zQUqp0NeP}dHbG521`&c%RYk6pz-TEJ*t!k13gIMrjKfEeE~PbJGo1eUTf##qxB{K9 z)VpEv#A2yiB1hgYN*0U+WnU9C1VwDLQ`AqsK7WScU=S01AD}BMg|@U5Pd08st$3^} zRreLR!*+C~JfIH_-k6iNpfkY3A{=SXfe=+*vTw`e{ep6Wk)YV)P>L`$Fo21nAyhwl zfK`Df80+uHkKT9CSCpfW-eVrETaR_i3V61h0_eOtuWACf(6azkHoeB1F#oDFFQv)L zD<_!c1qEQyIch~wf-;2hPXy)hL+SJpUGqGM?*si9d)o^^5TGJgkQJ-@Hm!BMZxAR; zJ$f4BJ%~Hxiak(=ciy}o&X5DK_9T-hUU91jVY3r{n*VL5()O})Hr8~I4e!{Q@$}KE zRIG2UnSI&3h1s;a1@R^9jFTyDFqv{5$s(M83<}HtgO^2%XbAt8@?f$k4<@64pX?TS U6@jyFr~m)}07*qoM6N<$f;Z&d_5c6? literal 0 HcmV?d00001 diff --git a/resources/icons/sla_support_points_tooltip.png b/resources/icons/sla_support_points_tooltip.png new file mode 100644 index 0000000000000000000000000000000000000000..1bdfd3440756bb9b336509f6e944a4262566dad9 GIT binary patch literal 4008 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 #include "libslic3r/Geometry.hpp" -#include #include #include @@ -1627,7 +1626,11 @@ void GLGizmoSlaSupports::set_model_object_ptr(ModelObject* model_object) { m_starting_center = Vec3d::Zero(); m_model_object = model_object; - m_model_object_matrix = model_object->instances.front()->get_matrix(); + + int selected_instance = m_parent.get_selection().get_instance_idx(); + assert(selected_instance < (int)model_object->instances.size()); + + m_instance_matrix = model_object->instances[selected_instance]->get_matrix(); if (is_mesh_update_necessary()) update_mesh(); } @@ -1639,7 +1642,7 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const ::glEnable(GL_DEPTH_TEST); // the dragged_offset is a vector measuring where was the object moved - // with the gizmo being on. This is reset in set_flattening_data and + // with the gizmo being on. This is reset in set_model_object_ptr and // does not work correctly when there are multiple copies. if (m_starting_center == Vec3d::Zero()) @@ -1653,7 +1656,7 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const } ::glPushMatrix(); - ::glTranslatef((GLfloat)dragged_offset(0), (GLfloat)dragged_offset(1), (GLfloat)dragged_offset(2)); + //::glTranslatef((GLfloat)dragged_offset(0), (GLfloat)dragged_offset(1), (GLfloat)dragged_offset(2)); render_grabbers(); ::glPopMatrix(); @@ -1675,33 +1678,35 @@ void GLGizmoSlaSupports::on_render_for_picking(const GLCanvas3D::Selection& sele void GLGizmoSlaSupports::render_grabbers(bool picking) const { - for (int i = 0; i < (int)m_grabbers.size(); ++i) - { - if (!m_grabbers[i].enabled) - continue; + for (const ModelInstance* inst : m_model_object->instances) { + for (int i = 0; i < (int)m_grabbers.size(); ++i) + { + if (!m_grabbers[i].enabled) + continue; - float render_color[3]; - if (!picking && m_hover_id == i) { - render_color[0] = 1.0f - m_grabbers[i].color[0]; - render_color[1] = 1.0f - m_grabbers[i].color[1]; - render_color[2] = 1.0f - m_grabbers[i].color[2]; + float render_color[3]; + if (!picking && m_hover_id == i) { + render_color[0] = 1.0f - m_grabbers[i].color[0]; + render_color[1] = 1.0f - m_grabbers[i].color[1]; + render_color[2] = 1.0f - m_grabbers[i].color[2]; + } + else + ::memcpy((void*)render_color, (const void*)m_grabbers[i].color, 3 * sizeof(float)); + if (!picking) + ::glEnable(GL_LIGHTING); + ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]); + ::glPushMatrix(); + Vec3d center = inst->get_matrix() * m_grabbers[i].center; + ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2)); + GLUquadricObj *quadric; + quadric = ::gluNewQuadric(); + ::gluQuadricDrawStyle(quadric, GLU_FILL ); + ::gluSphere( quadric , 0.75f, 36 , 18 ); + ::gluDeleteQuadric(quadric); + ::glPopMatrix(); + if (!picking) + ::glDisable(GL_LIGHTING); } - else - ::memcpy((void*)render_color, (const void*)m_grabbers[i].color, 3 * sizeof(float)); - if (!picking) - ::glEnable(GL_LIGHTING); - ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]); - ::glPushMatrix(); - Vec3d center = m_model_object_matrix * m_grabbers[i].center; - ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2)); - GLUquadricObj *quadric; - quadric = ::gluNewQuadric(); - ::gluQuadricDrawStyle(quadric, GLU_FILL ); - ::gluSphere( quadric , 0.75f, 36 , 18 ); - ::gluDeleteQuadric(quadric); - ::glPopMatrix(); - if (!picking) - ::glDisable(GL_LIGHTING); } } @@ -1710,7 +1715,7 @@ bool GLGizmoSlaSupports::is_mesh_update_necessary() const if (m_state != On || !m_model_object || m_model_object->instances.empty()) return false; - if ((m_model_object->instances.front()->get_matrix() * m_source_data.matrix.inverse() * Vec3d(1., 1., 1.) - Vec3d(1., 1., 1.)).norm() > 0.001) + if ((m_instance_matrix * m_source_data.matrix.inverse() * Vec3d(1., 1., 1.) - Vec3d(1., 1., 1.)).norm() > 0.001) return true; // following should detect direct mesh changes (can be removed after the mesh is made completely immutable): @@ -1726,7 +1731,7 @@ void GLGizmoSlaSupports::update_mesh() { Eigen::MatrixXf& V = m_V; Eigen::MatrixXi& F = m_F; - TriangleMesh mesh(m_model_object->mesh()); + TriangleMesh mesh = m_model_object->mesh(); const stl_file& stl = mesh.stl; V.resize(3 * stl.stats.number_of_facets, 3); F.resize(stl.stats.number_of_facets, 3); @@ -1739,15 +1744,19 @@ void GLGizmoSlaSupports::update_mesh() F(i, 1) = 3*i+1; F(i, 2) = 3*i+2; } - m_source_data.matrix = m_model_object->instances.front()->get_matrix(); - const float* first_vertex = m_model_object->volumes.front()->get_convex_hull().first_vertex(); - m_source_data.mesh_first_point = Vec3d((double)first_vertex[0], (double)first_vertex[1], (double)first_vertex[2]); + + m_AABB = igl::AABB(); + m_AABB.init(m_V, m_F); + + m_source_data.matrix = m_instance_matrix; + // we'll now reload Grabbers (selection might have changed): m_grabbers.clear(); for (const Vec3f& point : m_model_object->sla_support_points) { m_grabbers.push_back(Grabber()); m_grabbers.back().center = point.cast(); } + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) @@ -1763,24 +1772,21 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) Eigen::Matrix projection_matrix; ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data()); - int fid = 0; - Eigen::Vector3f bc(0, 0, 0); - if (!igl::unproject_onto_mesh(Vec2f(mouse_pos(0), viewport(3)-mouse_pos(1)), modelview_matrix.cast(), projection_matrix.cast(), viewport.cast(), m_V, m_F, fid, bc)) - /*if (!igl::embree::unproject_onto_mesh(Vec2f(mouse_pos(0), viewport(3)-mouse_pos(1)), - m_F, - modelview_matrix.cast(), - projection_matrix.cast(), - viewport.cast(), - m_intersector, - fid, - bc))*/ - throw "unable to unproject_onto_mesh"; + Vec3d point1; + Vec3d point2; + ::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)); - const Vec3f& a = m_V.row(m_F(fid, 0)); - const Vec3f& b = m_V.row(m_F(fid, 1)); - const Vec3f& c = m_V.row(m_F(fid, 2)); - Vec3f point = bc(0)*a + bc(1)*b + bc(2)*c; - return m_model_object->instances.front()->get_matrix().inverse().cast() * point; + igl::Hit hit; + + if (!m_AABB.intersect_ray(m_V, m_F, point1.cast(), (point2-point1).cast(), hit)) + throw std::invalid_argument("unproject_on_mesh(): No intersection found."); + + int fid = hit.id; + Vec3f bc(1-hit.u-hit.v, hit.u, hit.v); + Vec3f point = 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)); + + return m_instance_matrix.inverse().cast() * point; } void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position) @@ -1788,14 +1794,17 @@ void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position) Vec3f new_pos; try { new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new grabber in that case - m_grabbers.push_back(Grabber()); - m_grabbers.back().center = new_pos.cast(); - m_model_object->sla_support_points.push_back(new_pos); - - // This should trigger the support generation - // wxGetApp().plater()->reslice(); } - catch (...) {} + catch (...) { return; } + + m_grabbers.push_back(Grabber()); + m_grabbers.back().center = new_pos.cast(); + m_model_object->sla_support_points.push_back(new_pos); + + // This should trigger the support generation + // wxGetApp().plater()->reslice(); + + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } void GLGizmoSlaSupports::delete_current_grabber(bool delete_all) @@ -1816,6 +1825,8 @@ void GLGizmoSlaSupports::delete_current_grabber(bool delete_all) // This should trigger the support generation // wxGetApp().plater()->reslice(); } + + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } void GLGizmoSlaSupports::on_update(const UpdateData& data) @@ -1824,20 +1835,21 @@ void GLGizmoSlaSupports::on_update(const UpdateData& data) Vec3f new_pos; try { new_pos = unproject_on_mesh(Vec2d((*data.mouse_pos)(0), (*data.mouse_pos)(1))); - m_grabbers[m_hover_id].center = new_pos.cast(); - m_model_object->sla_support_points[m_hover_id] = new_pos; } - catch (...) {} + catch (...) { return; } + m_grabbers[m_hover_id].center = new_pos.cast(); + m_model_object->sla_support_points[m_hover_id] = new_pos; + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } } void GLGizmoSlaSupports::render_tooltip_texture() const { if (m_tooltip_texture.get_id() == 0) - if (!m_tooltip_texture.load_from_file(resources_dir() + "/icons/variable_layer_height_tooltip.png", false)) + if (!m_tooltip_texture.load_from_file(resources_dir() + "/icons/sla_support_points_tooltip.png", false)) return; if (m_reset_texture.get_id() == 0) - if (!m_reset_texture.load_from_file(resources_dir() + "/icons/variable_layer_height_reset.png", false)) + if (!m_reset_texture.load_from_file(resources_dir() + "/icons/sla_support_points_reset.png", false)) return; float zoom = m_parent.get_camera_zoom(); @@ -1863,7 +1875,8 @@ void GLGizmoSlaSupports::render_tooltip_texture() const { bool GLGizmoSlaSupports::on_is_activable(const GLCanvas3D::Selection& selection) const { - return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA); + return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) + && selection.is_from_single_instance(); } bool GLGizmoSlaSupports::on_is_selectable() const diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index 64bd71876..6ce22f395 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -1,6 +1,8 @@ #ifndef slic3r_GLGizmo_hpp_ #define slic3r_GLGizmo_hpp_ +#include + #include "../../slic3r/GUI/GLTexture.hpp" #include "../../slic3r/GUI/GLCanvas3D.hpp" #include "../../libslic3r/Point.hpp" @@ -449,11 +451,13 @@ class GLGizmoSlaSupports : public GLGizmoBase { private: ModelObject* m_model_object = nullptr; - Transform3d m_model_object_matrix; + Transform3d m_instance_matrix; Vec3f unproject_on_mesh(const Vec2d& mouse_pos); Eigen::MatrixXf m_V; // vertices Eigen::MatrixXi m_F; // facets indices + igl::AABB m_AABB; + struct SourceDataSummary { BoundingBoxf3 bounding_box; Transform3d matrix;