From 503166a6a4acd15fbe8e608fd1e7ccbf169bb1b3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 30 Oct 2018 16:03:03 +0100 Subject: [PATCH 01/10] Automatic placement of instance at bed level --- src/libslic3r/Model.cpp | 66 +++++++++++++++-- src/libslic3r/Model.hpp | 6 ++ src/slic3r/GUI/GLCanvas3D.cpp | 118 ++++++++++++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 3 + src/slic3r/GUI/GUI_ObjectList.cpp | 1 + src/slic3r/GUI/Plater.cpp | 5 ++ 6 files changed, 193 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 0ac5c0e22..15eedaa2d 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -712,18 +712,32 @@ void ModelObject::center_around_origin() if (!this->instances.empty()) { for (ModelInstance *i : this->instances) { -#if ENABLE_MIRROR i->set_offset(i->get_offset() - shift); -#else - // apply rotation and scaling to vector as well before translating instance, - // in order to leave final position unaltered - i->set_offset(i->get_offset() + i->transform_vector(-shift, true)); -#endif // ENABLE_MIRROR } this->invalidate_bounding_box(); } } +void ModelObject::ensure_on_bed() +{ + translate_instances(Vec3d(0.0, 0.0, -get_min_z())); +} + +void ModelObject::translate_instances(const Vec3d& vector) +{ + for (size_t i = 0; i < instances.size(); ++i) + { + translate_instance(i, vector); + } +} + +void ModelObject::translate_instance(size_t instance_idx, const Vec3d& vector) +{ + ModelInstance* i = instances[instance_idx]; + i->set_offset(i->get_offset() + vector); + invalidate_bounding_box(); +} + void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelVolume *v : this->volumes) @@ -895,6 +909,42 @@ void ModelObject::repair() v->mesh.repair(); } +double ModelObject::get_min_z() const +{ + if (instances.empty()) + return 0.0; + else + { + double min_z = DBL_MAX; + for (size_t i = 0; i < instances.size(); ++i) + { + min_z = std::min(min_z, get_instance_min_z(i)); + } + return min_z; + } +} + +double ModelObject::get_instance_min_z(size_t instance_idx) const +{ + double min_z = DBL_MAX; + + ModelInstance* inst = instances[instance_idx]; + Vec3d local_unit_z = (inst->world_matrix(true).inverse() * Vec3d::UnitZ()).normalized(); + + for (ModelVolume *v : volumes) + { + for (uint32_t f = 0; f < v->mesh.stl.stats.number_of_facets; ++f) + { + const stl_facet* facet = v->mesh.stl.facet_start + f; + min_z = std::min(min_z, local_unit_z.dot(facet->vertex[0].cast())); + min_z = std::min(min_z, local_unit_z.dot(facet->vertex[1].cast())); + min_z = std::min(min_z, local_unit_z.dot(facet->vertex[2].cast())); + } + } + + return min_z + inst->get_offset(Z); +} + unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume) { unsigned int num_printable = 0; @@ -1136,7 +1186,11 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes { // Rotate around mesh origin. TriangleMesh copy(*mesh); +#if ENABLE_MIRROR + copy.transform(world_matrix(true, false, true, true).cast()); +#else copy.transform(world_matrix(true, false, true).cast()); +#endif // ENABLE_MIRROR BoundingBoxf3 bbox = copy.bounding_box(); if (!empty(bbox)) { diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index e6ec9b0ae..89b068c40 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -153,6 +153,9 @@ public: // A snug bounding box around the transformed non-modifier object volumes. BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const; void center_around_origin(); + void ensure_on_bed(); + void translate_instances(const Vec3d& vector); + void translate_instance(size_t instance_idx, const Vec3d& vector); void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); } void translate(coordf_t x, coordf_t y, coordf_t z); void scale(const Vec3d &versor); @@ -167,6 +170,9 @@ public: void split(ModelObjectPtrs* new_objects); void repair(); + double get_min_z() const; + double get_instance_min_z(size_t instance_idx) const; + // Called by Print::validate() from the UI thread. unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fad99f6fe..ca593e8a9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1478,6 +1478,98 @@ void GLCanvas3D::Selection::mirror(Axis axis) } #endif // ENABLE_MIRROR +void GLCanvas3D::Selection::translate(unsigned int object_idx, const Vec3d& displacement) +{ + if (!m_valid) + return; + + for (unsigned int i : m_list) + { + GLVolume* v = (*m_volumes)[i]; + if (v->object_idx() == object_idx) + v->set_offset(v->get_offset() + displacement); + } + + std::set done; // prevent processing volumes twice + done.insert(m_list.begin(), m_list.end()); + + for (unsigned int i : m_list) + { + if (done.size() == m_volumes->size()) + break; + + const GLVolume* volume = (*m_volumes)[i]; + int object_idx = volume->object_idx(); + if (object_idx >= 1000) + continue; + + // Process unselected volumes of the object. + for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) + { + if (done.size() == m_volumes->size()) + break; + + if (done.find(j) != done.end()) + continue; + + GLVolume* v = (*m_volumes)[j]; + if (v->object_idx() != object_idx) + continue; + + v->set_offset(v->get_offset() + displacement); + done.insert(j); + } + } + + m_bounding_box_dirty = true; +} + +void GLCanvas3D::Selection::translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement) +{ + if (!m_valid) + return; + + for (unsigned int i : m_list) + { + GLVolume* v = (*m_volumes)[i]; + if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) + v->set_offset(v->get_offset() + displacement); + } + + std::set done; // prevent processing volumes twice + done.insert(m_list.begin(), m_list.end()); + + for (unsigned int i : m_list) + { + if (done.size() == m_volumes->size()) + break; + + const GLVolume* volume = (*m_volumes)[i]; + int object_idx = volume->object_idx(); + if (object_idx >= 1000) + continue; + + // Process unselected volumes of the object. + for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) + { + if (done.size() == m_volumes->size()) + break; + + if (done.find(j) != done.end()) + continue; + + GLVolume* v = (*m_volumes)[j]; + if ((v->object_idx() != object_idx) || (v->instance_idx() != instance_idx)) + continue; + + v->set_offset(v->get_offset() + displacement); + done.insert(j); + } + } + + m_bounding_box_dirty = true; +} + void GLCanvas3D::Selection::render(bool show_indirect_selection) const { if (is_empty()) @@ -6666,6 +6758,14 @@ void GLCanvas3D::_on_move() wipe_tower_origin = v->get_offset(); } + for (const std::pair& i : done) + { + ModelObject* m = m_model->objects[i.first]; + Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); + m_selection.translate(i.first, i.second, shift); + m->translate_instance(i.second, shift); + } + if (object_moved) post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED)); @@ -6700,10 +6800,19 @@ void GLCanvas3D::_on_rotate() if (model_object != nullptr) { model_object->instances[instance_idx]->set_rotation(v->get_rotation()); + model_object->instances[instance_idx]->set_offset(v->get_offset()); model_object->invalidate_bounding_box(); } } + for (const std::pair& i : done) + { + ModelObject* m = m_model->objects[i.first]; + Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); + m_selection.translate(i.first, i.second, shift); + m->translate_instance(i.second, shift); + } + post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } @@ -6734,10 +6843,19 @@ void GLCanvas3D::_on_scale() if (model_object != nullptr) { model_object->instances[instance_idx]->set_scaling_factor(v->get_scaling_factor()); + model_object->instances[instance_idx]->set_offset(v->get_offset()); model_object->invalidate_bounding_box(); } } + for (const std::pair& i : done) + { + ModelObject* m = m_model->objects[i.first]; + Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); + m_selection.translate(i.first, i.second, shift); + m->translate_instance(i.second, shift); + } + post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index b47a11a1d..4d2185825 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -508,6 +508,9 @@ public: void mirror(Axis axis); #endif // ENABLE_MIRROR + void translate(unsigned int object_idx, const Vec3d& displacement); + void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement); + void render(bool show_indirect_selection) const; private: diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 6c9077bad..1bd934213 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -706,6 +706,7 @@ void ObjectList::load_part( ModelObject* model_object, if (model_object->origin_translation != Vec3d::Zero()) { object->center_around_origin(); + object->ensure_on_bed(); delta = model_object->origin_translation - object->origin_translation; } for (auto volume : object->volumes) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 59ebe10b2..a26cde07c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1151,6 +1151,7 @@ std::vector Plater::priv::load_files(const std::vector &input_ if (type_3mf) { for (ModelObject* model_object : model.objects) { model_object->center_around_origin(); + model_object->ensure_on_bed(); } } @@ -1235,6 +1236,8 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs &mode } } + object->ensure_on_bed(); + // print.auto_assign_extruders(object); // print.add_model_object(object); } @@ -1628,6 +1631,7 @@ void Plater::priv::split_object() { m->name = current_model_object->name + "_" + std::to_string(counter++); m->center_around_origin(); + m->ensure_on_bed(); } remove(obj_idx); @@ -2552,6 +2556,7 @@ void Plater::changed_object_settings(int obj_idx) // recenter and re - align to Z = 0 auto model_object = p->model.objects[obj_idx]; model_object->center_around_origin(); + model_object->ensure_on_bed(); } // update print From da4903a37f24c44cccff7cceb7d78a4d9678af82 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Oct 2018 09:39:43 +0100 Subject: [PATCH 02/10] New selection -> Disabled instances synchronization --- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index ec775742b..a01c95f72 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -19,6 +19,7 @@ #define ENABLE_USE_UNIQUE_GLCONTEXT (1 && ENABLE_1_42_0) // New selections #define ENABLE_EXTENDED_SELECTION (1 && ENABLE_1_42_0) +#define DISABLE_INSTANCES_SYNCH (1 && ENABLE_EXTENDED_SELECTION) // Add mirror components along the three axes in ModelInstance and GLVolume #define ENABLE_MIRROR (1 && ENABLE_1_42_0) // Modified camera target behavior diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ca593e8a9..e33791681 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1426,8 +1426,10 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation) } } +#if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) _synchronize_unselected_instances(); +#endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; } @@ -1453,8 +1455,10 @@ void GLCanvas3D::Selection::scale(const Vec3d& scale) } } +#if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) _synchronize_unselected_instances(); +#endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; } @@ -1471,8 +1475,10 @@ void GLCanvas3D::Selection::mirror(Axis axis) (*m_volumes)[i]->set_mirror(axis, -(*m_volumes)[i]->get_mirror(axis)); } +#if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) _synchronize_unselected_instances(); +#endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; } @@ -1498,8 +1504,7 @@ void GLCanvas3D::Selection::translate(unsigned int object_idx, const Vec3d& disp if (done.size() == m_volumes->size()) break; - const GLVolume* volume = (*m_volumes)[i]; - int object_idx = volume->object_idx(); + int object_idx = (*m_volumes)[i]->object_idx(); if (object_idx >= 1000) continue; @@ -1544,8 +1549,7 @@ void GLCanvas3D::Selection::translate(unsigned int object_idx, unsigned int inst if (done.size() == m_volumes->size()) break; - const GLVolume* volume = (*m_volumes)[i]; - int object_idx = volume->object_idx(); + int object_idx = (*m_volumes)[i]->object_idx(); if (object_idx >= 1000) continue; From b23f7e583409301cef08ace0030c3b7cc1e8bcbc Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Oct 2018 09:53:48 +0100 Subject: [PATCH 03/10] New selection -> Restore selection after splitting an object to parts --- src/slic3r/GUI/GUI_ObjectList.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 1bd934213..2ebdf7e40 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -956,6 +956,11 @@ void ObjectList::split(const bool split_part) m_parts_changed = true; parts_changed(m_selected_object_id); + +#if ENABLE_EXTENDED_SELECTION + // restores selection + _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection().add_object(m_selected_object_id); +#endif // ENABLE_EXTENDED_SELECTION } bool ObjectList::get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume) From ae6c65dfffba0be1a4b4facf92011acdc58db77e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Oct 2018 11:24:56 +0100 Subject: [PATCH 04/10] New selection -> Fixed split object to objects --- src/slic3r/GUI/Plater.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a26cde07c..d538a0f53 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1621,24 +1621,30 @@ void Plater::priv::split_object() ModelObjectPtrs new_objects; current_model_object->split(&new_objects); if (new_objects.size() == 1) - { Slic3r::GUI::warning_catcher(q, _(L("The selected object couldn't be split because it contains only one part."))); - } else { unsigned int counter = 1; for (ModelObject* m : new_objects) { m->name = current_model_object->name + "_" + std::to_string(counter++); - m->center_around_origin(); - m->ensure_on_bed(); + for (ModelInstance* i : current_model_object->instances) + { + m->add_instance(*i); + } } remove(obj_idx); // load all model objects at once, otherwise the plate would be rearranged after each one // causing original positions not to be kept - load_model_objects(new_objects); + std::vector idxs = load_model_objects(new_objects); + + // select newly added objects + for (size_t idx : idxs) + { + get_selection().add_object((unsigned int)idx, false); + } } #endif // ENABLE_EXTENDED_SELECTION } From cc275707042c0e1aa8c8c7be6e1e0dc63b8a2556 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 31 Oct 2018 12:23:26 +0100 Subject: [PATCH 05/10] Fixed a crash when moving an object with wipe tower volume on screen --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e33791681..afa2ee991 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6744,10 +6744,10 @@ void GLCanvas3D::_on_move() if (done.find(done_id) != done.end()) continue; - done.insert(done_id); - if (object_idx < 1000) { + done.insert(done_id); + // Move instances. ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) From d2844bc39d2a67522ff8c26c2b2de788ba03325b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 31 Oct 2018 12:26:57 +0100 Subject: [PATCH 06/10] Ported show_sliced_info_sizer + some code-view changes --- src/slic3r/GUI/Field.cpp | 12 ++- src/slic3r/GUI/GUI_ObjectList.cpp | 4 +- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 2 +- src/slic3r/GUI/LambdaObjectDialog.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 93 ++++++++++++++++++----- src/slic3r/GUI/Plater.hpp | 1 + 6 files changed, 89 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 29d23eee5..8efb4ff30 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -29,7 +29,8 @@ namespace Slic3r { namespace GUI { } } - void Field::PostInitialize(){ + void Field::PostInitialize() + { auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); @@ -65,7 +66,8 @@ namespace Slic3r { namespace GUI { BUILD(); } - void Field::on_kill_focus(wxEvent& event) { + void Field::on_kill_focus(wxEvent& event) + { // Without this, there will be nasty focus bugs on Windows. // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all // non-command events to allow the default handling to take place." @@ -81,12 +83,14 @@ namespace Slic3r { namespace GUI { m_on_change(m_opt_id, get_value()); } - void Field::on_back_to_initial_value(){ + void Field::on_back_to_initial_value() + { if (m_back_to_initial_value != nullptr && m_is_modified_value) m_back_to_initial_value(m_opt_id); } - void Field::on_back_to_sys_value(){ + void Field::on_back_to_sys_value() + { if (m_back_to_sys_value != nullptr && m_is_nonsys_value) m_back_to_sys_value(m_opt_id); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2ebdf7e40..b74edcd8a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1091,7 +1091,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) auto stats = model_object->volumes[0]->mesh.stl.stats; int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + stats.facets_added + stats.facets_reversed + stats.backwards_edges; - if (errors > 0) { + if (errors > 0) { wxVariant variant; variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning); m_objects_model->SetValue(variant, item, 0); @@ -1241,7 +1241,7 @@ void ObjectList::update_selections_on_canvas() auto add_to_selection = [this](const wxDataViewItem& item, GLCanvas3D::Selection& selection, bool as_single_selection) { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)){ + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection); return; } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index ca3587118..344fb38ad 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -268,7 +268,7 @@ void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& sele { if (selection.is_single_full_object()) { - if (wxGetApp().mainframe->m_plater->model().objects[selection.get_object_idx()]->instances.size() == 1) + if (!wxGetApp().model_objects()->empty() && (*wxGetApp().model_objects())[selection.get_object_idx()]->instances.size() == 1) { // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); diff --git a/src/slic3r/GUI/LambdaObjectDialog.hpp b/src/slic3r/GUI/LambdaObjectDialog.hpp index 9ee7824fc..3a4d0cf05 100644 --- a/src/slic3r/GUI/LambdaObjectDialog.hpp +++ b/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -44,7 +44,7 @@ public: ~LambdaObjectDialog(){} bool CanClose() { return true; } // ??? - OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; } + OBJECT_PARAMETERS& ObjectParameters() { return object_parameters; } ConfigOptionsGroupShp init_modificator_options_page(const wxString& title); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d538a0f53..e9deed020 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -132,18 +132,27 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : Add(grid_sizer, 0, wxEXPAND); } +enum SlisedInfoIdx +{ + siFilament_m, + siFilament_mm3, + siFilament_g, + siCost, + siTimeNormal, + siTimeSilent, + siWTNumbetOfToolchanges, + + siCount +}; + class SlicedInfo : public wxStaticBoxSizer { public: SlicedInfo(wxWindow *parent); + void SetTextAndShow(SlisedInfoIdx idx, const wxString& text); private: - wxStaticText *info_filament_m; - wxStaticText *info_filament_mm3; - wxStaticText *info_filament_g; - wxStaticText *info_cost; - wxStaticText *info_time_normal; - wxStaticText *info_time_silent; + std::vector> info_vec; }; SlicedInfo::SlicedInfo(wxWindow *parent) : @@ -155,23 +164,37 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : grid_sizer->SetFlexibleDirection(wxHORIZONTAL); grid_sizer->AddGrowableCol(1, 1); - auto init_info_label = [parent, grid_sizer](wxStaticText *&info_label, wxString text_label) { + info_vec.reserve(siCount); + + auto init_info_label = [this, parent, grid_sizer](wxString text_label) { auto *text = new wxStaticText(parent, wxID_ANY, text_label); text->SetFont(wxGetApp().small_font()); - info_label = new wxStaticText(parent, wxID_ANY, "N/A"); + auto info_label = new wxStaticText(parent, wxID_ANY, "N/A"); info_label->SetFont(wxGetApp().small_font()); grid_sizer->Add(text, 0); grid_sizer->Add(info_label, 0); + info_vec.push_back(std::pair(text, info_label)); }; - init_info_label(info_filament_m, _(L("Used Filament (m)"))); - init_info_label(info_filament_mm3, _(L("Used Filament (mm³)"))); - init_info_label(info_filament_g, _(L("Used Filament (g)"))); - init_info_label(info_cost, _(L("Cost"))); - init_info_label(info_time_normal, _(L("Estimated printing time (normal mode)"))); - init_info_label(info_time_silent, _(L("Estimated printing time (silent mode)"))); + init_info_label(_(L("Used Filament (m)"))); + init_info_label(_(L("Used Filament (mm³)"))); + init_info_label(_(L("Used Filament (g)"))); + init_info_label(_(L("Cost"))); + init_info_label(_(L("Estimated printing time (normal mode)"))); + init_info_label(_(L("Estimated printing time (silent mode)"))); + init_info_label(_(L("Number of tool changes"))); Add(grid_sizer, 0, wxEXPAND); + this->Show(false); +} + +void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text) +{ + const bool show = text != "N/A"; + if (show) + info_vec[idx].second->SetLabelText(text); + info_vec[idx].first->Show(show); + info_vec[idx].second->Show(show); } PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) : @@ -633,7 +656,43 @@ void Sidebar::show_info_sizers(const bool show) { p->object_info->Show(show); p->object_info->manifold_warning_icon->Show(show && p->show_manifold_warning_icon); // where is g_show_manifold_warning_icon updating? #ys_FIXME - p->sliced_info->Show(show && p->show_print_info); // where is g_show_print_info updating? #ys_FIXME +// p->sliced_info->Show(show && p->show_print_info); +} + +void Sidebar::show_sliced_info_sizer(const bool show) +{ + p->plater->Freeze(); +// p->show_print_info = show; + p->sliced_info->Show(show); + if (show) { + const PrintStatistics& ps = p->plater->print().print_statistics(); + const bool is_wipe_tower = ps.total_wipe_tower_filament > 0; + + wxString info_text = is_wipe_tower ? + wxString::Format("%.2f (%.2f %s + %.2f %s)", ps.total_used_filament / 1000, + (ps.total_used_filament - ps.total_wipe_tower_filament) / 1000, _(L("objects")), + ps.total_wipe_tower_filament / 1000, _(L("wipe tower"))) : + wxString::Format("%.2f", ps.total_used_filament / 1000); + p->sliced_info->SetTextAndShow(siFilament_m, info_text); + p->sliced_info->SetTextAndShow(siFilament_mm3, wxString::Format("%.2f", ps.total_extruded_volume)); + p->sliced_info->SetTextAndShow(siFilament_g, wxString::Format("%.2f", ps.total_weight)); + + info_text = is_wipe_tower ? + wxString::Format("%.2f (%.2f %s + %.2f %s)", ps.total_cost, + (ps.total_cost - ps.total_wipe_tower_cost), _(L("objects")), + ps.total_wipe_tower_cost, _(L("wipe tower"))) : + wxString::Format("%.2f", ps.total_cost); + p->sliced_info->SetTextAndShow(siCost, info_text); + p->sliced_info->SetTextAndShow(siTimeNormal, ps.estimated_normal_print_time); + p->sliced_info->SetTextAndShow(siTimeSilent, ps.estimated_silent_print_time); + + // if there is a wipe tower, insert number of toolchanges info into the array: + p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->print().wipe_tower_data().number_of_toolchanges) : "N/A"); + } + + p->scrolled->Layout(); + p->plater->Layout(); + p->plater->Thaw(); } void Sidebar::show_buttons(const bool show) @@ -1678,7 +1737,7 @@ void Plater::priv::async_apply_config() if (invalidated == Print::APPLY_STATUS_INVALIDATED) { // Some previously calculated data on the Print was invalidated. // Hide the slicing results, as the current slicing status is no more valid. - this->sidebar->show_info_sizers(false); + this->sidebar->show_sliced_info_sizer(false); // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Otherwise they will be just refreshed. this->gcode_preview_data.reset(); @@ -1858,7 +1917,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) if (canceled) this->statusbar()->set_status_text(L("Cancelled")); - this->sidebar->show_info_sizers(success); + this->sidebar->show_sliced_info_sizer(success); // this updates buttons status //$self->object_list_changed; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 4c6d0ff30..0a69e68bd 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -78,6 +78,7 @@ public: wxButton* get_wiping_dialog_button(); void update_objects_list_extruder_column(int extruders_count); void show_info_sizers(const bool show); + void show_sliced_info_sizer(const bool show); void show_buttons(const bool show); void show_button(ButtonAction but_action, bool show); void enable_buttons(bool enable); From 7f08f460f10c3a83c795f22c7022c1492297d5c2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 31 Oct 2018 12:56:08 +0100 Subject: [PATCH 07/10] Some code review --- src/slic3r/GUI/2DBed.cpp | 16 +- src/slic3r/GUI/2DBed.hpp | 8 +- src/slic3r/GUI/BedShapeDialog.cpp | 15 +- src/slic3r/GUI/BedShapeDialog.hpp | 8 +- src/slic3r/GUI/ButtonsDescription.cpp | 2 +- src/slic3r/GUI/ButtonsDescription.hpp | 2 +- src/slic3r/GUI/Field.cpp | 514 +++++++++++----------- src/slic3r/GUI/GUI.cpp | 20 +- src/slic3r/GUI/GUI_App.cpp | 27 +- src/slic3r/GUI/GUI_ObjectList.cpp | 13 +- src/slic3r/GUI/GUI_ObjectList.hpp | 6 +- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 8 +- src/slic3r/GUI/LambdaObjectDialog.cpp | 19 +- src/slic3r/GUI/LambdaObjectDialog.hpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 100 ++--- src/slic3r/GUI/OptionsGroup.cpp | 41 +- src/slic3r/GUI/OptionsGroup.hpp | 16 +- src/slic3r/GUI/Plater.cpp | 36 +- src/slic3r/GUI/Preferences.hpp | 2 +- src/slic3r/GUI/Preset.cpp | 4 +- src/slic3r/GUI/PresetBundle.cpp | 10 +- src/slic3r/GUI/Tab.cpp | 149 ++++--- src/slic3r/GUI/Tab.hpp | 18 +- src/slic3r/GUI/wxExtensions.cpp | 20 +- src/slic3r/GUI/wxExtensions.hpp | 14 +- 25 files changed, 548 insertions(+), 522 deletions(-) diff --git a/src/slic3r/GUI/2DBed.cpp b/src/slic3r/GUI/2DBed.cpp index e19f839cd..d0f640433 100644 --- a/src/slic3r/GUI/2DBed.cpp +++ b/src/slic3r/GUI/2DBed.cpp @@ -89,7 +89,7 @@ void Bed_2D::repaint() dc.SetPen(wxPen(wxColour(230, 230, 230), 1, wxSOLID)); for (auto pl : polylines) { - for (size_t i = 0; i < pl.points.size()-1; i++){ + for (size_t i = 0; i < pl.points.size()-1; i++) { Point pt1 = to_pixels(unscale(pl.points[i])); Point pt2 = to_pixels(unscale(pl.points[i+1])); dc.DrawLine(pt1(0), pt1(1), pt2(0), pt2(1)); @@ -110,7 +110,7 @@ void Bed_2D::repaint() dc.SetPen(wxPen(wxColour(255, 0, 0), 2, wxSOLID)); // red auto x_end = Vec2d(origin_px(0) + axes_len, origin_px(1)); dc.DrawLine(wxPoint(origin_px(0), origin_px(1)), wxPoint(x_end(0), x_end(1))); - for (auto angle : { -arrow_angle, arrow_angle }){ + for (auto angle : { -arrow_angle, arrow_angle }) { auto end = Eigen::Translation2d(x_end) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- x_end) * Eigen::Vector2d(x_end(0) - arrow_len, x_end(1)); dc.DrawLine(wxPoint(x_end(0), x_end(1)), wxPoint(end(0), end(1))); } @@ -151,12 +151,14 @@ void Bed_2D::repaint() } // convert G - code coordinates into pixels -Point Bed_2D::to_pixels(Vec2d point){ +Point Bed_2D::to_pixels(Vec2d point) +{ auto p = point * m_scale_factor + m_shift; return Point(p(0), GetSize().GetHeight() - p(1)); } -void Bed_2D::mouse_event(wxMouseEvent event){ +void Bed_2D::mouse_event(wxMouseEvent event) +{ if (!m_interactive) return; if (!m_painted) return; @@ -170,11 +172,13 @@ void Bed_2D::mouse_event(wxMouseEvent event){ } // convert pixels into G - code coordinates -Vec2d Bed_2D::to_units(Point point){ +Vec2d Bed_2D::to_units(Point point) +{ return (Vec2d(point(0), GetSize().GetHeight() - point(1)) - m_shift) * (1. / m_scale_factor); } -void Bed_2D::set_pos(Vec2d pos){ +void Bed_2D::set_pos(Vec2d pos) +{ m_pos = pos; Refresh(); } diff --git a/src/slic3r/GUI/2DBed.hpp b/src/slic3r/GUI/2DBed.hpp index d7a7f4260..5df596136 100644 --- a/src/slic3r/GUI/2DBed.hpp +++ b/src/slic3r/GUI/2DBed.hpp @@ -34,12 +34,12 @@ public: #endif /*__APPLE__*/ Bind(wxEVT_PAINT, ([this](wxPaintEvent e) { repaint(); })); // EVT_ERASE_BACKGROUND($self, sub{}) if $self->{user_drawn_background}; -// Bind(EVT_MOUSE_EVENTS, ([this](wxMouseEvent event){/*mouse_event()*/; })); - Bind(wxEVT_LEFT_DOWN, ([this](wxMouseEvent event){ mouse_event(event); })); - Bind(wxEVT_MOTION, ([this](wxMouseEvent event){ mouse_event(event); })); +// Bind(EVT_MOUSE_EVENTS, ([this](wxMouseEvent event) {/*mouse_event()*/; })); + Bind(wxEVT_LEFT_DOWN, ([this](wxMouseEvent event) { mouse_event(event); })); + Bind(wxEVT_MOTION, ([this](wxMouseEvent event) { mouse_event(event); })); Bind(wxEVT_SIZE, ([this](wxSizeEvent e) { Refresh(); })); } - ~Bed_2D(){} + ~Bed_2D() {} std::vector m_bed_shape; diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 407da7ae3..c1fc58051 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -28,7 +28,7 @@ void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt) main_sizer->SetSizeHints(this); // needed to actually free memory - this->Bind(wxEVT_CLOSE_WINDOW, ([this](wxCloseEvent e){ + this->Bind(wxEVT_CLOSE_WINDOW, ([this](wxCloseEvent e) { EndModal(wxID_OK); Destroy(); })); @@ -115,14 +115,15 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) // Called from the constructor. // Create a panel for a rectangular / circular / custom bed shape. -ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title){ +ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title) +{ auto panel = new wxPanel(m_shape_options_book); ConfigOptionsGroupShp optgroup; optgroup = std::make_shared(panel, _(L("Settings"))); optgroup->label_width = 100; - optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { update_shape(); }; @@ -234,13 +235,13 @@ void BedShapePanel::update_shape() Vec2d rect_origin(Vec2d::Zero()); try{ rect_size = boost::any_cast(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_size")); } - catch (const std::exception &e){ + catch (const std::exception &e) { return; } try{ rect_origin = boost::any_cast(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_origin")); } - catch (const std::exception &e){ + catch (const std::exception &e) { return;} auto x = rect_size(0); @@ -269,7 +270,7 @@ void BedShapePanel::update_shape() try{ diameter = boost::any_cast(m_optgroups[SHAPE_CIRCULAR]->get_value("diameter")); } - catch (const std::exception &e){ + catch (const std::exception &e) { return; } if (diameter == 0.0) return ; @@ -277,7 +278,7 @@ void BedShapePanel::update_shape() auto twopi = 2 * PI; auto edges = 60; std::vector points; - for (size_t i = 1; i <= 60; ++i){ + for (size_t i = 1; i <= 60; ++i) { auto angle = i * twopi / edges; points.push_back(Vec2d(r*cos(angle), r*sin(angle))); } diff --git a/src/slic3r/GUI/BedShapeDialog.hpp b/src/slic3r/GUI/BedShapeDialog.hpp index d8ba5a912..8ea595b0b 100644 --- a/src/slic3r/GUI/BedShapeDialog.hpp +++ b/src/slic3r/GUI/BedShapeDialog.hpp @@ -22,8 +22,8 @@ class BedShapePanel : public wxPanel std::vector m_optgroups; public: - BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY){} - ~BedShapePanel(){} + BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) {} + ~BedShapePanel() {} void build_panel(ConfigOptionPoints* default_pt); @@ -42,8 +42,8 @@ class BedShapeDialog : public wxDialog BedShapePanel* m_panel; public: BedShapeDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, _(L("Bed Shape")), - wxDefaultPosition, wxSize(350, 700), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER){} - ~BedShapeDialog(){ } + wxDefaultPosition, wxSize(350, 700), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {} + ~BedShapeDialog() {} void build_dialog(ConfigOptionPoints* default_pt); std::vector GetValue() { return m_panel->GetValue(); } diff --git a/src/slic3r/GUI/ButtonsDescription.cpp b/src/slic3r/GUI/ButtonsDescription.cpp index 801838216..b0e8d56ad 100644 --- a/src/slic3r/GUI/ButtonsDescription.cpp +++ b/src/slic3r/GUI/ButtonsDescription.cpp @@ -45,7 +45,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* ic sys_label->Refresh(); })); size_t t= 0; - while (t < 3){ + while (t < 3) { grid_sizer->Add(new wxStaticText(this, wxID_ANY, ""), -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND); ++t; } diff --git a/src/slic3r/GUI/ButtonsDescription.hpp b/src/slic3r/GUI/ButtonsDescription.hpp index 4858eaaea..81baaf191 100644 --- a/src/slic3r/GUI/ButtonsDescription.hpp +++ b/src/slic3r/GUI/ButtonsDescription.hpp @@ -14,7 +14,7 @@ class ButtonsDescription : public wxDialog t_icon_descriptions* m_icon_descriptions; public: ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions); - ~ButtonsDescription(){} + ~ButtonsDescription() {} }; diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 8efb4ff30..518652e90 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -11,274 +11,275 @@ namespace Slic3r { namespace GUI { - wxString double_to_string(double const value) - { - if (value - int(value) == 0) - return wxString::Format(_T("%i"), int(value)); - else { - int precision = 4; - for (size_t p = 1; p < 4; p++) - { - double cur_val = pow(10, p)*value; - if (cur_val - int(cur_val) == 0) { - precision = p; - break; - } - } - return wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None); - } - } - - void Field::PostInitialize() - { - auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) { - m_Undo_btn->SetBackgroundColour(color); - m_Undo_to_sys_btn->SetBackgroundColour(color); - } - m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_initial_value(); })); - m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_sys_value(); })); - - //set default bitmap - wxBitmap bmp; - bmp.LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG); - set_undo_bitmap(&bmp); - set_undo_to_sys_bitmap(&bmp); - - switch (m_opt.type) +wxString double_to_string(double const value) +{ + if (value - int(value) == 0) + return wxString::Format(_T("%i"), int(value)); + else { + int precision = 4; + for (size_t p = 1; p < 4; p++) { - case coPercents: - case coFloats: - case coStrings: - case coBools: - case coInts: { - auto tag_pos = m_opt_id.find("#"); - if (tag_pos != std::string::npos) - m_opt_idx = stoi(m_opt_id.substr(tag_pos + 1, m_opt_id.size())); - break; - } - default: - break; - } - - BUILD(); - } - - void Field::on_kill_focus(wxEvent& event) - { - // Without this, there will be nasty focus bugs on Windows. - // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all - // non-command events to allow the default handling to take place." - event.Skip(); - // call the registered function if it is available - if (m_on_kill_focus!=nullptr) - m_on_kill_focus(); - } - void Field::on_change_field() - { -// std::cerr << "calling Field::_on_change \n"; - if (m_on_change != nullptr && !m_disable_change_event) - m_on_change(m_opt_id, get_value()); - } - - void Field::on_back_to_initial_value() - { - if (m_back_to_initial_value != nullptr && m_is_modified_value) - m_back_to_initial_value(m_opt_id); - } - - void Field::on_back_to_sys_value() - { - if (m_back_to_sys_value != nullptr && m_is_nonsys_value) - m_back_to_sys_value(m_opt_id); - } - - wxString Field::get_tooltip_text(const wxString& default_string) - { - wxString tooltip_text(""); - wxString tooltip = _(m_opt.tooltip); - if (tooltip.length() > 0) - tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " + - (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string + - (boost::iends_with(m_opt_id, "_gcode") ? "" : "\n") + - _(L("parameter name")) + "\t: " + m_opt_id; - - return tooltip_text; - } - - bool Field::is_matched(const std::string& string, const std::string& pattern) - { - std::regex regex_pattern(pattern, std::regex_constants::icase); // use ::icase to make the matching case insensitive like /i in perl - return std::regex_match(string, regex_pattern); - } - - void Field::get_value_by_opt_type(wxString& str) - { - switch (m_opt.type){ - case coInt: - m_value = wxAtoi(str); - break; - case coPercent: - case coPercents: - case coFloats: - case coFloat:{ - if (m_opt.type == coPercent && str.Last() == '%') - str.RemoveLast(); - else if (str.Last() == '%') { - wxString label = m_Label->GetLabel(); - if (label.Last() == '\n') label.RemoveLast(); - while (label.Last() == ' ') label.RemoveLast(); - if (label.Last() == ':') label.RemoveLast(); - show_error(m_parent, wxString::Format(_(L("%s doesn't support percentage")), label)); - set_value(double_to_string(m_opt.min), true); - m_value = double(m_opt.min); + double cur_val = pow(10, p)*value; + if (cur_val - int(cur_val) == 0) { + precision = p; break; } - double val; - if(!str.ToCDouble(&val)) - { - show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits"))); - set_value(double_to_string(val), true); - } - if (m_opt.min > val || val > m_opt.max) - { - show_error(m_parent, _(L("Input value is out of range"))); - if (m_opt.min > val) val = m_opt.min; - if (val > m_opt.max) val = m_opt.max; - set_value(double_to_string(val), true); - } - m_value = val; - break; } - case coString: - case coStrings: - case coFloatOrPercent: - m_value = str.ToStdString(); - break; - default: - break; } + return wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None); + } +} + +void Field::PostInitialize() +{ + auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) { + m_Undo_btn->SetBackgroundColour(color); + m_Undo_to_sys_btn->SetBackgroundColour(color); + } + m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); + m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); + + //set default bitmap + wxBitmap bmp; + bmp.LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG); + set_undo_bitmap(&bmp); + set_undo_to_sys_bitmap(&bmp); + + switch (m_opt.type) + { + case coPercents: + case coFloats: + case coStrings: + case coBools: + case coInts: { + auto tag_pos = m_opt_id.find("#"); + if (tag_pos != std::string::npos) + m_opt_idx = stoi(m_opt_id.substr(tag_pos + 1, m_opt_id.size())); + break; + } + default: + break; } - void TextCtrl::BUILD() { - auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + BUILD(); +} - wxString text_value = wxString(""); +void Field::on_kill_focus(wxEvent& event) +{ + // Without this, there will be nasty focus bugs on Windows. + // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all + // non-command events to allow the default handling to take place." + event.Skip(); + // call the registered function if it is available + if (m_on_kill_focus!=nullptr) + m_on_kill_focus(); +} - switch (m_opt.type) { - case coFloatOrPercent: - { - text_value = double_to_string(m_opt.default_value->getFloat()); - if (static_cast(m_opt.default_value)->percent) - text_value += "%"; +void Field::on_change_field() +{ + std::cerr << "calling Field::_on_change \n"; + if (m_on_change != nullptr && !m_disable_change_event) + m_on_change(m_opt_id, get_value()); +} + +void Field::on_back_to_initial_value() +{ + if (m_back_to_initial_value != nullptr && m_is_modified_value) + m_back_to_initial_value(m_opt_id); +} + +void Field::on_back_to_sys_value() +{ + if (m_back_to_sys_value != nullptr && m_is_nonsys_value) + m_back_to_sys_value(m_opt_id); +} + +wxString Field::get_tooltip_text(const wxString& default_string) +{ + wxString tooltip_text(""); + wxString tooltip = _(m_opt.tooltip); + if (tooltip.length() > 0) + tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " + + (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string + + (boost::iends_with(m_opt_id, "_gcode") ? "" : "\n") + + _(L("parameter name")) + "\t: " + m_opt_id; + + return tooltip_text; +} + +bool Field::is_matched(const std::string& string, const std::string& pattern) +{ + std::regex regex_pattern(pattern, std::regex_constants::icase); // use ::icase to make the matching case insensitive like /i in perl + return std::regex_match(string, regex_pattern); +} + +void Field::get_value_by_opt_type(wxString& str) +{ + switch (m_opt.type) { + case coInt: + m_value = wxAtoi(str); + break; + case coPercent: + case coPercents: + case coFloats: + case coFloat:{ + if (m_opt.type == coPercent && str.Last() == '%') + str.RemoveLast(); + else if (str.Last() == '%') { + wxString label = m_Label->GetLabel(); + if (label.Last() == '\n') label.RemoveLast(); + while (label.Last() == ' ') label.RemoveLast(); + if (label.Last() == ':') label.RemoveLast(); + show_error(m_parent, wxString::Format(_(L("%s doesn't support percentage")), label)); + set_value(double_to_string(m_opt.min), true); + m_value = double(m_opt.min); break; } - case coPercent: + double val; + if(!str.ToCDouble(&val)) { - text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat())); + show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits"))); + set_value(double_to_string(val), true); + } + if (m_opt.min > val || val > m_opt.max) + { + show_error(m_parent, _(L("Input value is out of range"))); + if (m_opt.min > val) val = m_opt.min; + if (val > m_opt.max) val = m_opt.max; + set_value(double_to_string(val), true); + } + m_value = val; + break; } + case coString: + case coStrings: + case coFloatOrPercent: + m_value = str.ToStdString(); + break; + default: + break; + } +} + +void TextCtrl::BUILD() { + auto size = wxSize(wxDefaultSize); + if (m_opt.height >= 0) size.SetHeight(m_opt.height); + if (m_opt.width >= 0) size.SetWidth(m_opt.width); + + wxString text_value = wxString(""); + + switch (m_opt.type) { + case coFloatOrPercent: + { + text_value = double_to_string(m_opt.default_value->getFloat()); + if (static_cast(m_opt.default_value)->percent) text_value += "%"; - break; - } - case coPercents: - case coFloats: - case coFloat: - { - double val = m_opt.type == coFloats ? - static_cast(m_opt.default_value)->get_at(m_opt_idx) : - m_opt.type == coFloat ? - m_opt.default_value->getFloat() : - static_cast(m_opt.default_value)->get_at(m_opt_idx); - text_value = double_to_string(val); - break; - } - case coString: - text_value = static_cast(m_opt.default_value)->value; - break; - case coStrings: - { - const ConfigOptionStrings *vec = static_cast(m_opt.default_value); - if (vec == nullptr || vec->empty()) break; //for the case of empty default value - text_value = vec->get_at(m_opt_idx); - break; - } - default: - break; - } + break; + } + case coPercent: + { + text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat())); + text_value += "%"; + break; + } + case coPercents: + case coFloats: + case coFloat: + { + double val = m_opt.type == coFloats ? + static_cast(m_opt.default_value)->get_at(m_opt_idx) : + m_opt.type == coFloat ? + m_opt.default_value->getFloat() : + static_cast(m_opt.default_value)->get_at(m_opt_idx); + text_value = double_to_string(val); + break; + } + case coString: + text_value = static_cast(m_opt.default_value)->value; + break; + case coStrings: + { + const ConfigOptionStrings *vec = static_cast(m_opt.default_value); + if (vec == nullptr || vec->empty()) break; //for the case of empty default value + text_value = vec->get_at(m_opt_idx); + break; + } + default: + break; + } - auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, (m_opt.multiline ? wxTE_MULTILINE : 0)); + auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, (m_opt.multiline ? wxTE_MULTILINE : 0)); - temp->SetToolTip(get_tooltip_text(text_value)); - - temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event) - { - //! to allow the default handling - event.Skip(); - //! eliminating the g-code pop up text description - bool flag = false; + temp->SetToolTip(get_tooltip_text(text_value)); + + temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event) + { + //! to allow the default handling + event.Skip(); + //! eliminating the g-code pop up text description + bool flag = false; #ifdef __WXGTK__ - // I have no idea why, but on GTK flag works in other way - flag = true; + // I have no idea why, but on GTK flag works in other way + flag = true; #endif // __WXGTK__ - temp->GetToolTip()->Enable(flag); - }), temp->GetId()); + temp->GetToolTip()->Enable(flag); + }), temp->GetId()); #if !defined(__WXGTK__) - temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e) - { - e.Skip();// on_kill_focus(e); - temp->GetToolTip()->Enable(true); - }), temp->GetId()); + temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e) + { + e.Skip();// on_kill_focus(e); + temp->GetToolTip()->Enable(true); + }), temp->GetId()); #endif // __WXGTK__ - temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt) - { -#ifdef __WXGTK__ - if (bChangedValueEvent) -#endif //__WXGTK__ - on_change_field(); - }), temp->GetId()); - -#ifdef __WXGTK__ - // to correct value updating on GTK we should: - // call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT - // and prevent value updating on wxEVT_KEY_DOWN - temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this); - temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this); -#endif //__WXGTK__ - - // select all text using Ctrl+A - temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event) - { - if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) - temp->SetSelection(-1, -1); //select all - event.Skip(); - })); - - // recast as a wxWindow to fit the calling convention - window = dynamic_cast(temp); - } - - boost::any& TextCtrl::get_value() + temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt) { - wxString ret_str = static_cast(window)->GetValue(); - get_value_by_opt_type(ret_str); - - return m_value; - } - - void TextCtrl::enable() { dynamic_cast(window)->Enable(); dynamic_cast(window)->SetEditable(true); } - void TextCtrl::disable() { dynamic_cast(window)->Disable(); dynamic_cast(window)->SetEditable(false); } +#ifdef __WXGTK__ + if (bChangedValueEvent) +#endif //__WXGTK__ + on_change_field(); + }), temp->GetId()); #ifdef __WXGTK__ - void TextCtrl::change_field_value(wxEvent& event) - { - if (bChangedValueEvent = event.GetEventType()==wxEVT_KEY_UP) - on_change_field(); - event.Skip(); - }; + // to correct value updating on GTK we should: + // call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT + // and prevent value updating on wxEVT_KEY_DOWN + temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this); + temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this); +#endif //__WXGTK__ + + // select all text using Ctrl+A + temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event) + { + if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) + temp->SetSelection(-1, -1); //select all + event.Skip(); + })); + + // recast as a wxWindow to fit the calling convention + window = dynamic_cast(temp); +} + +boost::any& TextCtrl::get_value() +{ + wxString ret_str = static_cast(window)->GetValue(); + get_value_by_opt_type(ret_str); + + return m_value; +} + +void TextCtrl::enable() { dynamic_cast(window)->Enable(); dynamic_cast(window)->SetEditable(true); } +void TextCtrl::disable() { dynamic_cast(window)->Disable(); dynamic_cast(window)->SetEditable(false); } + +#ifdef __WXGTK__ +void TextCtrl::change_field_value(wxEvent& event) +{ + if (bChangedValueEvent = event.GetEventType()==wxEVT_KEY_UP) + on_change_field(); + event.Skip(); +}; #endif //__WXGTK__ void CheckBox::BUILD() { @@ -388,10 +389,10 @@ void Choice::BUILD() { // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); - if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()){ + if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()) { } else{ - for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels){ + for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) { const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el; temp->Append(str); } @@ -406,7 +407,7 @@ void Choice::BUILD() { void Choice::set_selection() { wxString text_value = wxString(""); - switch (m_opt.type){ + switch (m_opt.type) { case coFloat: case coPercent: { double val = m_opt.default_value->getFloat(); @@ -485,12 +486,12 @@ void Choice::set_value(const boost::any& value, bool change_event) { m_disable_change_event = !change_event; - switch (m_opt.type){ + switch (m_opt.type) { case coInt: case coFloat: case coPercent: case coString: - case coStrings:{ + case coStrings: { wxString text_value; if (m_opt.type == coInt) text_value = wxString::Format(_T("%i"), int(boost::any_cast(value))); @@ -508,11 +509,11 @@ void Choice::set_value(const boost::any& value, bool change_event) dynamic_cast(window)->SetSelection(idx); break; } - case coEnum:{ + case coEnum: { int val = boost::any_cast(value); if (m_opt_id.compare("external_fill_pattern") == 0) { - if (!m_opt.enum_values.empty()){ + if (!m_opt.enum_values.empty()) { std::string key; t_config_enum_values map_names = ConfigOptionEnum::get_enum_values(); for (auto it : map_names) { @@ -583,7 +584,7 @@ boost::any& Choice::get_value() int ret_enum = static_cast(window)->GetSelection(); if (m_opt_id.compare("external_fill_pattern") == 0) { - if (!m_opt.enum_values.empty()){ + if (!m_opt.enum_values.empty()) { std::string key = m_opt.enum_values[ret_enum]; t_config_enum_values map_names = ConfigOptionEnum::get_enum_values(); int value = map_names.at(key); @@ -631,7 +632,8 @@ void ColourPicker::BUILD() temp->SetToolTip(get_tooltip_text(clr_str)); } -boost::any& ColourPicker::get_value(){ +boost::any& ColourPicker::get_value() +{ // boost::any m_value; auto colour = static_cast(window)->GetColour(); @@ -750,7 +752,7 @@ void SliderCtrl::BUILD() temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) { - if (!m_disable_change_event){ + if (!m_disable_change_event) { int val = boost::any_cast(get_value()); m_textctrl->SetLabel(wxString::Format("%d", val)); on_change_field(); @@ -759,7 +761,7 @@ void SliderCtrl::BUILD() m_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { std::string value = e.GetString().utf8_str().data(); - if (is_matched(value, "^-?\\d+(\\.\\d*)?$")){ + if (is_matched(value, "^-?\\d+(\\.\\d*)?$")) { m_disable_change_event = true; m_slider->SetValue(stoi(value)*m_scale); m_disable_change_event = false; diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 9e18cac02..3df1adaa6 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -135,11 +135,11 @@ PreviewIface* create_preview_iface(wxNotebook* parent, DynamicPrintConfig* confi void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/) { try{ - switch (config.def()->get(opt_key)->type){ + switch (config.def()->get(opt_key)->type) { case coFloatOrPercent:{ std::string str = boost::any_cast(value); bool percent = false; - if (str.back() == '%'){ + if (str.back() == '%') { str.pop_back(); percent = true; } @@ -172,7 +172,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt config.option(opt_key)->values = boost::any_cast>(value); } - else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0){ + else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0) { std::string str = boost::any_cast(value); if (str.back() == ';') str.pop_back(); // Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values. @@ -219,7 +219,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt } break; case coPoints:{ - if (opt_key.compare("bed_shape") == 0){ + if (opt_key.compare("bed_shape") == 0) { config.option(opt_key)->values = boost::any_cast>(value); break; } @@ -239,22 +239,26 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt } } -void show_error(wxWindow* parent, const wxString& message) { +void show_error(wxWindow* parent, const wxString& message) +{ ErrorDialog msg(parent, message); msg.ShowModal(); } -void show_error_id(int id, const std::string& message) { +void show_error_id(int id, const std::string& message) +{ auto *parent = id != 0 ? wxWindow::FindWindowById(id) : nullptr; show_error(parent, wxString::FromUTF8(message.data())); } -void show_info(wxWindow* parent, const wxString& message, const wxString& title){ +void show_info(wxWindow* parent, const wxString& message, const wxString& title) +{ wxMessageDialog msg_wingow(parent, message, title.empty() ? _(L("Notice")) : title, wxOK | wxICON_INFORMATION); msg_wingow.ShowModal(); } -void warning_catcher(wxWindow* parent, const wxString& message){ +void warning_catcher(wxWindow* parent, const wxString& message) +{ if (message == "GLUquadricObjPtr | " + _(L("Attempt to free unreferenced scalar")) ) return; wxMessageDialog msg(parent, message, _(L("Warning")), wxOK | wxICON_WARNING); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a40bf4438..59deccbc8 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -122,7 +122,7 @@ bool GUI_App::OnInit() // try to get the mutex. If we can't, just skip this idle event and get the next one. if (!callback_register.try_lock()) return; // pop callback - if (m_cb.size() != 0){ + if (m_cb.size() != 0) { cur_cb = m_cb.top(); m_cb.pop(); } @@ -143,7 +143,7 @@ bool GUI_App::OnInit() // On OS X the UI tends to freeze in weird ways if modal dialogs(config wizard, update notifications, ...) // are shown before or in the same event callback with the main frame creation. // Therefore we schedule them for later using CallAfter. - CallAfter([this](){ + CallAfter([this]() { // eval{ if (!preset_updater->config_update()) mainframe->Close(); @@ -154,7 +154,7 @@ bool GUI_App::OnInit() // } }); - CallAfter([this](){ + CallAfter([this]() { if (!config_wizard_startup(app_conf_exists)) { // Only notify if there was not wizard so as not to bother too much ... preset_updater->slic3r_update_notify(); @@ -196,13 +196,13 @@ void GUI_App::init_label_colours() void GUI_App::update_label_colours_from_appconfig() { - if (app_config->has("label_clr_sys")){ + if (app_config->has("label_clr_sys")) { auto str = app_config->get("label_clr_sys"); if (str != "") m_color_label_sys = wxColour(str); } - if (app_config->has("label_clr_modified")){ + if (app_config->has("label_clr_modified")) { auto str = app_config->get("label_clr_modified"); if (str != "") m_color_label_modified = wxColour(str); @@ -251,7 +251,7 @@ void GUI_App::recreate_GUI() // On OSX the UI was not initialized correctly if the wizard was called // before the UI was up and running. - CallAfter([](){ + CallAfter([]() { // Run the config wizard, don't offer the "reset user profile" checkbox. config_wizard_startup(true); }); @@ -267,7 +267,8 @@ void GUI_App::system_info() // static method accepting a wxWindow object as first parameter bool GUI_App::catch_error(std::function cb, // wxMessageDialog* message_dialog, - const std::string& err /*= ""*/){ + const std::string& err /*= ""*/) +{ if (!err.empty()) { if (cb) cb(); @@ -280,14 +281,16 @@ bool GUI_App::catch_error(std::function cb, } // static method accepting a wxWindow object as first parameter -void fatal_error(wxWindow* parent){ +void fatal_error(wxWindow* parent) +{ show_error(parent, ""); // exit 1; // #ys_FIXME } // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. -void GUI_App::update_ui_from_settings(){ +void GUI_App::update_ui_from_settings() +{ mainframe->update_ui_from_settings(); } @@ -364,7 +367,7 @@ bool GUI_App::select_language( wxArrayString & names, _(L("Array of language names and identifiers should have the same size."))); int init_selection = 0; long current_language = m_wxLocale ? m_wxLocale->GetLanguage() : wxLANGUAGE_UNKNOWN; - for (auto lang : identifiers){ + for (auto lang : identifiers) { if (lang == current_language) break; ++init_selection; @@ -526,7 +529,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) // TODO: for when we're able to flash dictionaries // local_menu->Append(config_id_base + FirmwareMenuDict, _(L("Flash language file")), _(L("Upload a language dictionary file into a Prusa printer"))); - local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event){ + local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) { switch (event.GetId() - config_id_base) { case ConfigMenuWizard: config_wizard(ConfigWizard::RR_USER); @@ -690,7 +693,7 @@ wxNotebook* GUI_App::tab_panel() const // } // Do we need this function??? -// void GUI_App::notify(message){ +// void GUI_App::notify(message) { // auto frame = GetTopWindow(); // // try harder to attract user attention on OS X // if (!frame->IsActive()) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b74edcd8a..bcd615278 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -209,7 +209,8 @@ void ObjectList::update_extruder_in_config(const wxString& selection) wxGetApp().plater()->update(); } -void ObjectList::init_icons(){ +void ObjectList::init_icons() +{ m_bmp_modifiermesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); m_bmp_solidmesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); @@ -297,7 +298,7 @@ void ObjectList::key_event(wxKeyEvent& event) #ifdef __WXOSX__ || event.GetKeyCode() == WXK_BACK #endif //__WXOSX__ - ){ + ) { printf("WXK_BACK\n"); remove(); } @@ -565,7 +566,7 @@ wxMenu* ObjectList::create_add_part_popupmenu() // Append settings popupmenu menu->Append(menu_item_settings(menu, config_id_base + i + 5, false)); - menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event){ + menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) { switch (event.GetId() - config_id_base) { case 0: load_subobject(); @@ -609,7 +610,7 @@ wxMenu* ObjectList::create_part_settings_popupmenu() // Append settings popupmenu menu->Append(menu_item_settings(menu, config_id_base + 1, true)); - menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event){ + menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) { switch (event.GetId() - config_id_base) { case 0: split(true); @@ -801,7 +802,7 @@ void ObjectList::load_lambda(const std::string& type_name) mesh = make_cylinder(params.cyl_r, params.cyl_h); else if (type_name == _("Sphere")) mesh = make_sphere(params.sph_rho); - else if (type_name == _("Slab")){ + else if (type_name == _("Slab")) { const auto& size = (*m_objects)[m_selected_object_id]->bounding_box().size(); mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h); // box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z @@ -1041,7 +1042,7 @@ void ObjectList::part_selection_changed() m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; } } - else if (m_objects_model->GetItemType(item) == itVolume){ + else if (m_objects_model->GetItemType(item) == itVolume) { og_name = _(L("Part manipulation")); is_part = true; const auto volume_id = m_objects_model->GetVolumeIdByItem(item); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 56d01b7f5..db07073d9 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -95,10 +95,10 @@ public: bool is_splittable_object(const bool split_part); wxPoint get_mouse_position_in_control(); - wxBoxSizer* get_sizer(){return m_sizer;} + wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; - bool is_parts_changed() const { return m_parts_changed; } - bool is_part_settings_changed() const{ return m_part_settings_changed; } + bool is_parts_changed() const { return m_parts_changed; } + bool is_part_settings_changed() const { return m_part_settings_changed; } void parts_changed(int obj_idx); void part_selection_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 344fb38ad..8b3d796bd 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -32,8 +32,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent): m_og->label_width = 100; m_og->set_grid_vgap(5); - m_og->m_on_change = [this](t_config_option_key opt_key, boost::any value){ - if (opt_key == "scale_unit"){ + m_og->m_on_change = [this](t_config_option_key opt_key, boost::any value) { + if (opt_key == "scale_unit") { const wxString& selection = boost::any_cast(value); std::vector axes{ "x", "y", "z" }; for (auto axis : axes) { @@ -80,7 +80,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent): if (option_name == "Scale") { line.near_label_widget = [](wxWindow* parent) { auto btn = new PrusaLockButton(parent, wxID_ANY); - btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event){ + btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event) { event.Skip(); wxTheApp->CallAfter([btn]() { wxGetApp().obj_manipul()->set_uniform_scaling(btn->IsLocked()); @@ -188,7 +188,7 @@ void ObjectManipulation::update_settings_list() #ifdef __WXMSW__ btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif // __WXMSW__ - btn->Bind(wxEVT_BUTTON, [opt_key, config](wxEvent &event){ + btn->Bind(wxEVT_BUTTON, [opt_key, config](wxEvent &event) { config->erase(opt_key); wxTheApp->CallAfter([]() { wxGetApp().obj_manipul()->update_settings_list(); }); }); diff --git a/src/slic3r/GUI/LambdaObjectDialog.cpp b/src/slic3r/GUI/LambdaObjectDialog.cpp index d1d8e6046..a55a5bc9b 100644 --- a/src/slic3r/GUI/LambdaObjectDialog.cpp +++ b/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -38,8 +38,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, ConfigOptionDef def; def.width = 70; auto optgroup = init_modificator_options_page(_(L("Box"))); - if (optgroup){ - optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + if (optgroup) { + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { int opt_id = opt_key == "l" ? 0 : opt_key == "w" ? 1 : opt_key == "h" ? 2 : -1; @@ -63,8 +63,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, } optgroup = init_modificator_options_page(_(L("Cylinder"))); - if (optgroup){ - optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + if (optgroup) { + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { int val = boost::any_cast(value); if (opt_key == "cyl_r") object_parameters.cyl_r = val; @@ -85,8 +85,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, } optgroup = init_modificator_options_page(_(L("Sphere"))); - if (optgroup){ - optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + if (optgroup) { + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { if (opt_key == "sph_rho") object_parameters.sph_rho = boost::any_cast(value); else return; @@ -100,8 +100,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, } optgroup = init_modificator_options_page(_(L("Slab"))); - if (optgroup){ - optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + if (optgroup) { + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { double val = boost::any_cast(value); if (opt_key == "slab_z") object_parameters.slab_z = val; @@ -171,7 +171,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, // Called from the constructor. // Create a panel for a rectangular / circular / custom bed shape. -ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(const wxString& title){ +ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(const wxString& title) +{ if (!m_type_name.IsEmpty() && m_type_name != title) return nullptr; diff --git a/src/slic3r/GUI/LambdaObjectDialog.hpp b/src/slic3r/GUI/LambdaObjectDialog.hpp index 3a4d0cf05..6cc99c8a7 100644 --- a/src/slic3r/GUI/LambdaObjectDialog.hpp +++ b/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -41,7 +41,7 @@ class LambdaObjectDialog : public wxDialog public: LambdaObjectDialog(wxWindow* parent, const wxString type_name = wxEmptyString); - ~LambdaObjectDialog(){} + ~LambdaObjectDialog() {} bool CanClose() { return true; } // ??? OBJECT_PARAMETERS& ObjectParameters() { return object_parameters; } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index c15532d70..1515b1386 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -81,7 +81,7 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL Layout(); // declare events - Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event){ + Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event) { if (event.CanVeto() && !wxGetApp().check_unsaved_changes()) { event.Veto(); return; @@ -118,7 +118,7 @@ void MainFrame::init_tabpanel() { m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL); - m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&){ + m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) { auto panel = m_tabpanel->GetCurrentPage(); // panel->OnActivate(); if panel->can('OnActivate'); @@ -162,7 +162,7 @@ void MainFrame::init_tabpanel() // Show a correct number of filament fields. // nozzle_diameter is undefined when SLA printer is selected - if (full_config.has("nozzle_diameter")){ + if (full_config.has("nozzle_diameter")) { m_plater->on_extruders_change(full_config.option("nozzle_diameter")->values.size()); } } @@ -181,7 +181,7 @@ std::vector& MainFrame::get_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; }); + [name](PresetTab& tab) { return name == tab.name; }); return it != preset_tabs.end() ? it->panel : nullptr; } @@ -218,7 +218,7 @@ void MainFrame::add_created_tab(Tab* panel) bool add_panel = true; auto it = std::find_if(preset_tabs.begin(), preset_tabs.end(), - [tab_name](PresetTab& tab){return tab.name == tab_name; }); + [tab_name](PresetTab& tab) {return tab.name == tab_name; }); if (it != preset_tabs.end()) { it->panel = panel; add_panel = it->technology == wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); @@ -236,59 +236,59 @@ void MainFrame::init_menubar() append_menu_item(fileMenu, wxID_ANY, _(L("Open STL/OBJ/AMF/3MF…\tCtrl+O")), _(L("Open a model")), [this](wxCommandEvent&) { if (m_plater) m_plater->add(); }, "brick_add.png"); append_menu_item(fileMenu, wxID_ANY, _(L("&Load Config…\tCtrl+L")), _(L("Load exported configuration file")), - [this](wxCommandEvent&){ load_config_file(); }, "plugin_add.png"); + [this](wxCommandEvent&) { load_config_file(); }, "plugin_add.png"); append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config…\tCtrl+E")), _(L("Export current configuration to file")), - [this](wxCommandEvent&){ export_config(); }, "plugin_go.png"); + [this](wxCommandEvent&) { export_config(); }, "plugin_go.png"); append_menu_item(fileMenu, wxID_ANY, _(L("&Load Config Bundle…")), _(L("Load presets from a bundle")), - [this](wxCommandEvent&){ load_configbundle(); }, "lorry_add.png"); + [this](wxCommandEvent&) { load_configbundle(); }, "lorry_add.png"); append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config Bundle…")), _(L("Export all presets to file")), - [this](wxCommandEvent&){ export_configbundle(); }, "lorry_go.png"); + [this](wxCommandEvent&) { export_configbundle(); }, "lorry_go.png"); fileMenu->AppendSeparator(); wxMenuItem* repeat = nullptr; append_menu_item(fileMenu, wxID_ANY, _(L("Q&uick Slice…\tCtrl+U")), _(L("Slice a file into a G-code")), - [this, repeat](wxCommandEvent&){ - wxTheApp->CallAfter([this, repeat](){ + [this, repeat](wxCommandEvent&) { + wxTheApp->CallAfter([this, repeat]() { quick_slice(); repeat->Enable(is_last_input_file()); }); }, "cog_go.png"); append_menu_item(fileMenu, wxID_ANY, _(L("Quick Slice and Save &As…\tCtrl+Alt+U")), _(L("Slice a file into a G-code, save as")), - [this, repeat](wxCommandEvent&){ - wxTheApp->CallAfter([this, repeat](){ + [this, repeat](wxCommandEvent&) { + wxTheApp->CallAfter([this, repeat]() { quick_slice(qsSaveAs); repeat->Enable(is_last_input_file()); }); }, "cog_go.png"); repeat = append_menu_item(fileMenu, wxID_ANY, _(L("&Repeat Last Quick Slice\tCtrl+Shift+U")), _(L("Repeat last quick slice")), - [this](wxCommandEvent&){ - wxTheApp->CallAfter([this](){ + [this](wxCommandEvent&) { + wxTheApp->CallAfter([this]() { quick_slice(qsReslice); }); }, "cog_go.png"); repeat->Enable(0); fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _(L("Slice to SV&G…\tCtrl+G")), _(L("Slice file to a multi-layer SVG")), - [this](wxCommandEvent&){ quick_slice(qsSaveAs | qsExportSVG); }, "shape_handles.png"); + [this](wxCommandEvent&) { quick_slice(qsSaveAs | qsExportSVG); }, "shape_handles.png"); append_menu_item(fileMenu, wxID_ANY, _(L("Slice to PNG…")), _(L("Slice file to a set of PNG files")), - [this](wxCommandEvent&){ slice_to_png(); /*$self->quick_slice(save_as = > 0, export_png = > 1);*/ }, "shape_handles.png"); + [this](wxCommandEvent&) { slice_to_png(); /*$self->quick_slice(save_as = > 0, export_png = > 1);*/ }, "shape_handles.png"); m_menu_item_reslice_now = append_menu_item(fileMenu, wxID_ANY, _(L("(&Re)Slice Now\tCtrl+S")), _(L("Start new slicing process")), - [this](wxCommandEvent&){ reslice_now(); }, "shape_handles.png"); + [this](wxCommandEvent&) { reslice_now(); }, "shape_handles.png"); fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _(L("Repair STL file…")), _(L("Automatically repair an STL file")), - [this](wxCommandEvent&){ repair_stl(); }, "wrench.png"); + [this](wxCommandEvent&) { repair_stl(); }, "wrench.png"); fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")), - [this](wxCommandEvent&){ Close(false); } ); + [this](wxCommandEvent&) { Close(false); } ); } // Plater menu if (m_plater) { m_plater_menu = new wxMenu(); append_menu_item(m_plater_menu, wxID_ANY, _(L("Export G-code...")), _(L("Export current plate as G-code")), - [this](wxCommandEvent&){ m_plater->export_gcode(); }, "cog_go.png"); + [this](wxCommandEvent&) { m_plater->export_gcode(); }, "cog_go.png"); append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as STL...")), _(L("Export current plate as STL")), - [this](wxCommandEvent&){ m_plater->export_stl(); }, "brick_go.png"); + [this](wxCommandEvent&) { m_plater->export_stl(); }, "brick_go.png"); append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as AMF...")), _(L("Export current plate as AMF")), - [this](wxCommandEvent&){ m_plater->export_amf(); }, "brick_go.png"); + [this](wxCommandEvent&) { m_plater->export_amf(); }, "brick_go.png"); append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as 3MF...")), _(L("Export current plate as 3MF")), - [this](wxCommandEvent&){ m_plater->export_3mf(); }, "brick_go.png"); + [this](wxCommandEvent&) { m_plater->export_3mf(); }, "brick_go.png"); } // Window menu @@ -297,18 +297,18 @@ void MainFrame::init_menubar() size_t tab_offset = 0; if (m_plater) { append_menu_item(windowMenu, wxID_ANY, L("Select &Plater Tab\tCtrl+1"), L("Show the plater"), - [this](wxCommandEvent&){ select_tab(0); }, "application_view_tile.png"); + [this](wxCommandEvent&) { select_tab(0); }, "application_view_tile.png"); tab_offset += 1; } if (tab_offset > 0) { windowMenu->AppendSeparator(); } append_menu_item(windowMenu, wxID_ANY, L("Select P&rint Settings Tab\tCtrl+2"), L("Show the print settings"), - [this, tab_offset](wxCommandEvent&){ select_tab(tab_offset + 0); }, "cog.png"); + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog.png"); append_menu_item(windowMenu, wxID_ANY, L("Select &Filament Settings Tab\tCtrl+3"), L("Show the filament settings"), - [this, tab_offset](wxCommandEvent&){ select_tab(tab_offset + 1); }, "spool.png"); + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 1); }, "spool.png"); append_menu_item(windowMenu, wxID_ANY, L("Select Print&er Settings Tab\tCtrl+4"), L("Show the printer settings"), - [this, tab_offset](wxCommandEvent&){ select_tab(tab_offset + 2); }, "printer_empty.png"); + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer_empty.png"); } // View menu @@ -317,40 +317,40 @@ void MainFrame::init_menubar() // \xA0 is a non-breaing space. It is entered here to spoil the automatic accelerators, // as the simple numeric accelerators spoil all numeric data entry. // The camera control accelerators are captured by GLCanvas3D::on_char(). - append_menu_item(m_viewMenu, wxID_ANY, _(L("Iso")) + "\t\xA0" + "0", _(L("Iso View")), [this](wxCommandEvent&){ select_view("iso"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Iso")) + "\t\xA0" + "0", _(L("Iso View")), [this](wxCommandEvent&) { select_view("iso"); }); m_viewMenu->AppendSeparator(); - append_menu_item(m_viewMenu, wxID_ANY, _(L("Top")) + "\t\xA0" + "1", _(L("Top View")), [this](wxCommandEvent&){ select_view("top"); }); - append_menu_item(m_viewMenu, wxID_ANY, _(L("Bottom")) + "\t\xA0" + "2", _(L("Bottom View")), [this](wxCommandEvent&){ select_view("bottom"); }); - append_menu_item(m_viewMenu, wxID_ANY, _(L("Front")) + "\t\xA0" + "3", _(L("Front View")), [this](wxCommandEvent&){ select_view("front"); }); - append_menu_item(m_viewMenu, wxID_ANY, _(L("Rear")) + "\t\xA0" + "4", _(L("Rear View")), [this](wxCommandEvent&){ select_view("rear"); }); - append_menu_item(m_viewMenu, wxID_ANY, _(L("Left")) + "\t\xA0" + "5", _(L("Left View")), [this](wxCommandEvent&){ select_view("left"); }); - append_menu_item(m_viewMenu, wxID_ANY, _(L("Right")) + "\t\xA0" + "6", _(L("Right View")), [this](wxCommandEvent&){ select_view("right"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Top")) + "\t\xA0" + "1", _(L("Top View")), [this](wxCommandEvent&) { select_view("top"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Bottom")) + "\t\xA0" + "2", _(L("Bottom View")), [this](wxCommandEvent&) { select_view("bottom"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Front")) + "\t\xA0" + "3", _(L("Front View")), [this](wxCommandEvent&) { select_view("front"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Rear")) + "\t\xA0" + "4", _(L("Rear View")), [this](wxCommandEvent&) { select_view("rear"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Left")) + "\t\xA0" + "5", _(L("Left View")), [this](wxCommandEvent&) { select_view("left"); }); + append_menu_item(m_viewMenu, wxID_ANY, _(L("Right")) + "\t\xA0" + "6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); }); } // Help menu auto helpMenu = new wxMenu(); { append_menu_item(helpMenu, wxID_ANY, _(L("Prusa 3D Drivers")), _(L("Open the Prusa3D drivers download page in your browser")), - [this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://www.prusa3d.com/drivers/"); }); + [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://www.prusa3d.com/drivers/"); }); append_menu_item(helpMenu, wxID_ANY, _(L("Prusa Edition Releases")), _(L("Open the Prusa Edition releases page in your browser")), - [this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/releases"); }); + [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/releases"); }); //# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{ //# wxTheApp->check_version(1); //# }); //# $versioncheck->Enable(wxTheApp->have_version_check); append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Website")), _(L("Open the Slic3r website in your browser")), - [this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://slic3r.org/"); }); + [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://slic3r.org/"); }); append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Manual")), _(L("Open the Slic3r manual in your browser")), - [this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://manual.slic3r.org/"); }); + [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://manual.slic3r.org/"); }); helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("System Info")), _(L("Show system information")), - [this](wxCommandEvent&){ wxGetApp().system_info(); }); + [this](wxCommandEvent&) { wxGetApp().system_info(); }); append_menu_item(helpMenu, wxID_ANY, _(L("Show &Configuration Folder")), _(L("Show user configuration folder (datadir)")), - [this](wxCommandEvent&){ Slic3r::GUI::desktop_open_datadir_folder(); }); + [this](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); }); append_menu_item(helpMenu, wxID_ANY, _(L("Report an Issue")), _(L("Report an issue on the Slic3r Prusa Edition")), - [this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); }); + [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); }); append_menu_item(helpMenu, wxID_ANY, _(L("&About Slic3r")), _(L("Show about dialog")), - [this](wxCommandEvent&){ Slic3r::GUI::about(); }); + [this](wxCommandEvent&) { Slic3r::GUI::about(); }); } // menubar @@ -369,14 +369,16 @@ void MainFrame::init_menubar() } } -void MainFrame::slice_to_png(){ +void MainFrame::slice_to_png() +{ // m_plater->stop_background_process(); // m_plater->async_apply_config(); m_appController->print_ctl()->slice_to_png(); } // To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG". -void MainFrame::quick_slice(const int qs){ +void MainFrame::quick_slice(const int qs) +{ // my $progress_dialog; wxString input_file; // eval @@ -422,7 +424,7 @@ void MainFrame::quick_slice(const int qs){ // // auto sprint = new Slic3r::Print::Simple( // print_center = > print_center, -// status_cb = > [](int percent, const wxString& msg){ +// status_cb = > [](int percent, const wxString& msg) { // m_progress_dialog->Update(percent, msg+"…"); // }); @@ -502,7 +504,7 @@ void MainFrame::quick_slice(const int qs){ // wxTheApp->notify(message); wxMessageDialog(this, message, _(L("Slicing Done!")), wxOK | wxICON_INFORMATION).ShowModal(); // }; -// Slic3r::GUI::catch_error(this, [](){ if (m_progress_dialog) m_progress_dialog->Destroy(); }); +// Slic3r::GUI::catch_error(this, []() { if (m_progress_dialog) m_progress_dialog->Destroy(); }); } void MainFrame::reslice_now() @@ -701,7 +703,7 @@ void MainFrame::on_presets_changed(SimpleEvent &event) // FIXME: The preset type really should be a property of Tab instead Slic3r::Preset::Type preset_type = tab->type(); - if (preset_type == Slic3r::Preset::TYPE_INVALID){ + if (preset_type == Slic3r::Preset::TYPE_INVALID) { wxASSERT(false); return; } @@ -737,7 +739,7 @@ void MainFrame::on_value_changed(wxCommandEvent& event) auto opt_key = event.GetString(); if (m_plater) { m_plater->on_config_change(*tab->get_config()); // propagate config change events to the plater - if (opt_key == "extruders_count"){ + if (opt_key == "extruders_count") { auto value = event.GetInt(); m_plater->on_extruders_change(value); } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 371747bc1..8e810fcda 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -66,13 +66,13 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co } // Grab a reference to fields for convenience const t_field& field = m_fields[id]; - field->m_on_change = [this](std::string opt_id, boost::any value){ + field->m_on_change = [this](std::string opt_id, boost::any value) { //! This function will be called from Field. //! Call OptionGroup._on_change(...) if (!m_disabled) this->on_change_OG(opt_id, value); }; - field->m_on_kill_focus = [this](){ + field->m_on_kill_focus = [this]() { //! This function will be called from Field. if (!m_disabled) this->on_kill_focus(); @@ -81,11 +81,11 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co //! Label to change background color, when option is modified field->m_Label = label; - field->m_back_to_initial_value = [this](std::string opt_id){ + field->m_back_to_initial_value = [this](std::string opt_id) { if (!m_disabled) this->back_to_initial_value(opt_id); }; - field->m_back_to_sys_value = [this](std::string opt_id){ + field->m_back_to_sys_value = [this](std::string opt_id) { if (!this->m_disabled) this->back_to_sys_value(opt_id); }; @@ -107,8 +107,8 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel } void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) { -//! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){ - if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){ +//! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)) { + if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width) { if (line.sizer != nullptr) { sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); return; @@ -313,7 +313,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b // get value //! auto field_value = get_value(opt_id); if (option.gui_flags.compare("serialized")==0) { - if (opt_index != -1){ + if (opt_index != -1) { // die "Can't set serialized option indexed value" ; } change_opt_value(*m_config, opt_key, value); @@ -355,7 +355,7 @@ void ConfigOptionsGroup::back_to_sys_value(const std::string& opt_key) void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key) { boost::any value; - if (opt_key == "extruders_count"){ + if (opt_key == "extruders_count") { auto *nozzle_diameter = dynamic_cast(config.option("nozzle_diameter")); value = int(nozzle_diameter->values.size()); } @@ -376,7 +376,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, on_change_OG(opt_key, get_value(opt_key)); } -void ConfigOptionsGroup::reload_config(){ +void ConfigOptionsGroup::reload_config() { for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { auto opt_id = it->first; std::string opt_key = m_opt_map.at(opt_id).first; @@ -420,7 +420,7 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) { return true; } -boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize){ +boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) { if (deserialize) { // Want to edit a vector value(currently only multi - strings) in a single edit box. @@ -444,7 +444,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config boost::any ret; wxString text_value = wxString(""); const ConfigOptionDef* opt = config.def()->get(opt_key); - switch (opt->type){ + switch (opt->type) { case coFloatOrPercent:{ const auto &value = *config.option(opt_key); if (value.percent) @@ -477,13 +477,13 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = static_cast(config.opt_string(opt_key)); break; case coStrings: - if (opt_key.compare("compatible_printers") == 0){ + if (opt_key.compare("compatible_printers") == 0) { ret = config.option(opt_key)->values; break; } if (config.option(opt_key)->values.empty()) ret = text_value; - else if (opt->gui_flags.compare("serialized") == 0){ + else if (opt->gui_flags.compare("serialized") == 0) { std::vector values = config.option(opt_key)->values; if (!values.empty() && values[0].compare("") != 0) for (auto el : values) @@ -507,19 +507,19 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config break; case coEnum:{ if (opt_key.compare("external_fill_pattern") == 0 || - opt_key.compare("fill_pattern") == 0 ){ + opt_key.compare("fill_pattern") == 0 ) { ret = static_cast(config.option>(opt_key)->value); } - else if (opt_key.compare("gcode_flavor") == 0 ){ + else if (opt_key.compare("gcode_flavor") == 0 ) { ret = static_cast(config.option>(opt_key)->value); } - else if (opt_key.compare("support_material_pattern") == 0){ + else if (opt_key.compare("support_material_pattern") == 0) { ret = static_cast(config.option>(opt_key)->value); } - else if (opt_key.compare("seam_position") == 0){ + else if (opt_key.compare("seam_position") == 0) { ret = static_cast(config.option>(opt_key)->value); } - else if (opt_key.compare("host_type") == 0){ + else if (opt_key.compare("host_type") == 0) { ret = static_cast(config.option>(opt_key)->value); } } @@ -537,13 +537,14 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config return ret; } -Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index){ +Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index) +{ Field* field = get_field(opt_key); if (field != nullptr) return field; std::string opt_id = ""; for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { - if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second){ + if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second) { opt_id = it->first; break; } diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 656ae1d72..f6b38d624 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -156,7 +156,7 @@ public: column_t extra_clmn = nullptr) : m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt), - staticbox(title!=""), extra_column(extra_clmn){ + staticbox(title!=""), extra_column(extra_clmn) { if (staticbox) { stb = new wxStaticBox(_parent, wxID_ANY, title); stb->SetFont(wxGetApp().bold_font()); @@ -177,7 +177,7 @@ public: #endif /* __WXGTK__ */ } - wxGridSizer* get_grid_sizer(){ return m_grid_sizer; } + wxGridSizer* get_grid_sizer() { return m_grid_sizer; } protected: std::map m_options; @@ -208,10 +208,10 @@ protected: const t_field& build_field(const Option& opt, wxStaticText* label = nullptr); void add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field); - virtual void on_kill_focus (){}; + virtual void on_kill_focus () {}; virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value); - virtual void back_to_initial_value(const std::string& opt_key){} - virtual void back_to_sys_value(const std::string& opt_key){} + virtual void back_to_initial_value(const std::string& opt_key) {} + virtual void back_to_sys_value(const std::string& opt_key) {} }; class ConfigOptionsGroup: public OptionsGroup { @@ -225,7 +225,7 @@ public: bool m_full_labels {0}; t_opt_map m_opt_map; - void set_config(DynamicPrintConfig* config){ m_config = config; } + void set_config(DynamicPrintConfig* config) { m_config = config; } Option get_option(const std::string& opt_key, int opt_index = -1); Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{ Option option = get_option(title, idx); @@ -258,8 +258,8 @@ public: class ogStaticText :public wxStaticText{ public: ogStaticText() {} - ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize){} - ~ogStaticText(){} + ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize) {} + ~ogStaticText() {} void SetText(const wxString& value, bool wrap = true); }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e9deed020..04f47228b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -279,13 +279,13 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : m_og->set_config(config); m_og->label_width = label_width; - m_og->m_on_change = [config, this](t_config_option_key opt_key, boost::any value){ + m_og->m_on_change = [config, this](t_config_option_key opt_key, boost::any value) { TabPrint* tab_print = nullptr; for (size_t i = 0; i < wxGetApp().tab_panel()->GetPageCount(); ++i) { Tab *tab = dynamic_cast(wxGetApp().tab_panel()->GetPage(i)); if (!tab) continue; - if (tab->name() == "print"){ + if (tab->name() == "print") { tab_print = static_cast(tab); break; } @@ -293,14 +293,14 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : if (tab_print == nullptr) return; - if (opt_key == "fill_density"){ + if (opt_key == "fill_density") { value = m_og->get_config_value(*config, opt_key); tab_print->set_value(opt_key, value); tab_print->update(); } else{ DynamicPrintConfig new_conf = *config; - if (opt_key == "brim"){ + if (opt_key == "brim") { double new_val; double brim_width = config->opt_float("brim_width"); if (boost::any_cast(value) == true) @@ -367,7 +367,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : Line line = { "", "" }; - line.widget = [config, this](wxWindow* parent){ + line.widget = [config, this](wxWindow* parent) { m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_wiping_dialog_button); @@ -952,7 +952,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) : background_process.set_sliced_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); // Register progress callback from the Print class to the Platter. - print.set_status_callback([this](int percent, const std::string &message){ + print.set_status_callback([this](int percent, const std::string &message) { wxCommandEvent event(EVT_PROGRESS_BAR); event.SetInt(percent); event.SetString(message); @@ -982,7 +982,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) : _3DScene::enable_force_zoom_to_bed(canvas3D, true); this->background_process_timer.SetOwner(this->q, 0); - this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt){ this->async_apply_config(); }); + this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->async_apply_config(); }); auto *bed_shape = config->opt("bed_shape"); _3DScene::set_bed_shape(canvas3D, bed_shape->values); @@ -1754,7 +1754,7 @@ void Plater::priv::async_apply_config() } if (invalidated != Print::APPLY_STATUS_UNCHANGED && this->get_config("background_processing") == "1" && this->print.num_object_instances() > 0 && this->background_process.start()) - this->statusbar()->set_cancel_callback([this](){ + this->statusbar()->set_cancel_callback([this]() { this->statusbar()->set_status_text(L("Cancelling")); this->background_process.stop(); }); @@ -2090,13 +2090,13 @@ void Plater::priv::on_update_geometry(Vec3dsEvent<2>&) bool Plater::priv::init_object_menu() { wxMenuItem* item_delete = append_menu_item(&object_menu, wxID_ANY, _(L("Delete\tDel")), _(L("Remove the selected object")), - [this](wxCommandEvent&){ q->remove_selected(); }, "brick_delete.png"); + [this](wxCommandEvent&) { q->remove_selected(); }, "brick_delete.png"); wxMenuItem* item_increase = append_menu_item(&object_menu, wxID_ANY, _(L("Increase copies\t+")), _(L("Place one more copy of the selected object")), - [this](wxCommandEvent&){ q->increase_instances(); }, "add.png"); + [this](wxCommandEvent&) { q->increase_instances(); }, "add.png"); wxMenuItem* item_decrease = append_menu_item(&object_menu, wxID_ANY, _(L("Decrease copies\t-")), _(L("Remove one copy of the selected object")), - [this](wxCommandEvent&){ q->decrease_instances(); }, "delete.png"); + [this](wxCommandEvent&) { q->decrease_instances(); }, "delete.png"); wxMenuItem* item_set_number_of_copies = append_menu_item(&object_menu, wxID_ANY, _(L("Set number of copies…")), _(L("Change the number of copies of the selected object")), - [this](wxCommandEvent&){ q->set_number_of_copies(); }, "textfield.png"); + [this](wxCommandEvent&) { q->set_number_of_copies(); }, "textfield.png"); object_menu.AppendSeparator(); @@ -2106,11 +2106,11 @@ bool Plater::priv::init_object_menu() return false; append_menu_item(mirror_menu, wxID_ANY, _(L("Along X axis")), _(L("Mirror the selected object along the X axis")), - [this](wxCommandEvent&){ mirror(X); }, "bullet_red.png", &object_menu); + [this](wxCommandEvent&) { mirror(X); }, "bullet_red.png", &object_menu); append_menu_item(mirror_menu, wxID_ANY, _(L("Along Y axis")), _(L("Mirror the selected object along the Y axis")), - [this](wxCommandEvent&){ mirror(Y); }, "bullet_green.png", &object_menu); + [this](wxCommandEvent&) { mirror(Y); }, "bullet_green.png", &object_menu); append_menu_item(mirror_menu, wxID_ANY, _(L("Along Z axis")), _(L("Mirror the selected object along the Z axis")), - [this](wxCommandEvent&){ mirror(Z); }, "bullet_blue.png", &object_menu); + [this](wxCommandEvent&) { mirror(Z); }, "bullet_blue.png", &object_menu); wxMenuItem* item_mirror = append_submenu(&object_menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object"))); #endif // ENABLE_MIRROR @@ -2120,9 +2120,9 @@ bool Plater::priv::init_object_menu() return false; wxMenuItem* item_split_objects = append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")), - [this](wxCommandEvent&){ split_object(); }, "shape_ungroup.png", &object_menu); + [this](wxCommandEvent&) { split_object(); }, "shape_ungroup.png", &object_menu); wxMenuItem* item_split_volumes = append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")), - [this](wxCommandEvent&){ split_volume(); }, "shape_ungroup.png", &object_menu); + [this](wxCommandEvent&) { split_volume(); }, "shape_ungroup.png", &object_menu); wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "shape_ungroup.png"); @@ -2515,7 +2515,7 @@ void Plater::reslice() // this->p->stop_background_process(); // Rather perform one additional unnecessary update of the print object instead of skipping a pending async update. this->p->async_apply_config(); - this->p->statusbar()->set_cancel_callback([this](){ + this->p->statusbar()->set_cancel_callback([this]() { this->p->statusbar()->set_status_text(L("Cancelling")); this->p->background_process.stop(); }); diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index 0b1dd5730..363daebbc 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -17,7 +17,7 @@ class PreferencesDialog : public wxDialog std::shared_ptr m_optgroup; public: PreferencesDialog(wxWindow* parent); - ~PreferencesDialog(){ } + ~PreferencesDialog() {} void build(); void accept(); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 07410e325..0a4fb121a 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -779,7 +779,7 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) bmp = m_bitmap_cache->insert(bitmap_key, bmps); } - if (preset.is_default || preset.is_system){ + if (preset.is_default || preset.is_system) { ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); if (i == m_idx_selected) @@ -839,7 +839,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati bmp = m_bitmap_cache->insert(bitmap_key, bmps); } - if (preset.is_default || preset.is_system){ + if (preset.is_default || preset.is_system) { ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); if (i == m_idx_selected) diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index f0f53ff6c..3314cdd94 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -315,7 +315,7 @@ void PresetBundle::load_selections(const AppConfig &config) sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name); printers.select_preset_by_name(initial_printer_profile_name, true); - if (printers.get_selected_preset().printer_technology() == ptFFF){ + if (printers.get_selected_preset().printer_technology() == ptFFF) { // Load the names of the other filament profiles selected for a multi-material printer. auto *nozzle_diameter = dynamic_cast(printers.get_selected_preset().config.option("nozzle_diameter")); size_t num_extruders = nozzle_diameter->values.size(); @@ -1179,7 +1179,7 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati prefered_print_profile.empty() ? this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible, - [&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; }); + [&prefered_print_profile](const std::string& profile_name) { return profile_name == prefered_print_profile; }); prefered_filament_profiles.empty() ? this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible, @@ -1199,7 +1199,7 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati const std::string &preferred = (idx < prefered_filament_profiles.size()) ? prefered_filament_profiles[idx] : prefered_filament_profiles.front(); filament_name = this->filaments.first_compatible( - [&preferred](const std::string& profile_name){ return profile_name == preferred; }).name; + [&preferred](const std::string& profile_name) { return profile_name == preferred; }).name; } } } @@ -1212,7 +1212,7 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati prefered_print_profile.empty() ? 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_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; }); + [&prefered_print_profile](const std::string& profile_name) { return profile_name == prefered_print_profile; }); } } } @@ -1361,7 +1361,7 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr bitmap = m_bitmapCache->insert(bitmap_key, bmps); } - if (preset.is_default || preset.is_system){ + if (preset.is_default || preset.is_system) { ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), (bitmap == 0) ? wxNullBitmap : *bitmap); if (selected) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index bba5161cc..2b3d7d856 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -125,16 +125,16 @@ void Tab::create_preset_tab() set_tooltips_text(); m_undo_btn->SetBitmap(m_bmp_white_bullet); - m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(); })); + m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); })); m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet); - m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(true); })); + m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); })); m_question_btn->SetBitmap(m_bmp_question); m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { auto dlg = new ButtonsDescription(this, &m_icon_descriptions); - if (dlg->ShowModal() == wxID_OK){ + if (dlg->ShowModal() == wxID_OK) { // Colors for ui "decoration" - for (Tab *tab : wxGetApp().tabs_list){ + for (Tab *tab : wxGetApp().tabs_list) { tab->m_sys_label_clr = wxGetApp().get_label_clr_sys(); tab->m_modified_label_clr = wxGetApp().get_label_clr_modified(); tab->update_labels_colour(); @@ -185,7 +185,7 @@ void Tab::create_preset_tab() m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this); m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this); - m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e){ + m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, //! but the OSX version derived from wxOwnerDrawnCombo, instead of: //! select_preset(m_presets_choice->GetStringSelection().ToStdString()); @@ -193,11 +193,11 @@ void Tab::create_preset_tab() int selected_item = m_presets_choice->GetSelection(); if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) return; - if (selected_item >= 0){ + if (selected_item >= 0) { std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); if (selected_string.find("-------") == 0 /*selected_string == "------- System presets -------" || - selected_string == "------- User presets -------"*/){ + selected_string == "------- User presets -------"*/) { m_presets_choice->SetSelection(m_selected_preset_item); return; } @@ -206,9 +206,9 @@ void Tab::create_preset_tab() } })); - m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e){ save_preset(); })); - m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e){ delete_preset(); })); - m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e){ + m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); })); + m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); })); + m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { toggle_show_hide_incompatible(); })); @@ -281,7 +281,7 @@ void Tab::update_labels_colour() const wxColour *color = &m_sys_label_clr; // value isn't equal to system value - if ((opt.second & osSystemValue) == 0){ + if ((opt.second & osSystemValue) == 0) { // value is equal to last saved if ((opt.second & osInitValue) != 0) color = &m_default_text_clr; @@ -304,7 +304,7 @@ void Tab::update_labels_colour() Thaw(); auto cur_item = m_treectrl->GetFirstVisibleItem(); - while (cur_item){ + while (cur_item) { auto title = m_treectrl->GetItemText(cur_item); for (auto page : m_pages) { @@ -331,7 +331,7 @@ void Tab::update_changed_ui() const bool deep_compare = (m_name == "printer" || m_name == "sla_material"); auto dirty_options = m_presets->current_dirty_options(deep_compare); auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare); - if (name() == "printer"){ + if (name() == "printer") { TabPrinter* tab = static_cast(this); if (tab->m_initial_extruders_count != tab->m_extruders_count) dirty_options.emplace_back("extruders_count"); @@ -360,7 +360,7 @@ void Tab::update_changed_ui() const wxString *tt = &m_tt_value_revert; // value isn't equal to system value - if ((opt.second & osSystemValue) == 0){ + if ((opt.second & osSystemValue) == 0) { is_nonsys_value = true; sys_icon = m_bmp_non_system; sys_tt = m_tt_non_system; @@ -426,7 +426,7 @@ void TabPrinter::init_options_list() for (const auto opt_key : m_config->keys()) { - if (opt_key == "bed_shape"){ + if (opt_key == "bed_shape") { m_options_list.emplace(opt_key, m_opt_status_value); continue; } @@ -451,7 +451,7 @@ void TabSLAMaterial::init_options_list() for (const auto opt_key : m_config->keys()) { - if (opt_key == "compatible_printers"){ + if (opt_key == "compatible_printers") { m_options_list.emplace(opt_key, m_opt_status_value); continue; } @@ -481,7 +481,7 @@ void Tab::update_changed_tree_ui() if (!cur_item || !m_treectrl->IsVisible(cur_item)) return; auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); - while (cur_item){ + while (cur_item) { auto title = m_treectrl->GetItemText(cur_item); for (auto page : m_pages) { @@ -489,13 +489,13 @@ void Tab::update_changed_tree_ui() continue; bool sys_page = true; bool modified_page = false; - if (title == _("General")){ + if (title == _("General")) { std::initializer_list optional_keys{ "extruders_count", "bed_shape" }; for (auto &opt_key : optional_keys) { get_sys_and_mod_flags(opt_key, sys_page, modified_page); } } - if (title == _("Dependencies")){ + if (title == _("Dependencies")) { if (name() != "printer") get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); else { @@ -523,7 +523,7 @@ void Tab::update_changed_tree_ui() page->m_is_nonsys_values = !sys_page; page->m_is_modified_values = modified_page; - if (selection == title){ + if (selection == title) { m_is_nonsys_values = page->m_is_nonsys_values; m_is_modified_values = page->m_is_modified_values; } @@ -561,20 +561,20 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/) auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); for (auto page : m_pages) if (page->title() == selection) { - for (auto group : page->m_optgroups){ - if (group->title == _("Capabilities")){ + for (auto group : page->m_optgroups) { + if (group->title == _("Capabilities")) { if ((m_options_list["extruders_count"] & os) == 0) to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count"); } - if (group->title == _("Size and coordinates")){ - if ((m_options_list["bed_shape"] & os) == 0){ + if (group->title == _("Size and coordinates")) { + if ((m_options_list["bed_shape"] & os) == 0) { to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape"); load_key_value("bed_shape", true/*some value*/, true); } } - if (group->title == _("Profile dependencies") && name() != "printer"){ - if ((m_options_list["compatible_printers"] & os) == 0){ + if (group->title == _("Profile dependencies") && name() != "printer") { + if ((m_options_list["compatible_printers"] & os) == 0) { to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers"); load_key_value("compatible_printers", true/*some value*/, true); @@ -598,7 +598,8 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/) // Update the combo box label of the selected preset based on its "dirty" state, // comparing the selected preset config with $self->{config}. -void Tab::update_dirty(){ +void Tab::update_dirty() +{ m_presets->update_dirty_ui(m_presets_choice); on_presets_changed(); update_changed_ui(); @@ -627,7 +628,8 @@ void Tab::load_config(const DynamicPrintConfig& config) } // Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields. -void Tab::reload_config(){ +void Tab::reload_config() +{ Freeze(); for (auto page : m_pages) page->reload_config(); @@ -656,7 +658,7 @@ void Tab::update_visibility(ConfigOptionMode mode) Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const { Field* field = nullptr; - for (auto page : m_pages){ + for (auto page : m_pages) { field = page->get_field(opt_key, opt_index); if (field != nullptr) return field; @@ -667,7 +669,7 @@ Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/ // Set a key/value pair on this page. Return true if the value has been modified. // Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer // after a preset is loaded. -bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value){ +bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value) { bool changed = false; for(auto page: m_pages) { if (page->set_value(opt_key, value)) @@ -785,7 +787,7 @@ void Tab::update_preset_description_line() description_line += "\n\n" + _(L("Additional information:")) + "\n"; description_line += "\t" + _(L("vendor")) + ": " + (name()=="printer" ? "\n\t\t" : "") + parent->vendor->name + ", ver: " + parent->vendor->config_version.to_string(); - if (name() == "printer"){ + if (name() == "printer") { const std::string &printer_model = preset.config.opt_string("printer_model"); const std::string &default_print_profile = preset.config.opt_string("default_print_profile"); const std::vector &default_filament_profiles = preset.config.option("default_filament_profile")->values; @@ -796,7 +798,7 @@ void Tab::update_preset_description_line() if (!default_filament_profiles.empty()) { description_line += "\n\n\t" + _(L("default filament profile")) + ": \n\t\t"; - for (auto& profile : default_filament_profiles){ + for (auto& profile : default_filament_profiles) { if (&profile != &*default_filament_profiles.begin()) description_line += ", "; description_line += profile; @@ -1041,7 +1043,7 @@ void TabPrint::build() page = add_options_page(_(L("Dependencies")), "wrench.png"); optgroup = page->new_optgroup(_(L("Profile dependencies"))); line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" }; - line.widget = [this](wxWindow* parent){ + 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); @@ -1059,7 +1061,8 @@ void TabPrint::build() } // Reload current config (aka presets->edited_preset->config) into the UI fields. -void TabPrint::reload_config(){ +void TabPrint::reload_config() +{ reload_compatible_printers_widget(); Tab::reload_config(); } @@ -1174,7 +1177,7 @@ void TabPrint::update() break; } } - if (!str_fill_pattern.empty()){ + if (!str_fill_pattern.empty()) { auto external_fill_pattern = m_config->def()->get("external_fill_pattern")->enum_values; bool correct_100p_fill = false; for (auto fill : external_fill_pattern) @@ -1184,7 +1187,7 @@ void TabPrint::update() } // get fill_pattern name from enum_labels for using this one at dialog_msg str_fill_pattern = m_config->def()->get("fill_pattern")->enum_labels[fill_pattern]; - if (!correct_100p_fill){ + if (!correct_100p_fill) { wxString msg_text = _(L("The ")) + str_fill_pattern + _(L(" infill pattern is not supposed to work at 100% density.\n" "\nShall I switch to rectilinear fill pattern?")); auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO); @@ -1367,7 +1370,7 @@ void TabFilament::build() optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower"); line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" }; - line.widget = [this](wxWindow* parent){ + line.widget = [this](wxWindow* parent) { auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(ramming_dialog_btn); @@ -1407,7 +1410,7 @@ void TabFilament::build() page = add_options_page(_(L("Dependencies")), "wrench.png"); optgroup = page->new_optgroup(_(L("Profile dependencies"))); line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" }; - line.widget = [this](wxWindow* parent){ + 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); @@ -1425,7 +1428,8 @@ void TabFilament::build() } // Reload current config (aka presets->edited_preset->config) into the UI fields. -void TabFilament::reload_config(){ +void TabFilament::reload_config() +{ reload_compatible_printers_widget(); Tab::reload_config(); } @@ -1502,7 +1506,7 @@ void TabPrinter::build_fff() auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; - line.widget = [this](wxWindow* parent){ + line.widget = [this](wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(wxGetApp().small_font()); btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); @@ -1514,7 +1518,7 @@ void TabPrinter::build_fff() { auto dlg = new BedShapeDialog(this); dlg->build_dialog(m_config->option("bed_shape")); - if (dlg->ShowModal() == wxID_OK){ + if (dlg->ShowModal() == wxID_OK) { load_key_value("bed_shape", dlg->GetValue()); update_changed_ui(); } @@ -1538,9 +1542,9 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup->append_single_option_line("single_extruder_multi_material"); - optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){ + optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { size_t extruders_count = boost::any_cast(optgroup->get_value("extruders_count")); - wxTheApp->CallAfter([this, opt_key, value, extruders_count](){ + wxTheApp->CallAfter([this, opt_key, value, extruders_count]() { if (opt_key.compare("extruders_count")==0 || opt_key.compare("single_extruder_multi_material")==0) { extruders_count_changed(extruders_count); update_dirty(); @@ -1561,7 +1565,7 @@ void TabPrinter::build_fff() optgroup = page->new_optgroup(_(L("USB/Serial connection"))); line = {_(L("Serial port")), ""}; Option serial_port = optgroup->get_option("serial_port"); - serial_port.side_widget = ([this](wxWindow* parent){ + serial_port.side_widget = ([this](wxWindow* parent) { auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(Slic3r::var("arrow_rotate_clockwise.png")), wxBITMAP_TYPE_PNG), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); btn->SetToolTip(_(L("Rescan serial ports"))); @@ -1571,7 +1575,7 @@ void TabPrinter::build_fff() btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {update_serial_ports(); }); return sizer; }); - auto serial_test = [this](wxWindow* parent){ + auto serial_test = [this](wxWindow* parent) { auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(Slic3r::GUI::small_font()); @@ -1579,7 +1583,7 @@ void TabPrinter::build_fff() auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e){ + btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e) { auto sender = Slic3r::make_unique(); auto res = sender->connect( m_config->opt_string("serial_port"), @@ -1664,7 +1668,7 @@ void TabPrinter::build_fff() auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e){ + btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e) { static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*")); wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (openFileDialog.ShowModal() != wxID_CANCEL) { @@ -1698,8 +1702,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("silent_mode"); optgroup->append_single_option_line("remaining_times"); - optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){ - wxTheApp->CallAfter([this, opt_key, value](){ + optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { + wxTheApp->CallAfter([this, opt_key, value]() { if (opt_key.compare("silent_mode") == 0) { bool val = boost::any_cast(value); if (m_use_silent_mode != val) { @@ -1788,7 +1792,7 @@ void TabPrinter::build_sla() auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; - line.widget = [this](wxWindow* parent){ + line.widget = [this](wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); // btn->SetFont(Slic3r::GUI::small_font); btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); @@ -1800,7 +1804,7 @@ void TabPrinter::build_sla() { auto dlg = new BedShapeDialog(this); dlg->build_dialog(m_config->option("bed_shape")); - if (dlg->ShowModal() == wxID_OK){ + if (dlg->ShowModal() == wxID_OK) { load_key_value("bed_shape", dlg->GetValue()); update_changed_ui(); } @@ -1850,13 +1854,15 @@ void TabPrinter::build_sla() optgroup->append_line(line); } -void TabPrinter::update_serial_ports(){ +void TabPrinter::update_serial_ports() +{ Field *field = get_field("serial_port"); Choice *choice = static_cast(field); choice->set_values(Utils::scan_serial_ports()); } -void TabPrinter::extruders_count_changed(size_t extruders_count){ +void TabPrinter::extruders_count_changed(size_t extruders_count) +{ m_extruders_count = extruders_count; m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); m_preset_bundle->update_multi_material_filament_presets(); @@ -1947,7 +1953,7 @@ void TabPrinter::build_extruder_pages() break; } - if (existed_page < n_before_extruders && is_marlin_flavor){ + if (existed_page < n_before_extruders && is_marlin_flavor) { auto page = build_kinematics_page(); m_pages.insert(m_pages.begin() + n_before_extruders, page); } @@ -1980,7 +1986,7 @@ void TabPrinter::build_extruder_pages() } - for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx){ + for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { //# build page char buf[MIN_BUF_LENGTH_FOR_L]; sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); @@ -2174,7 +2180,8 @@ void TabPrinter::update_fff() Thaw(); } -void TabPrinter::update_sla(){ ; } +void TabPrinter::update_sla() +{ ; } // Initialize the UI from the current preset void Tab::load_current_preset() @@ -2207,11 +2214,11 @@ void Tab::load_current_preset() update_tab_ui(); // update show/hide tabs - if (m_name == "printer"){ + if (m_name == "printer") { 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()){ + for (auto& tab : wxGetApp().mainframe->get_preset_tabs()) { if (tab.technology != printer_technology) { int page_id = wxGetApp().tab_panel()->FindPage(tab.panel); @@ -2230,7 +2237,7 @@ void Tab::load_current_preset() if (name() == "print") update_frequently_changed_parameters(); - if (m_name == "printer"){ + if (m_name == "printer") { static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; const Preset* parent_preset = m_presets->get_selected_preset_parent(); static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : @@ -2497,7 +2504,7 @@ void Tab::save_preset(std::string name /*= ""*/) if (dlg->ShowModal() != wxID_OK) return; name = dlg->get_name(); - if (name == ""){ + if (name == "") { show_error(this, _(L("The supplied name is empty. It can't be saved."))); return; } @@ -2741,7 +2748,7 @@ void Page::update_visibility(ConfigOptionMode mode) Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const { Field* field = nullptr; - for (auto opt : m_optgroups){ + for (auto opt : m_optgroups) { field = opt->get_fieldc(opt_key, opt_index); if (field != nullptr) return field; @@ -2749,7 +2756,7 @@ Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1* return field; } -bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value){ +bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value) { bool changed = false; for(auto optgroup: m_optgroups) { if (optgroup->set_value(opt_key, value)) @@ -2785,7 +2792,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la #else auto tab = GetParent(); #endif - optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value){ + optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value) { //! This function will be called from OptionGroup. //! Using of CallAfter is redundant. //! And in some cases it causes update() function to be recalled again @@ -2795,17 +2802,17 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la //! }); }; - optgroup->m_get_initial_config = [this, tab](){ + optgroup->m_get_initial_config = [this, tab]() { DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset().config; return config; }; - optgroup->m_get_sys_config = [this, tab](){ + optgroup->m_get_sys_config = [this, tab]() { DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset_parent()->config; return config; }; - optgroup->have_sys_config = [this, tab](){ + optgroup->have_sys_config = [this, tab]() { return static_cast(tab)->m_presets->get_selected_preset_parent() != nullptr; }; @@ -2846,8 +2853,8 @@ void SavePresetWindow::accept() bool is_unusable_symbol = false; bool is_unusable_postfix = false; const std::string unusable_postfix = PresetCollection::get_suffix_modified();//"(modified)"; - for (size_t i = 0; i < std::strlen(unusable_symbols); i++){ - if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos){ + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) { is_unusable_symbol = true; break; } @@ -2859,7 +2866,7 @@ void SavePresetWindow::accept() show_error(this,_(L("The supplied name is not valid;")) + "\n" + _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); } - else if (is_unusable_postfix){ + else if (is_unusable_postfix) { show_error(this,_(L("The supplied name is not valid;")) + "\n" + _(L("the following postfix are not allowed:")) + "\n\t" + //unusable_postfix); wxString::FromUTF8(unusable_postfix.c_str())); @@ -2892,7 +2899,7 @@ void TabSLAMaterial::build() optgroup->label_width = 190; std::vector corrections = { "material_correction_printing", "material_correction_curing" }; std::vector axes{ "X", "Y", "Z" }; - for (auto& opt_key : corrections){ + for (auto& opt_key : corrections) { auto line = Line{ m_config->def()->get(opt_key)->full_label, "" }; int id = 0; for (auto& axis : axes) { @@ -2916,7 +2923,7 @@ void TabSLAMaterial::build() 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){ + 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); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 196114256..d2d8506bd 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -59,7 +59,7 @@ public: m_item_color = &wxGetApp().get_label_clr_default(); SetSizer(m_vsizer); } - ~Page(){} + ~Page() {} bool m_is_modified_values{ false }; bool m_is_nonsys_values{ true }; @@ -205,7 +205,7 @@ public: set_type(); wxGetApp().tabs_list.push_back(this); } - ~Tab(){ + ~Tab() { wxGetApp().delete_tab_from_list(this); } @@ -244,7 +244,7 @@ public: PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false); virtual void OnActivate(); - virtual void on_preset_loaded(){} + virtual void on_preset_loaded() {} virtual void build() = 0; virtual void update() = 0; virtual void init_options_list(); @@ -282,7 +282,7 @@ public: TabPrint() {} TabPrint(wxNotebook* parent) : Tab(parent, _(L("Print Settings")), "print") {} - ~TabPrint(){} + ~TabPrint() {} ogStaticText* m_recommended_thin_wall_thickness_description_line; bool m_support_material_overhangs_queried = false; @@ -302,7 +302,7 @@ public: TabFilament() {} TabFilament(wxNotebook* parent) : Tab(parent, _(L("Filament Settings")), "filament") {} - ~TabFilament(){} + ~TabFilament() {} void build() override; void reload_config() override; @@ -334,7 +334,7 @@ public: TabPrinter() {} TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), "printer") {} - ~TabPrinter(){} + ~TabPrinter() {} void build() override; void build_fff(); @@ -357,7 +357,7 @@ public: TabSLAMaterial() {} TabSLAMaterial(wxNotebook* parent) : Tab(parent, _(L("SLA Material Settings")), "sla_material") {} - ~TabSLAMaterial(){} + ~TabSLAMaterial() {} void build() override; void update() override; @@ -367,8 +367,8 @@ public: class SavePresetWindow :public wxDialog { public: - SavePresetWindow(wxWindow* parent) :wxDialog(parent, wxID_ANY, _(L("Save preset"))){} - ~SavePresetWindow(){} + SavePresetWindow(wxWindow* parent) :wxDialog(parent, wxID_ANY, _(L("Save preset"))) {} + ~SavePresetWindow() {} std::string m_chosen_name; wxComboBox* m_combo; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index f9eb032c4..1ae0448f4 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -534,7 +534,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddInstanceChild(const wxDataViewItem & // Add instance nodes PrusaObjectDataViewModelNode *instance_node = nullptr; size_t counter = 0; - while (counter < num){ + while (counter < num) { instance_node = new PrusaObjectDataViewModelNode(inst_root_node, itInstance); inst_root_node->Append(instance_node); // notify control @@ -559,11 +559,11 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) // first remove the node from the parent's array of children; // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ // thus removing the node from it doesn't result in freeing it - if (node_parent){ + if (node_parent) { auto id = node_parent->GetChildren().Index(node); auto idx = node->GetIdx(); node_parent->GetChildren().Remove(node); - if (id > 0){ + if (id > 0) { if(id == node_parent->GetChildCount()) id--; ret_item = wxDataViewItem(node_parent->GetChildren().Item(id)); } @@ -607,7 +607,7 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) auto id = it - m_objects.begin(); if (it != m_objects.end()) m_objects.erase(it); - if (id > 0){ + if (id > 0) { if(id == m_objects.size()) id--; ret_item = wxDataViewItem(m_objects[id]); } @@ -862,7 +862,7 @@ wxDataViewItem PrusaObjectDataViewModel::MoveChildUp(const wxDataViewItem &item) return ret_item; auto volume_id = node->GetVolumeId(); - if (0 < volume_id && volume_id < node_parent->GetChildCount()){ + if (0 < volume_id && volume_id < node_parent->GetChildCount()) { node_parent->SwapChildrens(volume_id - 1, volume_id); ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id - 1)); ItemChanged(item); @@ -886,7 +886,7 @@ wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &ite return ret_item; auto volume_id = node->GetVolumeId(); - if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()){ + if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()) { node_parent->SwapChildrens(volume_id + 1, volume_id); ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id + 1)); ItemChanged(item); @@ -1586,7 +1586,7 @@ void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) } m_is_left_down = true; - if (is_point_in_rect(pos, m_rect_one_layer_icon)){ + if (is_point_in_rect(pos, m_rect_one_layer_icon)) { m_is_one_layer = !m_is_one_layer; m_selection == ssLower ? correct_lower_value() : correct_higher_value(); if (!m_selection) m_selection = ssHigher; @@ -1626,10 +1626,10 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) const wxClientDC dc(this); const wxPoint pos = event.GetLogicalPosition(dc); m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon); - if (!m_is_left_down && !m_is_one_layer){ + if (!m_is_left_down && !m_is_one_layer) { m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); } - else if (m_is_left_down || m_is_right_down){ + else if (m_is_left_down || m_is_right_down) { if (m_selection == ssLower) { m_lower_value = get_value_from_position(pos.x, pos.y); correct_lower_value(); @@ -1741,7 +1741,7 @@ void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) { if (key == WXK_LEFT || key == WXK_RIGHT) move_current_thumb(key == WXK_LEFT); - else if (key == WXK_UP || key == WXK_DOWN){ + else if (key == WXK_UP || key == WXK_DOWN) { m_selection = key == WXK_UP ? ssHigher : ssLower; Refresh(); } diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 80a564fd0..60bc083fe 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -638,7 +638,7 @@ public: long style = wxSL_VERTICAL, const wxValidator& val = wxDefaultValidator, const wxString& name = wxEmptyString); - ~PrusaDoubleSlider(){} + ~PrusaDoubleSlider() {} int GetLowerValue() const { return m_lower_value; @@ -661,12 +661,12 @@ public: } void ChangeOneLayerLock(); - void OnPaint(wxPaintEvent& ){ render();} + void OnPaint(wxPaintEvent& ) { render();} void OnLeftDown(wxMouseEvent& event); void OnMotion(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event); - void OnEnterWin(wxMouseEvent& event){ enter_window(event, true); } - void OnLeaveWin(wxMouseEvent& event){ enter_window(event, false); } + void OnEnterWin(wxMouseEvent& event) { enter_window(event, true); } + void OnLeaveWin(wxMouseEvent& event) { enter_window(event, false); } void OnWheel(wxMouseEvent& event); void OnKeyDown(wxKeyEvent &event); void OnKeyUp(wxKeyEvent &event); @@ -770,11 +770,11 @@ public: wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); - ~PrusaLockButton(){} + ~PrusaLockButton() {} void OnButton(wxCommandEvent& event); - void OnEnterBtn(wxMouseEvent& event){ enter_button(true); event.Skip(); } - void OnLeaveBtn(wxMouseEvent& event){ enter_button(false); event.Skip(); } + void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); } + void OnLeaveBtn(wxMouseEvent& event) { enter_button(false); event.Skip(); } bool IsLocked() const { return m_is_pushed; } From d6d632d4fcc8538bf4e2949af7215fd1ed75d869 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Oct 2018 14:56:51 +0100 Subject: [PATCH 08/10] Added Geometry::Transformation class. Use it into ModelInstance, ModelVolume and GLVolume --- src/libslic3r/Geometry.cpp | 164 +++++++++++++++++++++++++++++++-- src/libslic3r/Geometry.hpp | 89 +++++++++++++++++- src/libslic3r/Model.cpp | 23 +++++ src/libslic3r/Model.hpp | 84 +++++++++++++++++ src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/3DScene.cpp | 47 ++++++++++ src/slic3r/GUI/3DScene.hpp | 44 ++++++++- src/slic3r/GUI/GLGizmo.cpp | 4 + 8 files changed, 449 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index a100f520a..0cfd3f115 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1,3 +1,4 @@ +#include "libslic3r.h" #include "Geometry.hpp" #include "ClipperUtils.hpp" #include "ExPolygon.hpp" @@ -369,12 +370,6 @@ contains(const std::vector &vector, const Point &point) } template bool contains(const ExPolygons &vector, const Point &point); -double -rad2deg(double angle) -{ - return angle / PI * 180.0; -} - double rad2deg_dir(double angle) { @@ -1232,4 +1227,161 @@ Vec3d extract_euler_angles(const Transform3d& transform) return extract_euler_angles(m); } +#if ENABLE_MODELVOLUME_TRANSFORM +Transformation::Flags::Flags() + : dont_translate(true) + , dont_rotate(true) + , dont_scale(true) +#if ENABLE_MIRROR + , dont_mirror(true) +#endif // ENABLE_MIRROR +{ +} + +#if ENABLE_MIRROR +bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const +{ + return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror); +} + +void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) +{ + this->dont_translate = dont_translate; + this->dont_rotate = dont_rotate; + this->dont_scale = dont_scale; + this->dont_mirror = dont_mirror; +} +#else +bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale) const +{ + return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale); +} + +void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale) +{ + this->dont_translate = dont_translate; + this->dont_rotate = dont_rotate; + this->dont_scale = dont_scale; +} +#endif // ENABLE_MIRROR + +Transformation::Transformation() + : m_offset(Vec3d::Zero()) + , m_rotation(Vec3d::Zero()) + , m_scaling_factor(Vec3d::Ones()) +#if ENABLE_MIRROR + , m_mirror(Vec3d::Ones()) +#endif // ENABLE_MIRROR + , m_matrix(Transform3d::Identity()) + , m_dirty(false) +{ +} + +void Transformation::set_offset(const Vec3d& offset) +{ + set_offset(X, offset(0)); + set_offset(Y, offset(1)); + set_offset(Z, offset(2)); +} + +void Transformation::set_offset(Axis axis, double offset) +{ + if (m_offset(axis) != offset) + { + m_offset(axis) = offset; + m_dirty = true; + } +} + +void Transformation::set_rotation(const Vec3d& rotation) +{ + set_rotation(X, rotation(0)); + set_rotation(Y, rotation(1)); + set_rotation(Z, rotation(2)); +} + +void Transformation::set_rotation(Axis axis, double rotation) +{ + rotation = angle_to_0_2PI(rotation); + + if (m_rotation(axis) = rotation) + { + m_rotation(axis) = rotation; + m_dirty = true; + } +} + +void Transformation::set_scaling_factor(const Vec3d& scaling_factor) +{ + set_scaling_factor(X, scaling_factor(0)); + set_scaling_factor(Y, scaling_factor(1)); + set_scaling_factor(Z, scaling_factor(2)); +} + +void Transformation::set_scaling_factor(Axis axis, double scaling_factor) +{ + if (m_scaling_factor(axis) != std::abs(scaling_factor)) + { + m_scaling_factor(axis) = std::abs(scaling_factor); + m_dirty = true; + } +} + +void Transformation::set_mirror(const Vec3d& mirror) +{ + set_mirror(X, mirror(0)); + set_mirror(Y, mirror(1)); + set_mirror(Z, mirror(2)); +} + +void Transformation::set_mirror(Axis axis, double mirror) +{ + double abs_mirror = std::abs(mirror); + if (abs_mirror == 0.0) + mirror = 1.0; + else if (abs_mirror != 1.0) + mirror /= abs_mirror; + + if (m_mirror(axis) != mirror) + { + m_mirror(axis) = mirror; + m_dirty = true; + } +} + +#if ENABLE_MIRROR +const Transform3d& Transformation::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const +#else +const Transform3d& Transformation::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale) const +#endif // ENABLE_MIRROR +{ +#if ENABLE_MIRROR + if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror)) +#else + if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale)) +#endif // ENABLE_MIRROR + { + Vec3d translation = dont_translate ? Vec3d::Zero() : m_offset; + Vec3d rotation = dont_rotate ? Vec3d::Zero() : m_rotation; + Vec3d scale = dont_scale ? Vec3d::Ones() : m_scaling_factor; +#if ENABLE_MIRROR + Vec3d mirror = dont_mirror ? Vec3d::Ones() : m_mirror; + m_matrix = Geometry::assemble_transform(translation, rotation, scale, mirror); +#else + m_matrix = Geometry::assemble_transform(translation, rotation, scale); +#endif // ENABLE_MIRROR + +#if ENABLE_MIRROR + m_flags.set(dont_translate, dont_rotate, dont_scale, dont_mirror); +#else + m_flags.set(dont_translate, dont_rotate, dont_scale); +#endif // ENABLE_MIRROR + m_dirty = false; + } + + return m_matrix; +} + +#endif // ENABLE_MODELVOLUME_TRANSFORM + } } diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 9046add25..47fdec55a 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -117,9 +117,23 @@ void chained_path(const Points &points, std::vector &retval); template void chained_path_items(Points &points, T &items, T &retval); bool directions_parallel(double angle1, double angle2, double max_diff = 0); template bool contains(const std::vector &vector, const Point &point); -double rad2deg(double angle); +template T rad2deg(T angle) { return T(180.0) * angle / T(PI); } double rad2deg_dir(double angle); template T deg2rad(T angle) { return T(PI) * angle / T(180.0); } +template T angle_to_0_2PI(T angle) +{ + static const T TWO_PI = T(2) * T(PI); + while (angle < T(0)) + { + angle += TWO_PI; + } + while (TWO_PI < angle) + { + angle -= TWO_PI; + } + + return angle; +} void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval); double linint(double value, double oldmin, double oldmax, double newmin, double newmax); @@ -200,6 +214,79 @@ Vec3d extract_euler_angles(const Eigen::Matrix& // Returns the euler angles extracted from the given affine transform // Warning -> The transform should not contain any shear !!! Vec3d extract_euler_angles(const Transform3d& transform); + +#if ENABLE_MODELVOLUME_TRANSFORM +class Transformation +{ + struct Flags + { + bool dont_translate; + bool dont_rotate; + bool dont_scale; +#if ENABLE_MIRROR + bool dont_mirror; +#endif // ENABLE_MIRROR + + Flags(); + +#if ENABLE_MIRROR + bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const; + void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror); +#else + bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale) const; + void set(bool dont_translate, bool dont_rotate, bool dont_scale); +#endif // ENABLE_MIRROR + }; + + Vec3d m_offset; // In unscaled coordinates + Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point + Vec3d m_scaling_factor; // Scaling factors along the three axes +#if ENABLE_MIRROR + Vec3d m_mirror; // Mirroring along the three axes +#endif // ENABLE_MIRROR + mutable Transform3d m_matrix; + + mutable Flags m_flags; + mutable bool m_dirty; + +public: + Transformation(); + + const Vec3d& get_offset() const { return m_offset; } + double get_offset(Axis axis) const { return m_offset(axis); } + + void set_offset(const Vec3d& offset); + void set_offset(Axis axis, double offset); + + const Vec3d& get_rotation() const { return m_rotation; } + double get_rotation(Axis axis) const { return m_rotation(axis); } + + void set_rotation(const Vec3d& rotation); + void set_rotation(Axis axis, double rotation); + + Vec3d get_scaling_factor() const { return m_scaling_factor; } + double get_scaling_factor(Axis axis) const { return m_scaling_factor(axis); } + +#if ENABLE_MIRROR + void set_scaling_factor(const Vec3d& scaling_factor); + void set_scaling_factor(Axis axis, double scaling_factor); + + const Vec3d& get_mirror() const { return m_mirror; } + double get_mirror(Axis axis) const { return m_mirror(axis); } + + void set_mirror(const Vec3d& mirror); + void set_mirror(Axis axis, double mirror); + + const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; +#else + void set_scaling_factor(const Vec3d& scaling_factor) { m_scaling_factor = scaling_factor; } + void set_scaling_factor(Axis axis, double scaling_factor) { m_scaling_factor(axis) = scaling_factor; } + + const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const; +#endif // ENABLE_MIRROR +}; +#endif // ENABLE_MODELVOLUME_TRANSFORM + } } #endif diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 15eedaa2d..b68d2a108 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1124,6 +1124,7 @@ size_t ModelVolume::split(unsigned int max_extruders) return idx; } +#if !ENABLE_MODELVOLUME_TRANSFORM void ModelInstance::set_rotation(const Vec3d& rotation) { set_rotation(X, rotation(0)); @@ -1176,6 +1177,7 @@ void ModelInstance::set_mirror(Axis axis, double mirror) m_mirror(axis) = mirror; } #endif // ENABLE_MIRROR +#endif // !ENABLE_MODELVOLUME_TRANSFORM void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const { @@ -1197,17 +1199,29 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes // Scale the bounding box along the three axes. for (unsigned int i = 0; i < 3; ++i) { +#if ENABLE_MODELVOLUME_TRANSFORM + if (std::abs(m_transformation.get_scaling_factor((Axis)i)-1.0) > EPSILON) + { + bbox.min(i) *= m_transformation.get_scaling_factor((Axis)i); + bbox.max(i) *= m_transformation.get_scaling_factor((Axis)i); +#else if (std::abs(this->m_scaling_factor(i) - 1.0) > EPSILON) { bbox.min(i) *= this->m_scaling_factor(i); bbox.max(i) *= this->m_scaling_factor(i); +#endif // ENABLE_MODELVOLUME_TRANSFORM } } // Translate the bounding box. if (! dont_translate) { +#if ENABLE_MODELVOLUME_TRANSFORM + bbox.min += m_transformation.get_offset(); + bbox.max += m_transformation.get_offset(); +#else bbox.min += this->m_offset; bbox.max += this->m_offset; +#endif // ENABLE_MODELVOLUME_TRANSFORM } } return bbox; @@ -1225,12 +1239,20 @@ Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const void ModelInstance::transform_polygon(Polygon* polygon) const { +#if ENABLE_MODELVOLUME_TRANSFORM + // CHECK_ME -> Is the following correct or it should take in account all three rotations ? + polygon->rotate(m_transformation.get_rotation(Z)); // rotate around polygon origin + // CHECK_ME -> Is the following correct ? + polygon->scale(m_transformation.get_scaling_factor(X), m_transformation.get_scaling_factor(Y)); // scale around polygon origin +#else // CHECK_ME -> Is the following correct or it should take in account all three rotations ? polygon->rotate(this->m_rotation(2)); // rotate around polygon origin // CHECK_ME -> Is the following correct ? polygon->scale(this->m_scaling_factor(0), this->m_scaling_factor(1)); // scale around polygon origin +#endif // ENABLE_MODELVOLUME_TRANSFORM } +#if !ENABLE_MODELVOLUME_TRANSFORM #if ENABLE_MIRROR Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const #else @@ -1247,5 +1269,6 @@ Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, b return Geometry::assemble_transform(translation, rotation, scale); #endif // ENABLE_MIRROR } +#endif // !ENABLE_MODELVOLUME_TRANSFORM } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 89b068c40..9739956a8 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -11,6 +11,9 @@ #include #include #include +#if ENABLE_MODELVOLUME_TRANSFORM +#include "Geometry.hpp" +#endif // ENABLE_MODELVOLUME_TRANSFORM namespace Slic3r { @@ -210,6 +213,10 @@ class ModelVolume : public ModelBase // The convex hull of this model's mesh. TriangleMesh m_convex_hull; +#if ENABLE_MODELVOLUME_TRANSFORM + Geometry::Transformation m_transformation; +#endif // ENABLE_MODELVOLUME_TRANSFORM + public: std::string name; // The triangular model. @@ -257,6 +264,34 @@ public: static Type type_from_string(const std::string &s); static std::string type_to_string(const Type t); +#if ENABLE_MODELVOLUME_TRANSFORM + const Vec3d& get_offset() const { return m_transformation.get_offset(); } + double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } + + void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } + void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } + + const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } + double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } + + void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } + void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); } + + Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } + double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } + + void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } + void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } + +#if ENABLE_MIRROR + const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } + double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } + + void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } + void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } +#endif // ENABLE_MIRROR +#endif // ENABLE_MODELVOLUME_TRANSFORM + private: // Parent object owning this ModelVolume. ModelObject* object; @@ -306,12 +341,16 @@ public: friend class ModelObject; private: +#if ENABLE_MODELVOLUME_TRANSFORM + Geometry::Transformation m_transformation; +#else Vec3d m_offset; // in unscaled coordinates Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point Vec3d m_scaling_factor; // Scaling factors along the three axes #if ENABLE_MIRROR Vec3d m_mirror; // Mirroring along the three axes #endif // ENABLE_MIRROR +#endif // ENABLE_MODELVOLUME_TRANSFORM public: // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state()) @@ -319,6 +358,36 @@ public: ModelObject* get_object() const { return this->object; } +#if ENABLE_MODELVOLUME_TRANSFORM + const Geometry::Transformation& get_transformation() const { return m_transformation; } + void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; } + + const Vec3d& get_offset() const { return m_transformation.get_offset(); } + double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } + + void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } + void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } + + const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } + double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } + + void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } + void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); } + + Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } + double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } + + void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } + void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } + +#if ENABLE_MIRROR + const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } + double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } + + void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } + void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } +#endif // ENABLE_MIRROR +#else const Vec3d& get_offset() const { return m_offset; } double get_offset(Axis axis) const { return m_offset(axis); } @@ -349,6 +418,7 @@ public: void set_mirror(const Vec3d& mirror); void set_mirror(Axis axis, double mirror); #endif // ENABLE_MIRROR +#endif // ENABLE_MODELVOLUME_TRANSFORM // To be called on an external mesh void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const; @@ -361,11 +431,19 @@ public: // To be called on an external polygon. It does not translate the polygon, only rotates and scales. void transform_polygon(Polygon* polygon) const; +#if ENABLE_MODELVOLUME_TRANSFORM +#if ENABLE_MIRROR + const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.world_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } +#else + const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const { return m_transformation.world_matrix(dont_translate, dont_rotate, dont_scale); } +#endif // ENABLE_MIRROR +#else #if ENABLE_MIRROR Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; #else Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const; #endif // ENABLE_MIRROR +#endif // ENABLE_MODELVOLUME_TRANSFORM bool is_printable() const { return print_volume_state == PVS_Inside; } @@ -373,6 +451,11 @@ private: // Parent object, owning this instance. ModelObject* object; +#if ENABLE_MODELVOLUME_TRANSFORM + ModelInstance(ModelObject *object) : object(object), print_volume_state(PVS_Inside) {} + ModelInstance(ModelObject *object, const ModelInstance &other) : + m_transformation(other.m_transformation), object(object), print_volume_state(PVS_Inside) {} +#else #if ENABLE_MIRROR ModelInstance(ModelObject *object) : m_offset(Vec3d::Zero()), m_rotation(Vec3d::Zero()), m_scaling_factor(Vec3d::Ones()), m_mirror(Vec3d::Ones()), object(object), print_volume_state(PVS_Inside) {} ModelInstance(ModelObject *object, const ModelInstance &other) : @@ -382,6 +465,7 @@ private: ModelInstance(ModelObject *object, const ModelInstance &other) : m_rotation(other.m_rotation), m_scaling_factor(other.m_scaling_factor), m_offset(other.m_offset), object(object), print_volume_state(PVS_Inside) {} #endif // ENABLE_MIRROR +#endif // ENABLE_MODELVOLUME_TRANSFORM explicit ModelInstance(ModelInstance &rhs) = delete; ModelInstance& operator=(ModelInstance &rhs) = delete; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a01c95f72..fe3b19eb0 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -24,6 +24,8 @@ #define ENABLE_MIRROR (1 && ENABLE_1_42_0) // Modified camera target behavior #define ENABLE_MODIFIED_CAMERA_TARGET (1 && ENABLE_1_42_0) +// Add Geometry::Transformation class and use it into ModelInstance, ModelVolume and GLVolume +#define ENABLE_MODELVOLUME_TRANSFORM (1 && ENABLE_1_42_0) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 91f60947c..a85a27e1d 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -195,6 +195,9 @@ const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f }; const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f }; GLVolume::GLVolume(float r, float g, float b, float a) +#if ENABLE_MODELVOLUME_TRANSFORM + : m_transformed_bounding_box_dirty(true) +#else : m_offset(Vec3d::Zero()) , m_rotation(Vec3d::Zero()) , m_scaling_factor(Vec3d::Ones()) @@ -204,6 +207,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) , m_world_matrix(Transform3f::Identity()) , m_world_matrix_dirty(true) , m_transformed_bounding_box_dirty(true) +#endif // ENABLE_MODELVOLUME_TRANSFORM , m_transformed_convex_hull_bounding_box_dirty(true) , m_convex_hull(nullptr) , composite_id(-1) @@ -260,6 +264,7 @@ void GLVolume::set_render_color() set_render_color(color, 4); } +#if !ENABLE_MODELVOLUME_TRANSFORM const Vec3d& GLVolume::get_rotation() const { return m_rotation; @@ -360,6 +365,7 @@ void GLVolume::set_mirror(Axis axis, double mirror) } } #endif // ENABLE_MIRROR +#endif // !ENABLE_MODELVOLUME_TRANSFORM void GLVolume::set_convex_hull(const TriangleMesh& convex_hull) { @@ -386,6 +392,7 @@ void GLVolume::set_drag_group_id(const std::string& drag_by) } #endif // !ENABLE_EXTENDED_SELECTION +#if !ENABLE_MODELVOLUME_TRANSFORM const Transform3f& GLVolume::world_matrix() const { if (m_world_matrix_dirty) @@ -399,12 +406,17 @@ const Transform3f& GLVolume::world_matrix() const } return m_world_matrix; } +#endif // !ENABLE_MODELVOLUME_TRANSFORM const BoundingBoxf3& GLVolume::transformed_bounding_box() const { if (m_transformed_bounding_box_dirty) { +#if ENABLE_MODELVOLUME_TRANSFORM + m_transformed_bounding_box = bounding_box.transformed(world_matrix()); +#else m_transformed_bounding_box = bounding_box.transformed(world_matrix().cast()); +#endif // ENABLE_MODELVOLUME_TRANSFORM m_transformed_bounding_box_dirty = false; } @@ -415,10 +427,17 @@ const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const { if (m_transformed_convex_hull_bounding_box_dirty) { +#if ENABLE_MODELVOLUME_TRANSFORM + if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0)) + m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix()); + else + m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix()); +#else if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0)) m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix().cast()); else m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix().cast()); +#endif // ENABLE_MODELVOLUME_TRANSFORM m_transformed_convex_hull_bounding_box_dirty = false; } @@ -469,7 +488,11 @@ void GLVolume::render() const ::glCullFace(GL_BACK); ::glPushMatrix(); +#if ENABLE_MODELVOLUME_TRANSFORM + ::glMultMatrixd(world_matrix().data()); +#else ::glMultMatrixf(world_matrix().data()); +#endif // ENABLE_MODELVOLUME_TRANSFORM if (this->indexed_vertex_array.indexed()) this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); else @@ -507,7 +530,11 @@ void GLVolume::render_using_layer_height() const glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width); if (world_matrix_id >= 0) +#if ENABLE_MODELVOLUME_TRANSFORM + ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data()); +#else ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); +#endif // ENABLE_MODELVOLUME_TRANSFORM GLsizei w = (GLsizei)layer_height_texture_width(); GLsizei h = (GLsizei)layer_height_texture_height(); @@ -567,7 +594,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); if (worldmatrix_id != -1) +#if ENABLE_MODELVOLUME_TRANSFORM + ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data()); +#else ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); +#endif // ENABLE_MODELVOLUME_TRANSFORM render(); @@ -586,7 +617,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); if (worldmatrix_id != -1) +#if ENABLE_MODELVOLUME_TRANSFORM + ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data()); +#else ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); +#endif // ENABLE_MODELVOLUME_TRANSFORM ::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id); ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); @@ -594,7 +629,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c ::glPushMatrix(); +#if ENABLE_MODELVOLUME_TRANSFORM + ::glMultMatrixd(world_matrix().data()); +#else ::glMultMatrixf(world_matrix().data()); +#endif // ENABLE_MODELVOLUME_TRANSFORM if (n_triangles > 0) { @@ -638,7 +677,11 @@ void GLVolume::render_legacy() const ::glPushMatrix(); +#if ENABLE_MODELVOLUME_TRANSFORM + ::glMultMatrixd(world_matrix().data()); +#else ::glMultMatrixf(world_matrix().data()); +#endif // ENABLE_MODELVOLUME_TRANSFORM if (n_triangles > 0) ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first); @@ -767,12 +810,16 @@ std::vector GLVolumeCollection::load_object( } v.is_modifier = ! model_volume->is_model_part(); v.shader_outside_printer_detection_enabled = model_volume->is_model_part(); +#if ENABLE_MODELVOLUME_TRANSFORM + v.set_transformation(instance->get_transformation()); +#else v.set_offset(instance->get_offset()); v.set_rotation(instance->get_rotation()); v.set_scaling_factor(instance->get_scaling_factor()); #if ENABLE_MIRROR v.set_mirror(instance->get_mirror()); #endif // ENABLE_MIRROR +#endif // ENABLE_MODELVOLUME_TRANSFORM } } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 7e74ff92f..8c2427915 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -254,6 +254,9 @@ public: GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {} private: +#if ENABLE_MODELVOLUME_TRANSFORM + Geometry::Transformation m_transformation; +#else // Offset of the volume to be rendered. Vec3d m_offset; // Rotation around three axes of the volume to be rendered. @@ -268,6 +271,7 @@ private: mutable Transform3f m_world_matrix; // Whether or not is needed to recalculate the world matrix. mutable bool m_world_matrix_dirty; +#endif // ENABLE_MODELVOLUME_TRANSFORM // Bounding box of this volume, in unscaled coordinates. mutable BoundingBoxf3 m_transformed_bounding_box; // Whether or not is needed to recalculate the transformed bounding box. @@ -280,7 +284,6 @@ private: mutable bool m_transformed_convex_hull_bounding_box_dirty; public: - // Bounding box of this volume, in unscaled coordinates. BoundingBoxf3 bounding_box; // Color of the triangles / quads held by this volume. @@ -333,6 +336,36 @@ public: // Sets render color in dependence of current state void set_render_color(); +#if ENABLE_MODELVOLUME_TRANSFORM + const Geometry::Transformation& get_transformation() const { return m_transformation; } + void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; set_bounding_boxes_as_dirty(); } + + const Vec3d& get_offset() const { return m_transformation.get_offset(); } + double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } + + void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); } + void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); } + + const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } + double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } + + void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); } + void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); } + + Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } + double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } + + void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); } + void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); } + +#if ENABLE_MIRROR + const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } + double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } + + void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); } + void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); set_bounding_boxes_as_dirty(); } +#endif // ENABLE_MIRROR +#else const Vec3d& get_rotation() const; void set_rotation(const Vec3d& rotation); @@ -350,6 +383,7 @@ public: const Vec3d& get_offset() const; void set_offset(const Vec3d& offset); +#endif // ENABLE_MODELVOLUME_TRANSFORM void set_convex_hull(const TriangleMesh& convex_hull); @@ -362,7 +396,11 @@ public: int volume_idx() const { return (this->composite_id / 1000) % 1000; } int instance_idx() const { return this->composite_id % 1000; } +#if ENABLE_MODELVOLUME_TRANSFORM + const Transform3d& world_matrix() const { return m_transformation.world_matrix(); } +#else const Transform3f& world_matrix() const; +#endif // ENABLE_MODELVOLUME_TRANSFORM const BoundingBoxf3& transformed_bounding_box() const; const BoundingBoxf3& transformed_convex_hull_bounding_box() const; @@ -412,6 +450,10 @@ public: } void reset_layer_height_texture_data() { layer_height_texture_data.reset(); } + +#if ENABLE_MODELVOLUME_TRANSFORM + void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; } +#endif // ENABLE_MODELVOLUME_TRANSFORM }; #if ENABLE_EXTENDED_SELECTION diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 6965d95b7..62fba6c5a 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -926,7 +926,11 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const // gets transform from first selected volume const GLVolume* v = selection.get_volume(*idxs.begin()); +#if ENABLE_MODELVOLUME_TRANSFORM + transform = v->world_matrix(); +#else transform = v->world_matrix().cast(); +#endif // ENABLE_MODELVOLUME_TRANSFORM // gets angles from first selected volume angles = v->get_rotation(); From 5a4cef9ac1a7fe0453223ebf0eb3fa0552975107 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 31 Oct 2018 15:41:27 +0100 Subject: [PATCH 09/10] Fixed part settings updating --- src/slic3r/GUI/GUI_ObjectList.cpp | 22 ++++++++++++++++------ src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/GUI_ObjectManipulation.cpp | 3 +++ src/slic3r/GUI/Plater.cpp | 4 ++-- src/slic3r/GUI/Plater.hpp | 2 +- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index bcd615278..243da5136 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -150,7 +150,8 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt) GetMainWindow()->SetToolTip(""); // hide tooltip } -wxPoint ObjectList::get_mouse_position_in_control() { +wxPoint ObjectList::get_mouse_position_in_control() +{ const wxPoint& pt = wxGetMousePosition(); // wxWindow* win = GetMainWindow(); // wxPoint screen_pos = win->GetScreenPosition(); @@ -159,10 +160,9 @@ wxPoint ObjectList::get_mouse_position_in_control() { int ObjectList::get_selected_obj_idx() const { - if (GetSelectedItemsCount() == 1) { - auto item = GetSelection(); - return m_objects_model->GetIdByItem(item); - } + if (GetSelectedItemsCount() == 1) + return m_objects_model->GetIdByItem(m_objects_model->GetTopParent(GetSelection())); + return -1; } @@ -687,6 +687,7 @@ void ObjectList::load_part( ModelObject* model_object, { wxWindow* parent = wxGetApp().tab_panel()->GetPage(0); + m_parts_changed = false; wxArrayString input_files; wxGetApp().open_model(parent, input_files); for (int i = 0; i < input_files.size(); ++i) { @@ -739,6 +740,7 @@ void ObjectList::load_lambda( ModelObject* model_object, { auto dlg = new LambdaObjectDialog(GetMainWindow()); if (dlg->ShowModal() == wxID_CANCEL) { + m_parts_changed = false; return; } @@ -1002,9 +1004,17 @@ bool ObjectList::is_splittable_object(const bool split_part) return splittable; } +void ObjectList::part_settings_changed() +{ + m_part_settings_changed = true; + wxGetApp().plater()->changed_object(get_selected_obj_idx()); + m_part_settings_changed = false; +} + void ObjectList::parts_changed(int obj_idx) { - wxGetApp().mainframe->m_plater->changed_object_settings(obj_idx); + wxGetApp().plater()->changed_object(get_selected_obj_idx()); + m_parts_changed = false; } void ObjectList::part_selection_changed() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index db07073d9..0c680c6ac 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -99,6 +99,7 @@ public: int get_selected_obj_idx() const; bool is_parts_changed() const { return m_parts_changed; } bool is_part_settings_changed() const { return m_part_settings_changed; } + void part_settings_changed(); void parts_changed(int obj_idx); void part_selection_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 8b3d796bd..78031cf30 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -225,6 +225,9 @@ void ObjectManipulation::update_settings_list() optgroup->label_width = 150; optgroup->sidetext_width = 70; + optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { + wxGetApp().obj_list()->part_settings_changed(); }; + for (auto& opt : cat.second) { if (opt == "extruder") diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 04f47228b..0f6d59947 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2608,7 +2608,7 @@ wxGLCanvas* Plater::canvas3D() return p->canvas3D; } -void Plater::changed_object_settings(int obj_idx) +void Plater::changed_object(int obj_idx) { if (obj_idx < 0) return; @@ -2622,6 +2622,7 @@ void Plater::changed_object_settings(int obj_idx) auto model_object = p->model.objects[obj_idx]; model_object->center_around_origin(); model_object->ensure_on_bed(); + _3DScene::reload_scene(p->canvas3D, false); } // update print @@ -2632,7 +2633,6 @@ void Plater::changed_object_settings(int obj_idx) auto selections = p->collect_selections(); _3DScene::set_objects_selections(p->canvas3D, selections); #endif // !ENABLE_EXTENDED_SELECTION - _3DScene::reload_scene(p->canvas3D, false); #if !ENABLE_MODIFIED_CAMERA_TARGET _3DScene::zoom_to_volumes(p->canvas3D); #endif // !ENABLE_MODIFIED_CAMERA_TARGET diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 0a69e68bd..aa243d5fb 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -123,7 +123,7 @@ public: void export_amf(); void export_3mf(); void reslice(); - void changed_object_settings(int obj_idx); + void changed_object(int obj_idx); void send_gcode(); void on_extruders_change(int extruders_count); From afa907504f8f1e044630caf9b008d259601ac9a1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Oct 2018 16:13:07 +0100 Subject: [PATCH 10/10] Fixed autolevel on bed with non uniform scaling --- src/libslic3r/Model.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index b68d2a108..360a215cd 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -929,16 +929,16 @@ double ModelObject::get_instance_min_z(size_t instance_idx) const double min_z = DBL_MAX; ModelInstance* inst = instances[instance_idx]; - Vec3d local_unit_z = (inst->world_matrix(true).inverse() * Vec3d::UnitZ()).normalized(); + const Transform3d& m = inst->world_matrix(true); for (ModelVolume *v : volumes) { for (uint32_t f = 0; f < v->mesh.stl.stats.number_of_facets; ++f) { const stl_facet* facet = v->mesh.stl.facet_start + f; - min_z = std::min(min_z, local_unit_z.dot(facet->vertex[0].cast())); - min_z = std::min(min_z, local_unit_z.dot(facet->vertex[1].cast())); - min_z = std::min(min_z, local_unit_z.dot(facet->vertex[2].cast())); + min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[0].cast())); + min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[1].cast())); + min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[2].cast())); } }