From bac021d516ccee926ceb4986487e574a1d568096 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 28 Nov 2018 15:13:25 +0100 Subject: [PATCH] SLA slices preview - completed prototype --- src/libslic3r/SLAPrint.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 181 ++++++++++++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 2 + src/slic3r/GUI/GUI_Preview.cpp | 8 +- 4 files changed, 187 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 9ed89f16e5..78cb86f75a 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1013,7 +1013,7 @@ const TriangleMesh EMPTY_MESH; const std::vector &SLAPrintObject::get_support_slices() const { // assert(is_step_done(slaposSliceSupports)); - if(!!m_supportdata) return EMPTY_SLICES; + if (!m_supportdata) return EMPTY_SLICES; return m_supportdata->support_slices; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e9090e9c3b..5cf178c6bc 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3793,6 +3793,7 @@ void GLCanvas3D::render() } _render_objects(); + _render_sla_slices(); _render_selection(); if (!is_custom_bed) // textured bed needs to be rendered after objects @@ -5704,7 +5705,7 @@ void GLCanvas3D::_render_objects() const } if (m_use_clipping_planes) - m_volumes.set_z_range(m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]); + m_volumes.set_z_range(-m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]); else m_volumes.set_z_range(-FLT_MAX, FLT_MAX); @@ -5891,6 +5892,184 @@ void GLCanvas3D::_render_camera_target() const } #endif // ENABLE_SHOW_CAMERA_TARGET +void GLCanvas3D::_render_sla_slices() const +{ + if (!m_use_clipping_planes || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) + return; + + const SLAPrint* print = this->sla_print(); + if (print->objects().empty()) + // nothing to render, return + return; + + double clip_min_z = -m_clipping_planes[0].get_data()[3]; + double clip_max_z = m_clipping_planes[1].get_data()[3]; + for (const SLAPrintObject* obj : print->objects()) + { + if (obj->is_step_done(slaposIndexSlices)) + { + const SLAPrintObject::SliceIndex& index = obj->get_slice_index(); + const std::vector& model_slices = obj->get_model_slices(); + const std::vector& support_slices = obj->get_support_slices(); + const std::vector& instances = obj->instances(); + double shift_z = obj->get_current_elevation(); + + struct InstanceTransform + { + Vec3d offset; + float rotation; + }; + + std::vector instance_transforms; + for (const SLAPrintObject::Instance& inst : instances) + { + instance_transforms.push_back({ to_3d(unscale(inst.shift), shift_z), Geometry::rad2deg(inst.rotation) }); + } + + double min_z = clip_min_z - shift_z; + double max_z = clip_max_z - shift_z; + SLAPrintObject::SliceIndex::const_iterator it_min_z = std::find_if(index.begin(), index.end(), [min_z](const SLAPrintObject::SliceIndex::value_type& id) -> bool { return std::abs(min_z - id.first) < EPSILON; }); + SLAPrintObject::SliceIndex::const_iterator it_max_z = std::find_if(index.begin(), index.end(), [max_z](const SLAPrintObject::SliceIndex::value_type& id) -> bool { return std::abs(max_z - id.first) < EPSILON; }); + + ::glColor3f(1.0f, 0.37f, 0.0f); + + if (it_min_z != index.end()) + { + // render model bottom slices + if (it_min_z->second.model_slices_idx < model_slices.size()) + { + const ExPolygons& polys = model_slices[it_min_z->second.model_slices_idx]; + for (const ExPolygon& poly : polys) + { + Polygons triangles; + poly.triangulate(&triangles); + if (!triangles.empty()) + { + for (unsigned int i = 0; i < (unsigned int)instances.size(); ++i) + { + ::glPushMatrix(); + ::glTranslated(instance_transforms[i].offset(0), instance_transforms[i].offset(1), instance_transforms[i].offset(2)); + ::glRotatef(instance_transforms[i].rotation, 0.0, 0.0, 1.0); + + ::glBegin(GL_TRIANGLES); + ::glNormal3f(0.0f, 0.0f, -1.0f); + for (const Polygon& p : triangles) + { + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[2]), min_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[1]), min_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[0]), min_z).data()); + } + ::glEnd(); + + ::glPopMatrix(); + } + } + } + } + + // render support bottom slices + if (it_min_z->second.support_slices_idx < support_slices.size()) + { + const ExPolygons& polys = support_slices[it_min_z->second.support_slices_idx]; + for (const ExPolygon& poly : polys) + { + Polygons triangles; + poly.triangulate(&triangles); + if (!triangles.empty()) + { + for (unsigned int i = 0; i < (unsigned int)instances.size(); ++i) + { + ::glPushMatrix(); + ::glTranslated(instance_transforms[i].offset(0), instance_transforms[i].offset(1), instance_transforms[i].offset(2)); + ::glRotatef(instance_transforms[i].rotation, 0.0, 0.0, 1.0); + + ::glBegin(GL_TRIANGLES); + ::glNormal3f(0.0f, 0.0f, -1.0f); + for (const Polygon& p : triangles) + { + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[2]), min_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[1]), min_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[0]), min_z).data()); + } + ::glEnd(); + + ::glPopMatrix(); + } + } + } + } + } + + if (it_max_z != index.end()) + { + // render model top slices + if (it_max_z->second.model_slices_idx < model_slices.size()) + { + const ExPolygons& polys = model_slices[it_max_z->second.model_slices_idx]; + for (const ExPolygon& poly : polys) + { + Polygons triangles; + poly.triangulate(&triangles); + if (!triangles.empty()) + { + for (unsigned int i = 0; i < (unsigned int)instances.size(); ++i) + { + ::glPushMatrix(); + ::glTranslated(instance_transforms[i].offset(0), instance_transforms[i].offset(1), instance_transforms[i].offset(2)); + ::glRotatef(instance_transforms[i].rotation, 0.0, 0.0, 1.0); + + ::glBegin(GL_TRIANGLES); + ::glNormal3f(0.0f, 0.0f, 1.0f); + for (const Polygon& p : triangles) + { + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[0]), max_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[1]), max_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[2]), max_z).data()); + } + ::glEnd(); + + ::glPopMatrix(); + } + } + } + } + + // render support top slices + if (it_max_z->second.support_slices_idx < support_slices.size()) + { + const ExPolygons& polys = support_slices[it_max_z->second.support_slices_idx]; + for (const ExPolygon& poly : polys) + { + Polygons triangles; + poly.triangulate(&triangles); + if (!triangles.empty()) + { + for (unsigned int i = 0; i < (unsigned int)instances.size(); ++i) + { + ::glPushMatrix(); + ::glTranslated(instance_transforms[i].offset(0), instance_transforms[i].offset(1), instance_transforms[i].offset(2)); + ::glRotatef(instance_transforms[i].rotation, 0.0, 0.0, 1.0); + + ::glBegin(GL_TRIANGLES); + ::glNormal3f(0.0f, 0.0f, 1.0f); + for (const Polygon& p : triangles) + { + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[0]), max_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[1]), max_z).data()); + ::glVertex3dv((GLdouble*)to_3d(unscale(p.points[2]), max_z).data()); + } + ::glEnd(); + + ::glPopMatrix(); + } + } + } + } + } + } + } +} + void GLCanvas3D::_update_volumes_hover_state() const { for (GLVolume* v : m_volumes.volumes) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9762539afa..0a824ac2c2 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -941,6 +941,7 @@ private: #if ENABLE_SHOW_CAMERA_TARGET void _render_camera_target() const; #endif // ENABLE_SHOW_CAMERA_TARGET + void _render_sla_slices() const; void _update_volumes_hover_state() const; void _update_gizmos_data(); @@ -984,6 +985,7 @@ private: void _load_gcode_unretractions(const GCodePreviewData& preview_data); // generates objects and wipe tower geometry void _load_shells_fff(); + // generates objects geometry for sla void _load_shells_sla(); // sets gcode geometry visibility according to user selection void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index f9b78cc272..5e9a5ec201 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -619,7 +619,7 @@ void Preview::load_print_as_sla() unsigned int n_layers = 0; const SLAPrint* print = m_process->sla_print(); - std::set zs; + std::set zs; for (const SLAPrintObject* obj : print->objects()) { double shift_z = obj->get_current_elevation(); @@ -628,7 +628,7 @@ void Preview::load_print_as_sla() const SLAPrintObject::SliceIndex& index = obj->get_slice_index(); for (const SLAPrintObject::SliceIndex::value_type& id : index) { - zs.insert(shift_z + id.second.scale_back(id.first)); + zs.insert(shift_z + id.first); } } } @@ -670,8 +670,8 @@ void Preview::on_sliders_scroll_changed(wxEvent& event) } else if (tech == ptSLA) { - m_canvas->set_clipping_plane(0, GLCanvas3D::ClippingPlane(Vec3d::UnitZ(), -(m_slider->GetLowerValueD() - 1e-6))); - m_canvas->set_clipping_plane(1, GLCanvas3D::ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD() + 1e-6)); + m_canvas->set_clipping_plane(0, GLCanvas3D::ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD())); + m_canvas->set_clipping_plane(1, GLCanvas3D::ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD())); m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0); m_canvas_widget->Refresh(); }