Fix of "macos crash on WipeTower when using multi extruder + tower + support #1632"
Added a new validation into Print::validation() to verify, that the non-soluble supports need to be printed with "current" extruder. This check was already there, though for the global parameters only. Now the check is performed inside the Print class for the object override parameters as well. Improved the Print::validate() handling. The Print::validate() is only called if the Print::apply() indicates a change, or if the slicing was executed by the user explicitely (with the "Slice now" button, with the "Send to octoprint" button, or by switching to the print path preview).
This commit is contained in:
parent
31255d7a41
commit
2b0e1633cf
2 changed files with 29 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue