diff --git a/resources/models/mk2_bed.stl b/resources/models/mk2_bed.stl new file mode 100644 index 000000000..07b7655ea Binary files /dev/null and b/resources/models/mk2_bed.stl differ diff --git a/resources/models/mk3_bed.stl b/resources/models/mk3_bed.stl new file mode 100644 index 000000000..cfa6d8c6d Binary files /dev/null and b/resources/models/mk3_bed.stl differ diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 2f61cc008..c295d6def 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -404,7 +404,7 @@ void ConfigBase::load_from_gcode_file(const std::string &file) size_t key_value_pairs = load_from_gcode_string(data.data()); if (key_value_pairs < 80) - throw std::runtime_error((boost::format("Suspiciously low number of configuration values extracted from %1: %2") % file % key_value_pairs).str()); + throw std::runtime_error((boost::format("Suspiciously low number of configuration values extracted from %1%: %2%") % file % key_value_pairs).str()); } // Load the config keys from the given string. @@ -536,7 +536,7 @@ void DynamicConfig::read_cli(const std::vector &tokens, t_config_op args.emplace_back(const_cast("")); for (size_t i = 0; i < tokens.size(); ++ i) args.emplace_back(const_cast(tokens[i].c_str())); - this->read_cli(args.size(), &args[0], extra); + this->read_cli(int(args.size()), &args[0], extra); } bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4704c65f3..739c918c1 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -791,7 +791,7 @@ void GCode::_do_export(Print &print, FILE *file) } } else { for (const std::string &start_gcode : print.config().start_filament_gcode.values) - _writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config().start_filament_gcode.values.front()))); + _writeln(file, this->placeholder_parser_process("start_filament_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config().start_filament_gcode.values.front()))); } this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true); print.throw_if_canceled(); diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 55ce3fa2c..ffaee3135 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -927,9 +927,9 @@ Vec3d extract_euler_angles(const Eigen::Matrix& } else { - angles(0) = ::atan2(-rotation_matrix(1, 2), rotation_matrix(1, 1)); + angles(1) = 0.0; angles(1) = ::atan2(-rotation_matrix(2, 0), sy); - angles(2) = 0.0; + angles(2) = (angles(1) >-0.0) ? ::atan2(rotation_matrix(1, 2), rotation_matrix(1, 1)) : ::atan2(-rotation_matrix(1, 2), rotation_matrix(1, 1)); } return angles; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 20c4a44b2..900397f70 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -719,12 +719,13 @@ ModelInstance* ModelObject::add_instance(const ModelInstance &other) return i; } -ModelInstance* ModelObject::add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation) +ModelInstance* ModelObject::add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation, const Vec3d &mirror) { auto *instance = add_instance(); instance->set_offset(offset); instance->set_scaling_factor(scaling_factor); instance->set_rotation(rotation); + instance->set_mirror(mirror); return instance; } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index e65228d80..947301437 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -200,7 +200,7 @@ public: ModelInstance* add_instance(); ModelInstance* add_instance(const ModelInstance &instance); - ModelInstance* add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation); + ModelInstance* add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation, const Vec3d &mirror); void delete_instance(size_t idx); void delete_last_instance(); void clear_instances(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 2e9059807..625613213 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3416,6 +3416,13 @@ CLIConfigDef::CLIConfigDef() const CLIConfigDef cli_config_def; DynamicPrintAndCLIConfig::PrintAndCLIConfigDef DynamicPrintAndCLIConfig::s_def; +void DynamicPrintAndCLIConfig::handle_legacy(t_config_option_key &opt_key, std::string &value) const +{ + if (cli_config_def.options.find(opt_key) == cli_config_def.options.end()) { + PrintConfigDef::handle_legacy(opt_key, value); + } +} + std::ostream& print_cli_options(std::ostream& out) { for (const auto& opt : cli_config_def.options) { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4c88f3a18..b96176fe5 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1241,6 +1241,12 @@ public: const ConfigDef* def() const override { return &s_def; } t_config_option_keys keys() const override { return s_def.keys(); } + // Verify whether the opt_key has not been obsoleted or renamed. + // Both opt_key and value may be modified by handle_legacy(). + // If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy(). + // handle_legacy() is called internally by set_deserialize(). + void handle_legacy(t_config_option_key &opt_key, std::string &value) const override; + private: class PrintAndCLIConfigDef : public ConfigDef { diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c32fe3e8d..bab7f3b73 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -42,8 +42,10 @@ //==================== #define ENABLE_1_42_0_ALPHA2 1 +// Improves navigation between sidebar fields #define ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION (1 && ENABLE_1_42_0_ALPHA2) - +// Adds print bed models to 3D scene +#define ENABLE_PRINT_BED_MODELS (0 && ENABLE_1_42_0_ALPHA2) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 42b025093..d44789b7a 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -11,6 +11,9 @@ #include "libslic3r/Slicing.hpp" #include "libslic3r/GCode/Analyzer.hpp" #include "slic3r/GUI/PresetBundle.hpp" +#if ENABLE_PRINT_BED_MODELS +#include "libslic3r/Format/STL.hpp" +#endif // ENABLE_PRINT_BED_MODELS #include #include @@ -20,6 +23,11 @@ #include +#if ENABLE_PRINT_BED_MODELS +#include +#include +#endif // ENABLE_PRINT_BED_MODELS + #include #include @@ -249,11 +257,7 @@ void GLVolume::set_render_color(float r, float g, float b, float a) void GLVolume::set_render_color(const float* rgba, unsigned int size) { - size = std::min((unsigned int)4, size); - for (unsigned int i = 0; i < size; ++i) - { - render_color[i] = rgba[i]; - } + ::memcpy((void*)render_color, (const void*)rgba, (size_t)(std::min((unsigned int)4, size) * sizeof(float))); } void GLVolume::set_render_color() @@ -1790,17 +1794,27 @@ GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; #if ENABLE_SIDEBAR_VISUAL_HINTS GLModel::GLModel() : m_useVBOs(false) +#if ENABLE_PRINT_BED_MODELS + , m_filename("") +#endif // ENABLE_PRINT_BED_MODELS { m_volume.shader_outside_printer_detection_enabled = false; } GLModel::~GLModel() { +#if ENABLE_PRINT_BED_MODELS + reset(); +#else m_volume.release_geometry(); +#endif // ENABLE_PRINT_BED_MODELS } void GLModel::set_color(const float* color, unsigned int size) { +#if ENABLE_PRINT_BED_MODELS + ::memcpy((void*)m_volume.color, (const void*)color, (size_t)(std::min((unsigned int)4, size) * sizeof(float))); +#endif // ENABLE_PRINT_BED_MODELS m_volume.set_render_color(color, size); } @@ -1834,6 +1848,14 @@ void GLModel::set_scale(const Vec3d& scale) m_volume.set_volume_scaling_factor(scale); } +#if ENABLE_PRINT_BED_MODELS +void GLModel::reset() +{ + m_volume.release_geometry(); + m_filename = ""; +} +#endif // ENABLE_PRINT_BED_MODELS + void GLModel::render() const { if (m_useVBOs) @@ -1854,9 +1876,7 @@ void GLModel::render_VBOs() const GLint current_program_id; ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; - GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; - - m_volume.render_VBOs(color_id, print_box_detection_id, -1); + m_volume.render_VBOs(color_id, -1, -1); ::glBindBuffer(GL_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -2066,11 +2086,57 @@ bool GLCurvedArrow::on_init(bool useVBOs) else m_volume.indexed_vertex_array.load_mesh_flat_shading(TriangleMesh(vertices, triangles)); + m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); m_volume.finalize_geometry(m_useVBOs); return true; } #endif // ENABLE_SIDEBAR_VISUAL_HINTS +#if ENABLE_PRINT_BED_MODELS +bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) +{ + reset(); + + if (!boost::filesystem::exists(filename)) + return false; + + if (!boost::algorithm::iends_with(filename, ".stl")) + return false; + + Model model; + try + { + model = Model::read_from_file(filename); + } + catch (std::exception &e) + { + return false; + } + + m_filename = filename; + m_useVBOs = useVBOs; + + ModelObject* model_object = model.objects.front(); + model_object->center_around_origin(); + + TriangleMesh mesh = model.mesh(); + mesh.repair(); + + if (m_useVBOs) + m_volume.indexed_vertex_array.load_mesh_full_shading(mesh); + else + m_volume.indexed_vertex_array.load_mesh_flat_shading(mesh); + + float color[4] = { 0.235f, 0.235, 0.235f, 1.0f }; + set_color(color, 4); + + m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); + m_volume.finalize_geometry(m_useVBOs); + + return true; +} +#endif // ENABLE_PRINT_BED_MODELS + std::string _3DScene::get_gl_info(bool format_as_html, bool extensions) { return s_canvas_mgr.get_gl_info(format_as_html, extensions); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 38996dc04..b7b1af73d 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -569,13 +569,20 @@ class GLModel protected: GLVolume m_volume; bool m_useVBOs; +#if ENABLE_PRINT_BED_MODELS + std::string m_filename; +#endif // ENABLE_PRINT_BED_MODELS public: GLModel(); virtual ~GLModel(); bool init(bool useVBOs) { return on_init(useVBOs); } +#if ENABLE_PRINT_BED_MODELS + bool init_from_file(const std::string& filename, bool useVBOs) { return on_init_from_file(filename, useVBOs); } + void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box.center()); } +#endif // ENABLE_PRINT_BED_MODELS void set_color(const float* color, unsigned int size); const Vec3d& get_offset() const; @@ -585,10 +592,22 @@ public: const Vec3d& get_scale() const; void set_scale(const Vec3d& scale); +#if ENABLE_PRINT_BED_MODELS + const std::string& get_filename() const { return m_filename; } + const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box; } + + void reset(); +#endif // ENABLE_PRINT_BED_MODELS + void render() const; protected: +#if ENABLE_PRINT_BED_MODELS + virtual bool on_init(bool useVBOs) { return false; } + virtual bool on_init_from_file(const std::string& filename, bool useVBOs) { return false; } +#else virtual bool on_init(bool useVBOs) = 0; +#endif // ENABLE_PRINT_BED_MODELS private: void render_VBOs() const; @@ -613,6 +632,14 @@ protected: }; #endif // ENABLE_SIDEBAR_VISUAL_HINTS +#if ENABLE_PRINT_BED_MODELS +class GLBed : public GLModel +{ +protected: + virtual bool on_init_from_file(const std::string& filename, bool useVBOs); +}; +#endif // ENABLE_PRINT_BED_MODELS + class _3DScene { static GUI::GLCanvas3DManager s_canvas_mgr; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 44ac1bc71..4ef020bf8 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -126,7 +126,7 @@ public: } inline std::string get_name() const { - return fpath.GetName().ToStdString(); + return fpath.GetName().ToUTF8().data(); } template inline LayerWriter& operator<<(const T& arg) { diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index dbc9e36d8..feb44a922 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -305,7 +305,7 @@ void BedShapePanel::load_stl() dialog->GetPaths(input_file); dialog->Destroy(); - std::string file_name = input_file[0].ToStdString(); + std::string file_name = input_file[0].ToUTF8().data(); Model model; try { diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 028c0011c..b46f6ff93 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -73,8 +73,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons std::vector variants_panels; for (const auto &model : models) { - auto bitmap_file = wxString::Format("printers/%s_%s.png", vendor.id, model.id); - wxBitmap bitmap(GUI::from_u8(Slic3r::var(bitmap_file.ToStdString())), wxBITMAP_TYPE_PNG); + wxBitmap bitmap(GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())), wxBITMAP_TYPE_PNG); auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); title->SetFont(namefont); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index e1bec8578..501d1f1bc 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -188,7 +188,7 @@ void Field::get_value_by_opt_type(wxString& str) } } - m_value = str.ToStdString(); + m_value = str.ToUTF8().data(); break; } default: break; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1ed266d09..48e87f66e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -386,6 +386,35 @@ Point GLCanvas3D::Bed::point_projection(const Point& point) const return m_polygon.point_projection(point); } +#if ENABLE_PRINT_BED_MODELS +void GLCanvas3D::Bed::render(float theta, bool useVBOs) const +{ + switch (m_type) + { + case MK2: + { + _render_prusa("mk2", theta, useVBOs); + break; + } + case MK3: + { + _render_prusa("mk3", theta, useVBOs); + break; + } + case SL1: + { + _render_prusa("sl1", theta, useVBOs); + break; + } + default: + case Custom: + { + _render_custom(); + break; + } + } +} +#else void GLCanvas3D::Bed::render(float theta) const { switch (m_type) @@ -413,6 +442,7 @@ void GLCanvas3D::Bed::render(float theta) const } } } +#endif // ENABLE_PRINT_BED_MODELS void GLCanvas3D::Bed::_calc_bounding_box() { @@ -504,9 +534,18 @@ GLCanvas3D::Bed::EType GLCanvas3D::Bed::_detect_type() const return type; } +#if ENABLE_PRINT_BED_MODELS +void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta, bool useVBOs) const +#else void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const +#endif // ENABLE_PRINT_BED_MODELS { - std::string filename = resources_dir() + "/icons/bed/" + key + "_top.png"; + std::string tex_path = resources_dir() + "/icons/bed/" + key; +#if ENABLE_PRINT_BED_MODELS + std::string model_path = resources_dir() + "/models/" + key; +#endif // ENABLE_PRINT_BED_MODELS + + std::string filename = tex_path + "_top.png"; if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename)) { if (!m_top_texture.load_from_file(filename, true)) @@ -516,7 +555,7 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const } } - filename = resources_dir() + "/icons/bed/" + key + "_bottom.png"; + filename = tex_path + "_bottom.png"; if ((m_bottom_texture.get_id() == 0) || (m_bottom_texture.get_source() != filename)) { if (!m_bottom_texture.load_from_file(filename, true)) @@ -526,6 +565,22 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const } } +#if ENABLE_PRINT_BED_MODELS + if (theta <= 90.0f) + { + filename = model_path + "_bed.stl"; + if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) + m_model.center_around(m_bounding_box.center() - Vec3d(0.0, 0.0, 1.0 + 0.5 * m_model.get_bounding_box().size()(2))); + + if (!m_model.get_filename().empty()) + { + ::glEnable(GL_LIGHTING); + m_model.render(); + ::glDisable(GL_LIGHTING); + } + } +#endif // ENABLE_PRINT_BED_MODELS + unsigned int triangles_vcount = m_triangles.get_vertices_count(); if (triangles_vcount > 0) { @@ -4896,6 +4951,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } m_mouse.set_start_position_2D_as_invalid(); + m_mouse.set_start_position_3D_as_invalid(); #endif } else if (evt.Leaving()) @@ -6086,7 +6142,11 @@ void GLCanvas3D::_render_background() const void GLCanvas3D::_render_bed(float theta) const { +#if ENABLE_PRINT_BED_MODELS + m_bed.render(theta, m_use_VBOs); +#else m_bed.render(theta); +#endif // ENABLE_PRINT_BED_MODELS } void GLCanvas3D::_render_axes() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 73aa4bd02..c2f2074c1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -201,6 +201,9 @@ class GLCanvas3D GeometryBuffer m_gridlines; mutable GLTexture m_top_texture; mutable GLTexture m_bottom_texture; +#if ENABLE_PRINT_BED_MODELS + mutable GLBed m_model; +#endif // ENABLE_PRINT_BED_MODELS public: Bed(); @@ -216,14 +219,22 @@ class GLCanvas3D bool contains(const Point& point) const; Point point_projection(const Point& point) const; +#if ENABLE_PRINT_BED_MODELS + void render(float theta, bool useVBOs) const; +#else void render(float theta) const; +#endif // ENABLE_PRINT_BED_MODELS private: void _calc_bounding_box(); void _calc_triangles(const ExPolygon& poly); void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); EType _detect_type() const; +#if ENABLE_PRINT_BED_MODELS + void _render_prusa(const std::string &key, float theta, bool useVBOs) const; +#else void _render_prusa(const std::string &key, float theta) const; +#endif // ENABLE_PRINT_BED_MODELS void _render_custom() const; static bool _are_equal(const Pointfs& bed_1, const Pointfs& bed_2); }; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b1ecef7df..091071e16 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -461,10 +461,8 @@ bool GUI_App::select_language( wxArrayString & names, m_wxLocale->Init(identifiers[index]); m_wxLocale->AddCatalogLookupPathPrefix(wxString::FromUTF8(localization_dir())); m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE"); - wxSetlocale(LC_NUMERIC, "C"); -#ifdef WIN32 - ::SetLocaleInfoA(LOCALE_CUSTOM_DEFAULT, LOCALE_SDECIMAL, "."); -#endif /* WIN32 */ + //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only. + wxSetlocale(LC_NUMERIC, "C"); Preset::update_suffix_modified(); return true; } @@ -491,10 +489,8 @@ bool GUI_App::load_language() m_wxLocale->Init(identifiers[i]); m_wxLocale->AddCatalogLookupPathPrefix(wxString::FromUTF8(localization_dir())); m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE"); + //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only. wxSetlocale(LC_NUMERIC, "C"); -#ifdef WIN32 - ::SetLocaleInfoA(LOCALE_CUSTOM_DEFAULT, LOCALE_SDECIMAL, "."); -#endif /* WIN32 */ Preset::update_suffix_modified(); return true; } @@ -509,7 +505,7 @@ void GUI_App::save_language() if (m_wxLocale) language = m_wxLocale->GetCanonicalName(); - app_config->set("translation_language", language.ToStdString()); + app_config->set("translation_language", language.ToUTF8().data()); app_config->save(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index afeaca327..dffaf7afc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -298,13 +298,13 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) if (obj_idx < 0) return; if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - (*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToStdString(); + (*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToUTF8().data(); return; } const int volume_id = m_objects_model->GetVolumeIdByItem(item); if (volume_id < 0) return; - (*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToStdString(); + (*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToUTF8().data(); } void ObjectList::init_icons() @@ -657,7 +657,7 @@ void ObjectList::append_menu_item_add_generic(wxMenuItem* menu, const int type) std::vector menu_items = { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }; for (auto& item : menu_items) { append_menu_item(sub_menu, wxID_ANY, _(item), "", - [this, type, item](wxCommandEvent&) { load_generic_subobject(_(item).ToStdString(), type); }, "", menu->GetMenu()); + [this, type, item](wxCommandEvent&) { load_generic_subobject(_(item).ToUTF8().data(), type); }, "", menu->GetMenu()); } menu->SetSubMenu(sub_menu); @@ -683,10 +683,10 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu) append_menu_item(menu, wxID_ANY, _(L("Add part")), "", [this](wxCommandEvent&) { load_subobject(ModelVolume::MODEL_PART); }, *m_bmp_vector[ModelVolume::MODEL_PART]); append_menu_item(menu, wxID_ANY, _(L("Add support enforcer")), "", - [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToStdString(), ModelVolume::SUPPORT_ENFORCER); }, + [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToUTF8().data(), ModelVolume::SUPPORT_ENFORCER); }, *m_bmp_vector[ModelVolume::SUPPORT_ENFORCER]); append_menu_item(menu, wxID_ANY, _(L("Add support blocker")), "", - [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToStdString(), ModelVolume::SUPPORT_BLOCKER); }, + [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToUTF8().data(), ModelVolume::SUPPORT_BLOCKER); }, *m_bmp_vector[ModelVolume::SUPPORT_BLOCKER]); return; @@ -823,7 +823,7 @@ void ObjectList::load_part( ModelObject* model_object, wxArrayString input_files; wxGetApp().import_model(parent, input_files); for (int i = 0; i < input_files.size(); ++i) { - std::string input_file = input_files.Item(i).ToStdString(); + std::string input_file = input_files.Item(i).ToUTF8().data(); Model model; try { diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 32a38a77c..be421e5d3 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -438,7 +438,7 @@ void ObjectManipulation::change_scale_value(const Vec3d& scale) max_diff = abs_scale_diff(Z); max_diff_axis = Z; } - scaling_factor = Vec3d(scale(max_diff_axis), scale(max_diff_axis), scale(max_diff_axis)); + scaling_factor = scale(max_diff_axis) * Vec3d::Ones(); } scaling_factor *= 0.01; @@ -464,10 +464,38 @@ void ObjectManipulation::change_size_value(const Vec3d& size) ref_size = volume->bounding_box.size(); } - change_scale_value(100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2))); - #if ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION + Vec3d scale = 100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2)); + Vec3d scaling_factor = scale; + + if (selection.requires_uniform_scale()) + { + Vec3d abs_scale_diff = (scale - m_cache_scale).cwiseAbs(); + double max_diff = abs_scale_diff(X); + Axis max_diff_axis = X; + if (max_diff < abs_scale_diff(Y)) + { + max_diff = abs_scale_diff(Y); + max_diff_axis = Y; + } + if (max_diff < abs_scale_diff(Z)) + { + max_diff = abs_scale_diff(Z); + max_diff_axis = Z; + } + scaling_factor = scale(max_diff_axis) * Vec3d::Ones(); + } + + scaling_factor *= 0.01; + + auto canvas = wxGetApp().plater()->canvas3D(); + canvas->get_selection().start_dragging(); + canvas->get_selection().scale(scaling_factor, false); + canvas->do_scale(); + m_cache_size = size; +#else + change_scale_value(100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2))); #endif // ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b4d779dfe..099dd4c50 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -490,7 +490,7 @@ void MainFrame::quick_slice(const int qs) // }); // keep model around - auto model = Slic3r::Model::read_from_file(input_file.ToStdString()); + auto model = Slic3r::Model::read_from_file(input_file.ToUTF8().data()); // sprint->apply_config(config); // sprint->set_model(model); @@ -632,7 +632,7 @@ void MainFrame::export_config() if (!file.IsEmpty()) { wxGetApp().app_config->update_config_dir(get_dir_name(file)); m_last_config = file; - config.save(file.ToStdString()); + config.save(file.ToUTF8().data()); } } @@ -651,7 +651,7 @@ void MainFrame::load_config_file(wxString file/* = wxEmptyString*/) dlg->Destroy(); } try { - wxGetApp().preset_bundle->load_config_file(file.ToStdString()); + wxGetApp().preset_bundle->load_config_file(file.ToUTF8().data()); } catch (const std::exception &ex) { show_error(this, ex.what()); return; @@ -684,7 +684,7 @@ void MainFrame::export_configbundle() // Export the config bundle. wxGetApp().app_config->update_config_dir(get_dir_name(file)); try { - wxGetApp().preset_bundle->export_configbundle(file.ToStdString()); + wxGetApp().preset_bundle->export_configbundle(file.ToUTF8().data()); } catch (const std::exception &ex) { show_error(this, ex.what()); } @@ -712,7 +712,7 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re auto presets_imported = 0; try { - presets_imported = wxGetApp().preset_bundle->load_configbundle(file.ToStdString()); + presets_imported = wxGetApp().preset_bundle->load_configbundle(file.ToUTF8().data()); } catch (const std::exception &ex) { show_error(this, ex.what()); return; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c9440a9d0..941a181d3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2083,7 +2083,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) //! So, to get selected string we do //! combo->GetString(combo->GetSelection()) //! instead of - //! combo->GetStringSelection().ToStdString()); + //! combo->GetStringSelection().ToUTF8().data()); std::string selected_string = combo->GetString(combo->GetSelection()).ToUTF8().data(); @@ -2628,7 +2628,7 @@ void Plater::increase_instances(size_t num) float offset = 10.0; for (size_t i = 0; i < num; i++, offset += 10.0) { Vec3d offset_vec = model_instance->get_offset() + Vec3d(offset, offset, 0.0); - model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation()); + model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation(), model_instance->get_mirror()); // p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec)); } diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index ee7ba279f..274f2a7ef 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1164,6 +1164,22 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla section.first << "\" has already been loaded from another Confing Bundle."; continue; } + } else if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) { + // This is a user config bundle. + const Preset *existing = presets->find_preset(preset_name, false); + if (existing != nullptr) { + if (existing->is_system) { + assert(existing->vendor != nullptr); + BOOST_LOG_TRIVIAL(error) << "Error in a user provided Config Bundle \"" << path << "\": The " << presets->name() << " preset \"" << + existing->name << "\" is a system preset of vendor " << existing->vendor->name << " and it will be ignored."; + continue; + } else { + assert(existing->vendor == nullptr); + BOOST_LOG_TRIVIAL(trace) << "A " << presets->name() << " preset \"" << existing->name << "\" was overwritten with a preset from user Config Bundle \"" << path << "\""; + } + } else { + BOOST_LOG_TRIVIAL(trace) << "A new " << presets->name() << " preset \"" << preset_name << "\" was imported from user Config Bundle \"" << path << "\""; + } } // Decide a full path to this .ini file. auto file_name = boost::algorithm::iends_with(preset_name, ".ini") ? preset_name : preset_name + ".ini"; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 70751fd5d..83f7e1e73 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -209,7 +209,7 @@ void Tab::create_preset_tab() 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()); + //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data()); //! we doing next: int selected_item = m_presets_choice->GetSelection(); if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) @@ -2889,7 +2889,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep selections.Clear(); selections = dlg.GetSelections(); for (auto idx : selections) - value.push_back(presets[idx].ToStdString()); + value.push_back(presets[idx].ToUTF8().data()); if (value.empty()) { deps.checkbox->SetValue(1); deps.btn->Disable(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 6ea47b45b..466580074 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -422,13 +422,13 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorfind(m_name.ToStdString()); + wxBitmap *bmp = m_bitmap_cache->find(m_name.ToUTF8().data()); if (bmp == nullptr) { std::vector bmps; for (auto& cat : m_opt_categories) bmps.emplace_back(categories_icon.find(cat) == categories_icon.end() ? wxNullBitmap : categories_icon.at(cat)); - bmp = m_bitmap_cache->insert(m_name.ToStdString(), bmps); + bmp = m_bitmap_cache->insert(m_name.ToUTF8().data(), bmps); } m_bmp = *bmp; diff --git a/src/slic3r/Utils/Duet.cpp b/src/slic3r/Utils/Duet.cpp index 3449e610e..77137a7d2 100644 --- a/src/slic3r/Utils/Duet.cpp +++ b/src/slic3r/Utils/Duet.cpp @@ -75,6 +75,19 @@ bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn e http.set_post_body(upload_data.source_path) .on_complete([&](std::string body, unsigned status) { BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body; + + int err_code = get_err_code_from_body(body); + if (err_code != 0) { + BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Request completed but error code was received: %1%") % err_code; + error_fn(format_error(body, L("Unknown error occured"), 0)); + res = false; + } else if (upload_data.start_print) { + wxString errormsg; + res = start_print(errormsg, upload_data.upload_path.string()); + if (! res) { + error_fn(std::move(errormsg)); + } + } }) .on_error([&](std::string body, std::string error, unsigned status) { BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body; diff --git a/src/slic3r_app_msvc.cpp b/src/slic3r_app_msvc.cpp index 9823a325d..7cd97dfc3 100644 --- a/src/slic3r_app_msvc.cpp +++ b/src/slic3r_app_msvc.cpp @@ -181,10 +181,10 @@ extern "C" { } #ifdef SLIC3R_WRAPPER_NOCONSOLE -int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpCmdLine, int nCmdShow) +int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */) { int argc; - wchar_t **argv = CommandLineToArgvW(lpCmdLine, &argc); + wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); #else int wmain(int argc, wchar_t **argv) { diff --git a/version.inc b/version.inc index 4bb281767..c24762003 100644 --- a/version.inc +++ b/version.inc @@ -2,7 +2,7 @@ # (the version numbers are generated by the build script from the git current label) set(SLIC3R_FORK_NAME "Slic3r++") -set(SLIC3R_VERSION "1.42.0-alpha1") +set(SLIC3R_VERSION "1.42.0-alpha2") set(SLIC3R_BUILD "${SLIC3R_VERSION}+UNKNOWN") set(SLIC3R_BUILD_ID "${SLIC3R_BUILD_ID}") set(SLIC3R_RC_VERSION "1,42,0,0")