1 #include "GLSelectionRectangle.hpp" 2 #include "Camera.hpp" 3 #include "3DScene.hpp" 4 #include "GLCanvas3D.hpp" 5 #include "GUI_App.hpp" 6 #include "Plater.hpp" 7 8 #include <GL/glew.h> 9 10 namespace Slic3r { 11 namespace GUI { 12 start_dragging(const Vec2d & mouse_position,EState state)13 void GLSelectionRectangle::start_dragging(const Vec2d& mouse_position, EState state) 14 { 15 if (is_dragging() || (state == Off)) 16 return; 17 18 m_state = state; 19 m_start_corner = mouse_position; 20 m_end_corner = mouse_position; 21 } 22 dragging(const Vec2d & mouse_position)23 void GLSelectionRectangle::dragging(const Vec2d& mouse_position) 24 { 25 if (!is_dragging()) 26 return; 27 28 m_end_corner = mouse_position; 29 } 30 stop_dragging(const GLCanvas3D & canvas,const std::vector<Vec3d> & points)31 std::vector<unsigned int> GLSelectionRectangle::stop_dragging(const GLCanvas3D& canvas, const std::vector<Vec3d>& points) 32 { 33 std::vector<unsigned int> out; 34 35 if (!is_dragging()) 36 return out; 37 38 m_state = Off; 39 40 const Camera& camera = wxGetApp().plater()->get_camera(); 41 const std::array<int, 4>& viewport = camera.get_viewport(); 42 const Transform3d& modelview_matrix = camera.get_view_matrix(); 43 const Transform3d& projection_matrix = camera.get_projection_matrix(); 44 45 // bounding box created from the rectangle corners - will take care of order of the corners 46 BoundingBox rectangle(Points{ Point(m_start_corner.cast<coord_t>()), Point(m_end_corner.cast<coord_t>()) }); 47 48 // Iterate over all points and determine whether they're in the rectangle. 49 for (unsigned int i = 0; i<points.size(); ++i) { 50 const Vec3d& point = points[i]; 51 GLdouble out_x, out_y, out_z; 52 ::gluProject((GLdouble)point(0), (GLdouble)point(1), (GLdouble)point(2), (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); 53 out_y = canvas.get_canvas_size().get_height() - out_y; 54 55 if (rectangle.contains(Point(out_x, out_y))) 56 out.push_back(i); 57 } 58 59 return out; 60 } 61 stop_dragging()62 void GLSelectionRectangle::stop_dragging() 63 { 64 if (is_dragging()) 65 m_state = Off; 66 } 67 render(const GLCanvas3D & canvas) const68 void GLSelectionRectangle::render(const GLCanvas3D& canvas) const 69 { 70 if (!is_dragging()) 71 return; 72 73 const Camera& camera = wxGetApp().plater()->get_camera(); 74 float inv_zoom = (float)camera.get_inv_zoom(); 75 76 Size cnv_size = canvas.get_canvas_size(); 77 float cnv_half_width = 0.5f * (float)cnv_size.get_width(); 78 float cnv_half_height = 0.5f * (float)cnv_size.get_height(); 79 if ((cnv_half_width == 0.0f) || (cnv_half_height == 0.0f)) 80 return; 81 82 Vec2d start(m_start_corner(0) - cnv_half_width, cnv_half_height - m_start_corner(1)); 83 Vec2d end(m_end_corner(0) - cnv_half_width, cnv_half_height - m_end_corner(1)); 84 85 float left = (float)std::min(start(0), end(0)) * inv_zoom; 86 float top = (float)std::max(start(1), end(1)) * inv_zoom; 87 float right = (float)std::max(start(0), end(0)) * inv_zoom; 88 float bottom = (float)std::min(start(1), end(1)) * inv_zoom; 89 90 glsafe(::glLineWidth(1.5f)); 91 float color[3]; 92 color[0] = (m_state == Select) ? 0.3f : 1.0f; 93 color[1] = (m_state == Select) ? 1.0f : 0.3f; 94 color[2] = 0.3f; 95 glsafe(::glColor3fv(color)); 96 97 glsafe(::glDisable(GL_DEPTH_TEST)); 98 99 glsafe(::glPushMatrix()); 100 glsafe(::glLoadIdentity()); 101 // ensure that the rectangle is renderered inside the frustrum 102 glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5))); 103 // ensure that the overlay fits the frustrum near z plane 104 double gui_scale = camera.get_gui_scale(); 105 glsafe(::glScaled(gui_scale, gui_scale, 1.0)); 106 107 glsafe(::glPushAttrib(GL_ENABLE_BIT)); 108 glsafe(::glLineStipple(4, 0xAAAA)); 109 glsafe(::glEnable(GL_LINE_STIPPLE)); 110 111 ::glBegin(GL_LINE_LOOP); 112 ::glVertex2f((GLfloat)left, (GLfloat)bottom); 113 ::glVertex2f((GLfloat)right, (GLfloat)bottom); 114 ::glVertex2f((GLfloat)right, (GLfloat)top); 115 ::glVertex2f((GLfloat)left, (GLfloat)top); 116 glsafe(::glEnd()); 117 118 glsafe(::glPopAttrib()); 119 120 glsafe(::glPopMatrix()); 121 } 122 123 } // namespace GUI 124 } // namespace Slic3r 125