diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index a654f6554..e2fdcaaca 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -46,8 +46,6 @@ __PACKAGE__->mk_accessors( qw(_quat init on_move on_model_update volumes - cutting_plane_z - cut_lines_vertices background _mouse_pos _hover_volume_idx @@ -1071,19 +1069,23 @@ sub select_volume { sub SetCuttingPlane { my ($self, $z, $expolygons) = @_; - $self->cutting_plane_z($z); - - # grow slices in order to display them better - $expolygons = offset_ex([ map @$_, @$expolygons ], scale 0.1); - - my @verts = (); - foreach my $line (map @{$_->lines}, map @$_, @$expolygons) { - push @verts, ( - unscale($line->a->x), unscale($line->a->y), $z, #)) - unscale($line->b->x), unscale($line->b->y), $z, #)) - ); - } - $self->cut_lines_vertices(OpenGL::Array->new_list(GL_FLOAT, @verts)); +#============================================================================================================================== + Slic3r::GUI::_3DScene::set_cutting_plane($self, $z, $expolygons); + +# $self->cutting_plane_z($z); +# +# # grow slices in order to display them better +# $expolygons = offset_ex([ map @$_, @$expolygons ], scale 0.1); +# +# my @verts = (); +# foreach my $line (map @{$_->lines}, map @$_, @$expolygons) { +# push @verts, ( +# unscale($line->a->x), unscale($line->a->y), $z, #)) +# unscale($line->b->x), unscale($line->b->y), $z, #)) +# ); +# } +# $self->cut_lines_vertices(OpenGL::Array->new_list(GL_FLOAT, @verts)); +#============================================================================================================================== } # Given an axis and angle, compute quaternion. @@ -1516,7 +1518,7 @@ sub Render { # draw ground my $ground_z = GROUND_Z; #============================================================================================================================== - Slic3r::GUI::_3DScene::render($self); + Slic3r::GUI::_3DScene::render_bed($self); # if ($self->bed_triangles) { # glDisable(GL_DEPTH_TEST); @@ -1603,33 +1605,37 @@ sub Render { glEnable(GL_CULL_FACE) if ($self->enable_picking); } - if (defined $self->cutting_plane_z) { - # draw cutting plane - my $plane_z = $self->cutting_plane_z; - my $bb = $volumes_bb; - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBegin(GL_QUADS); - glColor4f(0.8, 0.8, 0.8, 0.5); - glVertex3f($bb->x_min-20, $bb->y_min-20, $plane_z); - glVertex3f($bb->x_max+20, $bb->y_min-20, $plane_z); - glVertex3f($bb->x_max+20, $bb->y_max+20, $plane_z); - glVertex3f($bb->x_min-20, $bb->y_max+20, $plane_z); - glEnd(); - glEnable(GL_CULL_FACE); - glDisable(GL_BLEND); - - # draw cutting contours - glEnableClientState(GL_VERTEX_ARRAY); - glLineWidth(2); - glColor3f(0, 0, 0); - glVertexPointer_c(3, GL_FLOAT, 0, $self->cut_lines_vertices->ptr()); - glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3); - glVertexPointer_c(3, GL_FLOAT, 0, 0); - glDisableClientState(GL_VERTEX_ARRAY); - } +#============================================================================================================================== + Slic3r::GUI::_3DScene::render_cutting_plane($self); + +# if (defined $self->cutting_plane_z) { +# # draw cutting plane +# my $plane_z = $self->cutting_plane_z; +# my $bb = $volumes_bb; +# glDisable(GL_CULL_FACE); +# glDisable(GL_LIGHTING); +# glEnable(GL_BLEND); +# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +# glBegin(GL_QUADS); +# glColor4f(0.8, 0.8, 0.8, 0.5); +# glVertex3f($bb->x_min-20, $bb->y_min-20, $plane_z); +# glVertex3f($bb->x_max+20, $bb->y_min-20, $plane_z); +# glVertex3f($bb->x_max+20, $bb->y_max+20, $plane_z); +# glVertex3f($bb->x_min-20, $bb->y_max+20, $plane_z); +# glEnd(); +# glEnable(GL_CULL_FACE); +# glDisable(GL_BLEND); +# +# # draw cutting contours +# glEnableClientState(GL_VERTEX_ARRAY); +# glLineWidth(2); +# glColor3f(0, 0, 0); +# glVertexPointer_c(3, GL_FLOAT, 0, $self->cut_lines_vertices->ptr()); +# glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3); +# glVertexPointer_c(3, GL_FLOAT, 0, 0); +# glDisableClientState(GL_VERTEX_ARRAY); +# } +#============================================================================================================================== # draw warning message $self->draw_warning; diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index d2e778ac6..9babd8bc6 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1808,6 +1808,11 @@ BoundingBoxf3 _3DScene::get_max_bounding_box(wxGLCanvas* canvas) return s_canvas_mgr.get_max_bounding_box(canvas); } +void _3DScene::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons) +{ + return s_canvas_mgr.set_cutting_plane(canvas, z, polygons); +} + unsigned int _3DScene::get_camera_type(wxGLCanvas* canvas) { return s_canvas_mgr.get_camera_type(canvas); @@ -1888,9 +1893,14 @@ void _3DScene::select_view(wxGLCanvas* canvas, const std::string& direction) s_canvas_mgr.select_view(canvas, direction); } -void _3DScene::render(wxGLCanvas* canvas) +void _3DScene::render_bed(wxGLCanvas* canvas) { - s_canvas_mgr.render(canvas); + s_canvas_mgr.render_bed(canvas); +} + +void _3DScene::render_cutting_plane(wxGLCanvas* canvas) +{ + s_canvas_mgr.render_cutting_plane(canvas); } void _3DScene::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback) diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 8d6345f97..eb03a5313 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -562,6 +562,8 @@ public: static BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas); static BoundingBoxf3 get_max_bounding_box(wxGLCanvas* canvas); + static void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons); + static unsigned int get_camera_type(wxGLCanvas* canvas); static void set_camera_type(wxGLCanvas* canvas, unsigned int type); static std::string get_camera_type_as_string(wxGLCanvas* canvas); @@ -585,7 +587,8 @@ public: static void zoom_to_volumes(wxGLCanvas* canvas); static void select_view(wxGLCanvas* canvas, const std::string& direction); - static void render(wxGLCanvas* canvas); + static void render_bed(wxGLCanvas* canvas); + static void render_cutting_plane(wxGLCanvas* canvas); static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 4a5a97c95..9631f7996 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -230,8 +230,7 @@ void GLCanvas3D::Bed::render() ::glColor4f(0.8f, 0.6f, 0.5f, 0.4f); ::glNormal3d(0.0f, 0.0f, 1.0f); ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_triangles.get_data()); - ::glDrawArrays(GL_TRIANGLES, 0, triangles_vcount); -// ::glDisableClientState(GL_VERTEX_ARRAY); + ::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount); // we need depth test for grid, otherwise it would disappear when looking // the object from below @@ -242,9 +241,8 @@ void GLCanvas3D::Bed::render() ::glLineWidth(3.0f); ::glColor4f(0.2f, 0.2f, 0.2f, 0.4f); -// ::glEnableClientState(GL_VERTEX_ARRAY); ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_gridlines.get_data()); - ::glDrawArrays(GL_LINES, 0, gridlines_vcount); + ::glDrawArrays(GL_LINES, 0, (GLsizei)gridlines_vcount); ::glDisableClientState(GL_VERTEX_ARRAY); @@ -299,6 +297,66 @@ void GLCanvas3D::Bed::_calc_gridlines(const ExPolygon& poly, const BoundingBox& printf("Unable to create bed grid lines\n"); } +GLCanvas3D::CuttingPlane::CuttingPlane() + : m_z(-1.0f) +{ +} + +bool GLCanvas3D::CuttingPlane::set(float z, const ExPolygons& polygons) +{ + m_z = z; + + // grow slices in order to display them better + ExPolygons expolygons = offset_ex(polygons, scale_(0.1)); + Lines lines = to_lines(expolygons); + return m_lines.set_from_lines(lines, m_z); +} + +void GLCanvas3D::CuttingPlane::render_plane(const BoundingBoxf3& bb) +{ + if (m_z >= 0.0f) + { + ::glDisable(GL_CULL_FACE); + ::glDisable(GL_LIGHTING); + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + float margin = 20.0f; + float min_x = bb.min.x - margin; + float max_x = bb.max.x + margin; + float min_y = bb.min.y - margin; + float max_y = bb.max.y + margin; + + ::glBegin(GL_QUADS); + ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glVertex3f(min_x, min_y, m_z); + ::glVertex3f(max_x, min_y, m_z); + ::glVertex3f(max_x, max_y, m_z); + ::glVertex3f(min_x, max_y, m_z); + ::glEnd(); + + ::glEnable(GL_CULL_FACE); + ::glDisable(GL_BLEND); + } +} + +void GLCanvas3D::CuttingPlane::render_contour() +{ + ::glEnableClientState(GL_VERTEX_ARRAY); + + if (m_z >= 0.0f) + { + unsigned int lines_vcount = m_lines.get_data_size() / 3; + + ::glLineWidth(2.0f); + ::glColor3f(0.0f, 0.0f, 0.0f); + ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_lines.get_data()); + ::glDrawArrays(GL_LINES, 0, (GLsizei)lines_vcount); + } + + ::glDisableClientState(GL_VERTEX_ARRAY); +} + GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) : m_canvas(canvas) , m_context(context) @@ -446,6 +504,11 @@ void GLCanvas3D::set_bed_origin(const Pointf& origin) m_bed.set_origin(origin); } +void GLCanvas3D::set_cutting_plane(float z, const ExPolygons& polygons) +{ + m_cutting_plane.set(z, polygons); +} + GLCanvas3D::Camera::EType GLCanvas3D::get_camera_type() const { return m_camera.get_type(); @@ -580,11 +643,17 @@ void GLCanvas3D::select_view(const std::string& direction) } } -void GLCanvas3D::render() +void GLCanvas3D::render_bed() { m_bed.render(); } +void GLCanvas3D::render_cutting_plane() +{ + m_cutting_plane.render_plane(volumes_bounding_box()); + m_cutting_plane.render_contour(); +} + void GLCanvas3D::register_on_viewport_changed_callback(void* callback) { if (callback != nullptr) diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 507964136..a7e9dbfb0 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -3,6 +3,7 @@ #include "../../libslic3r/BoundingBox.hpp" #include "../../libslic3r/Utils.hpp" +#include "../../libslic3r/ExPolygon.hpp" class wxGLCanvas; class wxGLContext; @@ -100,11 +101,26 @@ public: void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); }; + class CuttingPlane + { + float m_z; + GeometryBuffer m_lines; + + public: + CuttingPlane(); + + bool set(float z, const ExPolygons& polygons); + + void render_plane(const BoundingBoxf3& bb); + void render_contour(); + }; + private: wxGLCanvas* m_canvas; wxGLContext* m_context; Camera m_camera; Bed m_bed; + CuttingPlane m_cutting_plane; GLVolumeCollection* m_volumes; @@ -140,6 +156,8 @@ public: const Pointf& get_bed_origin() const; void set_bed_origin(const Pointf& origin); + void set_cutting_plane(float z, const ExPolygons& polygons); + Camera::EType get_camera_type() const; void set_camera_type(Camera::EType type); std::string get_camera_type_as_string() const; @@ -167,7 +185,8 @@ public: void zoom_to_volumes(); void select_view(const std::string& direction); - void render(); + void render_bed(); + void render_cutting_plane(); void register_on_viewport_changed_callback(void* callback); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 61867c61c..911fb2f0e 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -232,6 +232,13 @@ BoundingBoxf3 GLCanvas3DManager::get_max_bounding_box(wxGLCanvas* canvas) return (it != m_canvases.end()) ? it->second->max_bounding_box() : BoundingBoxf3(); } +void GLCanvas3DManager::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->set_cutting_plane(z, polygons); +} + unsigned int GLCanvas3DManager::get_camera_type(wxGLCanvas* canvas) const { CanvasesMap::const_iterator it = _get_canvas(canvas); @@ -343,11 +350,18 @@ void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direc it->second->select_view(direction); } -void GLCanvas3DManager::render(wxGLCanvas* canvas) +void GLCanvas3DManager::render_bed(wxGLCanvas* canvas) { CanvasesMap::iterator it = _get_canvas(canvas); if (it != m_canvases.end()) - it->second->render(); + it->second->render_bed(); +} + +void GLCanvas3DManager::render_cutting_plane(wxGLCanvas* canvas) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->render_cutting_plane(); } void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback) diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index bf0b9c066..4d8066597 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -1,7 +1,7 @@ #ifndef slic3r_GLCanvas3DManager_hpp_ #define slic3r_GLCanvas3DManager_hpp_ -#include "GLCanvas3D.hpp" +#include "../../slic3r/GUI/GLCanvas3D.hpp" #include @@ -72,6 +72,8 @@ public: BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas); BoundingBoxf3 get_max_bounding_box(wxGLCanvas* canvas); + void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons); + unsigned int get_camera_type(wxGLCanvas* canvas) const; void set_camera_type(wxGLCanvas* canvas, unsigned int type); std::string get_camera_type_as_string(wxGLCanvas* canvas) const; @@ -95,7 +97,8 @@ public: void zoom_to_volumes(wxGLCanvas* canvas); void select_view(wxGLCanvas* canvas, const std::string& direction); - void render(wxGLCanvas* canvas); + void render_bed(wxGLCanvas* canvas); + void render_cutting_plane(wxGLCanvas* canvas); void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index c62c7e958..2efe8f11b 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -283,6 +283,14 @@ is_shown_on_screen(canvas) OUTPUT: RETVAL +void +set_cutting_plane(canvas, z, polygons) + SV *canvas; + float z; + ExPolygons polygons; + CODE: + _3DScene::set_cutting_plane((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), z, polygons); + unsigned int get_camera_type(canvas) SV *canvas; @@ -401,10 +409,16 @@ select_view(canvas, direction) _3DScene::select_view((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), direction); void -render(canvas) +render_bed(canvas) SV *canvas; CODE: - _3DScene::render((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + _3DScene::render_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + +void +render_cutting_plane(canvas) + SV *canvas; + CODE: + _3DScene::render_cutting_plane((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); void register_on_viewport_changed_callback(canvas, callback)