diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 0ac5c97712..f87f1283e5 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1257,12 +1257,12 @@ std::string Print::validate() const if (! equal_layering(slicing_params, slicing_params0)) return L("The Wipe Tower is only supported for multiple objects if they are sliced equally."); - if ( m_config.variable_layer_height ) { // comparing layer height profiles + if (m_config.variable_layer_height) { // comparing layer height profiles bool failed = false; // layer_height_profile should be set by Print::apply(). - if (tallest_object->layer_height_profile.size() >= object->layer_height_profile.size() ) { + if (tallest_object->layer_height_profile.size() >= object->layer_height_profile.size()) { int i = 0; - while ( i < object->layer_height_profile.size() && i < tallest_object->layer_height_profile.size()) { + while (i < object->layer_height_profile.size() && i < tallest_object->layer_height_profile.size()) { if (std::abs(tallest_object->layer_height_profile[i] - object->layer_height_profile[i])) { failed = true; break; @@ -1303,15 +1303,25 @@ std::string Print::validate() const #endif for (PrintObject *object : m_objects) { - if ((object->config().support_material_extruder == -1 || object->config().support_material_interface_extruder == -1) && - (object->config().raft_layers > 0 || object->config().support_material.value)) { - // The object has some form of support and either support_material_extruder or support_material_interface_extruder - // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles - // are of the same diameter. - if (nozzle_diameters.size() > 1) + if (object->config().raft_layers > 0 || object->config().support_material.value) { + if ((object->config().support_material_extruder == 0 || object->config().support_material_interface_extruder == 0) && nozzle_diameters.size() > 1) { + // The object has some form of support and either support_material_extruder or support_material_interface_extruder + // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles + // are of the same diameter. return L("Printing with multiple extruders of differing nozzle diameters. " "If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), " "all nozzles have to be of the same diameter."); + } + if (object->config().support_material_contact_distance == 0) { + // Soluble interface + if (object->config().support_material_contact_distance == 0 && ! object->config().support_material_synchronize_layers) + return L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers."); + } else { + // Non-soluble interface + if (object->config().support_material_extruder != 0 || object->config().support_material_interface_extruder != 0) + return L("The Wipe Tower currently supports the non-soluble supports only if they are printed with the current extruder without triggering a tool change. " + "(both support_material_extruder and support_material_interface_extruder need to be set to 0)."); + } } // validate first_layer_height diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index eebd5fefab..7015084cd2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -983,7 +983,7 @@ struct Plater::priv UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT = 16, }; // returns bit mask of UpdateBackgroundProcessReturnState - unsigned int update_background_process(); + unsigned int update_background_process(bool force_validation = false); // Restart background processing thread based on a bitmask of UpdateBackgroundProcessReturnState. bool restart_background_process(unsigned int state); void update_restart_background_process(bool force_scene_update, bool force_preview_update); @@ -1178,7 +1178,7 @@ void Plater::priv::update(bool force_full_scene_refresh) if (this->printer_technology == ptSLA) // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data. - update_status = this->update_background_process(); + update_status = this->update_background_process(false); this->view3D->reload_scene(false, force_full_scene_refresh); this->preview->reload_print(); if (this->printer_technology == ptSLA) @@ -1826,7 +1826,7 @@ void Plater::priv::update_print_volume_state() // Update background processing thread from the current config and Model. // Returns a bitmask of UpdateBackgroundProcessReturnState. -unsigned int Plater::priv::update_background_process() +unsigned int Plater::priv::update_background_process(bool force_validation) { // bitmap of enum UpdateBackgroundProcessReturnState unsigned int return_state = 0; @@ -1866,19 +1866,21 @@ unsigned int Plater::priv::update_background_process() } } - if (! this->background_process.empty()) { + if ((invalidated != Print::APPLY_STATUS_UNCHANGED || force_validation) && ! this->background_process.empty()) { + // The state of the Print changed, and it is non-zero. Let's validate it and give the user feedback on errors. std::string err = this->background_process.validate(); if (err.empty()) { if (invalidated != Print::APPLY_STATUS_UNCHANGED && this->background_processing_enabled()) return_state |= UPDATE_BACKGROUND_PROCESS_RESTART; } else { // The print is not valid. + // The error returned from the Print needs to be translated into the local language. GUI::show_error(this->q, _(err)); return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; } } - if (invalidated != Print::APPLY_STATUS_UNCHANGED && was_running && ! this->background_process.running() && + if (invalidated != Print::APPLY_STATUS_UNCHANGED && was_running && ! this->background_process.running() && (return_state & UPDATE_BACKGROUND_PROCESS_RESTART) == 0) { // The background processing was killed and it will not be restarted. wxCommandEvent evt(EVT_PROCESS_COMPLETED); @@ -1923,7 +1925,7 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) } // bitmask of UpdateBackgroundProcessReturnState - unsigned int state = update_background_process(); + unsigned int state = update_background_process(true); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) view3D->reload_scene(false); @@ -1942,7 +1944,7 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) void Plater::priv::update_restart_background_process(bool force_update_scene, bool force_update_preview) { // bitmask of UpdateBackgroundProcessReturnState - unsigned int state = this->update_background_process(); + unsigned int state = this->update_background_process(false); if (force_update_scene || (state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0) view3D->reload_scene(false); @@ -2858,7 +2860,7 @@ void Plater::reslice() { //FIXME Don't reslice if export of G-code or sending to OctoPrint is running. // bitmask of UpdateBackgroundProcessReturnState - unsigned int state = this->p->update_background_process(); + unsigned int state = this->p->update_background_process(true); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) this->p->view3D->reload_scene(false); // Only restarts if the state is valid.