diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index cbfe0e5fe..0b9596261 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -141,7 +141,7 @@ sub OnInit { $self->CallAfter(sub { eval { if (! $self->{preset_updater}->config_update()) { - exit 0; + $self->{mainframe}->Close; } }; if ($@) { diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 9fdc320f3..9e070f66b 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -127,6 +127,8 @@ sub new { $range->[1] *= $variation; } $_->set_scaling_factor($scale) for @{ $model_object->instances }; + + $self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%"); $object->transform_thumbnail($self->{model}, $obj_idx); #update print and start background processing @@ -1671,7 +1673,7 @@ sub reload_from_disk { my $model_object = $self->{model}->objects->[$obj_idx]; #FIXME convert to local file encoding return if !$model_object->input_file - || !-e $model_object->input_file; + || !-e Slic3r::encode_path($model_object->input_file); my @new_obj_idx = $self->load_files([$model_object->input_file]); return if !@new_obj_idx; @@ -2119,7 +2121,8 @@ sub object_list_changed { my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file}; my $model_fits = $self->{canvas3D} ? Slic3r::GUI::_3DScene::check_volumes_outside_state($self->{canvas3D}, $self->{config}) : 1; - my $method = ($have_objects && ! $export_in_progress && $model_fits) ? 'Enable' : 'Disable'; + # $model_fits == 1 -> ModelInstance::PVS_Partly_Outside + my $method = ($have_objects && ! $export_in_progress && ($model_fits != 1)) ? 'Enable' : 'Disable'; $self->{"btn_$_"}->$method for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode); } diff --git a/resources/icons/bed/mk2_top.png b/resources/icons/bed/mk2_top.png index 142050c3a..cab4b966f 100644 Binary files a/resources/icons/bed/mk2_top.png and b/resources/icons/bed/mk2_top.png differ diff --git a/resources/icons/bed/mk3_bottom.png b/resources/icons/bed/mk3_bottom.png index 072c14dae..3f12e7efb 100644 Binary files a/resources/icons/bed/mk3_bottom.png and b/resources/icons/bed/mk3_bottom.png differ diff --git a/resources/icons/bed/mk3_top.png b/resources/icons/bed/mk3_top.png index 0403c2f05..b44007ad4 100644 Binary files a/resources/icons/bed/mk3_top.png and b/resources/icons/bed/mk3_top.png differ diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp index 2c32db1a6..dd3500eba 100644 --- a/xs/src/libslic3r/Format/3mf.cpp +++ b/xs/src/libslic3r/Format/3mf.cpp @@ -1989,7 +1989,7 @@ namespace Slic3r { // stores object's name if (!obj->name.empty()) - stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << obj->name << "\"/>\n"; + stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << xml_escape(obj->name) << "\"/>\n"; // stores object's config data for (const std::string& key : obj->config.keys()) @@ -2012,7 +2012,7 @@ namespace Slic3r { // stores volume's name if (!volume->name.empty()) - stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << volume->name << "\"/>\n"; + stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n"; // stores volume's modifier field if (volume->modifier) diff --git a/xs/src/libslic3r/Format/AMF.cpp b/xs/src/libslic3r/Format/AMF.cpp index 21d4b4d3b..600aa6cd9 100644 --- a/xs/src/libslic3r/Format/AMF.cpp +++ b/xs/src/libslic3r/Format/AMF.cpp @@ -8,6 +8,7 @@ #include "../libslic3r.h" #include "../Model.hpp" #include "../GCode.hpp" +#include "../Utils.hpp" #include "../slic3r/GUI/PresetBundle.hpp" #include "AMF.hpp" @@ -686,33 +687,6 @@ bool load_amf(const char *path, PresetBundle* bundle, Model *model) return false; } -std::string xml_escape(std::string text) -{ - std::string::size_type pos = 0; - for (;;) - { - pos = text.find_first_of("\"\'&<>", pos); - if (pos == std::string::npos) - break; - - std::string replacement; - switch (text[pos]) - { - case '\"': replacement = """; break; - case '\'': replacement = "'"; break; - case '&': replacement = "&"; break; - case '<': replacement = "<"; break; - case '>': replacement = ">"; break; - default: break; - } - - text.replace(pos, 1, replacement); - pos += replacement.size(); - } - - return text; -} - bool store_amf(const char *path, Model *model, Print* print, bool export_print_config) { if ((path == nullptr) || (model == nullptr) || (print == nullptr)) @@ -761,7 +735,7 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c for (const std::string &key : object->config.keys()) stream << " " << object->config.serialize(key) << "\n"; if (!object->name.empty()) - stream << " " << object->name << "\n"; + stream << " " << xml_escape(object->name) << "\n"; std::vector layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector(); if (layer_height_profile.size() >= 4 && (layer_height_profile.size() % 2) == 0) { // Store the layer height profile as a single semicolon separated list. @@ -805,7 +779,7 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c for (const std::string &key : volume->config.keys()) stream << " " << volume->config.serialize(key) << "\n"; if (!volume->name.empty()) - stream << " " << volume->name << "\n"; + stream << " " << xml_escape(volume->name) << "\n"; if (volume->modifier) stream << " 1\n"; for (int i = 0; i < volume->mesh.stl.stats.number_of_facets; ++i) { diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index f0b37ade3..89a72a725 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -309,10 +309,12 @@ std::vector>> GCode::collec size_t object_idx; size_t layer_idx; }; - std::vector> per_object(print.objects.size(), std::vector()); + + PrintObjectPtrs printable_objects = print.get_printable_objects(); + std::vector> per_object(printable_objects.size(), std::vector()); std::vector ordering; - for (size_t i = 0; i < print.objects.size(); ++ i) { - per_object[i] = collect_layers_to_print(*print.objects[i]); + for (size_t i = 0; i < printable_objects.size(); ++i) { + per_object[i] = collect_layers_to_print(*printable_objects[i]); OrderingItem ordering_item; ordering_item.object_idx = i; ordering.reserve(ordering.size() + per_object[i].size()); @@ -337,8 +339,8 @@ std::vector>> GCode::collec std::pair> merged; // Assign an average print_z to the set of layers with nearly equal print_z. merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z); - merged.second.assign(print.objects.size(), LayerToPrint()); - for (; i < j; ++ i) { + merged.second.assign(printable_objects.size(), LayerToPrint()); + for (; i < j; ++i) { const OrderingItem &oi = ordering[i]; assert(merged.second[oi.object_idx].layer() == nullptr); merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]); @@ -472,9 +474,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. m_layer_count = 0; + PrintObjectPtrs printable_objects = print.get_printable_objects(); if (print.config.complete_objects.value) { // Add each of the object's layers separately. - for (auto object : print.objects) { + for (auto object : printable_objects) { std::vector zs; zs.reserve(object->layers.size() + object->support_layers.size()); for (auto layer : object->layers) @@ -487,7 +490,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) } else { // Print all objects with the same print_z together. std::vector zs; - for (auto object : print.objects) { + for (auto object : printable_objects) { zs.reserve(zs.size() + object->layers.size() + object->support_layers.size()); for (auto layer : object->layers) zs.push_back(layer->print_z); @@ -506,8 +509,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) { // get the minimum cross-section used in the print std::vector mm3_per_mm; - for (auto object : print.objects) { - for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) { + for (auto object : printable_objects) { + for (size_t region_id = 0; region_id < print.regions.size(); ++region_id) { auto region = print.regions[region_id]; for (auto layer : object->layers) { auto layerm = layer->regions[region_id]; @@ -567,7 +570,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _write(file, "\n"); } // Write some terse information on the slicing parameters. - const PrintObject *first_object = print.objects.front(); + const PrintObject *first_object = printable_objects.front(); const double layer_height = first_object->config.layer_height.value; const double first_layer_height = first_object->config.first_layer_height.get_abs_value(layer_height); for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) { @@ -596,13 +599,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) size_t initial_print_object_id = 0; bool has_wipe_tower = false; if (print.config.complete_objects.value) { - // Find the 1st printing object, find its tool ordering and the initial extruder ID. - for (; initial_print_object_id < print.objects.size(); ++initial_print_object_id) { - tool_ordering = ToolOrdering(*print.objects[initial_print_object_id], initial_extruder_id); - if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1) - break; - } - } else { + // Find the 1st printing object, find its tool ordering and the initial extruder ID. + for (; initial_print_object_id < printable_objects.size(); ++initial_print_object_id) { + tool_ordering = ToolOrdering(*printable_objects[initial_print_object_id], initial_extruder_id); + if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1) + break; + } + } + else { // Find tool ordering for all the objects at once, and the initial extruder ID. // If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it. tool_ordering = print.m_tool_ordering.empty() ? @@ -676,7 +680,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) // Collect outer contours of all objects over all layers. // Discard objects only containing thin walls (offset would fail on an empty polygon). Polygons islands; - for (const PrintObject *object : print.objects) + for (const PrintObject *object : printable_objects) for (const Layer *layer : object->layers) for (const ExPolygon &expoly : layer->slices.expolygons) for (const Point © : object->_shifted_copies) { @@ -724,7 +728,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) if (print.config.complete_objects.value) { // Print objects from the smallest to the tallest to avoid collisions // when moving onto next object starting point. - std::vector objects(print.objects); + std::vector objects(printable_objects); std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size.z < po2->size.z; }); size_t finished_objects = 0; for (size_t object_id = initial_print_object_id; object_id < objects.size(); ++ object_id) { @@ -788,7 +792,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) PrintObjectPtrs printable_objects = print.get_printable_objects(); for (PrintObject *object : printable_objects) object_reference_points.push_back(object->_shifted_copies.front()); - Slic3r::Geometry::chained_path(object_reference_points, object_indices); + Slic3r::Geometry::chained_path(object_reference_points, object_indices); // Sort layers by Z. // All extrusion moves with the same top layer height are extruded uninterrupted. std::vector>> layers_to_print = collect_layers_to_print(print); diff --git a/xs/src/libslic3r/GCode/ToolOrdering.cpp b/xs/src/libslic3r/GCode/ToolOrdering.cpp index 9b3f2694f..189a94d49 100644 --- a/xs/src/libslic3r/GCode/ToolOrdering.cpp +++ b/xs/src/libslic3r/GCode/ToolOrdering.cpp @@ -451,10 +451,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int return volume_to_wipe; // Soluble filament cannot be wiped in a random infill, neither the filament after it // we will sort objects so that dedicated for wiping are at the beginning: - PrintObjectPtrs object_list = print.objects; + PrintObjectPtrs object_list = print.get_printable_objects(); std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config.wipe_into_objects; }); - // We will now iterate through // - first the dedicated objects to mark perimeters or infills (depending on infill_first) // - second through the dedicated ones again to mark infills or perimeters (depending on infill_first) @@ -548,7 +547,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config); unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config); - for (const PrintObject* object : print.objects) { + PrintObjectPtrs printable_objects = print.get_printable_objects(); + for (const PrintObject* object : printable_objects) { // Finds this layer: auto this_layer_it = std::find_if(object->layers.begin(), object->layers.end(), [<](const Layer* lay) { return std::abs(lt.print_z - lay->print_z)layers.end()) diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp index a501fa4d3..349222854 100644 --- a/xs/src/libslic3r/Utils.hpp +++ b/xs/src/libslic3r/Utils.hpp @@ -84,6 +84,8 @@ inline T next_highest_power_of_2(T v) return ++ v; } +extern std::string xml_escape(std::string text); + class PerlCallback { public: PerlCallback(void *sv) : m_callback(nullptr) { this->register_callback(sv); } diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp index 13ec1d066..55164bbdd 100644 --- a/xs/src/libslic3r/utils.cpp +++ b/xs/src/libslic3r/utils.cpp @@ -387,4 +387,31 @@ unsigned get_current_pid() #endif } +std::string xml_escape(std::string text) +{ + std::string::size_type pos = 0; + for (;;) + { + pos = text.find_first_of("\"\'&<>", pos); + if (pos == std::string::npos) + break; + + std::string replacement; + switch (text[pos]) + { + case '\"': replacement = """; break; + case '\'': replacement = "'"; break; + case '&': replacement = "&"; break; + case '<': replacement = "<"; break; + case '>': replacement = ">"; break; + default: break; + } + + text.replace(pos, 1, replacement); + pos += replacement.size(); + } + + return text; +} + }; // namespace Slic3r diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 29ea5fb9c..c00a9a08e 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1651,7 +1651,7 @@ void _3DScene::update_volumes_selection(wxGLCanvas* canvas, const std::vector& selections); - static bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config); + static int check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config); static bool move_volume_up(wxGLCanvas* canvas, unsigned int id); static bool move_volume_down(wxGLCanvas* canvas, unsigned int id); diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp index 0c42168bb..9f736ded8 100644 --- a/xs/src/slic3r/GUI/ConfigWizard.cpp +++ b/xs/src/slic3r/GUI/ConfigWizard.cpp @@ -223,7 +223,7 @@ void ConfigWizardPage::enable_next(bool enable) { parent->p->enable_next(enable) // Wizard pages -PageWelcome::PageWelcome(ConfigWizard *parent) : +PageWelcome::PageWelcome(ConfigWizard *parent, bool check_first_variant) : ConfigWizardPage(parent, wxString::Format(_(L("Welcome to the Slic3r %s")), ConfigWizard::name()), _(L("Welcome"))), printer_picker(nullptr), others_buttons(new wxPanel(parent)), @@ -247,7 +247,10 @@ PageWelcome::PageWelcome(ConfigWizard *parent) : AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors; printer_picker = new PrinterPicker(this, vendor_prusa->second, appconfig_vendors); - printer_picker->select_one(0, true); // Select the default (first) model/variant on the Prusa vendor + if (check_first_variant) { + // Select the default (first) model/variant on the Prusa vendor + printer_picker->select_one(0, true); + } printer_picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) { appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable); this->on_variant_checked(); @@ -788,7 +791,6 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese app_config->set("version_check", page_update->version_check ? "1" : "0"); app_config->set("preset_update", page_update->preset_update ? "1" : "0"); app_config->reset_selections(); - // ^ TODO: replace with appropriate printer selection preset_bundle->load_presets(*app_config); } else { for (ConfigWizardPage *page = page_firmware; page != nullptr; page = page->page_next()) { @@ -840,7 +842,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) : p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING); p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING); - p->add_page(p->page_welcome = new PageWelcome(this)); + p->add_page(p->page_welcome = new PageWelcome(this, reason == RR_DATA_EMPTY || reason == RR_DATA_LEGACY)); p->add_page(p->page_update = new PageUpdate(this)); p->add_page(p->page_vendors = new PageVendors(this)); p->add_page(p->page_firmware = new PageFirmware(this)); diff --git a/xs/src/slic3r/GUI/ConfigWizard_private.hpp b/xs/src/slic3r/GUI/ConfigWizard_private.hpp index c027f300d..2c8f23cd3 100644 --- a/xs/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/xs/src/slic3r/GUI/ConfigWizard_private.hpp @@ -104,7 +104,7 @@ struct PageWelcome: ConfigWizardPage wxPanel *others_buttons; wxCheckBox *cbox_reset; - PageWelcome(ConfigWizard *parent); + PageWelcome(ConfigWizard *parent, bool check_first_variant); virtual wxPanel* extra_buttons() { return others_buttons; } virtual void on_page_set(); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index eee601520..b71f1ae91 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1883,9 +1883,11 @@ void GLCanvas3D::update_volumes_selection(const std::vector& selections) } } -bool GLCanvas3D::check_volumes_outside_state(const DynamicPrintConfig* config) const +int GLCanvas3D::check_volumes_outside_state(const DynamicPrintConfig* config) const { - return m_volumes.check_outside_state(config, nullptr); + ModelInstance::EPrintVolumeState state; + m_volumes.check_outside_state(config, &state); + return (int)state; } bool GLCanvas3D::move_volume_up(unsigned int id) diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 67f6ef32f..9bca50dad 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -501,7 +501,7 @@ public: void deselect_volumes(); void select_volume(unsigned int id); void update_volumes_selection(const std::vector& selections); - bool check_volumes_outside_state(const DynamicPrintConfig* config) const; + int check_volumes_outside_state(const DynamicPrintConfig* config) const; bool move_volume_up(unsigned int id); bool move_volume_down(unsigned int id); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index ef1d7fd19..75cf78bdc 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -237,7 +237,7 @@ void GLCanvas3DManager::update_volumes_selection(wxGLCanvas* canvas, const std:: it->second->update_volumes_selection(selections); } -bool GLCanvas3DManager::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const +int GLCanvas3DManager::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const { CanvasesMap::const_iterator it = _get_canvas(canvas); return (it != m_canvases.end()) ? it->second->check_volumes_outside_state(config) : false; diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 724c1e4c6..ace6515d2 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -75,7 +75,7 @@ public: void deselect_volumes(wxGLCanvas* canvas); void select_volume(wxGLCanvas* canvas, unsigned int id); void update_volumes_selection(wxGLCanvas* canvas, const std::vector& selections); - bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const; + int check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const; bool move_volume_up(wxGLCanvas* canvas, unsigned int id); bool move_volume_down(wxGLCanvas* canvas, unsigned int id); diff --git a/xs/src/slic3r/GUI/GLTexture.cpp b/xs/src/slic3r/GUI/GLTexture.cpp index 2af555707..18c9f5dea 100644 --- a/xs/src/slic3r/GUI/GLTexture.cpp +++ b/xs/src/slic3r/GUI/GLTexture.cpp @@ -79,7 +79,8 @@ bool GLTexture::load_from_file(const std::string& filename, bool generate_mipmap if (generate_mipmaps) { // we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards - _generate_mipmaps(image); + unsigned int levels_count = _generate_mipmaps(image); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 + levels_count); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else @@ -149,14 +150,14 @@ void GLTexture::render_texture(unsigned int tex_id, float left, float right, flo ::glDisable(GL_BLEND); } -void GLTexture::_generate_mipmaps(wxImage& image) +unsigned int GLTexture::_generate_mipmaps(wxImage& image) { int w = image.GetWidth(); int h = image.GetHeight(); GLint level = 0; std::vector data(w * h * 4, 0); - while ((w > 1) && (h > 1)) + while ((w > 1) || (h > 1)) { ++level; @@ -183,6 +184,8 @@ void GLTexture::_generate_mipmaps(wxImage& image) ::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); } + + return (unsigned int)level; } } // namespace GUI diff --git a/xs/src/slic3r/GUI/GLTexture.hpp b/xs/src/slic3r/GUI/GLTexture.hpp index 2e936161e..3113fcab2 100644 --- a/xs/src/slic3r/GUI/GLTexture.hpp +++ b/xs/src/slic3r/GUI/GLTexture.hpp @@ -32,7 +32,7 @@ namespace GUI { static void render_texture(unsigned int tex_id, float left, float right, float bottom, float top); protected: - void _generate_mipmaps(wxImage& image); + unsigned int _generate_mipmaps(wxImage& image); }; } // namespace GUI diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index b9a010659..58553e1bc 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -268,7 +268,7 @@ void PresetBundle::load_installed_printers(const AppConfig &config) } // Load selections (current print, current filaments, current printer) from config.ini -// This is done just once on application start up. +// This is done on application start up or after updates are applied. void PresetBundle::load_selections(const AppConfig &config) { // Update visibility of presets based on application vendor / model / variant configuration. diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp index b5eab115b..c962a2c82 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.cpp +++ b/xs/src/slic3r/Utils/PresetUpdater.cpp @@ -570,6 +570,7 @@ bool PresetUpdater::config_update() const if (! wizard.run(GUI::get_preset_bundle(), this)) { return false; } + GUI::load_current_presets(); } else { BOOST_LOG_TRIVIAL(info) << "User wants to exit Slic3r, bye..."; return false; @@ -599,7 +600,6 @@ bool PresetUpdater::config_update() const // Reload global configuration auto *app_config = GUI::get_app_config(); - app_config->reset_selections(); GUI::get_preset_bundle()->load_presets(*app_config); GUI::load_current_presets(); } else { diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 0caaac1d6..b906a3ce9 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -230,7 +230,7 @@ update_volumes_selection(canvas, selections) CODE: _3DScene::update_volumes_selection((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections); -bool +int check_volumes_outside_state(canvas, config) SV *canvas; DynamicPrintConfig *config;