mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Add a notification when custom support enforcers are not used due to supports being off
It is now emitted from Print::validate and has a hyperlink to enable supports
This commit is contained in:
		
							parent
							
								
									a7255235e5
								
							
						
					
					
						commit
						abd5a9a46e
					
				
					 10 changed files with 89 additions and 11 deletions
				
			
		|  | @ -1245,7 +1245,7 @@ static inline bool sequential_print_vertical_clearance_valid(const Print &print) | |||
| } | ||||
| 
 | ||||
| // Precondition: Print::validate() requires the Print::apply() to be called its invocation.
 | ||||
| std::string Print::validate() const | ||||
| std::string Print::validate(std::string* warning) const | ||||
| { | ||||
|     if (m_objects.empty()) | ||||
|         return L("All objects are outside of the print volume."); | ||||
|  | @ -1440,7 +1440,22 @@ std::string Print::validate() const | |||
|     				} | ||||
|                 } | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             // Do we have custom support data that would not be used?
 | ||||
|             // Notify the user in that case.
 | ||||
|             if (! object->has_support() && warning) { | ||||
|                 for (const ModelVolume* mv : object->model_object()->volumes) { | ||||
|                     bool has_enforcers = mv->is_support_enforcer() | ||||
|                         || (mv->is_model_part() | ||||
|                             && ! mv->supported_facets.empty() | ||||
|                             && ! mv->supported_facets.get_facets(*mv, EnforcerBlockerType::ENFORCER).indices.empty()); | ||||
|                     if (has_enforcers) { | ||||
|                         *warning = "_SUPPORTS_OFF"; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // validate first_layer_height
 | ||||
|             double first_layer_height = object->config().get_abs_value("first_layer_height"); | ||||
|             double first_layer_min_nozzle_diameter; | ||||
|  |  | |||
|  | @ -444,7 +444,7 @@ public: | |||
|     bool                has_brim() const; | ||||
| 
 | ||||
|     // Returns an empty string if valid, otherwise returns an error message.
 | ||||
|     std::string         validate() const override; | ||||
|     std::string         validate(std::string* warning = nullptr) const override; | ||||
|     double              skirt_first_layer_height() const; | ||||
|     Flow                brim_flow() const; | ||||
|     Flow                skirt_flow() const; | ||||
|  |  | |||
|  | @ -366,7 +366,7 @@ public: | |||
|     virtual std::vector<ObjectID> print_object_ids() const = 0; | ||||
| 
 | ||||
|     // Validate the print, return empty string if valid, return error if process() cannot (or should not) be started.
 | ||||
|     virtual std::string     validate() const { return std::string(); } | ||||
|     virtual std::string     validate(std::string* warning = nullptr) const { return std::string(); } | ||||
| 
 | ||||
|     enum ApplyStatus { | ||||
|         // No change after the Print::apply() call.
 | ||||
|  |  | |||
|  | @ -430,6 +430,24 @@ void PrintObject::generate_support_material() | |||
|                 if (layer->empty()) | ||||
|                     throw Slic3r::SlicingError("Levitating objects cannot be printed without supports."); | ||||
| #endif | ||||
| 
 | ||||
|             // Do we have custom support data that would not be used?
 | ||||
|             // Notify the user in that case.
 | ||||
|             if (! this->has_support()) { | ||||
|                 for (const ModelVolume* mv : this->model_object()->volumes) { | ||||
|                     bool has_enforcers = mv->is_support_enforcer() | ||||
|                         || (mv->is_model_part() | ||||
|                             && ! mv->supported_facets.empty() | ||||
|                             && ! mv->supported_facets.get_facets(*mv, EnforcerBlockerType::ENFORCER).indices.empty()); | ||||
|                     if (has_enforcers) { | ||||
|                         this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, | ||||
|                             L("An object has custom support enforcers which will not be used " | ||||
|                               "because supports are off. Consider turning them on.") + "\n" + | ||||
|                             (L("Object name")) + ": " + this->model_object()->name); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         this->set_done(posSupportMaterial); | ||||
|     } | ||||
|  |  | |||
|  | @ -617,7 +617,7 @@ std::string SLAPrint::output_filename(const std::string &filename_base) const | |||
|     return this->PrintBase::output_filename(m_print_config.output_filename_format.value, ".sl1", filename_base, &config); | ||||
| } | ||||
| 
 | ||||
| std::string SLAPrint::validate() const | ||||
| std::string SLAPrint::validate(std::string*) const | ||||
| { | ||||
|     for(SLAPrintObject * po : m_objects) { | ||||
| 
 | ||||
|  |  | |||
|  | @ -458,7 +458,7 @@ public: | |||
| 
 | ||||
|     const SLAPrintStatistics&   print_statistics() const { return m_print_statistics; } | ||||
| 
 | ||||
|     std::string validate() const override; | ||||
|     std::string validate(std::string* warning = nullptr) const override; | ||||
| 
 | ||||
|     // An aggregation of SliceRecord-s from all the print objects for each
 | ||||
|     // occupied layer. Slice record levels dont have to match exactly.
 | ||||
|  |  | |||
|  | @ -430,10 +430,10 @@ bool BackgroundSlicingProcess::empty() const | |||
| 	return m_print->empty(); | ||||
| } | ||||
| 
 | ||||
| std::string BackgroundSlicingProcess::validate() | ||||
| std::string BackgroundSlicingProcess::validate(std::string* warning) | ||||
| { | ||||
| 	assert(m_print != nullptr); | ||||
| 	return m_print->validate(); | ||||
|     return m_print->validate(warning); | ||||
| } | ||||
| 
 | ||||
| // Apply config over the print. Returns false, if the new config values caused any of the already
 | ||||
|  |  | |||
|  | @ -131,7 +131,7 @@ public: | |||
| 	bool 		empty() const; | ||||
| 	// Validate the print. Returns an empty string if valid, returns an error message if invalid.
 | ||||
| 	// Call validate before calling start().
 | ||||
| 	std::string validate(); | ||||
|     std::string validate(std::string* warning = nullptr); | ||||
| 
 | ||||
| 	// Set the export path of the G-code.
 | ||||
| 	// Once the path is set, the G-code 
 | ||||
|  |  | |||
|  | @ -71,7 +71,9 @@ enum class NotificationType | |||
|     // Notification that custom supports/seams were deleted after mesh repair.
 | ||||
|     CustomSupportsAndSeamRemovedAfterRepair, | ||||
|     // Notification that auto adding of color changes is impossible
 | ||||
| 	EmptyAutoColorChange | ||||
|     EmptyAutoColorChange, | ||||
|     // Notification emitted by Print::validate
 | ||||
|     PrintValidateWarning | ||||
| }; | ||||
| 
 | ||||
| class NotificationManager | ||||
|  |  | |||
|  | @ -1599,6 +1599,8 @@ struct Plater::priv | |||
|     void suppress_snapshots()   { this->m_prevent_snapshots++; } | ||||
|     void allow_snapshots()      { this->m_prevent_snapshots--; } | ||||
| 
 | ||||
|     void process_validation_warning(const std::string& warning) const; | ||||
| 
 | ||||
|     bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } | ||||
|     void update_print_volume_state(); | ||||
|     void schedule_background_process(); | ||||
|  | @ -2787,6 +2789,41 @@ void Plater::priv::update_print_volume_state() | |||
|     this->q->model().update_print_volume_state(print_volume); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void Plater::priv::process_validation_warning(const std::string& warning) const | ||||
| { | ||||
|     if (warning.empty()) | ||||
|         notification_manager->close_notification_of_type(NotificationType::PrintValidateWarning); | ||||
|     else { | ||||
|         std::string text = warning; | ||||
|         std::string hypertext = ""; | ||||
|         std::function<bool(wxEvtHandler*)> action_fn = [](wxEvtHandler*){ return false; }; | ||||
| 
 | ||||
|         if (text == "_SUPPORTS_OFF") { | ||||
|             text = _u8L("An object has custom support enforcers which will not be used " | ||||
|                         "because supports are disabled.")+"\n"; | ||||
|             hypertext = _u8L("Enable supports for enforcers only"); | ||||
|             action_fn = [](wxEvtHandler*) { | ||||
|                 Tab* print_tab = wxGetApp().get_tab(Preset::TYPE_PRINT); | ||||
|                 assert(print_tab); | ||||
|                 DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; | ||||
|                 config.set_key_value("support_material", new ConfigOptionBool(true)); | ||||
|                 config.set_key_value("support_material_auto", new ConfigOptionBool(false)); | ||||
|                 print_tab->on_value_change("support_material", config.opt_bool("support_material")); | ||||
|                 print_tab->on_value_change("support_material_auto", config.opt_bool("support_material_auto")); | ||||
|                 return true; | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         notification_manager->push_notification( | ||||
|             NotificationType::PrintValidateWarning, | ||||
|             NotificationManager::NotificationLevel::ImportantNotification, | ||||
|             text, hypertext, action_fn | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Update background processing thread from the current config and Model.
 | ||||
| // Returns a bitmask of UpdateBackgroundProcessReturnState.
 | ||||
| unsigned int Plater::priv::update_background_process(bool force_validation, bool postpone_error_messages) | ||||
|  | @ -2829,17 +2866,23 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool | |||
| 		// The delayed error message is no more valid.
 | ||||
| 		this->delayed_error_message.clear(); | ||||
| 		// 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(); | ||||
|         std::string warning; | ||||
|         std::string err = this->background_process.validate(&warning); | ||||
|         if (err.empty()) { | ||||
| 			notification_manager->set_all_slicing_errors_gray(true); | ||||
|             if (invalidated != Print::APPLY_STATUS_UNCHANGED && this->background_processing_enabled()) | ||||
|                 return_state |= UPDATE_BACKGROUND_PROCESS_RESTART; | ||||
| 
 | ||||
|             // Pass a warning from validation and either show a notification,
 | ||||
|             // or hide the old one.
 | ||||
|             process_validation_warning(warning); | ||||
|         } else { | ||||
| 			// The print is not valid.
 | ||||
| 			// Show error as notification.
 | ||||
|             notification_manager->push_slicing_error_notification(err); | ||||
|             return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; | ||||
|         } | ||||
| 
 | ||||
|     } else if (! this->delayed_error_message.empty()) { | ||||
|     	// Reusing the old state.
 | ||||
|         return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena