From ef5807e36b356ca3772a147829b74d2b0890dc2a Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 16 Nov 2018 17:25:23 +0100 Subject: [PATCH 01/23] Separate methods to get the sliced polygons. --- src/libslic3r/SLAPrint.cpp | 18 ++++++++++++++++++ src/libslic3r/SLAPrint.hpp | 9 +++++++++ 2 files changed, 27 insertions(+) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index da24e71c69..cb21539682 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -438,6 +438,24 @@ SLAPrintObject::SLAPrintObject(SLAPrint *print, ModelObject *model_object): SLAPrintObject::~SLAPrintObject() {} +double SLAPrintObject::get_elevation() const { + return m_supportdata && m_supportdata->support_tree_ptr? + m_supportdata->support_tree_ptr->get_elevation() : + 0; +} + +const std::vector &SLAPrintObject::get_support_slices() const +{ + if(!m_supportdata) return {}; + + return m_supportdata->support_slices; +} + +const std::vector &SLAPrintObject::get_model_slices() const +{ + return m_model_slices; +} + TriangleMesh SLAPrintObject::support_mesh() const { TriangleMesh trm; diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index de8c6cdae2..485dcf068c 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -62,6 +62,15 @@ public: std::vector transformed_support_points() const; + // Get the needed Z elevation for the model geometry if supports should be + // displayed. This Z offset should also be applied to the support + // geometries. Note that this is not the same as the value stored in config + // as the pad height also needs to be considered. + double get_elevation() const; + + const std::vector& get_support_slices() const; + const std::vector& get_model_slices() const; + // I refuse to grantee copying (Tamas) SLAPrintObject(const SLAPrintObject&) = delete; SLAPrintObject& operator=(const SLAPrintObject&) = delete; From 6629d7585310c04fe2108356cb3e31222d68d750 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 18 Oct 2018 15:13:38 +0200 Subject: [PATCH 02/23] Cutting --- src/libslic3r/Model.cpp | 55 +++++- src/libslic3r/Model.hpp | 4 +- src/slic3r.cpp | 29 +-- src/slic3r/GUI/3DScene.cpp | 5 - src/slic3r/GUI/3DScene.hpp | 2 - src/slic3r/GUI/GLCanvas3D.cpp | 116 +++--------- src/slic3r/GUI/GLCanvas3D.hpp | 31 +--- src/slic3r/GUI/GLCanvas3DManager.cpp | 7 - src/slic3r/GUI/GLCanvas3DManager.hpp | 2 - src/slic3r/GUI/GLGizmo.cpp | 261 ++++++++++++++++++++++++++- src/slic3r/GUI/GLGizmo.hpp | 45 +++++ src/slic3r/GUI/GLToolbar.cpp | 1 - src/slic3r/GUI/GLToolbar.hpp | 1 - src/slic3r/GUI/GUI_Utils.cpp | 12 ++ src/slic3r/GUI/GUI_Utils.hpp | 43 +++++ src/slic3r/GUI/MainFrame.cpp | 2 +- src/slic3r/GUI/MainFrame.hpp | 1 + src/slic3r/GUI/Plater.cpp | 65 ++++--- src/slic3r/GUI/Plater.hpp | 2 + 19 files changed, 502 insertions(+), 182 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index c9a097aea3..27ffef636e 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -951,25 +951,54 @@ bool ModelObject::needed_repair() const return false; } -void ModelObject::cut(coordf_t z, Model* model) const +template static void cut_reset_transform(T *thing) { + const Vec3d offset = thing->get_offset(); + thing->set_transformation(Geometry::Transformation()); + thing->set_offset(offset); +} + +ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z) { - // clone this one to duplicate instances, materials etc. - ModelObject* upper = model->add_object(*this); - ModelObject* lower = model->add_object(*this); + // Clone the object to duplicate instances, materials etc. + ModelObject* upper = ModelObject::new_clone(*this); + ModelObject* lower = ModelObject::new_clone(*this); + upper->set_model(nullptr); + lower->set_model(nullptr); upper->sla_support_points.clear(); lower->sla_support_points.clear(); upper->clear_volumes(); lower->clear_volumes(); upper->input_file = ""; lower->input_file = ""; - - for (ModelVolume *volume : this->volumes) { + + const auto instance_matrix = instances[instance]->get_matrix(true); + + // Because transformations are going to be applied to meshes directly, + // we reset transformation of all instances and volumes, + // _except_ for translation, which is preserved in the transformation matrix + // and not applied to the mesh transform. + // TODO: Do the same for Z-rotation as well? + + // Convert z from relative to bb's base to object coordinates + // FIXME: doesn't work well for rotated objects + const auto bb = instance_bounding_box(instance, true); + z -= bb.min(2); + + for (auto *instance : upper->instances) { cut_reset_transform(instance); } + for (auto *instance : lower->instances) { cut_reset_transform(instance); } + + for (ModelVolume *volume : volumes) { if (! volume->is_model_part()) { // don't cut modifiers upper->add_volume(*volume); lower->add_volume(*volume); } else { TriangleMesh upper_mesh, lower_mesh; + + // Transform the mesh by the object transformation matrix + volume->mesh.transform(instance_matrix * volume->get_matrix(true)); + cut_reset_transform(volume); + TriangleMeshSlicer tms(&volume->mesh); tms.cut(z, &upper_mesh, &lower_mesh); @@ -977,7 +1006,7 @@ void ModelObject::cut(coordf_t z, Model* model) const lower_mesh.repair(); upper_mesh.reset_repair_stats(); lower_mesh.reset_repair_stats(); - + if (upper_mesh.facets_count() > 0) { ModelVolume* vol = upper->add_volume(upper_mesh); vol->name = volume->name; @@ -992,6 +1021,15 @@ void ModelObject::cut(coordf_t z, Model* model) const } } } + + upper->invalidate_bounding_box(); + lower->invalidate_bounding_box(); + + ModelObjectPtrs res; + if (upper->volumes.size() > 0) { res.push_back(upper); } + if (lower->volumes.size() > 0) { res.push_back(lower); } + + return res; } void ModelObject::split(ModelObjectPtrs* new_objects) @@ -1011,7 +1049,8 @@ void ModelObject::split(ModelObjectPtrs* new_objects) mesh->repair(); - ModelObject* new_object = m_model->add_object(); + // XXX: this seems to be the only real usage of m_model, maybe refactor this so that it's not needed? + ModelObject* new_object = m_model->add_object(); new_object->name = this->name; new_object->config = this->config; new_object->instances.reserve(this->instances.size()); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 354d71dc46..8e3ee3f306 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -237,7 +237,7 @@ public: size_t materials_count() const; size_t facets_count() const; bool needed_repair() const; - void cut(coordf_t z, Model* model) const; + ModelObjectPtrs cut(size_t instance, coordf_t z); void split(ModelObjectPtrs* new_objects); void repair(); @@ -607,7 +607,7 @@ public: bool delete_object(ModelID id); bool delete_object(ModelObject* object); void clear_objects(); - + ModelMaterial* add_material(t_model_material_id material_id); ModelMaterial* add_material(t_model_material_id material_id, const ModelMaterial &other); ModelMaterial* get_material(t_model_material_id material_id) { diff --git a/src/slic3r.cpp b/src/slic3r.cpp index e9fa54ce03..376ade95a4 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -192,20 +192,21 @@ int main(int argc, char **argv) model.repair(); model.translate(0, 0, - model.bounding_box().min(2)); if (! model.objects.empty()) { - Model out; - model.objects.front()->cut(cli_config.cut, &out); - ModelObject &upper = *out.objects[0]; - ModelObject &lower = *out.objects[1]; - // Use the input name and trim off the extension. - std::string outfile = cli_config.output.value; - if (outfile.empty()) - outfile = model.objects.front()->input_file; - outfile = outfile.substr(0, outfile.find_last_of('.')); - std::cerr << outfile << "\n"; - if (upper.facets_count() > 0) - upper.mesh().write_binary((outfile + "_upper.stl").c_str()); - if (lower.facets_count() > 0) - lower.mesh().write_binary((outfile + "_lower.stl").c_str()); + // XXX + // Model out; + // model.objects.front()->cut(cli_config.cut, &out); + // ModelObject &upper = *out.objects[0]; + // ModelObject &lower = *out.objects[1]; + // // Use the input name and trim off the extension. + // std::string outfile = cli_config.output.value; + // if (outfile.empty()) + // outfile = model.objects.front()->input_file; + // outfile = outfile.substr(0, outfile.find_last_of('.')); + // std::cerr << outfile << "\n"; + // if (upper.facets_count() > 0) + // upper.mesh().write_binary((outfile + "_upper.stl").c_str()); + // if (lower.facets_count() > 0) + // lower.mesh().write_binary((outfile + "_lower.stl").c_str()); } } else if (cli_config.slice) { std::string outfile = cli_config.output.value; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 45c700482e..2350cdffcc 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1915,11 +1915,6 @@ void _3DScene::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape) s_canvas_mgr.set_bed_shape(canvas, shape); } -void _3DScene::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons) -{ - s_canvas_mgr.set_cutting_plane(canvas, z, polygons); -} - void _3DScene::set_color_by(wxGLCanvas* canvas, const std::string& value) { s_canvas_mgr.set_color_by(canvas, value); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 5d81b57bbd..16523af686 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -577,8 +577,6 @@ public: static void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape); - static void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons); - static void set_color_by(wxGLCanvas* canvas, const std::string& value); static bool is_layers_editing_enabled(wxGLCanvas* canvas); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1f8ca9aaee..6e47c08673 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -641,70 +641,6 @@ void GLCanvas3D::Axes::render(bool depth_test) const ::glEnd(); } -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, (float)scale_(0.1)); - Lines lines = to_lines(expolygons); - return m_lines.set_from_lines(lines, m_z); -} - -void GLCanvas3D::CuttingPlane::render(const BoundingBoxf3& bb) const -{ - _render_plane(bb); - _render_contour(); -} - -void GLCanvas3D::CuttingPlane::_render_plane(const BoundingBoxf3& bb) const -{ - if (m_z >= 0.0f) - { - ::glDisable(GL_CULL_FACE); - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - float margin = 20.0f; - float min_x = bb.min(0) - margin; - float max_x = bb.max(0) + margin; - float min_y = bb.min(1) - margin; - float max_y = bb.max(1) + 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() const -{ - ::glEnableClientState(GL_VERTEX_ARRAY); - - if (m_z >= 0.0f) - { - unsigned int lines_vcount = m_lines.get_vertices_count(); - - ::glLineWidth(2.0f); - ::glColor3f(0.0f, 0.0f, 0.0f); - ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_lines.get_vertices()); - ::glDrawArrays(GL_LINES, 0, (GLsizei)lines_vcount); - } - - ::glDisableClientState(GL_VERTEX_ARRAY); -} GLCanvas3D::Shader::Shader() : m_shader(nullptr) @@ -2380,6 +2316,13 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); + gizmo = new GLGizmoCut(parent); + if (! gizmo->init()) { + return false; + } + + m_gizmos.insert({ Cut, gizmo }); + gizmo = new GLGizmoSlaSupports(parent); if (gizmo == nullptr) return false; @@ -2391,7 +2334,6 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo)); - return true; } @@ -2764,6 +2706,13 @@ void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas) const ::glPopMatrix(); } +void GLCanvas3D::Gizmos::create_external_gizmo_widgets(wxWindow *parent) +{ + for (auto &entry : m_gizmos) { + entry.second->create_external_gizmo_widgets(parent); + } +} + void GLCanvas3D::Gizmos::_reset() { for (GizmosMap::value_type& gizmo : m_gizmos) @@ -3166,6 +3115,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) , m_regenerate_volumes(true) , m_color_by("volume") , m_reload_delayed(false) + , m_external_gizmo_widgets_parent(nullptr) { if (m_canvas != nullptr) { @@ -3267,8 +3217,16 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) if (!m_volumes.empty()) m_volumes.finalize_geometry(m_use_VBOs); - if (m_gizmos.is_enabled() && !m_gizmos.init(*this)) - return false; + if (m_gizmos.is_enabled()) { + if (! m_gizmos.init(*this)) { + return false; + } + + if (m_external_gizmo_widgets_parent != nullptr) { + m_gizmos.create_external_gizmo_widgets(m_external_gizmo_widgets_parent); + m_canvas->GetParent()->Layout(); + } + } if (!_init_toolbar()) return false; @@ -3371,11 +3329,6 @@ void GLCanvas3D::set_axes_length(float length) m_axes.length = length; } -void GLCanvas3D::set_cutting_plane(float z, const ExPolygons& polygons) -{ - m_cutting_plane.set(z, polygons); -} - void GLCanvas3D::set_color_by(const std::string& value) { m_color_by = value; @@ -3629,7 +3582,6 @@ void GLCanvas3D::render() #endif // ENABLE_GIZMOS_ON_TOP _render_current_gizmo(); - _render_cutting_plane(); #if ENABLE_SHOW_CAMERA_TARGET _render_camera_target(); #endif // ENABLE_SHOW_CAMERA_TARGET @@ -4524,6 +4476,11 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) const } } +void GLCanvas3D::set_external_gizmo_widgets_parent(wxWindow *parent) +{ + m_external_gizmo_widgets_parent = parent; +} + bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; @@ -4624,14 +4581,6 @@ bool GLCanvas3D::_init_toolbar() if (!m_toolbar.add_item(item)) return false; - item.name = "cut"; - item.tooltip = GUI::L_str("Cut..."); - item.sprite_id = 7; - item.is_toggable = false; - item.action_event = EVT_GLTOOLBAR_CUT; - if (!m_toolbar.add_item(item)) - return false; - if (!m_toolbar.add_separator()) return false; @@ -5030,11 +4979,6 @@ void GLCanvas3D::_render_selection() const m_selection.render(); } -void GLCanvas3D::_render_cutting_plane() const -{ - m_cutting_plane.render(volumes_bounding_box()); -} - void GLCanvas3D::_render_warning_texture() const { if (!m_warning_texture_enabled) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 3f76f5b4e7..cf7c840854 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -16,6 +16,7 @@ class wxKeyEvent; class wxMouseEvent; class wxTimerEvent; class wxPaintEvent; +class wxGLCanvas; namespace Slic3r { @@ -219,23 +220,6 @@ class GLCanvas3D void render(bool depth_test) const; }; - class CuttingPlane - { - float m_z; - GeometryBuffer m_lines; - - public: - CuttingPlane(); - - bool set(float z, const ExPolygons& polygons); - - void render(const BoundingBoxf3& bb) const; - - private: - void _render_plane(const BoundingBoxf3& bb) const; - void _render_contour() const; - }; - class Shader { GLShader* m_shader; @@ -479,6 +463,8 @@ public: Selection(); void set_volumes(GLVolumePtrs* volumes); + + Model* get_model() const { return m_model; } void set_model(Model* model); EMode get_mode() const { return m_mode; } @@ -580,6 +566,7 @@ private: Rotate, Flatten, SlaSupports, + Cut, Num_Types }; @@ -642,6 +629,8 @@ private: void render_overlay(const GLCanvas3D& canvas) const; + void create_external_gizmo_widgets(wxWindow *parent); + private: void _reset(); @@ -698,7 +687,6 @@ private: Camera m_camera; Bed m_bed; Axes m_axes; - CuttingPlane m_cutting_plane; LayersEditing m_layers_editing; Shader m_shader; Mouse m_mouse; @@ -734,6 +722,8 @@ private: GCodePreviewVolumeIndex m_gcode_preview_volume_index; + wxWindow *m_external_gizmo_widgets_parent; + void post_event(wxEvent &&event); void viewport_changed(); @@ -775,8 +765,6 @@ public: void set_axes_length(float length); - void set_cutting_plane(float z, const ExPolygons& polygons); - void set_color_by(const std::string& value); float get_camera_zoom() const; @@ -855,6 +843,8 @@ public: void set_tooltip(const std::string& tooltip) const; + void set_external_gizmo_widgets_parent(wxWindow *parent); + private: bool _is_shown_on_screen() const; void _force_zoom_to_bed(); @@ -881,7 +871,6 @@ private: void _render_axes(bool depth_test) const; void _render_objects() const; void _render_selection() const; - void _render_cutting_plane() const; void _render_warning_texture() const; void _render_legend_texture() const; void _render_layer_editing_overlay() const; diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 7172195200..abf7834605 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -293,13 +293,6 @@ void GLCanvas3DManager::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape) it->second->set_bed_shape(shape); } -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); -} - void GLCanvas3DManager::set_color_by(wxGLCanvas* canvas, const std::string& value) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index 237d3558c4..097d3a118f 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -99,8 +99,6 @@ public: void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape); - void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons); - void set_color_by(wxGLCanvas* canvas, const std::string& value); bool is_layers_editing_enabled(wxGLCanvas* canvas) const; diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 8cbb850685..b8988077e7 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1,4 +1,4 @@ -#include "../../libslic3r/libslic3r.h" +#include "libslic3r/libslic3r.h" #include "GLGizmo.hpp" #include "GUI.hpp" @@ -8,15 +8,29 @@ #include "PresetBundle.hpp" #include -#include "../../libslic3r/Geometry.hpp" +#include "libslic3r/Geometry.hpp" #include #include #include -#include +#include #include +#include + +#include +#include +#include +#include +#include +#include + +#include "GUI.hpp" +#include "GUI_Utils.hpp" +#include "GUI_App.hpp" + +// TODO: Display tooltips quicker on Linux static const float DEFAULT_BASE_COLOR[3] = { 0.625f, 0.625f, 0.625f }; static const float DEFAULT_DRAG_COLOR[3] = { 1.0f, 1.0f, 1.0f }; @@ -252,6 +266,8 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const } } +void GLGizmoBase::create_external_gizmo_widgets(wxWindow *parent) {} + void GLGizmoBase::set_tooltip(const std::string& tooltip) const { m_parent.set_tooltip(tooltip); @@ -259,9 +275,10 @@ void GLGizmoBase::set_tooltip(const std::string& tooltip) const std::string GLGizmoBase::format(float value, unsigned int decimals) const { - char buf[1024]; - ::sprintf(buf, "%.*f", decimals, value); - return buf; + size_t needed_size = std::snprintf(nullptr, 0, "%.*f", decimals, value); + std::string res(needed_size, '\0'); + std::snprintf(&res.front(), res.size(), "%.*f", decimals, value); + return res; } const float GLGizmoRotate::Offset = 5.0f; @@ -1770,5 +1787,237 @@ std::string GLGizmoSlaSupports::on_get_name() const return L("SLA Support Points"); } + + +// GLGizmoCut + +class GLGizmoCutPanel : public wxPanel +{ +public: + GLGizmoCutPanel(wxWindow *parent); + + void display(bool display); +private: + bool m_active; + wxCheckBox *m_cb_rotate; + wxButton *m_btn_cut; + wxButton *m_btn_cancel; +}; + +GLGizmoCutPanel::GLGizmoCutPanel(wxWindow *parent) + : wxPanel(parent) + , m_active(false) + , m_cb_rotate(new wxCheckBox(this, wxID_ANY, _(L("Rotate lower part upwards")))) + , m_btn_cut(new wxButton(this, wxID_OK, _(L("Perform cut")))) + , m_btn_cancel(new wxButton(this, wxID_CANCEL, _(L("Cancel")))) +{ + enum { MARGIN = 5 }; + + auto *sizer = new wxBoxSizer(wxHORIZONTAL); + + auto *label = new wxStaticText(this, wxID_ANY, _(L("Cut object:"))); + sizer->Add(label, 0, wxALL | wxALIGN_CENTER, MARGIN); + sizer->Add(m_cb_rotate, 0, wxALL | wxALIGN_CENTER, MARGIN); + sizer->AddStretchSpacer(); + sizer->Add(m_btn_cut, 0, wxALL | wxALIGN_CENTER, MARGIN); + sizer->Add(m_btn_cancel, 0, wxALL | wxALIGN_CENTER, MARGIN); + + SetSizer(sizer); +} + +void GLGizmoCutPanel::display(bool display) +{ + Show(display); + GetParent()->Layout(); +} + + +const double GLGizmoCut::Offset = 10.0; +const double GLGizmoCut::Margin = 20.0; +const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 }; + +GLGizmoCut::GLGizmoCut(GLCanvas3D& parent) + : GLGizmoBase(parent) + , m_cut_z(0.0) + , m_panel(nullptr) +{} + +void GLGizmoCut::create_external_gizmo_widgets(wxWindow *parent) +{ + wxASSERT(m_panel == nullptr); + + m_panel = new GLGizmoCutPanel(parent); + parent->GetSizer()->Add(m_panel, 0, wxEXPAND); + + parent->Layout(); + parent->Fit(); + auto prev_heigh = parent->GetMinSize().GetHeight(); + parent->SetMinSize(wxSize(-1, std::max(prev_heigh, m_panel->GetSize().GetHeight()))); + + m_panel->Hide(); + m_panel->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + perform_cut(); + }, wxID_OK); +} + +bool GLGizmoCut::on_init() +{ + // TODO: icon + + std::string path = resources_dir() + "/icons/overlay/"; + + if (!m_textures[Off].load_from_file(path + "cut_off.png", false)) { + return false; + } + + if (!m_textures[Hover].load_from_file(path + "cut_hover.png", false)) { + return false; + } + + if (!m_textures[On].load_from_file(path + "cut_on.png", false)) { + return false; + } + + m_grabbers.emplace_back(); + + return true; +} + +std::string GLGizmoCut::on_get_name() const +{ + return L("Cut"); +} + +void GLGizmoCut::on_set_state() +{ + // Reset m_cut_z on gizmo activation + if (get_state() == On) { + m_cut_z = 0.0; + } + + // Display or hide the extra panel + if (m_panel != nullptr) { + m_panel->display(get_state() == On); + } +} + +bool GLGizmoCut::on_is_activable(const GLCanvas3D::Selection& selection) const +{ + return selection.is_single_full_instance() && !selection.is_wipe_tower(); +} + +void GLGizmoCut::on_start_dragging(const GLCanvas3D::Selection& selection) +{ + if (m_hover_id == -1) { return; } + + const BoundingBoxf3& box = selection.get_bounding_box(); + m_start_z = m_cut_z; + m_max_z = box.size()(2) / 2.0; + m_drag_pos = m_grabbers[m_hover_id].center; + m_drag_center = box.center(); + m_drag_center(2) += m_cut_z; +} + +void GLGizmoCut::on_update(const UpdateData& data) +{ + if (m_hover_id != -1) { + // Clamp the plane to the object's bounding box + const double new_z = m_start_z + calc_projection(data.mouse_ray); + m_cut_z = std::max(-m_max_z, std::min(m_max_z, new_z)); + } +} + +void GLGizmoCut::on_render(const GLCanvas3D::Selection& selection) const +{ + if (m_grabbers[0].dragging) { + set_tooltip("Z: " + format(m_cut_z, 2)); + } + + const BoundingBoxf3& box = selection.get_bounding_box(); + Vec3d plane_center = box.center(); + plane_center(2) += m_cut_z; + + const float min_x = box.min(0) - Margin; + const float max_x = box.max(0) + Margin; + const float min_y = box.min(1) - Margin; + const float max_y = box.max(1) + Margin; + ::glEnable(GL_DEPTH_TEST); + ::glDisable(GL_CULL_FACE); + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Draw the cutting plane + ::glBegin(GL_QUADS); + ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glVertex3f(min_x, min_y, plane_center(2)); + ::glVertex3f(max_x, min_y, plane_center(2)); + ::glVertex3f(max_x, max_y, plane_center(2)); + ::glVertex3f(min_x, max_y, plane_center(2)); + ::glEnd(); + + ::glEnable(GL_CULL_FACE); + ::glDisable(GL_BLEND); + + // TODO: draw cut part contour? + + // Draw the grabber and the connecting line + m_grabbers[0].center = plane_center; + m_grabbers[0].center(2) = plane_center(2) + Offset; + + ::glDisable(GL_DEPTH_TEST); + ::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f); + ::glColor3f(1.0, 1.0, 0.0); + ::glBegin(GL_LINES); + ::glVertex3dv(plane_center.data()); + ::glVertex3dv(m_grabbers[0].center.data()); + ::glEnd(); + + std::copy(std::begin(GrabberColor), std::end(GrabberColor), m_grabbers[0].color); + m_grabbers[0].render(m_hover_id == 0, box.max_size()); +} + +void GLGizmoCut::on_render_for_picking(const GLCanvas3D::Selection& selection) const +{ + ::glDisable(GL_DEPTH_TEST); + + render_grabbers_for_picking(selection.get_bounding_box()); +} + +void GLGizmoCut::perform_cut() +{ + const auto &selection = m_parent.get_selection(); + + const auto instance_idx = selection.get_instance_idx(); + const auto object_idx = selection.get_object_idx(); + + wxCHECK_RET(instance_idx >= 0 && object_idx >= 0, "GLGizmoCut: Invalid object selection"); + + wxGetApp().plater()->cut(object_idx, instance_idx, m_cut_z); +} + +double GLGizmoCut::calc_projection(const Linef3& mouse_ray) const +{ + double projection = 0.0; + + const Vec3d starting_vec = m_drag_pos - m_drag_center; + const double len_starting_vec = starting_vec.norm(); + if (len_starting_vec != 0.0) + { + Vec3d mouse_dir = mouse_ray.unit_vector(); + // finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position + // use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection algebric form + // in our case plane normal and ray direction are the same (orthogonal view) + // when moving to perspective camera the negative z unit axis of the camera needs to be transformed in world space and used as plane normal + Vec3d inters = mouse_ray.a + (m_drag_pos - mouse_ray.a).dot(mouse_dir) / mouse_dir.squaredNorm() * mouse_dir; + // vector from the starting position to the found intersection + Vec3d inters_vec = inters - m_drag_pos; + + // finds projection of the vector along the staring direction + projection = inters_vec.dot(starting_vec.normalized()); + } + return projection; +} + + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index eac9693bcb..376c286904 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -6,7 +6,13 @@ #include "../../libslic3r/Point.hpp" #include "../../libslic3r/BoundingBox.hpp" +#include #include +#include + + +class wxWindow; + namespace Slic3r { @@ -120,6 +126,8 @@ public: void render(const GLCanvas3D::Selection& selection) const { on_render(selection); } void render_for_picking(const GLCanvas3D::Selection& selection) const { on_render_for_picking(selection); } + virtual void create_external_gizmo_widgets(wxWindow *parent); + protected: virtual bool on_init() = 0; virtual std::string on_get_name() const = 0; @@ -450,6 +458,43 @@ protected: bool on_is_activable(const GLCanvas3D::Selection& selection) const override; }; + +class GLGizmoCutPanel; + +class GLGizmoCut : public GLGizmoBase +{ + static const double Offset; + static const double Margin; + static const std::array GrabberColor; + + double m_cut_z; + double m_start_z; + double m_max_z; + Vec3d m_drag_pos; + Vec3d m_drag_center; + GLGizmoCutPanel *m_panel; + +public: + explicit GLGizmoCut(GLCanvas3D& parent); + + virtual void create_external_gizmo_widgets(wxWindow *parent); + +protected: + virtual bool on_init(); + virtual std::string on_get_name() const; + virtual void on_set_state(); + virtual bool on_is_activable(const GLCanvas3D::Selection& selection) const; + virtual void on_start_dragging(const GLCanvas3D::Selection& selection); + virtual void on_update(const UpdateData& data); + virtual void on_render(const GLCanvas3D::Selection& selection) const; + virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const; + +private: + void perform_cut(); + double calc_projection(const Linef3& mouse_ray) const; +}; + + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 26ca4a4dca..0e99f88ff8 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -24,7 +24,6 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_VOLUMES, SimpleEvent); -wxDEFINE_EVENT(EVT_GLTOOLBAR_CUT, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent); diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 6669bc9664..dde62c6452 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -24,7 +24,6 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_VOLUMES, SimpleEvent); -wxDECLARE_EVENT(EVT_GLTOOLBAR_CUT, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent); class GLToolbarItem diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index c9fa96f4c6..43b3c38f71 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -15,6 +15,18 @@ namespace Slic3r { namespace GUI { +wxTopLevelWindow* find_toplevel_parent(wxWindow *window) +{ + for (; window != nullptr; window = window->GetParent()) { + if (window->IsTopLevel()) { + return dynamic_cast(window); + } + } + + return nullptr; +} + + CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index fe96e5a1b8..9cee986b0c 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -6,6 +6,7 @@ #include +#include #include #include #include @@ -19,6 +20,48 @@ namespace Slic3r { namespace GUI { +wxTopLevelWindow* find_toplevel_parent(wxWindow *window); + + +class EventGuard +{ +public: + EventGuard() {} + EventGuard(const EventGuard&) = delete; + EventGuard(EventGuard &&other) : unbinder(std::move(other.unbinder)) {} + + ~EventGuard() { + if (unbinder) { + unbinder(false); + } + } + + template void bind(wxEvtHandler *emitter, const EvTag &type, Fun fun) + { + // This is a way to type-erase both the event type as well as the handler: + + unbinder = std::move([=](bool bind) { + if (bind) { + emitter->Bind(type, fun); + } else { + emitter->Unbind(type, fun); + } + }); + + unbinder(true); + } + + EventGuard& operator=(const EventGuard&) = delete; + EventGuard& operator=(EventGuard &&other) + { + unbinder.swap(other.unbinder); + return *this; + } +private: + std::function unbinder; +}; + + class CheckboxFileDialog : public wxFileDialog { public: diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index c5883dcf52..85ac442f71 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "Tab.hpp" @@ -100,7 +101,6 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL }); update_ui_from_settings(); - return; } void MainFrame::init_tabpanel() diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 7722d0b65f..b324586c45 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -81,6 +81,7 @@ public: MainFrame(const bool no_plater, const bool loaded); ~MainFrame() {} + Plater* plater() { return m_plater; } void init_tabpanel(); const std::map& options_tabs() const { return m_options_tabs; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7768df7dd5..cb0e04e37c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -20,7 +20,8 @@ #include #include #include -#include +#include +#include #include "libslic3r/libslic3r.h" #include "libslic3r/PrintConfig.hpp" @@ -881,6 +882,7 @@ struct Plater::priv // GUI elements wxNotebook *notebook; Sidebar *sidebar; + wxWindow *panel3d; wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can Preview *preview; @@ -959,7 +961,6 @@ struct Plater::priv void on_action_add(SimpleEvent&); void on_action_split_objects(SimpleEvent&); void on_action_split_volumes(SimpleEvent&); - void on_action_cut(SimpleEvent&); void on_action_layersediting(SimpleEvent&); void on_object_select(SimpleEvent&); @@ -978,7 +979,6 @@ private: bool can_decrease_instances() const; bool can_split_to_objects() const; bool can_split_to_volumes() const; - bool can_cut_object() const; bool layers_height_allowed() const; bool can_delete_all() const; bool can_arrange() const; @@ -988,19 +988,20 @@ private: const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase); const std::regex Plater::priv::pattern_3mf(".*3mf", std::regex::icase); const std::regex Plater::priv::pattern_zip_amf(".*[.]zip[.]amf", std::regex::icase); -Plater::priv::priv(Plater *q, MainFrame *main_frame) : - q(q), - main_frame(main_frame), - config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ +Plater::priv::priv(Plater *q, MainFrame *main_frame) + : q(q) + , main_frame(main_frame) + , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ "bed_shape", "complete_objects", "extruder_clearance_radius", "skirts", "skirt_distance", "brim_width", "variable_layer_height", "serial_port", "serial_speed", "host_type", "print_host", "printhost_apikey", "printhost_cafile", "nozzle_diameter", "single_extruder_multi_material", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", - "extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology" - })), - notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)), - sidebar(new Sidebar(q)), - canvas3D(GLCanvas3DManager::create_wxglcanvas(notebook)) + "extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology" + })) + , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) + , sidebar(new Sidebar(q)) + , panel3d(new wxWindow(notebook, wxID_ANY)) + , canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) #if ENABLE_NEW_MENU_LAYOUT , project_filename(wxEmptyString) #endif // ENABLE_NEW_MENU_LAYOUT @@ -1027,9 +1028,19 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) : _3DScene::add_canvas(canvas3D); _3DScene::allow_multisample(canvas3D, GLCanvas3DManager::can_multisample()); - notebook->AddPage(canvas3D, _(L("3D"))); + + auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); + panel3dsizer->Add(canvas3D, 1, wxEXPAND); + auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); + panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL)); + panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND); + + panel3d->SetSizer(panel3dsizer); + notebook->AddPage(panel3d, _(L("3D"))); preview = new GUI::Preview(notebook, config, &print, &gcode_preview_data, [this](){ schedule_background_process(); }); + _3DScene::get_canvas(canvas3D)->set_external_gizmo_widgets_parent(panel_gizmo_widgets); + // XXX: If have OpenGL _3DScene::enable_picking(canvas3D, true); _3DScene::enable_moving(canvas3D, true); @@ -1092,7 +1103,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) : canvas3D->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); }); canvas3D->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); canvas3D->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); - canvas3D->Bind(EVT_GLTOOLBAR_CUT, &priv::on_action_cut, this); canvas3D->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); // Preview events: @@ -1475,7 +1485,6 @@ void Plater::priv::selection_changed() _3DScene::enable_toolbar_item(canvas3D, "fewer", can_decrease_instances()); _3DScene::enable_toolbar_item(canvas3D, "splitobjects", can_split_to_objects()); _3DScene::enable_toolbar_item(canvas3D, "splitvolumes", can_split_to_volumes()); - _3DScene::enable_toolbar_item(canvas3D, "cut", can_cut_object()); _3DScene::enable_toolbar_item(canvas3D, "layersediting", layers_height_allowed()); // forces a frame render to update the view (to avoid a missed update if, for example, the context menu appears) _3DScene::render(canvas3D); @@ -1970,11 +1979,6 @@ void Plater::priv::on_action_split_volumes(SimpleEvent&) split_volume(); } -void Plater::priv::on_action_cut(SimpleEvent&) -{ - // TODO -} - void Plater::priv::on_action_layersediting(SimpleEvent&) { bool enable = !_3DScene::is_layers_editing_enabled(canvas3D); @@ -2114,12 +2118,6 @@ bool Plater::priv::can_split_to_volumes() const return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && !model.objects[obj_idx]->is_multiparts(); } -bool Plater::priv::can_cut_object() const -{ - int obj_idx = get_selected_object_idx(); - return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()); -} - bool Plater::priv::layers_height_allowed() const { int obj_idx = get_selected_object_idx(); @@ -2313,6 +2311,21 @@ void Plater::set_number_of_copies(/*size_t num*/) decrease_instances(-diff); } +void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z) +{ + wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds"); + auto *object = p->model.objects[obj_idx]; + + wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds"); + + const auto new_objects = object->cut(instance_idx, z); + + remove(obj_idx); + p->load_model_objects(new_objects); + + p->arrange(); +} + void Plater::export_gcode(fs::path output_path) { if (p->model.objects.empty()) diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index f23fbe72f3..d6716c620a 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -135,6 +135,8 @@ public: void decrease_instances(size_t num = 1); void set_number_of_copies(/*size_t num*/); + void cut(size_t obj_idx, size_t instance_idx, coordf_t z); + // Note: empty path means "use the default" void export_gcode(boost::filesystem::path output_path = boost::filesystem::path()); void export_stl(); From 6430fb2ec2c5cb0f6c66ffe3c7cfb2d0f9a09bdd Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 19 Nov 2018 11:17:51 +0100 Subject: [PATCH 03/23] Connecting UI parameters to the calculation input. * I also added temporary default values in PrintConfig to not get random values. --- src/libslic3r/PrintConfig.hpp | 37 ++++++++++++++-------------- src/libslic3r/SLA/SLASupportTree.hpp | 2 +- src/libslic3r/SLAPrint.cpp | 16 ++++++++++-- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e5b6da0a12..4a4d9535ad 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -905,46 +905,47 @@ public: ConfigOptionFloat layer_height; // Radius in mm of the pointing side of the head. - ConfigOptionFloat support_head_front_radius /*= 0.2*/; + ConfigOptionFloat support_head_front_radius = 0.2; // How much the pinhead has to penetrate the model surface - ConfigOptionFloat support_head_penetraiton /*= 0.2*/; + ConfigOptionFloat support_head_penetraiton = 0.2; - // Radius of the back side of the 3d arrow. - ConfigOptionFloat support_head_back_radius /*= 0.5*/; + // Radius of the back side of the 3d arrow. TODO: consider renaming this + // to actual pillar radius, because that's what it boils down to. + ConfigOptionFloat support_head_back_radius = 0.5; // Width in mm from the back sphere center to the front sphere center. - ConfigOptionFloat support_head_width /*= 1.0*/; + ConfigOptionFloat support_head_width = 1.0; // Radius in mm of the support pillars. - // TODO: This parameter is invalid. The pillar radius will be dynamic in + // TODO: This parameter is questionable. The pillar radius will be dynamic in // nature. Merged pillars will have an increased thickness. This parameter // may serve as the maximum radius, or maybe an increase when two are merged // The default radius will be derived from head_back_radius_mm - ConfigOptionFloat support_pillar_radius /*= 0.8*/; + ConfigOptionFloat support_pillar_radius = 0.8; // Radius in mm of the pillar base. - ConfigOptionFloat support_base_radius /*= 2.0*/; + ConfigOptionFloat support_base_radius = 2.0; // The height of the pillar base cone in mm. - ConfigOptionFloat support_base_height /*= 1.0*/; + ConfigOptionFloat support_base_height = 1.0; // The default angle for connecting support sticks and junctions. - ConfigOptionFloat support_critical_angle /*= M_PI/4*/; + ConfigOptionFloat support_critical_angle = 45; // The max length of a bridge in mm - ConfigOptionFloat support_max_bridge_length /*= 15.0*/; + ConfigOptionFloat support_max_bridge_length = 15.0; // The elevation in Z direction upwards. This is the space between the pad - // and the model object's bounding box bottom. - ConfigOptionFloat support_object_elevation; + // and the model object's bounding box bottom. Units in mm. + ConfigOptionFloat support_object_elevation = 5.0; - // Now for the base pool (plate) /////////////////////////////////////////// + // Now for the base pool (pad) ///////////////////////////////////////////// - ConfigOptionFloat pad_wall_thickness /*= 2*/; - ConfigOptionFloat pad_wall_height /*= 5*/; - ConfigOptionFloat pad_max_merge_distance /*= 50*/; - ConfigOptionFloat pad_edge_radius /*= 1*/; + ConfigOptionFloat pad_wall_thickness= 2; + ConfigOptionFloat pad_wall_height = 5; + ConfigOptionFloat pad_max_merge_distance = 50; + ConfigOptionFloat pad_edge_radius = 1; protected: void initialize(StaticCacheBase &cache, const char *base_ptr) diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index f0605a356f..5cf59571a1 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -33,7 +33,7 @@ struct SupportConfig { double head_front_radius_mm = 0.2; // How much the pinhead has to penetrate the model surface - double head_penetraiton = 0.2; + double head_penetraiton_mm = 0.2; // Radius of the back side of the 3d arrow. double head_back_radius_mm = 0.5; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index e209720a0a..f93187cf9a 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -169,7 +169,17 @@ void SLAPrint::process() auto& emesh = po.m_supportdata->emesh; auto& pts = po.m_supportdata->support_points; // nowhere filled yet try { - SupportConfig scfg; // TODO fill or replace with po.m_config + sla::SupportConfig scfg; + SLAPrintObjectConfig& c = po.m_config; + + scfg.head_front_radius_mm = c.support_head_front_radius.getFloat(); + scfg.head_back_radius_mm = c.support_head_back_radius.getFloat(); + scfg.head_penetraiton_mm = c.support_head_penetraiton.getFloat(); + scfg.head_width_mm = c.support_head_width.getFloat(); + scfg.object_elevation_mm = c.support_object_elevation.getFloat(); + scfg.tilt = c.support_critical_angle.getFloat() * 180.0 / PI; + scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); + scfg.pillar_radius_mm = c.support_pillar_radius.getFloat(); sla::Controller ctl; ctl.statuscb = [this](unsigned st, const std::string& msg) { @@ -445,8 +455,10 @@ double SLAPrintObject::get_elevation() const { const std::vector &SLAPrintObject::get_support_slices() const { - if(!m_supportdata) return {}; + // I don't want to return a copy but the points may not exist, so ... + static const std::vector dummy_empty; + if(!m_supportdata) return dummy_empty; return m_supportdata->support_slices; } From b950e9e575686cfb6135d50854d7433092e41fb6 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 19 Nov 2018 11:07:39 +0100 Subject: [PATCH 04/23] Fix build --- src/libslic3r/Utils.hpp | 2 ++ src/libslic3r/utils.cpp | 21 +++++++++++++++++++++ src/slic3r/GUI/GLGizmo.cpp | 5 +---- xs/xsp/Model.xsp | 6 ------ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 0fbad537cc..7f2c94f034 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -68,6 +68,8 @@ namespace PerlUtils { extern std::string path_to_parent_path(const char *src); }; +std::string string_printf(const char *format, ...); + // Timestamp formatted for header_slic3r_generated(). extern std::string timestamp_str(); // Standard "generated by Slic3r version xxx timestamp xxx" header string, diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 466df8a352..7a51a61046 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #ifdef WIN32 #include @@ -297,6 +299,25 @@ namespace PerlUtils { std::string path_to_parent_path(const char *src) { return boost::filesystem::path(src).parent_path().string(); } }; + +std::string string_printf(const char *format, ...) +{ + va_list args1; + va_start(args1, format); + va_list args2; + va_copy(args2, args1); + + size_t needed_size = ::vsnprintf(nullptr, 0, format, args1) + 1; + va_end(args1); + + std::string res(needed_size, '\0'); + ::vsnprintf(&res.front(), res.size(), format, args2); + va_end(args2); + + return res; +} + + std::string timestamp_str() { const auto now = boost::posix_time::second_clock::local_time(); diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index b8988077e7..54dd1427da 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -275,10 +275,7 @@ void GLGizmoBase::set_tooltip(const std::string& tooltip) const std::string GLGizmoBase::format(float value, unsigned int decimals) const { - size_t needed_size = std::snprintf(nullptr, 0, "%.*f", decimals, value); - std::string res(needed_size, '\0'); - std::snprintf(&res.front(), res.size(), "%.*f", decimals, value); - return res; + return Slic3r::string_printf("%.*f", decimals, value); } const float GLGizmoRotate::Offset = 5.0f; diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp index ffcb81defc..6091d00ad4 100644 --- a/xs/xsp/Model.xsp +++ b/xs/xsp/Model.xsp @@ -231,12 +231,6 @@ ModelMaterial::attributes() void rotate(float angle, Vec3d* axis) %code{% THIS->rotate(angle, *axis); %}; void mirror(Axis axis); - - Model* cut(double z) - %code%{ - RETVAL = new Model(); - THIS->cut(z, RETVAL); - %}; ModelObjectPtrs* split_object() %code%{ From 1f546de59a88563992ea53a33d67536228c698f9 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 19 Nov 2018 11:42:36 +0100 Subject: [PATCH 05/23] Fix for elevation and added functionality for head penetration. --- src/libslic3r/SLA/SLASupportTree.cpp | 19 +++++++++++++------ src/libslic3r/SLA/SLASupportTree.hpp | 3 ++- src/libslic3r/SLAPrint.cpp | 16 ++++++++-------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index a4c5abc9b7..cd2f491c6f 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -213,6 +213,7 @@ struct Head { double r_back_mm = 1; double r_pin_mm = 0.5; double width_mm = 2; + double penetration_mm = 0.5; // For identification purposes. This will be used as the index into the // container holding the head structures. See SLASupportTree::Impl @@ -224,11 +225,13 @@ struct Head { Head(double r_big_mm, double r_small_mm, double length_mm, + double penetration, Vec3d direction = {0, 0, -1}, // direction (normal to the dull end ) Vec3d offset = {0, 0, 0}, // displacement const size_t circlesteps = 45): steps(circlesteps), dir(direction), tr(offset), - r_back_mm(r_big_mm), r_pin_mm(r_small_mm), width_mm(length_mm) + r_back_mm(r_big_mm), r_pin_mm(r_small_mm), width_mm(length_mm), + penetration_mm(penetration) { // We create two spheres which will be connected with a robe that fits @@ -281,7 +284,7 @@ struct Head { // To simplify further processing, we translate the mesh so that the // last vertex of the pointing sphere (the pinpoint) will be at (0,0,0) - for(auto& p : mesh.points) { z(p) -= (h + 0.5 * r_small_mm); } + for(auto& p : mesh.points) z(p) -= (h + r_small_mm - penetration_mm); } void transform() @@ -298,11 +301,11 @@ struct Head { } double fullwidth() const { - return 1.5 * r_pin_mm + width_mm + 2*r_back_mm; + return 2 * r_pin_mm + width_mm + 2*r_back_mm - penetration_mm; } Vec3d junction_point() const { - return tr + ( 1.5 * r_pin_mm + width_mm + r_back_mm)*dir; + return tr + ( 2 * r_pin_mm + width_mm + r_back_mm - penetration_mm)*dir; } double request_pillar_radius(double radius) const { @@ -540,7 +543,8 @@ EigenMesh3D to_eigenmesh(const Contour3D& cntr) { void create_head(TriangleMesh& out, double r1_mm, double r2_mm, double width_mm) { - Head head(r1_mm, r2_mm, width_mm, {0, std::sqrt(0.5), -std::sqrt(0.5)}, + Head head(r1_mm, r2_mm, width_mm, 0, + {0, std::sqrt(0.5), -std::sqrt(0.5)}, {0, 0, 30}); out.merge(mesh(head.mesh)); @@ -1154,6 +1158,7 @@ bool SLASupportTree::generate(const PointSet &points, cfg.head_back_radius_mm, cfg.head_front_radius_mm, cfg.head_width_mm, + cfg.head_penetraiton_mm, nmls.row(i), // dir head_pos.row(i) // displacement ); @@ -1521,6 +1526,7 @@ bool SLASupportTree::generate(const PointSet &points, Head base_head(cfg.head_back_radius_mm, cfg.head_front_radius_mm, cfg.head_width_mm, + cfg.head_penetraiton_mm, {0.0, 0.0, 1.0}, {headend(X), headend(Y), headend(Z) - gh}); @@ -1735,7 +1741,7 @@ double SLASupportTree::get_elevation() const { double ph = m_impl->pad().empty()? 0 : m_impl->pad().cfg.min_wall_height_mm/2.0; - return -m_impl->ground_level + ph; + return m_elevation + ph; } SLASupportTree::SLASupportTree(const Model& model, @@ -1752,6 +1758,7 @@ SLASupportTree::SLASupportTree(const PointSet &points, const Controller &ctl): m_impl(new Impl()), m_ctl(ctl) { + m_elevation = cfg.object_elevation_mm; m_impl->ground_level = emesh.ground_level - cfg.object_elevation_mm; generate(points, emesh, cfg, ctl); } diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index 5cf59571a1..c2f7e6f210 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -33,7 +33,7 @@ struct SupportConfig { double head_front_radius_mm = 0.2; // How much the pinhead has to penetrate the model surface - double head_penetraiton_mm = 0.2; + double head_penetraiton_mm = 0.5; // Radius of the back side of the 3d arrow. double head_back_radius_mm = 0.5; @@ -134,6 +134,7 @@ class SLASupportTree { class Impl; std::unique_ptr m_impl; Controller m_ctl; + double m_elevation = 0; Impl& get() { return *m_impl; } const Impl& get() const { return *m_impl; } diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index f93187cf9a..27566365c7 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -172,14 +172,14 @@ void SLAPrint::process() sla::SupportConfig scfg; SLAPrintObjectConfig& c = po.m_config; - scfg.head_front_radius_mm = c.support_head_front_radius.getFloat(); - scfg.head_back_radius_mm = c.support_head_back_radius.getFloat(); - scfg.head_penetraiton_mm = c.support_head_penetraiton.getFloat(); - scfg.head_width_mm = c.support_head_width.getFloat(); - scfg.object_elevation_mm = c.support_object_elevation.getFloat(); - scfg.tilt = c.support_critical_angle.getFloat() * 180.0 / PI; - scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); - scfg.pillar_radius_mm = c.support_pillar_radius.getFloat(); +// scfg.head_front_radius_mm = c.support_head_front_radius.getFloat(); +// scfg.head_back_radius_mm = c.support_head_back_radius.getFloat(); +// scfg.head_penetraiton_mm = c.support_head_penetraiton.getFloat(); +// scfg.head_width_mm = c.support_head_width.getFloat(); +// scfg.object_elevation_mm = c.support_object_elevation.getFloat(); +// scfg.tilt = c.support_critical_angle.getFloat() * 180.0 / PI; +// scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); +// scfg.pillar_radius_mm = c.support_pillar_radius.getFloat(); sla::Controller ctl; ctl.statuscb = [this](unsigned st, const std::string& msg) { From b1228537d2dfa213d8dee6947483de16b030d1b2 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 19 Nov 2018 11:54:34 +0100 Subject: [PATCH 06/23] Plater: Fix on_notebook_changed --- src/slic3r/GUI/Plater.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cb0e04e37c..29174dca71 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -882,7 +882,7 @@ struct Plater::priv // GUI elements wxNotebook *notebook; Sidebar *sidebar; - wxWindow *panel3d; + wxPanel *panel3d; wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can Preview *preview; @@ -1000,7 +1000,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) })) , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) , sidebar(new Sidebar(q)) - , panel3d(new wxWindow(notebook, wxID_ANY)) + , panel3d(new wxPanel(notebook, wxID_ANY)) , canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) #if ENABLE_NEW_MENU_LAYOUT , project_filename(wxEmptyString) @@ -1819,7 +1819,7 @@ void Plater::priv::fix_through_netfabb(const int obj_idx) void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) { const auto current_id = notebook->GetCurrentPage()->GetId(); - if (current_id == canvas3D->GetId()) { + if (current_id == panel3d->GetId()) { if (_3DScene::is_reload_delayed(canvas3D)) { // Delayed loading of the 3D scene. if (this->printer_technology == ptSLA) { From eb4d1e9d5e41edf245fe63aa659d5a6297f44a58 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 19 Nov 2018 12:20:44 +0100 Subject: [PATCH 07/23] Shift-up volumes after SLA support volumes creation --- src/slic3r/GUI/GLCanvas3D.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2ffcf8ad80..dc3e0d4e27 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3949,9 +3949,17 @@ void GLCanvas3D::reload_scene(bool force) m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, -1, instance_idx); } } - for (size_t istep = 0; istep < sla_steps.size(); ++ istep) - if (! instances[istep].empty()) - m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_use_VBOs && m_initialized); + for (size_t istep = 0; istep < sla_steps.size(); ++istep) + if (!instances[istep].empty()) + m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_use_VBOs && m_initialized); + + // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed + Vec3d shift_z(0.0, 0.0, print_object->get_elevation()); + for (GLVolume* volume : m_volumes.volumes) + { + if (volume->object_idx() == object_idx) + volume->set_instance_offset(volume->get_instance_offset() + shift_z); + } } } From fd5841dd2e2c743c97ca0e87823ad2a700cb8070 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 19 Nov 2018 12:51:02 +0100 Subject: [PATCH 08/23] Cleanup: removing obsolete methods from support tree generation interface --- sandboxes/CMakeLists.txt | 1 - sandboxes/slasupporttree/CMakeLists.txt | 2 - sandboxes/slasupporttree/slasupporttree.cpp | 48 ------- src/libslic3r/SLA/SLASupportTree.cpp | 135 -------------------- src/libslic3r/SLA/SLASupportTree.hpp | 32 +---- 5 files changed, 6 insertions(+), 212 deletions(-) delete mode 100644 sandboxes/slasupporttree/CMakeLists.txt delete mode 100644 sandboxes/slasupporttree/slasupporttree.cpp diff --git a/sandboxes/CMakeLists.txt b/sandboxes/CMakeLists.txt index 5905c438e9..0e1f52d6cf 100644 --- a/sandboxes/CMakeLists.txt +++ b/sandboxes/CMakeLists.txt @@ -1,2 +1 @@ add_subdirectory(slabasebed) -add_subdirectory(slasupporttree) diff --git a/sandboxes/slasupporttree/CMakeLists.txt b/sandboxes/slasupporttree/CMakeLists.txt deleted file mode 100644 index a3323a83de..0000000000 --- a/sandboxes/slasupporttree/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_executable(slasupporttree EXCLUDE_FROM_ALL slasupporttree.cpp) -target_link_libraries(slasupporttree libslic3r) \ No newline at end of file diff --git a/sandboxes/slasupporttree/slasupporttree.cpp b/sandboxes/slasupporttree/slasupporttree.cpp deleted file mode 100644 index 0cfc60f7aa..0000000000 --- a/sandboxes/slasupporttree/slasupporttree.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -#include -#include "TriangleMesh.hpp" -#include "Model.hpp" -#include "callback.hpp" -#include "SLA/SLASupportTree.hpp" -#include "benchmark.h" - -const std::string USAGE_STR = { - "Usage: slasupporttree stlfilename.stl" -}; - -void confess_at(const char * /*file*/, - int /*line*/, - const char * /*func*/, - const char * /*pat*/, - ...) {} - -namespace Slic3r { - -void PerlCallback::deregister_callback() {} -} - -int main(const int argc, const char *argv[]) { - using namespace Slic3r; - using std::cout; using std::endl; - - if(argc < 2) { - cout << USAGE_STR << endl; - return EXIT_SUCCESS; - } - - Benchmark bench; - TriangleMesh result; - - bench.start(); - sla::create_head(result, 3, 1, 4); - bench.stop(); - - cout << "Support tree creation time: " << std::setprecision(10) - << bench.getElapsedSec() << " seconds." << endl; - - result.write_ascii("out.stl"); - - return EXIT_SUCCESS; -} diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index cd2f491c6f..029c45069c 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -541,20 +541,6 @@ EigenMesh3D to_eigenmesh(const Contour3D& cntr) { return emesh; } -void create_head(TriangleMesh& out, double r1_mm, double r2_mm, double width_mm) -{ - Head head(r1_mm, r2_mm, width_mm, 0, - {0, std::sqrt(0.5), -std::sqrt(0.5)}, - {0, 0, 30}); - out.merge(mesh(head.mesh)); - - Pillar cst(head, {0, 0, 0}); - cst.add_base(); - - out.merge(mesh(cst.mesh)); - out.merge(mesh(cst.base)); -} - // The minimum distance for two support points to remain valid. static const double /*constexpr*/ D_SP = 0.1; @@ -597,21 +583,6 @@ EigenMesh3D to_eigenmesh(const ModelObject& modelobj) { return to_eigenmesh(modelobj.raw_mesh()); } -EigenMesh3D to_eigenmesh(const Model& model) { - TriangleMesh combined_mesh; - - for(ModelObject *o : model.objects) { - TriangleMesh tmp = o->raw_mesh(); - for(ModelInstance * inst: o->instances) { - TriangleMesh ttmp(tmp); - inst->transform_mesh(&ttmp); - combined_mesh.merge(ttmp); - } - } - - return to_eigenmesh(combined_mesh); -} - PointSet to_point_set(const std::vector &v) { PointSet ret(v.size(), 3); @@ -623,43 +594,6 @@ Vec3d model_coord(const ModelInstance& object, const Vec3f& mesh_coord) { return object.transform_vector(mesh_coord.cast()); } -PointSet support_points(const Model& model) { - size_t sum = 0; - for(auto *o : model.objects) - sum += o->instances.size() * o->sla_support_points.size(); - - PointSet ret(sum, 3); - - for(ModelObject *o : model.objects) - for(ModelInstance *inst : o->instances) { - int i = 0; - for(Vec3f& msource : o->sla_support_points) { - ret.row(i++) = model_coord(*inst, msource); - } - } - - return ret; -} - -PointSet support_points(const ModelObject& modelobject) -{ - PointSet ret(modelobject.sla_support_points.size(), 3); - auto rot = modelobject.instances.front()->get_rotation(); -// auto scaling = modelobject.instances.front()->get_scaling_factor(); - -// Transform3d tr; -// tr.rotate(Eigen::AngleAxisd(rot(X), Vec3d::UnitX()) * -// Eigen::AngleAxisd(rot(Y), Vec3d::UnitY())); - - long i = 0; - for(const Vec3f& msource : modelobject.sla_support_points) { - Vec3d&& p = msource.cast(); -// p = tr * p; - ret.row(i++) = p; - } - return ret; -} - double ray_mesh_intersect(const Vec3d& s, const Vec3d& dir, const EigenMesh3D& m); @@ -1744,14 +1678,6 @@ double SLASupportTree::get_elevation() const return m_elevation + ph; } -SLASupportTree::SLASupportTree(const Model& model, - const SupportConfig& cfg, - const Controller& ctl): - m_impl(new Impl()), m_ctl(ctl) -{ - generate(support_points(model), to_eigenmesh(model), cfg, ctl); -} - SLASupportTree::SLASupportTree(const PointSet &points, const EigenMesh3D& emesh, const SupportConfig &cfg, @@ -1774,66 +1700,5 @@ SLASupportTree &SLASupportTree::operator=(const SLASupportTree &c) SLASupportTree::~SLASupportTree() {} -void add_sla_supports(Model &model, - const SupportConfig &cfg, - const Controller &ctl) -{ - Benchmark bench; - - bench.start(); - SLASupportTree _stree(model, cfg, ctl); - bench.stop(); - - std::cout << "Support tree creation time: " << bench.getElapsedSec() - << " seconds" << std::endl; - - bench.start(); - ModelObject* o = model.add_object(); - o->add_instance(); - - TriangleMesh streemsh; - _stree.merged_mesh(streemsh); - o->add_volume(streemsh); - - bench.stop(); - std::cout << "support tree added to model in: " << bench.getElapsedSec() - << " seconds" << std::endl; - - // TODO this would roughly be the code for the base pool - ExPolygons plate; - auto modelmesh = model.mesh(); - TriangleMesh poolmesh; - sla::PoolConfig poolcfg; - poolcfg.min_wall_height_mm = 1; - poolcfg.edge_radius_mm = 0.1; - poolcfg.min_wall_thickness_mm = 0.8; - - bench.start(); - sla::base_plate(modelmesh, plate); - bench.stop(); - - std::cout << "Base plate calculation time: " << bench.getElapsedSec() - << " seconds." << std::endl; - - bench.start(); - sla::create_base_pool(plate, poolmesh, poolcfg); - bench.stop(); - - std::cout << "Pool generation completed in " << bench.getElapsedSec() - << " second." << std::endl; - - bench.start(); - poolmesh.translate(.0f, .0f, float(poolcfg.min_wall_height_mm / 2)); - o->add_volume(poolmesh); - bench.stop(); - - // TODO: will cause incorrect placement of the model; -// o->translate({0, 0, poolcfg.min_wall_height_mm / 2}); - - std::cout << "Added pool to model in " << bench.getElapsedSec() - << " seconds." << std::endl; - -} - } } diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index c2f7e6f210..cf61f07b0d 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -90,34 +90,17 @@ struct EigenMesh3D { Eigen::MatrixXd V; Eigen::MatrixXi F; double ground_level = 0; - - // igl crashes with the following data types: -// Eigen::Matrix V; -// Eigen::Matrix F; }; -//using PointSet = Eigen::Matrix; //Eigen::MatrixXd; using PointSet = Eigen::MatrixXd; -/* ************************************************************************** */ -/* TODO: May not be needed: */ -/* ************************************************************************** */ - -void create_head(TriangleMesh&, double r1_mm, double r2_mm, double width_mm); - -/// Add support volumes to the model directly -void add_sla_supports(Model& model, const SupportConfig& cfg = {}, - const Controller& ctl = {}); - EigenMesh3D to_eigenmesh(const TriangleMesh& m); -PointSet to_point_set(const std::vector&); - -// obsolete, not used anymore -EigenMesh3D to_eigenmesh(const Model& model); +// needed for find best rotation EigenMesh3D to_eigenmesh(const ModelObject& model); -PointSet support_points(const ModelObject& modelobject); -PointSet support_points(const Model& model); + +// Simple conversion of 'vector of points' to an Eigen matrix +PointSet to_point_set(const std::vector&); /* ************************************************************************** */ @@ -134,6 +117,8 @@ class SLASupportTree { class Impl; std::unique_ptr m_impl; Controller m_ctl; + + // the only value from config that is also needed after construction double m_elevation = 0; Impl& get() { return *m_impl; } @@ -150,11 +135,6 @@ class SLASupportTree { const Controller& ctl = {}); public: - // Constructors will throw if the stop condition becomes true. - SLASupportTree(const Model& model, - const SupportConfig& cfg = {}, - const Controller& ctl = {}); - SLASupportTree(const PointSet& pts, const EigenMesh3D& em, const SupportConfig& cfg = {}, From dbc9bf5be799a7d81757588eabbe4ac3557b449c Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 19 Nov 2018 13:04:19 +0100 Subject: [PATCH 09/23] Lift-up of SLA volumes only when at least one volume is generated --- src/slic3r/GUI/GLCanvas3D.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8e0065a3a6..da1c9fca5b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3901,16 +3901,24 @@ void GLCanvas3D::reload_scene(bool force) m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, -1, instance_idx); } } + + // stores the current volumes count + size_t volumes_count = m_volumes.volumes.size(); + for (size_t istep = 0; istep < sla_steps.size(); ++istep) if (!instances[istep].empty()) m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_use_VBOs && m_initialized); - // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed - Vec3d shift_z(0.0, 0.0, print_object->get_elevation()); - for (GLVolume* volume : m_volumes.volumes) + if (volumes_count != m_volumes.volumes.size()) { - if (volume->object_idx() == object_idx) - volume->set_instance_offset(volume->get_instance_offset() + shift_z); + // If any volume has been added + // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed + Vec3d shift_z(0.0, 0.0, print_object->get_elevation()); + for (GLVolume* volume : m_volumes.volumes) + { + if (volume->object_idx() == object_idx) + volume->set_instance_offset(volume->get_instance_offset() + shift_z); + } } } } From 60563e6702fff77cf48892c9b7e99d905abc28fc Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 19 Nov 2018 13:05:10 +0100 Subject: [PATCH 10/23] Plater: Revert usage of panel_gizmo_widgets for now --- src/slic3r/GUI/Plater.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 29174dca71..8dc221aad1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -35,7 +35,6 @@ #include "libslic3r/Format/STL.hpp" #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" -//#include "slic3r/AppController.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" @@ -1000,8 +999,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) })) , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) , sidebar(new Sidebar(q)) - , panel3d(new wxPanel(notebook, wxID_ANY)) - , canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) + // , panel3d(new wxPanel(notebook, wxID_ANY)) + , panel3d(nullptr) + // , canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) + , canvas3D(GLCanvas3DManager::create_wxglcanvas(notebook)) #if ENABLE_NEW_MENU_LAYOUT , project_filename(wxEmptyString) #endif // ENABLE_NEW_MENU_LAYOUT @@ -1029,17 +1030,21 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) _3DScene::add_canvas(canvas3D); _3DScene::allow_multisample(canvas3D, GLCanvas3DManager::can_multisample()); - auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); - panel3dsizer->Add(canvas3D, 1, wxEXPAND); - auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); - panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL)); - panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND); + // XXX: reverting panel3d and panel_gizmo_widgets + // ! cf. on_notebook_changed - panel3d->SetSizer(panel3dsizer); - notebook->AddPage(panel3d, _(L("3D"))); + // auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); + // panel3dsizer->Add(canvas3D, 1, wxEXPAND); + // auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); + // panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL)); + // panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND); + + // panel3d->SetSizer(panel3dsizer); + // notebook->AddPage(panel3d, _(L("3D"))); + notebook->AddPage(canvas3D, _(L("3D"))); preview = new GUI::Preview(notebook, config, &print, &gcode_preview_data, [this](){ schedule_background_process(); }); - _3DScene::get_canvas(canvas3D)->set_external_gizmo_widgets_parent(panel_gizmo_widgets); + // _3DScene::get_canvas(canvas3D)->set_external_gizmo_widgets_parent(panel_gizmo_widgets); // XXX: If have OpenGL _3DScene::enable_picking(canvas3D, true); @@ -1819,7 +1824,8 @@ void Plater::priv::fix_through_netfabb(const int obj_idx) void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) { const auto current_id = notebook->GetCurrentPage()->GetId(); - if (current_id == panel3d->GetId()) { + // if (current_id == panel3d->GetId()) { + if (current_id == canvas3D->GetId()) { if (_3DScene::is_reload_delayed(canvas3D)) { // Delayed loading of the 3D scene. if (this->printer_technology == ptSLA) { From a914e7de2d1261043697259d478bde7a947e6733 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 19 Nov 2018 13:13:05 +0100 Subject: [PATCH 11/23] Default values in config does not compile under gcc and clang --- src/libslic3r/PrintConfig.hpp | 62 +++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4a4d9535ad..fa283e1937 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -31,7 +31,7 @@ enum PrinterTechnology }; enum GCodeFlavor { - gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit, + gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit, gcfSmoothie, gcfNoExtrusion, }; @@ -167,7 +167,7 @@ private: // This definition is constant. extern const PrintConfigDef print_config_def; -// Slic3r dynamic configuration, used to override the configuration +// Slic3r dynamic configuration, used to override the configuration // per object, per modification volume or per printing material. // The dynamic configuration is also used to store user modifications of the print global parameters, // so the modified configuration values may be diffed against the active configuration @@ -274,12 +274,12 @@ protected: m_defaults = defaults; m_keys.clear(); m_keys.reserve(m_map_name_to_offset.size()); - for (const auto &kvp : defs->options) { - // Find the option given the option name kvp.first by an offset from (char*)m_defaults. - ConfigOption *opt = this->optptr(kvp.first, m_defaults); - if (opt == nullptr) - // This option is not defined by the ConfigBase of type T. - continue; + for (const auto &kvp : defs->options) { + // Find the option given the option name kvp.first by an offset from (char*)m_defaults. + ConfigOption *opt = this->optptr(kvp.first, m_defaults); + if (opt == nullptr) + // This option is not defined by the ConfigBase of type T. + continue; m_keys.emplace_back(kvp.first); const ConfigOptionDef *def = defs->get(kvp.first); assert(def != nullptr); @@ -463,7 +463,7 @@ public: ConfigOptionInt top_solid_layers; ConfigOptionFloatOrPercent top_solid_infill_speed; ConfigOptionBool wipe_into_infill; - + protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { @@ -768,7 +768,7 @@ public: ConfigOptionInt pixel_height; ConfigOptionFloat exp_time; ConfigOptionFloat exp_time_first; - + protected: PrintConfig(int) : GCodeConfig(1) {} void initialize(StaticCacheBase &cache, const char *base_ptr) @@ -859,7 +859,7 @@ public: ConfigOptionString printhost_cafile; ConfigOptionString serial_port; ConfigOptionInt serial_speed; - + protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { @@ -873,14 +873,14 @@ protected: }; // This object is mapped to Perl as Slic3r::Config::Full. -class FullPrintConfig : - public PrintObjectConfig, +class FullPrintConfig : + public PrintObjectConfig, public PrintRegionConfig, public PrintConfig, public HostConfig { STATIC_PRINT_CONFIG_CACHE_DERIVED(FullPrintConfig) - FullPrintConfig() : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0), HostConfig(0) { initialize_cache(); *this = s_cache_FullPrintConfig.defaults(); } + FullPrintConfig() : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0), HostConfig(0) { initialize_cache(); *this = s_cache_FullPrintConfig.defaults(); } public: // Validate the FullPrintConfig. Returns an empty string on success, otherwise an error message is returned. @@ -905,47 +905,47 @@ public: ConfigOptionFloat layer_height; // Radius in mm of the pointing side of the head. - ConfigOptionFloat support_head_front_radius = 0.2; + ConfigOptionFloat support_head_front_radius /*= 0.2*/; // How much the pinhead has to penetrate the model surface - ConfigOptionFloat support_head_penetraiton = 0.2; + ConfigOptionFloat support_head_penetraiton /*= 0.2*/; // Radius of the back side of the 3d arrow. TODO: consider renaming this // to actual pillar radius, because that's what it boils down to. - ConfigOptionFloat support_head_back_radius = 0.5; + ConfigOptionFloat support_head_back_radius /*= 0.5*/; // Width in mm from the back sphere center to the front sphere center. - ConfigOptionFloat support_head_width = 1.0; + ConfigOptionFloat support_head_width /*= 1.0*/; // Radius in mm of the support pillars. // TODO: This parameter is questionable. The pillar radius will be dynamic in // nature. Merged pillars will have an increased thickness. This parameter // may serve as the maximum radius, or maybe an increase when two are merged // The default radius will be derived from head_back_radius_mm - ConfigOptionFloat support_pillar_radius = 0.8; + ConfigOptionFloat support_pillar_radius /*= 0.8*/; // Radius in mm of the pillar base. - ConfigOptionFloat support_base_radius = 2.0; + ConfigOptionFloat support_base_radius /*= 2.0*/; // The height of the pillar base cone in mm. - ConfigOptionFloat support_base_height = 1.0; + ConfigOptionFloat support_base_height /*= 1.0*/; // The default angle for connecting support sticks and junctions. - ConfigOptionFloat support_critical_angle = 45; + ConfigOptionFloat support_critical_angle /*= 45*/; // The max length of a bridge in mm - ConfigOptionFloat support_max_bridge_length = 15.0; + ConfigOptionFloat support_max_bridge_length /*= 15.0*/; // The elevation in Z direction upwards. This is the space between the pad // and the model object's bounding box bottom. Units in mm. - ConfigOptionFloat support_object_elevation = 5.0; + ConfigOptionFloat support_object_elevation /*= 5.0*/; // Now for the base pool (pad) ///////////////////////////////////////////// - ConfigOptionFloat pad_wall_thickness= 2; - ConfigOptionFloat pad_wall_height = 5; - ConfigOptionFloat pad_max_merge_distance = 50; - ConfigOptionFloat pad_edge_radius = 1; + ConfigOptionFloat pad_wall_thickness /*= 2*/; + ConfigOptionFloat pad_wall_height /*= 5*/; + ConfigOptionFloat pad_max_merge_distance /*= 50*/; + ConfigOptionFloat pad_edge_radius /*= 1*/; protected: void initialize(StaticCacheBase &cache, const char *base_ptr) @@ -1069,7 +1069,7 @@ public: ConfigOptionFloat scale; // ConfigOptionPoint3 scale_to_fit; ConfigOptionBool slice; - + CLIConfig() : ConfigBase(), StaticConfig() { this->set_defaults(); @@ -1077,7 +1077,7 @@ public: // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. const ConfigDef* def() const override { return &cli_config_def; } - t_config_option_keys keys() const override { return cli_config_def.keys(); } + t_config_option_keys keys() const override { return cli_config_def.keys(); } ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) override { @@ -1119,7 +1119,7 @@ private: class PrintAndCLIConfigDef : public ConfigDef { public: - PrintAndCLIConfigDef() { + PrintAndCLIConfigDef() { this->options.insert(print_config_def.options.begin(), print_config_def.options.end()); this->options.insert(cli_config_def.options.begin(), cli_config_def.options.end()); } From ee33f0f1d7de609f3e7c48e5c2bf40b95c5f80cb Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 19 Nov 2018 13:46:56 +0100 Subject: [PATCH 12/23] Add missing icons --- resources/icons/overlay/cut_hover.png | Bin 0 -> 2812 bytes resources/icons/overlay/cut_off.png | Bin 0 -> 2769 bytes resources/icons/overlay/cut_on.png | Bin 0 -> 2447 bytes src/slic3r/GUI/Plater.cpp | 29 ++++++++++---------------- 4 files changed, 11 insertions(+), 18 deletions(-) create mode 100644 resources/icons/overlay/cut_hover.png create mode 100644 resources/icons/overlay/cut_off.png create mode 100644 resources/icons/overlay/cut_on.png diff --git a/resources/icons/overlay/cut_hover.png b/resources/icons/overlay/cut_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..99dc4cf8dbef9bf88bc6fa0a903705c400a815ed GIT binary patch literal 2812 zcmVyRv`cY3W-TX zK~#9!<(qqKQ`a5GKi78byn_={LW5mMNgSFLWvL6K0X00vpy3W7m>Se>>dM+KRo6|0 zGL5Q}+D%MA2Zd_dN*4{aE2W5{DVOpXq$Mg@6%hqcU|Ae1a~dZEC&aZA5}cR!hi^=r zhvTMp>}g-gfB4>W&%NK@`JMB7og)xth@zMSECX_Z2j$-!API<wP8n_Qg1rkHleGkwjYe)s~S4ol@qCx8jU?> zv$-j(8X$^d60i~YHSiG8g?eB&P%cT5E94p=iefrY3hW2ci9XB*MBuK`Xf&J6=AMuV zKorFXfM3ZYuZ%QPl}bfsW+wCJ&nGoC6}Q`s+wC6VvkK4{jmCeO&1UDfngXII3V>c# zt*0VQeAcX4tXZ>$qM{-U27~W=E?nUB>C?2fwvJr>5ZDE@NRs54mIfG&#&lpO z@LZ(H>-Boxc;gLLtXM%xN(wh_+@QX`9-GZZLP7%h`T49`wFgfO-&6Z zlZpKNe6C%)Mn^}73djd6X0y3&qP`WAjD8XDI*<}+@|l^Lm`o<@b~|NdWq3T3PG`RQ z>MM>MIRe0zEn5%-0hz;ZWKL5HKorFc;HR=%JJLzSke!{4APAf~b&B5J-YMJH)YRZ` zILOV-B_YA5yxG8WGPfx;U<>d>v>122UJu|m=L5m*c60giW#Z!ENKf~3SJuniCKrGl zyO#i3-zphl4Nxc)zIh&W=-AWaTO3D03v3ldaZw-*cpk{}i#P(zxtW07?u~I06N8Ve z7cKH~bUMfRL3uLA@d6M<(EtlOgZmMshF`SkR3j7B34hl7rejn9b&4rR?;qmKVQSQ5faX)YQcA@GvHm$rlI2#l?}Bn227lr?9Y)7hil4 zlgUJ9XD7RN@20)IJy4eez;(0P+@z8(Y>>mrkd1Jt*N%@r{+N!A4oXT&C@d_bu&{7k zo2sfRKKS4R+S=NJ4V}-A2w(;GQq&=z$DzV!pM6GERTUkkE>_@8U;jVhCa_usEFEk5X42%Pq@<9PltfZe5?Za6#Kc4{U%pIN zS68@S9}6s10pG=2um~$+Vq#dlcrlrondo#nQd3izJ$p8D=FA~BHWsB)={J}6?Aa6c zPXcmPK-NqMpt!i0XPOqR`c@9FB2CR=W}$*%ggV@u3GI(d`7$?QbxG6wA2^2*4EbY$tR!q;&_16 z)YO^DH{jizFr!$%em$#KuLhvKy`6&x590B7=;-L6udfflFYg~l^eO=0d(NqnGtrRq@?i5E3f!W+|i>)u~;nk zLbQPa?%cWKvjpE3!^6XYZVv&S3c!YUOG;Rw(P-GdeYJ7B1HQ#Bf*1g9Oe-7~1ObD=fWcruqtVdU*GFSxqc4Ly8FF%Ra5|k6rnDjz z4hsOHDAwXl83&cDGZ+jM6&0b=>Ck92ba!`Sv)QGT66oU$l^&2)AX|puwViq zeX)KN;i}A$2?ZcYQax}KaEu<2!NEb2lao=Yf=eB$)oPSVWwcoV2XIv8$YdG-Z~{0z zI-=_7=|QK{k(QPg)SEIhGl_|bp{1oIngno0=0-pPNRreF`~~lpbUYpp7K;UiLczLq z>w;>RPN znp&;KU@(xFn25{eqPe;G8*OC^GyVv?B}tNXO3yRc9*c{M4IYo@=Yk;oLZMK^5S&LO~F8QAWNV?>VOTB}uv+bnG#mH;JP7J>W;c zW+GHt8baoBiqqAB zK~#9!?OT6rQ`Z&#{A|DH*iIfv9wY%`5-bzqdbf z9U13`-8B9owMV*t*zdk~-}&x$&$;Kkb7hFX&;V2b7ywGr6aXjyGSWu^AOZ-G<_F*< zO^D~q$>Q`}4QXirwgkpQ>|2*cBv z#V;ciQJNzlBwP8=Br;?Pio}CR@c=*pfR)STIg%vFk$NI0o<|}eh%>nalmId*ipms4 zQJU_0`wEKPBYM4Fxqtuu;+&kEOpnLoJ#*$vXG=?qBdp6H00#l$D+8b)l+Pf)gGrcK z0KoR`+qt^By3P6d`42G+vv|xch@!`8wVF0ru6~hWm_h*Xcsy-huh%M*$rM_xb{S36^F>h{?&#=fT(M$Bi_hniD2j55 zqIh>I5U3~yk0mWx$^!rl2E*K4yLSDNVVFXm=gmf=aidnN{Tat`wb|L(PnDIGJ=E6L zW{@PwzjW!+y%vk*SLD{v`%}|lKn8$0=*+Yr$ZU=Q!@+ix)3G7_I+~9Xp-?Ais0x&bjN?ulpw1*0YfS zgpi?94S<%G7Dsz~`yT*c{rdI4Gn>uj6ZI=EFHh_3?R|#hxE~6F&{tPi_wp1QyfLQB z!YpLYBn${983Q>0bai#@TDWlGF9Cq(d9%f0dCzLKexXvSn1X_WlKlMqO$@^<2m}JQ z6DLmWs;a8GF~u|e0PX-74goNS_d5na>#MK6dbGa2 zz9)vX+7JMH2!I7sSpSp(0016%;DNN~pMQR>PN(~pN~M}3Ns`~`boRXa?z@+F?AUSh zOFY*Hphrgh;{1trNht!rjOP=G1OW6ZNGd65uCJn^VntC=QMyj2%h2g`SuD$HjYi`K z=gysLOF$}3C5y8DXN&>4xw%CL4<7vXvSrH_XJut^85tSbTCH}DTCL8dC@M`ZmygX< zPfyQ33knLh#hC#j0H=aj{yGCm^9|O<`eSNg@DHBr5RPx^?T>ef##^@_0N#S6A0yM@Prd zrAwFo{mLt^{N%C69xJ0H;^&_i=!|gZeF0ey862>yzs&?rBay| z3}VyN_f)qz<~qbuc)Y~Cf>kz=+L3x zo~{MnmoHy_J>K*O z;7{0A*km$QZQ8VHF90~5&dxP!);xXV#*P0bF&Gj7I4O*ln#7#}4u@kH00cpB9yoB| zP=b_?#sHrpQ2;#t_~WnJY__4!&Q9lRuf6tu3WUiL0B#=vhrcITAim* zC{%(V3_2W+Tg}bQ=Z_pYVoT+O%0vkf#9#*i0DJcA$u$@ZyE%@loM;CrilXQC?c2x8 z%F14}TCKqp24GxDOoP#+=ww+T96o%wpr)qg7{f4&0)c?FySw{TM@L7y!{Ko2bh;e9 zUSFD*m-l0eqSAPt|64&p!PDeJW-0;@z-Us`BMS=+^GSASoaps><@M{=-&CnoOZxl! zPw(8h^Es2rH12cr(W6Hf?%cWah)SheYPDMbGO;^OyBCX+SE08kUq-wjfB z8-8&RlN1##S+Zn309?3m!8q0Tc>t)ZtLwgb^X4%CSiO4nI;5WXF;3GOtx;_MqmYt3nE|13}0`MyoicGy;AJfNEold8c z$z<|mgxXOuTP{RYnNQ^RT?nho=XqZA`~5>SP3J!H$RjzijI?FTmJ*pvM!Vhat`q`b znCOOR00aq< z)YjJOIgXpv*Vo54G&Fqn`RAVp;+0XFN;YraoEZ_D%xJlMC?HBxDwT_EHXH45IEIj# zB9U1iiZ=6K8i0_|EGjC}4Gauud7c+iOnHH*1&J$7R(;_} z*m|E9BjsNad2dAUl!%Y5A{o;iM)_%bns1KI#%Y$mmWQXOVn*cgc{wINJ|9GakI(-f X`3>!?!WdHJ00000NkvXXu0mjffwVm9 literal 0 HcmV?d00001 diff --git a/resources/icons/overlay/cut_on.png b/resources/icons/overlay/cut_on.png new file mode 100644 index 0000000000000000000000000000000000000000..7e78e0e6a3a0f36ce2a8a85e4ebdfa9ab6ec62c1 GIT binary patch literal 2447 zcmV;A32^p_P)j8 zK~#9!<(qqORP`0dKX-TYCXj@X1QLQkc*gQjM&8p1SPSxyN(Yd~tPfB-L_5%_V<|Xb ztL^w|r641qcWgjvsYTHU1qxOkQkjChMBWI27!qCy33=`9ALqAhmSnS+us3^WI5RhQ zbNB4M_k4fncb>nWhQ(yK=?)A4vVqR(NCo17SjAQjlmbP-8Q>VO7uc!k9JccPGz$cF z03(41fx$pqAPR^CA^;cQ4Dj<>phg{)>NpQ<2Q~ofHJw^p0${l520R7~2U36}phbvo zUj|%M8nPL9Pt*C%762G-?gnN81A%TzwXLL5;5%R^@Q$W)AS?hFZc>0Lz<6MY71Jr$ zD*)SowLqSxQ`Bq#7;Z)Y(|`$e3|Y9S9QX)$U(?xWDFB9>cwijx0?-qC(YL_Mz$co{ z)sO>VxJd(^@W6bBSads5HLws^uIUtp3;@GT2Vjl?xt2|IhZ8&|J)A2NGI~LLGE|jA z!67IsuFJ6qcwN&ueOmw+ZZx31QmrXrAK#X#F!XU4I0e$Peb=v-!k6#Dzu$(!8{Tmx z@EhQareib}fHXDVpAEb4?RrA)N08P{{y*|1Ts#8~7uSy+WUJpU>DOf!l3{PO*f`jnkujTXT7eLccGR#*p z1qZ-zlMXzo!dmZ5!bhF@%R6jZ1QjOS`@Vd*d>*XW%`N1P7v&rgUH57t zFxha^qcIJb3H0%w6Q1w_P^@B^xJ2{6=`vX5jTdhIrjL@bJ^+TBOdtn{_6NWSGXN*$ ze9yz?_)|JV=K*2|O6moIQ9zE0Z0l*j(?BQNMfZolkdYiX6?%^j&Odg(Oq*RFK=t*8 zI65j>eE=A4T&j}Ou-nrd;RB$o7(RSnK0m3$-48a*7ZnGS--N-_W#m77InW(j0mGEc z@&~wIm9YYZg-x&n4i|W8LIc9K_aG?)#xI09>m?feCSL@Nh?ZDkh#OM7z@@XW=x0z? z(&$7{GH>((FdAqRvQg6xIoh&J_TANL0oGY(bxp|<}lN=P=0Z zD+Vp09VBH+9v>Aa>9Ln~uYtusZ`yOr36GLF+XZwn4Z!Wth*>c4HFLaa-9$UA4Z>VN zmIKJB;|{H(y0JuUHC(#{r}x0F)o}F(f8N*xh={TJjUs@KF69!OmIJV95uDvG#f#D+ z@zYm}#G>~d>(ARF8Cs>mg%ei3krPOE0WF)w@Ks-j{p;(i`ZKG2hU@5d$bLXdT&Y=B z0{{@`AXsO|sxUY*1|DA_dAm2z+4$!=0c*2(`|V)08(ON}2Oy;(YMzp>U1AWdR_VK3V3^x zPd53u${IJMjNeN82lUzX4D$yUEjEl}(L z<@vtWRQQ=1Iy5uuX^0U#-vg@d7x!6+V5%>NlzePP%}jz)-AefOzTN@#5k@0-%)v zx@~(tmcx3g0ggFCUESi)vR~g_B=5RD|@W ztbuU#0u&vyO*-7Pf=GI{6e*M13jo(j;QV3O^*1R=*`IC{M7&ARcBFk2*XYj@GvJZm z!=PymH%!L8DAC;71)(pAg?K_LnQvr)>yd77U;xs(Lhf2=Rb4y-Tb9D{uSES5)1i9~ z{CEb8`K|cyrIW+oR0&KaN@l!MAOhF{^lLbCj)eLDh4#J0eXXADAGUg_ZFhKT6?Ete zoBslNxpoC$H!w)ksdfNpI@Q3IfKlO(MvCwU{sr$o(Xj9!c3|lwxKaqiXGw>~epCu< zQ8N2=hTeeyi;8+bBj9u>DY8u6AArbMS)pMzc)5H|3LMe#;wtS!dzFkd z2!N*ZEwBpkO>&P%YIrS@#Tc5Zw#9(cC0fvMgEAa+30S3MB#;IGtO4?UAww;cUy_kb zOgHza4t=Eze(n$)+hG>~K3B5QC;*yH0k9m@dVIrxle=Xq7~G^)8jiV6nB~$u zFyK*`z64@gK}{8$*d-;bR;fOBcj1HtONY1GVf5dksY_)Q09uvd$SkUfdNa*cIo_pt zq?SKomMmUu)6vI#?ht&n3cgq-4Uh2C?Jt)0Qo+=itkPQNybh7&)1x&N2}VRqS{#=o zYj_F{-rDk4YiTj?nx=CqXlcXj9Zyb)%dGG?b2D7!&&4}yBCscUH%zS1bk3Wq?c7oo z!A;BKRV^M(abABe-dWS#X2M&$W#%Rz9zZrtJ;I%|Y3e2rQh=$z!`x}x=57KaoEs;X zX*&CF=Vn%HogIO!!%HM|TW7D~+d8`mJ8hk900<|t-2NxPAk1%`HUJOOvZ}_ndAd-Q z>ox%Sw%t742p~O>?ejf>EZ{C68CjU&T?bR4V)jeGIiy>)hi2G5|9_-S+Q`YQ$SVK< N002ovPDHLkV1hbhW7_}# literal 0 HcmV?d00001 diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8dc221aad1..3b3e30235f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -999,10 +999,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) })) , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) , sidebar(new Sidebar(q)) - // , panel3d(new wxPanel(notebook, wxID_ANY)) - , panel3d(nullptr) - // , canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) - , canvas3D(GLCanvas3DManager::create_wxglcanvas(notebook)) + , panel3d(new wxPanel(notebook, wxID_ANY)) + , canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) #if ENABLE_NEW_MENU_LAYOUT , project_filename(wxEmptyString) #endif // ENABLE_NEW_MENU_LAYOUT @@ -1030,21 +1028,17 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) _3DScene::add_canvas(canvas3D); _3DScene::allow_multisample(canvas3D, GLCanvas3DManager::can_multisample()); - // XXX: reverting panel3d and panel_gizmo_widgets - // ! cf. on_notebook_changed + auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); + panel3dsizer->Add(canvas3D, 1, wxEXPAND); + auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); + panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL)); + panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND); - // auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); - // panel3dsizer->Add(canvas3D, 1, wxEXPAND); - // auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); - // panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL)); - // panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND); - - // panel3d->SetSizer(panel3dsizer); - // notebook->AddPage(panel3d, _(L("3D"))); - notebook->AddPage(canvas3D, _(L("3D"))); + panel3d->SetSizer(panel3dsizer); + notebook->AddPage(panel3d, _(L("3D"))); preview = new GUI::Preview(notebook, config, &print, &gcode_preview_data, [this](){ schedule_background_process(); }); - // _3DScene::get_canvas(canvas3D)->set_external_gizmo_widgets_parent(panel_gizmo_widgets); + _3DScene::get_canvas(canvas3D)->set_external_gizmo_widgets_parent(panel_gizmo_widgets); // XXX: If have OpenGL _3DScene::enable_picking(canvas3D, true); @@ -1824,8 +1818,7 @@ void Plater::priv::fix_through_netfabb(const int obj_idx) void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) { const auto current_id = notebook->GetCurrentPage()->GetId(); - // if (current_id == panel3d->GetId()) { - if (current_id == canvas3D->GetId()) { + if (current_id == panel3d->GetId()) { if (_3DScene::is_reload_delayed(canvas3D)) { // Delayed loading of the 3D scene. if (this->printer_technology == ptSLA) { From 7cb99f8e27ab749b02705c3cb4a436c66f811336 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 19 Nov 2018 14:03:28 +0100 Subject: [PATCH 13/23] Added debug error message when missing icons for gizmos --- src/slic3r/GUI/GLCanvas3D.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6e47c08673..d45bdf685a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3219,7 +3219,8 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) if (m_gizmos.is_enabled()) { if (! m_gizmos.init(*this)) { - return false; + std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl; + return false; } if (m_external_gizmo_widgets_parent != nullptr) { From 2fa055903fcb45da9bb90479b7378dc32b0c1431 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 16 Nov 2018 17:36:23 +0100 Subject: [PATCH 14/23] "SLA Print Settings" implementation (start) --- src/libslic3r/GCode.cpp | 5 +- src/libslic3r/PrintConfig.cpp | 114 ++++++++++++++++++++++++++++++++ src/libslic3r/PrintConfig.hpp | 4 +- src/slic3r/GUI/MainFrame.cpp | 8 ++- src/slic3r/GUI/Plater.cpp | 24 ++++--- src/slic3r/GUI/Preset.cpp | 28 ++++++++ src/slic3r/GUI/Preset.hpp | 2 + src/slic3r/GUI/PresetBundle.cpp | 64 +++++++++++++++++- src/slic3r/GUI/PresetBundle.hpp | 2 + src/slic3r/GUI/Tab.cpp | 52 +++++++++++++-- src/slic3r/GUI/Tab.hpp | 13 ++++ 11 files changed, 296 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4f1ec05af0..b9625523d3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1663,8 +1663,9 @@ void GCode::append_full_config(const Print& print, std::string& str) } const DynamicConfig &full_config = print.placeholder_parser().config(); for (const char *key : { - "print_settings_id", "filament_settings_id", "sla_material_settings_id", "printer_settings_id", - "printer_model", "printer_variant", "default_print_profile", "default_filament_profile", "default_sla_material_profile", + "print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id", + "printer_model", "printer_variant", + "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile", "compatible_printers_condition_cummulative", "inherits_cummulative" }) { const ConfigOption *opt = full_config.option(key); if (opt != nullptr) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 8e8a494926..1e8f26d381 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2434,6 +2434,120 @@ void PrintConfigDef::init_sla_params() def = this->add("sla_material_settings_id", coString); def->default_value = new ConfigOptionString(""); + + + def = this->add("default_sla_print_profile", coString); + def->label = L("Default SLA material profile"); + def->tooltip = L("Default print profile associated with the current printer profile. " + "On selection of the current printer profile, this print profile will be activated."); + def->default_value = new ConfigOptionString(); + + def = this->add("sla_print_settings_id", coString); + def->default_value = new ConfigOptionString(""); + + def = this->add("support_head_front_radius", coFloat); + def->label = L("Support head front radius"); + def->tooltip = L("Radius of the pointing side of the head"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(0.2); + + def = this->add("support_head_penetration", coFloat); + def->label = L("Support head penetration"); + def->tooltip = L("How much the pinhead has to penetrate the model surface"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(0.2); + + def = this->add("support_head_back_radius", coFloat); + def->label = L("Support head back radius"); + def->tooltip = L("Radius of the back side of the 3d arrow"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(0.5); + + def = this->add("support_head_width", coFloat); + def->label = L("Support head width"); + def->tooltip = L("Width from the back sphere center to the front sphere center"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(1.0); + + def = this->add("support_pillar_radius", coFloat); + def->label = L("Support pillar radius"); + def->tooltip = L("Radius in mm of the support pillars"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(0.8); + + def = this->add("support_base_radius", coFloat); + def->label = L("Support base radius"); + def->tooltip = L("Radius in mm of the pillar base"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(2.0); + + def = this->add("support_base_height", coFloat); + def->label = L("Support base height"); + def->tooltip = L("The height of the pillar base cone"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(1.0); + + def = this->add("support_critical_angle", coFloat); + def->label = L("Critical angle"); + def->tooltip = L("The default angle for connecting support sticks and junctions."); + def->sidetext = L("°"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(45); + + def = this->add("support_max_bridge_length", coFloat); + def->label = L("Max bridge length"); + def->tooltip = L("The max length of a bridge"); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(); + + def = this->add("pad_wall_thickness", coFloat); + def->label = L("Pad wall thickness"); + def->tooltip = L(""); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(2.0); + + def = this->add("pad_wall_height", coFloat); + def->label = L("Pad wall height"); + def->tooltip = L(""); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(5.0); + + def = this->add("pad_max_merge_distance", coFloat); + def->label = L("Max merge distance"); + def->tooltip = L(""); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(50.0); + + def = this->add("pad_edge_radius", coFloat); + def->label = L("pad edge radius"); + def->tooltip = L(""); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(1.0); } void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e5b6da0a12..545f6d8be3 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -908,7 +908,7 @@ public: ConfigOptionFloat support_head_front_radius /*= 0.2*/; // How much the pinhead has to penetrate the model surface - ConfigOptionFloat support_head_penetraiton /*= 0.2*/; + ConfigOptionFloat support_head_penetration /*= 0.2*/; // Radius of the back side of the 3d arrow. ConfigOptionFloat support_head_back_radius /*= 0.5*/; @@ -951,7 +951,7 @@ protected: { OPT_PTR(layer_height); OPT_PTR(support_head_front_radius); - OPT_PTR(support_head_penetraiton); + OPT_PTR(support_head_penetration); OPT_PTR(support_head_back_radius); OPT_PTR(support_head_width); OPT_PTR(support_pillar_radius); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 85ac442f71..458c322620 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -140,7 +140,7 @@ void MainFrame::init_tabpanel() Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); create_preset_tabs(); - std::vector tab_names = { "print", "filament", "sla_material", "printer" }; + std::vector tab_names = { "print", "filament", "sla_print", "sla_material", "printer" }; for (auto tab_name : tab_names) m_options_tabs[tab_name] = get_preset_tab(tab_name.c_str()); @@ -160,6 +160,7 @@ void MainFrame::init_tabpanel() std::vector preset_tabs = { { "print", nullptr, ptFFF }, { "filament", nullptr, ptFFF }, + { "sla_print", nullptr, ptSLA }, { "sla_material", nullptr, ptSLA } }; @@ -194,6 +195,7 @@ void MainFrame::create_preset_tabs() { wxGetApp().update_label_colours_from_appconfig(); add_created_tab(new TabPrint(m_tabpanel)); + add_created_tab(new TabSLAPrint(m_tabpanel)); add_created_tab(new TabFilament(m_tabpanel)); add_created_tab(new TabSLAMaterial(m_tabpanel)); add_created_tab(new TabPrinter(m_tabpanel)); @@ -202,7 +204,7 @@ void MainFrame::create_preset_tabs() void MainFrame::add_created_tab(Tab* panel) { panel->create_preset_tab(); - + /* const wxString& tab_name = panel->GetName(); bool add_panel = true; @@ -214,6 +216,8 @@ void MainFrame::add_created_tab(Tab* panel) } if (add_panel) +*/ + if (panel->supports_printer_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology())) m_tabpanel->AddPage(panel, panel->title()); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3b3e30235f..eb0d7cc494 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -424,6 +424,7 @@ struct Sidebar::priv PresetComboBox *combo_print; std::vector combos_filament; wxBoxSizer *sizer_filaments; + PresetComboBox *combo_sla_print; PresetComboBox *combo_sla_material; PresetComboBox *combo_printer; @@ -454,7 +455,7 @@ void Sidebar::priv::show_preset_comboboxes() for (size_t i = 0; i < 4; ++i) sizer_presets->Show(i, !showSLA); - for (size_t i = 4; i < 6; ++i) { + for (size_t i = 4; i < 8; ++i) { if (sizer_presets->IsShown(i) != showSLA) sizer_presets->Show(i, showSLA); } @@ -479,7 +480,7 @@ Sidebar::Sidebar(Plater *parent) p->scrolled->SetSizer(scrolled_sizer); // The preset chooser - p->sizer_presets = new wxFlexGridSizer(4, 2, 1, 2); + p->sizer_presets = new wxFlexGridSizer(5, 2, 1, 2); p->sizer_presets->AddGrowableCol(1, 1); p->sizer_presets->SetFlexibleDirection(wxBOTH); p->sizer_filaments = new wxBoxSizer(wxVERTICAL); @@ -502,10 +503,11 @@ Sidebar::Sidebar(Plater *parent) }; p->combos_filament.push_back(nullptr); - init_combo(&p->combo_print, _(L("Print settings")), Preset::TYPE_PRINT, false); - init_combo(&p->combos_filament[0], _(L("Filament")), Preset::TYPE_FILAMENT, true); - init_combo(&p->combo_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false); - init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false); + init_combo(&p->combo_print, _(L("Print settings")), Preset::TYPE_PRINT, false); + init_combo(&p->combos_filament[0], _(L("Filament")), Preset::TYPE_FILAMENT, true); + init_combo(&p->combo_sla_print, _(L("SLA print")), Preset::TYPE_SLA_PRINT, false); + init_combo(&p->combo_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false); + init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false); // calculate width of the preset labels p->sizer_presets->Layout(); @@ -620,6 +622,10 @@ void Sidebar::update_presets(Preset::Type preset_type) preset_bundle.prints.update_platter_ui(p->combo_print); break; + case Preset::TYPE_SLA_PRINT: + preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print); + break; + case Preset::TYPE_SLA_MATERIAL: preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); break; @@ -629,8 +635,10 @@ void Sidebar::update_presets(Preset::Type preset_type) // Update the print choosers to only contain the compatible presets, update the dirty flags. if (p->plater->printer_technology() == ptFFF) preset_bundle.prints.update_platter_ui(p->combo_print); - else - preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); + else { + preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print); + preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); + } // Update the printer choosers, update the dirty flags. preset_bundle.printers.update_platter_ui(p->combo_printer); // Update the filament choosers to only contain the compatible presets, update the color preview, diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index b6d19b8ef4..1599af0c4d 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -396,6 +396,34 @@ const std::vector& Preset::sla_material_options() return s_opts; } +const std::vector& Preset::sla_print_options() +{ + static std::vector s_opts; + if (s_opts.empty()) { + s_opts = { + "layer_height", + "support_head_front_radius", + "support_head_penetration", + "support_head_back_radius", + "support_head_width", + "support_pillar_radius", + "support_base_radius", + "support_base_height", + "support_critical_angle", + "support_max_bridge_length", + "pad_wall_thickness", + "pad_wall_height", + "pad_max_merge_distance", + "pad_edge_radius", + "default_sla_print_profile", + "compatible_printers", + "compatible_printers_condition", + "inherits" + }; + } + return s_opts; +} + PresetCollection::PresetCollection(Preset::Type type, const std::vector &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name) : m_type(type), m_edited_preset(type, "", false), diff --git a/src/slic3r/GUI/Preset.hpp b/src/slic3r/GUI/Preset.hpp index 96c313b1b6..fc459d8dd1 100644 --- a/src/slic3r/GUI/Preset.hpp +++ b/src/slic3r/GUI/Preset.hpp @@ -84,6 +84,7 @@ public: { TYPE_INVALID, TYPE_PRINT, + TYPE_SLA_PRINT, TYPE_FILAMENT, TYPE_SLA_MATERIAL, TYPE_PRINTER, @@ -173,6 +174,7 @@ public: static const std::vector& sla_printer_options(); static const std::vector& sla_material_options(); + static const std::vector& sla_print_options(); static void update_suffix_modified(); static void normalize(DynamicPrintConfig &config); diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index bd7e7ab139..c092cae431 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -45,6 +45,7 @@ PresetBundle::PresetBundle() : prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast(FullPrintConfig::defaults())), filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast(FullPrintConfig::defaults())), sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast(SLAFullPrintConfig::defaults())), + sla_prints(Preset::TYPE_SLA_PRINT, Preset::sla_print_options(), static_cast(SLAFullPrintConfig::defaults())), printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast(FullPrintConfig::defaults()), "- default FFF -"), m_bitmapCompatible(new wxBitmap), m_bitmapIncompatible(new wxBitmap), @@ -76,6 +77,10 @@ PresetBundle::PresetBundle() : this->sla_materials.default_preset().compatible_printers_condition(); this->sla_materials.default_preset().inherits(); + this->sla_prints.default_preset().config.optptr("sla_print_settings_id", true); + this->sla_prints.default_preset().compatible_printers_condition(); + this->sla_prints.default_preset().inherits(); + this->printers.add_default_preset(Preset::sla_printer_options(), static_cast(SLAFullPrintConfig::defaults()), "- default SLA -"); this->printers.preset(1).printer_technology() = ptSLA; for (size_t i = 0; i < 2; ++ i) { @@ -88,14 +93,18 @@ PresetBundle::PresetBundle() : if (i == 0) { preset.config.optptr("default_print_profile", true); preset.config.option("default_filament_profile", true)->values = { "" }; - } else + } + else { preset.config.optptr("default_sla_material_profile", true); + preset.config.optptr("default_sla_print_profile", true); + } // default_sla_material_profile preset.inherits(); } // Load the default preset bitmaps. this->prints .load_bitmap_default("cog.png"); + this->sla_prints .load_bitmap_default("package_green.png"); this->filaments .load_bitmap_default("spool.png"); this->sla_materials.load_bitmap_default("package_green.png"); this->printers .load_bitmap_default("printer_empty.png"); @@ -103,6 +112,7 @@ PresetBundle::PresetBundle() : // Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above. this->prints .select_preset(0); + this->sla_prints .select_preset(0); this->filaments .select_preset(0); this->sla_materials.select_preset(0); this->printers .select_preset(0); @@ -133,12 +143,14 @@ void PresetBundle::reset(bool delete_files) // Clear the existing presets, delete their respective files. this->vendors.clear(); this->prints .reset(delete_files); + this->sla_prints .reset(delete_files); this->filaments .reset(delete_files); this->sla_materials.reset(delete_files); this->printers .reset(delete_files); this->filament_presets.clear(); this->filament_presets.emplace_back(this->filaments.get_selected_preset_name()); this->obsolete_presets.prints.clear(); + this->obsolete_presets.sla_prints.clear(); this->obsolete_presets.filaments.clear(); this->obsolete_presets.sla_materials.clear(); this->obsolete_presets.printers.clear(); @@ -193,6 +205,11 @@ void PresetBundle::load_presets(const AppConfig &config) } catch (const std::runtime_error &err) { errors_cummulative += err.what(); } + try { + this->sla_prints.load_presets(dir_user_presets, "sla_print"); + } catch (const std::runtime_error &err) { + errors_cummulative += err.what(); + } try { this->filaments.load_presets(dir_user_presets, "filament"); } catch (const std::runtime_error &err) { @@ -267,13 +284,16 @@ std::vector PresetBundle::merge_presets(PresetBundle &&other) { this->vendors.insert(other.vendors.begin(), other.vendors.end()); std::vector duplicate_prints = this->prints .merge_presets(std::move(other.prints), this->vendors); + std::vector duplicate_sla_prints = this->sla_prints .merge_presets(std::move(other.sla_prints), this->vendors); std::vector duplicate_filaments = this->filaments .merge_presets(std::move(other.filaments), this->vendors); std::vector duplicate_sla_materials = this->sla_materials.merge_presets(std::move(other.sla_materials), this->vendors); std::vector duplicate_printers = this->printers .merge_presets(std::move(other.printers), this->vendors); append(this->obsolete_presets.prints, std::move(other.obsolete_presets.prints)); + append(this->obsolete_presets.sla_prints, std::move(other.obsolete_presets.sla_prints)); append(this->obsolete_presets.filaments, std::move(other.obsolete_presets.filaments)); append(this->obsolete_presets.sla_materials, std::move(other.obsolete_presets.sla_materials)); append(this->obsolete_presets.printers, std::move(other.obsolete_presets.printers)); + append(duplicate_prints, std::move(duplicate_sla_prints)); append(duplicate_prints, std::move(duplicate_filaments)); append(duplicate_prints, std::move(duplicate_sla_materials)); append(duplicate_prints, std::move(duplicate_printers)); @@ -307,6 +327,7 @@ void PresetBundle::load_selections(const AppConfig &config) // Parse the initial print / filament / printer profile names. std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print")); + std::string initial_sla_print_profile_name = remove_ini_suffix(config.get("presets", "sla_print")); std::string initial_filament_profile_name = remove_ini_suffix(config.get("presets", "filament")); std::string initial_sla_material_profile_name = remove_ini_suffix(config.get("presets", "sla_material")); std::string initial_printer_profile_name = remove_ini_suffix(config.get("presets", "printer")); @@ -320,10 +341,12 @@ void PresetBundle::load_selections(const AppConfig &config) if (printer_technology == ptFFF) { prints.select_preset_by_name_strict(initial_print_profile_name); filaments.select_preset_by_name_strict(initial_filament_profile_name); + sla_prints.select_preset_by_name(initial_sla_material_profile_name, true); sla_materials.select_preset_by_name(initial_sla_material_profile_name, true); } else { prints.select_preset_by_name(initial_print_profile_name, true); filaments.select_preset_by_name(initial_filament_profile_name, true); + sla_prints.select_preset_by_name_strict(initial_sla_material_profile_name); sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name); } @@ -358,6 +381,7 @@ void PresetBundle::export_selections(AppConfig &config) assert(this->printers.get_edited_preset().printer_technology() != ptFFF || filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front()); config.clear_section("presets"); config.set("presets", "print", prints.get_selected_preset_name()); + config.set("presets", "sla_print", sla_prints.get_selected_preset_name()); config.set("presets", "filament", filament_presets.front()); for (int i = 1; i < filament_presets.size(); ++i) { char name[64]; @@ -378,6 +402,7 @@ void PresetBundle::export_selections(PlaceholderParser &pp) pp.set("filament_preset", filament_presets); break; case ptSLA: + pp.set("sla_print_preset", sla_prints.get_selected_preset().name); pp.set("sla_material_preset", sla_materials.get_selected_preset().name); break; } @@ -401,24 +426,28 @@ bool PresetBundle::load_compatible_bitmaps() if (loaded_compatible) { prints .set_bitmap_compatible(m_bitmapCompatible); filaments .set_bitmap_compatible(m_bitmapCompatible); + sla_prints .set_bitmap_compatible(m_bitmapCompatible); sla_materials.set_bitmap_compatible(m_bitmapCompatible); // printers .set_bitmap_compatible(m_bitmapCompatible); } if (loaded_incompatible) { prints .set_bitmap_incompatible(m_bitmapIncompatible); filaments .set_bitmap_incompatible(m_bitmapIncompatible); + sla_prints .set_bitmap_incompatible(m_bitmapIncompatible); sla_materials.set_bitmap_incompatible(m_bitmapIncompatible); // printers .set_bitmap_incompatible(m_bitmapIncompatible); } if (loaded_lock) { prints .set_bitmap_lock(m_bitmapLock); filaments .set_bitmap_lock(m_bitmapLock); + sla_prints .set_bitmap_lock(m_bitmapLock); sla_materials.set_bitmap_lock(m_bitmapLock); printers .set_bitmap_lock(m_bitmapLock); } if (loaded_lock_open) { prints .set_bitmap_lock_open(m_bitmapLock); filaments .set_bitmap_lock_open(m_bitmapLock); + sla_prints .set_bitmap_lock_open(m_bitmapLock); sla_materials.set_bitmap_lock_open(m_bitmapLock); printers .set_bitmap_lock_open(m_bitmapLock); } @@ -533,14 +562,17 @@ DynamicPrintConfig PresetBundle::full_sla_config() const { DynamicPrintConfig out; out.apply(SLAFullPrintConfig::defaults()); + out.apply(this->sla_prints.get_edited_preset().config); out.apply(this->sla_materials.get_edited_preset().config); out.apply(this->printers.get_edited_preset().config); // There are no project configuration values as of now, the project_config is reserved for FFF printers. // out.apply(this->project_config); - // Collect the "compatible_printers_condition" and "inherits" values over all presets (sla_materials, printers) into a single vector. + // Collect the "compatible_printers_condition" and "inherits" values over all presets (sla_prints, sla_materials, printers) into a single vector. std::vector compatible_printers_condition; std::vector inherits; + compatible_printers_condition.emplace_back(this->/*prints*/sla_prints.get_edited_preset().compatible_printers_condition()); + inherits .emplace_back(this->/*prints*/sla_prints.get_edited_preset().inherits()); compatible_printers_condition.emplace_back(this->/*prints*/sla_materials.get_edited_preset().compatible_printers_condition()); inherits .emplace_back(this->/*prints*/sla_materials.get_edited_preset().inherits()); inherits .emplace_back(this->printers.get_edited_preset().inherits()); @@ -550,6 +582,7 @@ DynamicPrintConfig PresetBundle::full_sla_config() const out.erase("compatible_printers_condition"); out.erase("inherits"); + out.option("sla_print_settings_id", true)->value = this->sla_prints.get_selected_preset().name; out.option("sla_material_settings_id", true)->value = this->sla_materials.get_selected_preset().name; out.option("printer_settings_id", true)->value = this->printers.get_selected_preset().name; @@ -661,6 +694,8 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool // 2) If the loading succeeded, split and load the config into print / filament / printer settings. // First load the print and printer presets. + + // #ys_FIXME_SLA_PRINT for (size_t i_group = 0; i_group < 2; ++ i_group) { PresetCollection &presets = (i_group == 0) ? ((printer_technology == ptFFF) ? this->prints : this->sla_materials) : this->printers; // Split the "compatible_printers_condition" and "inherits" values one by one from a single vector to the print & printer profiles. @@ -794,6 +829,7 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const return preset_name_dst; }; load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset().name, true); + load_one(this->sla_prints, tmp_bundle.sla_prints, tmp_bundle.sla_prints .get_selected_preset().name, true); load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filaments .get_selected_preset().name, true); load_one(this->sla_materials, tmp_bundle.sla_materials, tmp_bundle.sla_materials.get_selected_preset().name, true); load_one(this->printers, tmp_bundle.printers, tmp_bundle.printers .get_selected_preset().name, true); @@ -919,6 +955,7 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree, co static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree) { flatten_configbundle_hierarchy(tree, "print"); + flatten_configbundle_hierarchy(tree, "sla_print"); flatten_configbundle_hierarchy(tree, "filament"); flatten_configbundle_hierarchy(tree, "sla_material"); flatten_configbundle_hierarchy(tree, "printer"); @@ -957,10 +994,12 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla // Parse the obsolete preset names, to be deleted when upgrading from the old configuration structure. std::vector loaded_prints; std::vector loaded_filaments; + std::vector loaded_sla_prints; std::vector loaded_sla_materials; std::vector loaded_printers; std::string active_print; std::vector active_filaments; + std::string active_sla_print; std::string active_sla_material; std::string active_printer; size_t presets_loaded = 0; @@ -976,6 +1015,10 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla presets = &this->filaments; loaded = &loaded_filaments; preset_name = section.first.substr(9); + } else if (boost::starts_with(section.first, "sla_print:")) { + presets = &this->sla_prints; + loaded = &loaded_sla_prints; + preset_name = section.first.substr(13); } else if (boost::starts_with(section.first, "sla_material:")) { presets = &this->sla_materials; loaded = &loaded_sla_materials; @@ -996,6 +1039,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla active_filaments.resize(idx + 1, std::string()); active_filaments[idx] = kvp.second.data(); } + } else if (kvp.first == "sla_print") { + active_sla_print = kvp.second.data(); } else if (kvp.first == "sla_material") { active_sla_material = kvp.second.data(); } else if (kvp.first == "printer") { @@ -1011,6 +1056,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla dst = &this->obsolete_presets.prints; else if (kvp.first == "filament") dst = &this->obsolete_presets.filaments; + else if (kvp.first == "sla_print") + dst = &this->obsolete_presets.sla_prints; else if (kvp.first == "sla_material") dst = &this->obsolete_presets.sla_materials; else if (kvp.first == "printer") @@ -1113,6 +1160,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) { if (! active_print.empty()) prints.select_preset_by_name(active_print, true); + if (! active_sla_print.empty()) + sla_materials.select_preset_by_name(active_sla_print, true); if (! active_sla_material.empty()) sla_materials.select_preset_by_name(active_sla_material, true); if (! active_printer.empty()) @@ -1217,6 +1266,13 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible, [&prefered_sla_material_profile](const std::string& profile_name){ return profile_name == prefered_sla_material_profile; }); + + const std::string &prefered_sla_print_profile = printer_preset.config.opt_string("default_sla_print_profile"); + prefered_sla_print_profile.empty() ? + this->sla_prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : + this->sla_prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible, + [&prefered_sla_print_profile](const std::string& profile_name){ return profile_name == prefered_sla_print_profile; }); + break; } } @@ -1231,6 +1287,8 @@ void PresetBundle::export_configbundle(const std::string &path) //, const Dynami c << "# " << Slic3r::header_slic3r_generated() << std::endl; // Export the print, filament and printer profiles. + + // #ys_FIXME_SLA_PRINT for (size_t i_group = 0; i_group < 3; ++ i_group) { const PresetCollection &presets = (i_group == 0) ? this->prints : (i_group == 1) ? this->filaments : this->printers; for (const Preset &preset : presets()) { @@ -1246,6 +1304,7 @@ void PresetBundle::export_configbundle(const std::string &path) //, const Dynami // Export the names of the active presets. c << std::endl << "[presets]" << std::endl; c << "print = " << this->prints.get_selected_preset().name << std::endl; + c << "sla_print = " << this->sla_prints.get_selected_preset().name << std::endl; c << "sla_material = " << this->sla_materials.get_selected_preset().name << std::endl; c << "printer = " << this->printers.get_selected_preset().name << std::endl; for (size_t i = 0; i < this->filament_presets.size(); ++ i) { @@ -1401,6 +1460,7 @@ void PresetBundle::set_default_suppressed(bool default_suppressed) { prints.set_default_suppressed(default_suppressed); filaments.set_default_suppressed(default_suppressed); + sla_prints.set_default_suppressed(default_suppressed); sla_materials.set_default_suppressed(default_suppressed); printers.set_default_suppressed(default_suppressed); } diff --git a/src/slic3r/GUI/PresetBundle.hpp b/src/slic3r/GUI/PresetBundle.hpp index 07f89bc701..06ae950940 100644 --- a/src/slic3r/GUI/PresetBundle.hpp +++ b/src/slic3r/GUI/PresetBundle.hpp @@ -39,6 +39,7 @@ public: void export_selections(PlaceholderParser &pp); PresetCollection prints; + PresetCollection sla_prints; PresetCollection filaments; PresetCollection sla_materials; PrinterPresetCollection printers; @@ -57,6 +58,7 @@ public: struct ObsoletePresets { std::vector prints; + std::vector sla_prints; std::vector filaments; std::vector sla_materials; std::vector printers; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 307f9fe62b..2d42facb79 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -27,7 +27,6 @@ #include "wxExtensions.hpp" #include -#include #include "GUI_App.hpp" namespace Slic3r { @@ -41,6 +40,7 @@ wxDEFINE_EVENT(EVT_TAB_PRESETS_CHANGED, SimpleEvent); void Tab::set_type() { if (m_name == "print") { m_type = Slic3r::Preset::TYPE_PRINT; } + else if (m_name == "sla_print") { m_type = Slic3r::Preset::TYPE_SLA_PRINT; } else if (m_name == "filament") { m_type = Slic3r::Preset::TYPE_FILAMENT; } else if (m_name == "sla_material") { m_type = Slic3r::Preset::TYPE_SLA_MATERIAL; } else if (m_name == "printer") { m_type = Slic3r::Preset::TYPE_PRINTER; } @@ -828,6 +828,10 @@ void Tab::update_preset_description_line() const std::string &default_sla_material_profile = preset.config.opt_string("default_sla_material_profile"); if (!default_sla_material_profile.empty()) description_line += "\n\n\t" + _(L("default SLA material profile")) + ": \n\t\t" + default_sla_material_profile; + + const std::string &default_sla_print_profile = preset.config.opt_string("default_sla_print_profile"); + if (!default_sla_print_profile.empty()) + description_line += "\n\n\t" + _(L("default SLA print profile")) + ": \n\t\t" + default_sla_print_profile; break; } } @@ -2347,6 +2351,7 @@ void Tab::select_preset(std::string preset_name) auto current_dirty = m_presets->current_is_dirty(); auto printer_tab = m_presets->name() == "printer"; auto canceled = false; +// m_reload_dependent_tabs = {}; m_dependent_tabs = {}; if (current_dirty && !may_discard_current_dirty_preset()) { canceled = true; @@ -2370,6 +2375,7 @@ void Tab::select_preset(std::string preset_name) }; std::vector updates = { { Preset::Type::TYPE_PRINT, &m_preset_bundle->prints, ptFFF }, + { Preset::Type::TYPE_SLA_PRINT, &m_preset_bundle->sla_prints, ptSLA }, { Preset::Type::TYPE_FILAMENT, &m_preset_bundle->filaments, ptFFF }, { Preset::Type::TYPE_SLA_MATERIAL,&m_preset_bundle->sla_materials, ptSLA } }; @@ -2382,8 +2388,10 @@ void Tab::select_preset(std::string preset_name) if (! canceled) { for (PresetUpdate &pu : updates) { // The preset will be switched to a different, compatible preset, or the '-- default --'. - if (pu.technology == new_printer_technology) + if (pu.technology == new_printer_technology) { +// m_reload_dependent_tabs.emplace_back(pu.name); m_dependent_tabs.emplace_back(pu.tab_type); + } if (pu.old_preset_dirty) pu.presets->discard_current_changes(); } @@ -2918,7 +2926,7 @@ void TabSLAMaterial::build() auto page = add_options_page(_(L("Material")), "package_green.png"); auto optgroup = page->new_optgroup(_(L("Layers"))); - optgroup->append_single_option_line("layer_height"); +// optgroup->append_single_option_line("layer_height"); optgroup->append_single_option_line("initial_layer_height"); optgroup = page->new_optgroup(_(L("Exposure"))); @@ -2973,7 +2981,43 @@ void TabSLAMaterial::build() void TabSLAMaterial::update() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) - return; // ys_FIXME + return; // #ys_FIXME +} + +void TabSLAPrint::build() +{ + m_presets = &m_preset_bundle->sla_prints; + load_initial_data(); + + auto page = add_options_page(_(L("Layers and perimeters")), "package_green.png"); + + auto optgroup = page->new_optgroup(_(L("Layers"))); + optgroup->append_single_option_line("layer_height"); + + page = add_options_page(_(L("Dependencies")), "wrench.png"); + optgroup = page->new_optgroup(_(L("Profile dependencies"))); + Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" }; + line.widget = [this](wxWindow* parent) { + return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn); + }; + optgroup->append_line(line, &m_colored_Label); + + Option option = optgroup->get_option("compatible_printers_condition"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); + + line = Line{ "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_parent_preset_description_line); + }; + optgroup->append_line(line); +} + +void TabSLAPrint::update() +{ + if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) + return; // #ys_FIXME } } // GUI diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 0f2b1b41c7..9b897b6f7a 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -370,6 +370,19 @@ public: bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptSLA; } }; +class TabSLAPrint : public Tab +{ +public: + TabSLAPrint() {} + TabSLAPrint(wxNotebook* parent) : + Tab(parent, _(L("SLA Print Settings")), "sla_print") {} + ~TabSLAPrint() {} + void build() override; + void update() override; +// void init_options_list() override; + bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptSLA; } +}; + class SavePresetWindow :public wxDialog { public: From ae4f116b460c057f64dbb48d7e6bc40719b77fe9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 19 Nov 2018 09:15:53 +0100 Subject: [PATCH 15/23] Added the context to the TabPrintSLA --- src/slic3r/GUI/MainFrame.cpp | 9 ++------- src/slic3r/GUI/Tab.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 458c322620..099bec5c54 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -204,19 +204,14 @@ void MainFrame::create_preset_tabs() void MainFrame::add_created_tab(Tab* panel) { panel->create_preset_tab(); - /* + const wxString& tab_name = panel->GetName(); - bool add_panel = true; auto it = std::find_if(preset_tabs.begin(), preset_tabs.end(), [tab_name](PresetTab& tab) {return tab.name == tab_name; }); - if (it != preset_tabs.end()) { + if (it != preset_tabs.end()) it->panel = panel; - add_panel = it->technology == wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); - } - if (add_panel) -*/ if (panel->supports_printer_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology())) m_tabpanel->AddPage(panel, panel->title()); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 2d42facb79..72147d6c7d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2994,6 +2994,28 @@ void TabSLAPrint::build() auto optgroup = page->new_optgroup(_(L("Layers"))); optgroup->append_single_option_line("layer_height"); + page = add_options_page(_(L("Supports")), "building.png"); + optgroup = page->new_optgroup(_(L("Support head"))); + optgroup->append_single_option_line("support_head_front_radius"); + optgroup->append_single_option_line("support_head_back_radius"); + optgroup->append_single_option_line("support_head_penetration"); + optgroup->append_single_option_line("support_head_width"); + + optgroup = page->new_optgroup(_(L("Support pillar"))); + optgroup->append_single_option_line("support_pillar_radius"); + optgroup->append_single_option_line("support_base_radius"); + optgroup->append_single_option_line("support_base_height"); + + optgroup = page->new_optgroup(_(L("Connection of the support sticks and junctions"))); + optgroup->append_single_option_line("support_critical_angle"); + optgroup->append_single_option_line("support_max_bridge_length"); + + optgroup = page->new_optgroup(_(L("Pad"))); + optgroup->append_single_option_line("pad_wall_thickness"); + optgroup->append_single_option_line("pad_wall_height"); + optgroup->append_single_option_line("pad_max_merge_distance"); + optgroup->append_single_option_line("pad_edge_radius"); + page = add_options_page(_(L("Dependencies")), "wrench.png"); optgroup = page->new_optgroup(_(L("Profile dependencies"))); Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" }; From 703f367e6961c16cfcd9c0a156eb541ee4548f85 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 19 Nov 2018 11:10:22 +0100 Subject: [PATCH 16/23] Fixed preset updating --- src/slic3r/GUI/AppConfig.cpp | 1 + src/slic3r/GUI/MainFrame.cpp | 19 ------------------- src/slic3r/GUI/Plater.cpp | 2 -- src/slic3r/GUI/PresetBundle.cpp | 8 +++++--- src/slic3r/Utils/PresetUpdater.cpp | 3 ++- 5 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index d7307cc320..7a277b1191 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -241,6 +241,7 @@ void AppConfig::reset_selections() if (it != m_storage.end()) { it->second.erase("print"); it->second.erase("filament"); + it->second.erase("sla_print"); it->second.erase("sla_material"); it->second.erase("printer"); m_dirty = true; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 099bec5c54..3e454061fd 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -796,7 +796,6 @@ void MainFrame::on_presets_changed(SimpleEvent &event) // Update preset combo boxes(Print settings, Filament, Material, Printer) from their respective tabs. auto presets = tab->get_presets(); if (m_plater != nullptr && presets != nullptr) { -// auto reload_dependent_tabs = tab->get_dependent_tabs(); // FIXME: The preset type really should be a property of Tab instead Slic3r::Preset::Type preset_type = tab->type(); @@ -804,25 +803,7 @@ void MainFrame::on_presets_changed(SimpleEvent &event) wxASSERT(false); return; } -/* - m_plater->sidebar().update_presets(preset_type); - if (preset_type == Slic3r::Preset::TYPE_PRINTER) { - // Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors. - // XXX: Do this in a more C++ way - for (const auto tab_name_other : { "print", "filament", "sla_material" }) { - Tab* cur_tab = m_options_tabs[tab_name_other]; - // If the printer tells us that the print or filament preset has been switched or invalidated, - // refresh the print or filament tab page.Otherwise just refresh the combo box. - if (reload_dependent_tabs.empty() || - find(reload_dependent_tabs.begin(), reload_dependent_tabs.end(), tab_name_other) == - reload_dependent_tabs.end() ) - cur_tab->update_tab_ui(); - else - cur_tab->load_current_preset(); - } - } -*/ m_plater->on_config_change(*tab->get_config()); m_plater->sidebar().update_presets(preset_type); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index eb0d7cc494..5bef5deb1c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1879,8 +1879,6 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) } } - // Synchronize config.ini with the current selections. - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); // update plater with new config wxGetApp().plater()->on_config_change(wxGetApp().preset_bundle->full_config()); } diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index c092cae431..55729d7e4e 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -168,12 +168,14 @@ void PresetBundle::setup_directories() data_dir / "presets", data_dir / "presets" / "print", data_dir / "presets" / "filament", + data_dir / "presets" / "sla_print", data_dir / "presets" / "sla_material", data_dir / "presets" / "printer" #else // Store the print/filament/printer presets at the same location as the upstream Slic3r. data_dir / "print", data_dir / "filament", + data_dir / "sla_print", data_dir / "sla_material", data_dir / "printer" #endif @@ -381,13 +383,13 @@ void PresetBundle::export_selections(AppConfig &config) assert(this->printers.get_edited_preset().printer_technology() != ptFFF || filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front()); config.clear_section("presets"); config.set("presets", "print", prints.get_selected_preset_name()); - config.set("presets", "sla_print", sla_prints.get_selected_preset_name()); config.set("presets", "filament", filament_presets.front()); for (int i = 1; i < filament_presets.size(); ++i) { char name[64]; sprintf(name, "filament_%d", i); config.set("presets", name, filament_presets[i]); } + config.set("presets", "sla_print", sla_prints.get_selected_preset_name()); config.set("presets", "sla_material", sla_materials.get_selected_preset_name()); config.set("presets", "printer", printers.get_selected_preset_name()); } @@ -955,8 +957,8 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree, co static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree) { flatten_configbundle_hierarchy(tree, "print"); - flatten_configbundle_hierarchy(tree, "sla_print"); flatten_configbundle_hierarchy(tree, "filament"); + flatten_configbundle_hierarchy(tree, "sla_print"); flatten_configbundle_hierarchy(tree, "sla_material"); flatten_configbundle_hierarchy(tree, "printer"); } @@ -1018,7 +1020,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla } else if (boost::starts_with(section.first, "sla_print:")) { presets = &this->sla_prints; loaded = &loaded_sla_prints; - preset_name = section.first.substr(13); + preset_name = section.first.substr(10); } else if (boost::starts_with(section.first, "sla_material:")) { presets = &this->sla_materials; loaded = &loaded_sla_materials; diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 026e340da5..47eece8abd 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -448,7 +448,8 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons for (const auto &name : bundle.obsolete_presets.prints) { obsolete_remover("print", name); } for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("filament", name); } - for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("sla_material", name); } + for (const auto &name : bundle.obsolete_presets.sla_prints) { obsolete_remover("sla_print", name); } + for (const auto &name : bundle.obsolete_presets.sla_materials/*filaments*/) { obsolete_remover("sla_material", name); } for (const auto &name : bundle.obsolete_presets.printers) { obsolete_remover("printer", name); } } } From 398f15d54684540220dedc202f9ae87d33ac9413 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 19 Nov 2018 13:17:14 +0100 Subject: [PATCH 17/23] Some code rebase --- src/slic3r/GUI/MainFrame.cpp | 73 ++++++------------------------------ src/slic3r/GUI/MainFrame.hpp | 7 ---- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 18 ++++----- 4 files changed, 21 insertions(+), 79 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 3e454061fd..94bb0bd5eb 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -109,20 +109,15 @@ void MainFrame::init_tabpanel() m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) { auto panel = m_tabpanel->GetCurrentPage(); -// panel->OnActivate(); if panel->can('OnActivate'); if (panel == nullptr) return; - for (auto& tab_name : { "print", "filament", "printer" }) { - if (tab_name == panel->GetName()) { - // On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered - // before the MainFrame is fully set up. - auto it = m_options_tabs.find(tab_name); - assert(it != m_options_tabs.end()); - if (it != m_options_tabs.end()) - it->second->OnActivate(); - } + auto& tabs_list = wxGetApp().tabs_list; + if (find(tabs_list.begin(), tabs_list.end(), panel) != tabs_list.end()) { + // On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered + // before the MainFrame is fully set up. + static_cast(panel)->OnActivate(); } }); @@ -140,9 +135,6 @@ void MainFrame::init_tabpanel() Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); create_preset_tabs(); - std::vector tab_names = { "print", "filament", "sla_print", "sla_material", "printer" }; - for (auto tab_name : tab_names) - m_options_tabs[tab_name] = get_preset_tab(tab_name.c_str()); if (m_plater) { // load initial config @@ -157,46 +149,12 @@ void MainFrame::init_tabpanel() } } -std::vector preset_tabs = { - { "print", nullptr, ptFFF }, - { "filament", nullptr, ptFFF }, - { "sla_print", nullptr, ptSLA }, - { "sla_material", nullptr, ptSLA } -}; - -std::vector& MainFrame::get_preset_tabs() { - return preset_tabs; -} - -Tab* MainFrame::get_tab(const std::string& name) -{ - std::vector::iterator it = std::find_if(preset_tabs.begin(), preset_tabs.end(), - [name](PresetTab& tab) { return name == tab.name; }); - return it != preset_tabs.end() ? it->panel : nullptr; -} - -Tab* MainFrame::get_preset_tab(const std::string& name) -{ - Tab* tab = get_tab(name); - if (tab) return tab; - - for (size_t i = 0; i < m_tabpanel->GetPageCount(); ++i) { - tab = dynamic_cast(m_tabpanel->GetPage(i)); - if (!tab) - continue; - if (tab->name() == name) { - return tab; - } - } - return nullptr; -} - void MainFrame::create_preset_tabs() { wxGetApp().update_label_colours_from_appconfig(); add_created_tab(new TabPrint(m_tabpanel)); - add_created_tab(new TabSLAPrint(m_tabpanel)); add_created_tab(new TabFilament(m_tabpanel)); + add_created_tab(new TabSLAPrint(m_tabpanel)); add_created_tab(new TabSLAMaterial(m_tabpanel)); add_created_tab(new TabPrinter(m_tabpanel)); } @@ -205,14 +163,9 @@ void MainFrame::add_created_tab(Tab* panel) { panel->create_preset_tab(); - const wxString& tab_name = panel->GetName(); + const auto printer_tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); - auto it = std::find_if(preset_tabs.begin(), preset_tabs.end(), - [tab_name](PresetTab& tab) {return tab.name == tab_name; }); - if (it != preset_tabs.end()) - it->panel = panel; - - if (panel->supports_printer_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology())) + if (panel->supports_printer_technology(printer_tech)) m_tabpanel->AddPage(panel, panel->title()); } @@ -767,8 +720,8 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re // Also update the platter with the new presets. void MainFrame::load_config(const DynamicPrintConfig& config) { - for (auto tab : m_options_tabs) - tab.second->load_config(config); + for (auto tab : wxGetApp().tabs_list) + tab->load_config(config); if (m_plater) m_plater->on_config_change(config); } @@ -838,11 +791,7 @@ void MainFrame::update_ui_from_settings() { m_menu_item_reslice_now->Enable(wxGetApp().app_config->get("background_processing") == "1"); // if (m_plater) m_plater->update_ui_from_settings(); - /* - std::vector tab_names = { "print", "filament", "printer" }; - for (auto tab_name: tab_names) - m_options_tabs[tab_name]->update_ui_from_settings(); - */ + for (auto tab: wxGetApp().tabs_list) tab->update_ui_from_settings(); } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index b324586c45..8cac3e8e23 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -53,8 +53,6 @@ class MainFrame : public wxFrame wxString m_qs_last_output_file = wxEmptyString; wxString m_last_config = wxEmptyString; - std::map m_options_tabs; - wxMenuItem* m_menu_item_repeat { nullptr }; wxMenuItem* m_menu_item_reslice_now { nullptr }; #if !ENABLE_NEW_MENU_LAYOUT @@ -67,7 +65,6 @@ class MainFrame : public wxFrame void on_presets_changed(SimpleEvent&); void on_value_changed(wxCommandEvent&); - Tab* get_tab(const std::string& name); #if ENABLE_NEW_MENU_LAYOUT bool can_save() const; @@ -84,8 +81,6 @@ public: Plater* plater() { return m_plater; } void init_tabpanel(); - const std::map& options_tabs() const { return m_options_tabs; } - Tab* get_preset_tab(const std::string& name); void create_preset_tabs(); void add_created_tab(Tab* panel); void init_menubar(); @@ -105,8 +100,6 @@ public: void select_tab(size_t tab) const; void select_view(const std::string& direction); - std::vector& get_preset_tabs(); - Plater* m_plater { nullptr }; wxNotebook* m_tabpanel { nullptr }; wxProgressDialog* m_progress_dialog { nullptr }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5bef5deb1c..abf58798f1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2027,7 +2027,7 @@ void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) DynamicPrintConfig cfg; cfg.opt("wipe_tower_x", true)->value = evt.data(0); cfg.opt("wipe_tower_y", true)->value = evt.data(1); - main_frame->get_preset_tab("print")->load_config(cfg); + wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); } void Plater::priv::on_enable_action_buttons(Event&) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 72147d6c7d..4c9e56bbd9 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -765,9 +765,7 @@ void Tab::on_presets_changed() { // If the printer tells us that the print or filament/sla_material preset has been switched or invalidated, // refresh the print or filament/sla_material tab page. - Tab* tab = wxGetApp().get_tab(t); - if (tab) - tab->load_current_preset(); + wxGetApp().get_tab(t)->load_current_preset(); } } @@ -2251,14 +2249,16 @@ void Tab::load_current_preset() PrinterTechnology& printer_technology = m_presets->get_edited_preset().printer_technology(); if (printer_technology != static_cast(this)->m_printer_technology) { - for (auto& tab : wxGetApp().mainframe->get_preset_tabs()) { - if (tab.technology != printer_technology) - { - int page_id = wxGetApp().tab_panel()->FindPage(tab.panel); + for (auto tab : wxGetApp().tabs_list) { + if (tab->type() == Preset::TYPE_PRINTER) // Printer tab is shown every time + continue; + if (tab->supports_printer_technology(printer_technology)) + wxGetApp().tab_panel()->InsertPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title()); + else { + int page_id = wxGetApp().tab_panel()->FindPage(tab); wxGetApp().tab_panel()->GetPage(page_id)->Show(false); wxGetApp().tab_panel()->RemovePage(page_id); - } else - wxGetApp().tab_panel()->InsertPage(wxGetApp().tab_panel()->FindPage(this), tab.panel, tab.panel->title()); + } } static_cast(this)->m_printer_technology = printer_technology; } From d658d918d764899b01b9bbb3a4fc11c771185e66 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 19 Nov 2018 14:01:14 +0100 Subject: [PATCH 18/23] Fixed crashing when project with modifier is imported --- src/slic3r/GUI/GUI_ObjectList.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 25aaf16f25..0d70a7ae56 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1123,7 +1123,8 @@ void ObjectList::add_object_to_list(size_t obj_idx) m_objects_model->AddVolumeChild(item, model_object->volumes[id]->name, ModelVolume::MODEL_PART, - model_object->volumes[id]->config.option("extruder")->value, + !model_object->volumes[id]->config.has("extruder") ? 0 : + model_object->volumes[id]->config.option("extruder")->value, false); Expand(item); } From d322fa0fd560b97f1fa2299f83e8dd9b31d1ceb3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 19 Nov 2018 14:46:37 +0100 Subject: [PATCH 19/23] Fixed gizmos overlay rendering/selection by adding GLGizmoBase::is_selectable() method --- src/slic3r/GUI/GLCanvas3D.cpp | 17 +++++++++++------ src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GLGizmo.cpp | 5 +++++ src/slic3r/GUI/GLGizmo.hpp | 7 +++++-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d45bdf685a..d3d5320c1e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2317,11 +2317,15 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); gizmo = new GLGizmoCut(parent); - if (! gizmo->init()) { + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) { + _reset(); return false; } - m_gizmos.insert({ Cut, gizmo }); + m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); gizmo = new GLGizmoSlaSupports(parent); if (gizmo == nullptr) @@ -2359,7 +2363,7 @@ std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, con float top_y = 0.5f * (cnv_h - height); for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { - if (it->second == nullptr) + if ((it->second == nullptr) || !it->second->is_selectable()) continue; float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale; @@ -2389,7 +2393,7 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec float top_y = 0.5f * (cnv_h - height); for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { - if (it->second == nullptr) + if ((it->second == nullptr) || !it->second->is_selectable()) continue; float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale; @@ -2487,7 +2491,7 @@ bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const float top_y = 0.5f * (cnv_h - height); for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { - if (it->second == nullptr) + if ((it->second == nullptr) || !it->second->is_selectable()) continue; float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale; @@ -2739,8 +2743,9 @@ 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 (it->first == SlaSupports && wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) + if ((it->second == nullptr) || !it->second->is_selectable()) 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); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index cf7c840854..a45ceb846b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -565,8 +565,8 @@ private: Scale, Rotate, Flatten, - SlaSupports, Cut, + SlaSupports, Num_Types }; diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 54dd1427da..3f7dc6cacf 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1779,6 +1779,11 @@ bool GLGizmoSlaSupports::on_is_activable(const GLCanvas3D::Selection& selection) return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA); } +bool GLGizmoSlaSupports::on_is_selectable() const +{ + return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA); +} + std::string GLGizmoSlaSupports::on_get_name() const { return L("SLA Support Points"); diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index 376c286904..feebc00e38 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -101,6 +101,7 @@ public: void set_state(EState state) { m_state = state; on_set_state(); } bool is_activable(const GLCanvas3D::Selection& selection) const { return on_is_activable(selection); } + bool is_selectable() const { return on_is_selectable(); } unsigned int get_texture_id() const { return m_textures[m_state].get_id(); } int get_textures_size() const { return m_textures[Off].get_width(); } @@ -134,6 +135,7 @@ protected: virtual void on_set_state() {} virtual void on_set_hover_id() {} virtual bool on_is_activable(const GLCanvas3D::Selection& selection) const { return true; } + virtual bool on_is_selectable() const { return true; } virtual void on_enable_grabber(unsigned int id) {} virtual void on_disable_grabber(unsigned int id) {} virtual void on_start_dragging(const GLCanvas3D::Selection& selection) {} @@ -454,8 +456,9 @@ protected: } } - std::string on_get_name() const override; - bool on_is_activable(const GLCanvas3D::Selection& selection) const override; + virtual std::string on_get_name() const; + virtual bool on_is_activable(const GLCanvas3D::Selection& selection) const; + virtual bool on_is_selectable() const; }; From c5bb8bb4a197404d32db6259f9f68538f291c765 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 19 Nov 2018 15:34:34 +0100 Subject: [PATCH 20/23] Fixed export to 3mf of objects splitted into parts --- src/libslic3r/Format/3mf.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 6e8483949d..0c2e20ea42 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1858,7 +1858,7 @@ namespace Slic3r { if (volume == nullptr) continue; - VolumeToOffsetsMap::iterator volume_it = volumes_offsets.insert(VolumeToOffsetsMap::value_type(volume, Offsets(vertices_count))).first; + volumes_offsets.insert(VolumeToOffsetsMap::value_type(volume, Offsets(vertices_count))).first; if (!volume->mesh.repaired) volume->mesh.repair(); @@ -1878,9 +1878,16 @@ namespace Slic3r { for (int i = 0; i < stl.stats.shared_vertices; ++i) { stream << " <" << VERTEX_TAG << " "; +#if ENABLE_MODELVOLUME_TRANSFORM + Vec3d v = volume->get_matrix() * stl.v_shared[i].cast(); + stream << "x=\"" << v(0) << "\" "; + stream << "y=\"" << v(1) << "\" "; + stream << "z=\"" << v(2) << "\" />\n"; +#else stream << "x=\"" << stl.v_shared[i](0) << "\" "; stream << "y=\"" << stl.v_shared[i](1) << "\" "; stream << "z=\"" << stl.v_shared[i](2) << "\" />\n"; +#endif // ENABLE_MODELVOLUME_TRANSFORM } } From 946d43bc9531ee543f8272a690a968e73c127a55 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 19 Nov 2018 15:49:59 +0100 Subject: [PATCH 21/23] Improved fix of export to 3mf of objects splitted into parts --- src/libslic3r/Format/3mf.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 0c2e20ea42..6356fa17a6 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1875,11 +1875,15 @@ namespace Slic3r { vertices_count += stl.stats.shared_vertices; +#if ENABLE_MODELVOLUME_TRANSFORM + Transform3d matrix = volume->get_matrix(); +#endif // ENABLE_MODELVOLUME_TRANSFORM + for (int i = 0; i < stl.stats.shared_vertices; ++i) { stream << " <" << VERTEX_TAG << " "; #if ENABLE_MODELVOLUME_TRANSFORM - Vec3d v = volume->get_matrix() * stl.v_shared[i].cast(); + Vec3d v = matrix * stl.v_shared[i].cast(); stream << "x=\"" << v(0) << "\" "; stream << "y=\"" << v(1) << "\" "; stream << "z=\"" << v(2) << "\" />\n"; From 87d49cf82ffafc409858dc8ccfa54bd6fedc11d9 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 19 Nov 2018 17:58:08 +0100 Subject: [PATCH 22/23] Adding object elevation param. Quick attempt to build with MinGW 7.3. Successful compile, failed linking --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/avrdude/CMakeLists.txt | 2 +- src/avrdude/main.c | 2 +- src/libslic3r/PrintConfig.cpp | 12 +++++++++-- src/libslic3r/PrintConfig.hpp | 1 + src/libslic3r/SLA/SLASupportTree.cpp | 16 ++++++++------- src/libslic3r/SLA/SLASupportTree.hpp | 2 +- src/libslic3r/SLAPrint.cpp | 30 ++++++++++++++++------------ src/slic3r/GUI/Preset.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 2 +- 12 files changed, 45 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 520b913c18..18a3be3a33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ if(SLIC3R_STATIC) # set(Boost_USE_STATIC_RUNTIME ON) endif() #set(Boost_DEBUG ON) -set(Boost_COMPILER "-vc120") +# set(Boost_COMPILER "-vc120") find_package(Boost REQUIRED COMPONENTS system filesystem thread log locale regex) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 32d2c5b03f..21ee023d1c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,7 +80,7 @@ elseif (MSVC) # Manifest is provided through slic3r.rc, don't generate your own. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") else () - target_link_libraries(slic3r -ldl -lstdc++) + target_link_libraries(slic3r ${CMAKE_DL_LIBS} -lstdc++) endif () # Add the Slic3r GUI library, libcurl, OpenGL and GLU libraries. diff --git a/src/avrdude/CMakeLists.txt b/src/avrdude/CMakeLists.txt index d885633689..ad0835ec01 100644 --- a/src/avrdude/CMakeLists.txt +++ b/src/avrdude/CMakeLists.txt @@ -66,7 +66,7 @@ set(AVRDUDE_SOURCES avrdude-slic3r.hpp avrdude-slic3r.cpp ) -if (WIN32) +if (MSVC) set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES} windows/unistd.cpp windows/getopt.c diff --git a/src/avrdude/main.c b/src/avrdude/main.c index ebda0ba19b..9ada27be35 100644 --- a/src/avrdude/main.c +++ b/src/avrdude/main.c @@ -43,7 +43,7 @@ #include #include -#if !defined(WIN32NATIVE) +#if !defined(WIN32NATIVE) || defined(__GNUC__) # include # include # include diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1e8f26d381..96c4922926 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2515,7 +2515,15 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->cli = ""; def->min = 0; - def->default_value = new ConfigOptionFloat(); + def->default_value = new ConfigOptionFloat(15.0); + + def = this->add("support_object_elevation", coFloat); + def->label = L("Object elevation"); + def->tooltip = L("How much the supports should lift up the supported object."); + def->sidetext = L("mm"); + def->cli = ""; + def->min = 0; + def->default_value = new ConfigOptionFloat(5.0); def = this->add("pad_wall_thickness", coFloat); def->label = L("Pad wall thickness"); @@ -2542,7 +2550,7 @@ void PrintConfigDef::init_sla_params() def->default_value = new ConfigOptionFloat(50.0); def = this->add("pad_edge_radius", coFloat); - def->label = L("pad edge radius"); + def->label = L("Pad edge radius"); def->tooltip = L(""); def->sidetext = L("mm"); def->cli = ""; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 8c9fb00565..54d6274a9c 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -960,6 +960,7 @@ protected: OPT_PTR(support_base_height); OPT_PTR(support_critical_angle); OPT_PTR(support_max_bridge_length); + OPT_PTR(support_object_elevation); OPT_PTR(pad_wall_thickness); OPT_PTR(pad_wall_height); OPT_PTR(pad_max_merge_distance); diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index 029c45069c..55e0c5010a 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -510,7 +510,9 @@ struct Pad { Pad(const TriangleMesh& object_support_mesh, const ExPolygons& baseplate, double ground_level, - const PoolConfig& cfg) : zlevel(ground_level + cfg.min_wall_height_mm/2) + const PoolConfig& pcfg) : + cfg(pcfg), + zlevel(ground_level + cfg.min_wall_height_mm/2) { ExPolygons basep; base_plate(object_support_mesh, basep, @@ -1092,7 +1094,7 @@ bool SLASupportTree::generate(const PointSet &points, cfg.head_back_radius_mm, cfg.head_front_radius_mm, cfg.head_width_mm, - cfg.head_penetraiton_mm, + cfg.head_penetration_mm, nmls.row(i), // dir head_pos.row(i) // displacement ); @@ -1460,7 +1462,7 @@ bool SLASupportTree::generate(const PointSet &points, Head base_head(cfg.head_back_radius_mm, cfg.head_front_radius_mm, cfg.head_width_mm, - cfg.head_penetraiton_mm, + cfg.head_penetration_mm, {0.0, 0.0, 1.0}, {headend(X), headend(Y), headend(Z) - gh}); @@ -1659,10 +1661,10 @@ const TriangleMesh &SLASupportTree::add_pad(const SliceLayer& baseplate, TriangleMesh mm; merged_mesh(mm); PoolConfig pcfg; -// pcfg.min_wall_thickness_mm = min_wall_thickness_mm; -// pcfg.min_wall_height_mm = min_wall_height_mm; -// pcfg.max_merge_distance_mm = max_merge_distance_mm; -// pcfg.edge_radius_mm = edge_radius_mm; + pcfg.min_wall_thickness_mm = min_wall_thickness_mm; + pcfg.min_wall_height_mm = min_wall_height_mm; + pcfg.max_merge_distance_mm = max_merge_distance_mm; + pcfg.edge_radius_mm = edge_radius_mm; return m_impl->create_pad(mm, baseplate, pcfg).tmesh; } diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index cf61f07b0d..6295a45b08 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -33,7 +33,7 @@ struct SupportConfig { double head_front_radius_mm = 0.2; // How much the pinhead has to penetrate the model surface - double head_penetraiton_mm = 0.5; + double head_penetration_mm = 0.5; // Radius of the back side of the 3d arrow. double head_back_radius_mm = 0.5; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 27566365c7..aad86e9a15 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -85,7 +85,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, // Temporary: just to have to correct layer height for the rasterization DynamicPrintConfig config(config_in); config.normalize(); - auto lh = config.opt("layer_height"); + //auto lh = config.opt("layer_height"); // Temporary quick fix, just invalidate everything. { @@ -102,7 +102,10 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, // Generate new SLAPrintObjects. for (ModelObject *model_object : m_model.objects) { auto po = new SLAPrintObject(this, model_object); - po->m_config.layer_height.set(lh); + + // po->m_config.layer_height.set(lh); + po->m_config.apply(config, true); + m_objects.emplace_back(po); for (ModelInstance *oinst : model_object->instances) { Point tr = Point::new_scale(oinst->get_offset()(X), @@ -172,14 +175,14 @@ void SLAPrint::process() sla::SupportConfig scfg; SLAPrintObjectConfig& c = po.m_config; -// scfg.head_front_radius_mm = c.support_head_front_radius.getFloat(); -// scfg.head_back_radius_mm = c.support_head_back_radius.getFloat(); -// scfg.head_penetraiton_mm = c.support_head_penetraiton.getFloat(); -// scfg.head_width_mm = c.support_head_width.getFloat(); -// scfg.object_elevation_mm = c.support_object_elevation.getFloat(); -// scfg.tilt = c.support_critical_angle.getFloat() * 180.0 / PI; -// scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); -// scfg.pillar_radius_mm = c.support_pillar_radius.getFloat(); + scfg.head_front_radius_mm = c.support_head_front_radius.getFloat(); + scfg.head_back_radius_mm = c.support_head_back_radius.getFloat(); + scfg.head_penetration_mm = c.support_head_penetration.getFloat(); + scfg.head_width_mm = c.support_head_width.getFloat(); + scfg.object_elevation_mm = c.support_object_elevation.getFloat(); + scfg.tilt = c.support_critical_angle.getFloat() * PI / 180.0 ; + scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); + scfg.pillar_radius_mm = c.support_pillar_radius.getFloat(); sla::Controller ctl; ctl.statuscb = [this](unsigned st, const std::string& msg) { @@ -216,10 +219,11 @@ void SLAPrint::process() double lh = po.m_config.layer_height.getFloat(); double elevation = po.m_config.support_object_elevation.getFloat(); + std::cout << "Pad height " << h << std::endl; + sla::ExPolygons bp; - if(elevation < h/2) - sla::base_plate(po.transformed_mesh(), bp, - float(h/2), float(lh)); + if(elevation < h/2) sla::base_plate(po.transformed_mesh(), bp, + float(h/2), float(lh)); po.m_supportdata->support_tree_ptr->add_pad(bp, wt, h, md, er); } diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 1599af0c4d..541e5c79b7 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -411,6 +411,7 @@ const std::vector& Preset::sla_print_options() "support_base_height", "support_critical_angle", "support_max_bridge_length", + "support_object_elevation", "pad_wall_thickness", "pad_wall_height", "pad_max_merge_distance", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 4c9e56bbd9..dcd5f33fcf 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3005,6 +3005,7 @@ void TabSLAPrint::build() optgroup->append_single_option_line("support_pillar_radius"); optgroup->append_single_option_line("support_base_radius"); optgroup->append_single_option_line("support_base_height"); + optgroup->append_single_option_line("support_object_elevation"); optgroup = page->new_optgroup(_(L("Connection of the support sticks and junctions"))); optgroup->append_single_option_line("support_critical_angle"); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 5d0b44d471..b80976e652 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -308,7 +308,7 @@ bool PrusaCollapsiblePaneMSW::Create(wxWindow *parent, wxWindowID id, const wxSt m_pPane = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER, wxT("wxCollapsiblePanePane")); - wxColour& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + wxColour&& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); m_pDisclosureTriangleButton->SetBackgroundColour(clr); this->SetBackgroundColour(clr); m_pPane->SetBackgroundColour(clr); From 7482b619b55805444ceb2c3828baad51937f29b9 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 20 Nov 2018 11:59:40 +0100 Subject: [PATCH 23/23] Working on proper merging and leveling of the support layers. --- src/libslic3r/SLA/SLABasePool.cpp | 6 --- src/libslic3r/SLAPrint.cpp | 71 ++++++++++++++++++++----------- src/libslic3r/SLAPrint.hpp | 5 ++- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/libslic3r/SLA/SLABasePool.cpp b/src/libslic3r/SLA/SLABasePool.cpp index 3a92f371ec..6ecc63576a 100644 --- a/src/libslic3r/SLA/SLABasePool.cpp +++ b/src/libslic3r/SLA/SLABasePool.cpp @@ -424,12 +424,6 @@ void base_plate(const TriangleMesh &mesh, ExPolygons &output, float h, TriangleMesh m = mesh; TriangleMeshSlicer slicer(&m); -// TriangleMesh upper, lower; -// slicer.cut(h, &upper, &lower); - - // TODO: this might be slow (in fact it was) -// output = lower.horizontal_projection(); - auto bb = mesh.bounding_box(); float gnd = float(bb.min(Z)); std::vector heights = {float(bb.min(Z))}; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index aad86e9a15..e9e2688cf8 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -85,7 +85,8 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, // Temporary: just to have to correct layer height for the rasterization DynamicPrintConfig config(config_in); config.normalize(); - //auto lh = config.opt("layer_height"); + m_material_config.initial_layer_height.set( + config.opt("initial_layer_height")); // Temporary quick fix, just invalidate everything. { @@ -129,6 +130,8 @@ void SLAPrint::process() // shortcut to initial layer height auto ilh = float(m_material_config.initial_layer_height.getFloat()); + std::cout << "Initial layer height: " << m_material_config.initial_layer_height.getFloat() << std::endl; + // Slicing the model object. This method is oversimplified and needs to // be compared with the fff slicing algorithm for verification auto slice_model = [this, ilh](SLAPrintObject& po) { @@ -140,8 +143,12 @@ void SLAPrint::process() auto H = bb3d.max(Z) - bb3d.min(Z); auto gnd = float(bb3d.min(Z)); + + double elevation = po.m_config.support_object_elevation.getFloat(); + float ih = elevation > 0 ? lh : ilh; + std::vector heights = {gnd}; - for(float h = gnd + ilh; h < gnd + H; h += lh) heights.emplace_back(h); + for(float h = gnd + ih; h < gnd + H; h += lh) heights.emplace_back(h); auto& layers = po.m_model_slices; slicer.slice(heights, &layers, [this](){ @@ -219,8 +226,6 @@ void SLAPrint::process() double lh = po.m_config.layer_height.getFloat(); double elevation = po.m_config.support_object_elevation.getFloat(); - std::cout << "Pad height " << h << std::endl; - sla::ExPolygons bp; if(elevation < h/2) sla::base_plate(po.transformed_mesh(), bp, float(h/2), float(lh)); @@ -251,43 +256,59 @@ void SLAPrint::process() lref(std::cref(lyr)), copies(std::cref(cp)) {} }; + using LevelID = long long; using LayerRefs = std::vector; // layers according to quantized height levels - std::map levels; + std::map levels; + + auto sinitlh = LevelID(scale_(ilh)); // For all print objects, go through its initial layers and place them // into the layers hash for(SLAPrintObject *o : m_objects) { double gndlvl = o->transformed_mesh().bounding_box().min(Z); + double elevation = o->m_config.support_object_elevation.getFloat(); double lh = o->m_config.layer_height.getFloat(); + + // TODO: this juust misses the support layers with a slight offset... + double ih = elevation > 0 ? lh : ilh; + + auto sgl = LevelID(scale_(gndlvl)); + auto slh = LevelID(scale_(lh)); // scaled layer height + auto sih = LevelID(scale_(ih)); + SlicedModel & oslices = o->m_model_slices; for(int i = 0; i < oslices.size(); ++i) { int a = i == 0 ? 0 : 1; int b = i == 0 ? 0 : i - 1; - double h = gndlvl + ilh * a + b * lh; - long long lyridx = static_cast(scale_(h)); - auto& lyrs = levels[lyridx]; // this initializes a new record + LevelID h = sgl + sih * a + b * slh; + + std::cout << "Model layer level: " << h << std::endl; + + auto& lyrs = levels[h]; // this initializes a new record lyrs.emplace_back(oslices[i], o->m_instances); } if(o->m_supportdata) { // deal with the support slices if present auto& sslices = o->m_supportdata->support_slices; - double el = o->m_config.support_object_elevation.getFloat(); - //TODO: remove next line: - el = SupportConfig().object_elevation_mm; + + // Supports start below the ground level. + // Counting the pad height as well + double el = o->get_elevation(); + auto sel = LevelID(scale_(el)); for(int i = 0; i < sslices.size(); ++i) { int a = i == 0 ? 0 : 1; int b = i == 0 ? 0 : i - 1; - double h = gndlvl - el + ilh * a + b * lh; + LevelID h = sgl - sel + sinitlh * a + b * slh; + std::cout << "Support layer level: " << h << std::endl; - long long lyridx = static_cast(scale_(h)); - auto& lyrs = levels[lyridx]; + auto& lyrs = levels[h]; lyrs.emplace_back(sslices[i], o->m_instances); } } @@ -457,19 +478,19 @@ double SLAPrintObject::get_elevation() const { 0; } -const std::vector &SLAPrintObject::get_support_slices() const -{ - // I don't want to return a copy but the points may not exist, so ... - static const std::vector dummy_empty; +//const std::vector &SLAPrintObject::get_support_slices() const +//{ +// // I don't want to return a copy but the points may not exist, so ... +// static const std::vector dummy_empty; - if(!m_supportdata) return dummy_empty; - return m_supportdata->support_slices; -} +// if(!m_supportdata) return dummy_empty; +// return m_supportdata->support_slices; +//} -const std::vector &SLAPrintObject::get_model_slices() const -{ - return m_model_slices; -} +//const std::vector &SLAPrintObject::get_model_slices() const +//{ +// return m_model_slices; +//} bool SLAPrintObject::has_mesh(SLAPrintObjectStep step) const { diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 57052b7c21..ef30943093 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -69,8 +69,8 @@ public: // as the pad height also needs to be considered. double get_elevation() const; - const std::vector& get_support_slices() const; - const std::vector& get_model_slices() const; +// const std::vector& get_support_slices() const; +// const std::vector& get_model_slices() const; // I refuse to grantee copying (Tamas) SLAPrintObject(const SLAPrintObject&) = delete; @@ -93,6 +93,7 @@ protected: bool invalidate_step(SLAPrintObjectStep step); private: + // Object specific configuration, pulled from the configuration layer. SLAPrintObjectConfig m_config; // Translation in Z + Rotation by Y and Z + Scaling / Mirroring.