mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Polishing of NotificationManager:
Fixed pairing of PrintObjects with slicing warning notifications. Removed or commented out dead code. Added documentation.
This commit is contained in:
		
							parent
							
								
									c47d4cdc03
								
							
						
					
					
						commit
						447f4b8303
					
				
					 9 changed files with 89 additions and 68 deletions
				
			
		|  | @ -577,6 +577,16 @@ void Print::config_diffs( | |||
|     } | ||||
| } | ||||
| 
 | ||||
| std::vector<ObjectID> Print::print_object_ids() const  | ||||
| {  | ||||
|     std::vector<ObjectID> out;  | ||||
|     // Reserve one more for the caller to append the ID of the Print itself.
 | ||||
|     out.reserve(m_objects.size() + 1); | ||||
|     for (const PrintObject *print_object : m_objects) | ||||
|         out.emplace_back(print_object->id()); | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
| Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_config) | ||||
| { | ||||
| #ifdef _DEBUG | ||||
|  |  | |||
|  | @ -370,6 +370,8 @@ public: | |||
|     // a cancellation callback is executed to stop the background processing before the operation.
 | ||||
|     void                clear() override; | ||||
|     bool                empty() const override { return m_objects.empty(); } | ||||
|     // List of existing PrintObject IDs, to remove notifications for non-existent IDs.
 | ||||
|     std::vector<ObjectID> print_object_ids() const override; | ||||
| 
 | ||||
|     ApplyStatus         apply(const Model &model, DynamicPrintConfig config) override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -348,6 +348,8 @@ public: | |||
|     // The Print is empty either after clear() or after apply() over an empty model,
 | ||||
|     // or after apply() over a model, where no object is printable (all outside the print volume).
 | ||||
|     virtual bool            empty() const = 0; | ||||
|     // List of existing PrintObject IDs, to remove notifications for non-existent IDs.
 | ||||
|     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(); } | ||||
|  |  | |||
|  | @ -175,6 +175,16 @@ static std::vector<SLAPrintObject::Instance> sla_instances(const ModelObject &mo | |||
|     return instances; | ||||
| } | ||||
| 
 | ||||
| std::vector<ObjectID> SLAPrint::print_object_ids() const  | ||||
| {  | ||||
|     std::vector<ObjectID> out; | ||||
|     // Reserve one more for the caller to append the ID of the Print itself.
 | ||||
|     out.reserve(m_objects.size() + 1); | ||||
|     for (const SLAPrintObject *print_object : m_objects) | ||||
|         out.emplace_back(print_object->id()); | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
| SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig config) | ||||
| { | ||||
| #ifdef _DEBUG | ||||
|  |  | |||
|  | @ -420,6 +420,8 @@ public: | |||
| 
 | ||||
|     void                clear() override; | ||||
|     bool                empty() const override { return m_objects.empty(); } | ||||
|     // List of existing PrintObject IDs, to remove notifications for non-existent IDs.
 | ||||
|     std::vector<ObjectID> print_object_ids() const; | ||||
|     ApplyStatus         apply(const Model &model, DynamicPrintConfig config) override; | ||||
|     void                set_task(const TaskParams ¶ms) override; | ||||
|     void                process() override; | ||||
|  |  | |||
|  | @ -640,16 +640,17 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool | |||
|         error = true; | ||||
|         break; | ||||
|     } | ||||
|     if(state) { | ||||
|     auto ¬ification_manager = *wxGetApp().plater()->get_notification_manager(); | ||||
|     if (state) { | ||||
|         if(error) | ||||
|             wxGetApp().plater()->get_notification_manager()->push_plater_error_notification(text,*(wxGetApp().plater()->get_current_canvas3D())); | ||||
|             notification_manager.push_plater_error_notification(text,*(wxGetApp().plater()->get_current_canvas3D())); | ||||
|         else | ||||
|             wxGetApp().plater()->get_notification_manager()->push_plater_warning_notification(text, *(wxGetApp().plater()->get_current_canvas3D())); | ||||
|             notification_manager.push_plater_warning_notification(text, *(wxGetApp().plater()->get_current_canvas3D())); | ||||
|     } else { | ||||
|         if (error) | ||||
|             wxGetApp().plater()->get_notification_manager()->close_plater_error_notification(text); | ||||
|             notification_manager.close_plater_error_notification(text); | ||||
|         else | ||||
|             wxGetApp().plater()->get_notification_manager()->close_plater_warning_notification(text); | ||||
|             notification_manager.close_plater_warning_notification(text); | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|  |  | |||
|  | @ -625,7 +625,7 @@ void NotificationManager::SlicingCompleteLargeNotification::render_text(ImGuiWra | |||
| 		 | ||||
| 	} | ||||
| } | ||||
| void NotificationManager::SlicingCompleteLargeNotification::set_print_info(std::string info) | ||||
| void NotificationManager::SlicingCompleteLargeNotification::set_print_info(const std::string &info) | ||||
| { | ||||
| 	m_print_info = info; | ||||
| 	m_has_print_info = true; | ||||
|  | @ -679,13 +679,13 @@ void NotificationManager::push_slicing_error_notification(const std::string& tex | |||
| 	push_notification_data({ NotificationType::SlicingError, NotificationLevel::ErrorNotification, 0,  _u8L("ERROR:") + "\n" + text }, canvas, 0); | ||||
| 	close_notification_of_type(NotificationType::SlicingComplete); | ||||
| } | ||||
| void NotificationManager::push_slicing_warning_notification(const std::string& text, bool gray, GLCanvas3D& canvas, size_t oid, int warning_step) | ||||
| void NotificationManager::push_slicing_warning_notification(const std::string& text, bool gray, GLCanvas3D& canvas, ObjectID oid, int warning_step) | ||||
| { | ||||
| 	NotificationData data { NotificationType::SlicingWarning, NotificationLevel::WarningNotification, 0,  _u8L("WARNING:") + "\n" + text }; | ||||
| 
 | ||||
| 	auto notification = std::make_unique<NotificationManager::SlicingWarningNotification>(data, m_id_provider, m_evt_handler); | ||||
| 	notification->set_object_id(oid); | ||||
| 	notification->set_warning_step(warning_step); | ||||
| 	notification->object_id = oid; | ||||
| 	notification->warning_step = warning_step; | ||||
| 	if (push_notification_data(std::move(notification), canvas, 0)) { | ||||
| 		notification->set_gray(gray);		 | ||||
| 	} | ||||
|  | @ -732,6 +732,7 @@ void NotificationManager::set_all_slicing_warnings_gray(bool g) | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| /*
 | ||||
| void NotificationManager::set_slicing_warning_gray(const std::string& text, bool g) | ||||
| { | ||||
| 	for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) { | ||||
|  | @ -740,6 +741,7 @@ void NotificationManager::set_slicing_warning_gray(const std::string& text, bool | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| */ | ||||
| void NotificationManager::close_slicing_errors_and_warnings() | ||||
| { | ||||
| 	for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) { | ||||
|  | @ -752,7 +754,7 @@ void NotificationManager::push_slicing_complete_notification(GLCanvas3D& canvas, | |||
| { | ||||
| 	std::string hypertext; | ||||
| 	int         time = 10; | ||||
|     if (has_error_notification()) | ||||
|     if (has_slicing_error_notification()) | ||||
|         return; | ||||
| 	if (large) { | ||||
| 		hypertext = _u8L("Export G-Code."); | ||||
|  | @ -762,7 +764,7 @@ void NotificationManager::push_slicing_complete_notification(GLCanvas3D& canvas, | |||
| 	push_notification_data(std::make_unique<NotificationManager::SlicingCompleteLargeNotification>(data, m_id_provider, m_evt_handler, large), | ||||
| 		canvas, timestamp); | ||||
| } | ||||
| void NotificationManager::set_slicing_complete_print_time(std::string info) | ||||
| void NotificationManager::set_slicing_complete_print_time(const std::string &info) | ||||
| { | ||||
| 	for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) { | ||||
| 		if (notification->get_type() == NotificationType::SlicingComplete) { | ||||
|  | @ -788,22 +790,14 @@ void NotificationManager::close_notification_of_type(const NotificationType type | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| void NotificationManager::compare_warning_oids(const std::vector<size_t>& living_oids) | ||||
| void NotificationManager::remove_slicing_warnings_of_released_objects(const std::vector<ObjectID>& living_oids) | ||||
| { | ||||
| 	for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) { | ||||
| 	for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) | ||||
| 		if (notification->get_type() == NotificationType::SlicingWarning) { | ||||
| 			auto w = dynamic_cast<SlicingWarningNotification*>(notification.get()); | ||||
| 			bool found = false; | ||||
| 			for (size_t oid : living_oids) { | ||||
| 				if (w->get_object_id() == oid) { | ||||
| 					found = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (!found) | ||||
| 			if (! std::binary_search(living_oids.begin(), living_oids.end(), | ||||
| 				static_cast<SlicingWarningNotification*>(notification.get())->object_id)) | ||||
| 				notification->close(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| bool NotificationManager::push_notification_data(const NotificationData ¬ification_data,  GLCanvas3D& canvas, int timestamp) | ||||
| { | ||||
|  | @ -839,7 +833,7 @@ void NotificationManager::render_notifications(GLCanvas3D& canvas, float overlay | |||
| 	sort_notifications(); | ||||
| 	// iterate thru notifications and render them / erease them
 | ||||
| 	for (auto it = m_pop_notifications.begin(); it != m_pop_notifications.end();) { | ||||
| 		if ((*it)->get_finished()) { | ||||
| 		if (! (*it)->get_finished()) { | ||||
| 			it = m_pop_notifications.erase(it); | ||||
| 		} else { | ||||
| 			(*it)->set_paused(m_hovered); | ||||
|  | @ -885,7 +879,8 @@ void NotificationManager::render_notifications(GLCanvas3D& canvas, float overlay | |||
| 
 | ||||
| void NotificationManager::sort_notifications() | ||||
| { | ||||
| 	std::sort(m_pop_notifications.begin(), m_pop_notifications.end(), [](const std::unique_ptr<PopNotification> &n1, const std::unique_ptr<PopNotification> &n2) { | ||||
| 	// Stable sorting, so that the order of equal ranges is stable.
 | ||||
| 	std::stable_sort(m_pop_notifications.begin(), m_pop_notifications.end(), [](const std::unique_ptr<PopNotification> &n1, const std::unique_ptr<PopNotification> &n2) { | ||||
| 		int n1l = (int)n1->get_data().level; | ||||
| 		int n2l = (int)n2->get_data().level; | ||||
| 		if (n1l == n2l && n1->get_is_gray() && !n2->get_is_gray()) | ||||
|  | @ -907,7 +902,7 @@ bool NotificationManager::find_older(NotificationManager::PopNotification* notif | |||
| 				auto w1 = dynamic_cast<SlicingWarningNotification*>(notification); | ||||
| 				auto w2 = dynamic_cast<SlicingWarningNotification*>(it->get()); | ||||
| 				if (w1 != nullptr && w2 != nullptr) { | ||||
| 					if (!(*it)->compare_text(text) || w1->get_object_id() != w2->get_object_id()) { | ||||
| 					if (!(*it)->compare_text(text) || w1->object_id != w2->object_id) { | ||||
| 						continue; | ||||
| 					} | ||||
| 				} else { | ||||
|  | @ -931,18 +926,11 @@ void NotificationManager::set_in_preview(bool preview) | |||
|             notification->hide(preview);      | ||||
|     } | ||||
| } | ||||
| bool NotificationManager::has_error_notification() | ||||
| bool NotificationManager::has_slicing_error_notification() | ||||
| { | ||||
|     for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) { | ||||
|         if (notification->get_data().level == NotificationLevel::ErrorNotification) | ||||
|             return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void NotificationManager::dpi_changed() | ||||
| { | ||||
| 
 | ||||
| 	return std::any_of(m_pop_notifications.begin(), m_pop_notifications.end(), [](auto &n) { | ||||
|     	return n->get_type() == NotificationType::SlicingError; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| }//namespace GUI
 | ||||
|  |  | |||
|  | @ -4,6 +4,8 @@ | |||
| #include "Event.hpp" | ||||
| #include "I18N.hpp" | ||||
| 
 | ||||
| #include <libslic3r/ObjectID.hpp> | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <deque> | ||||
|  | @ -78,30 +80,37 @@ public: | |||
| 	// creates Slicing Error notification with custom text
 | ||||
| 	void push_slicing_error_notification(const std::string& text, GLCanvas3D& canvas); | ||||
| 	// creates Slicing Warning notification with custom text
 | ||||
| 	void push_slicing_warning_notification(const std::string& text, bool gray, GLCanvas3D& canvas, size_t oid, int warning_step); | ||||
| 	void push_slicing_warning_notification(const std::string& text, bool gray, GLCanvas3D& canvas, ObjectID oid, int warning_step); | ||||
| 	// marks slicing errors as gray
 | ||||
| 	void set_all_slicing_errors_gray(bool g); | ||||
| 	// marks slicing warings as gray
 | ||||
| 	void set_all_slicing_warnings_gray(bool g); | ||||
| 	void set_slicing_warning_gray(const std::string& text, bool g); | ||||
| 	// imidietly stops showing slicing errors
 | ||||
| //	void set_slicing_warning_gray(const std::string& text, bool g);
 | ||||
| 	// immediately stops showing slicing errors
 | ||||
| 	void close_slicing_errors_and_warnings(); | ||||
| 	void compare_warning_oids(const std::vector<size_t>& living_oids); | ||||
| 	// Release those slicing warnings, which refer to an ObjectID, which is not in the list.
 | ||||
| 	// living_oids is expected to be sorted.
 | ||||
| 	void remove_slicing_warnings_of_released_objects(const std::vector<ObjectID>& living_oids); | ||||
| 	// Object partially outside of the printer working space, cannot print.
 | ||||
| 	void push_plater_error_notification(const std::string& text, GLCanvas3D& canvas); | ||||
| 	// Object fully out of the printer working space and such.
 | ||||
| 	void push_plater_warning_notification(const std::string& text, GLCanvas3D& canvas); | ||||
| 	// Closes error or warning of same text
 | ||||
| 	// Closes error or warning of the same text
 | ||||
| 	void close_plater_error_notification(const std::string& text); | ||||
| 	void close_plater_warning_notification(const std::string& text); | ||||
| 	// creates special notification slicing complete
 | ||||
| 	// if large = true prints printing time and export button 
 | ||||
| 	void push_slicing_complete_notification(GLCanvas3D& canvas, int timestamp, bool large); | ||||
| 	void set_slicing_complete_print_time(std::string info); | ||||
| 	// Add a print time estimate to an existing SlicingComplete notification.
 | ||||
| 	void set_slicing_complete_print_time(const std::string &info); | ||||
| 	// Called when the side bar changes its visibility, as the "slicing complete" notification supplements
 | ||||
| 	// the "slicing info" normally shown at the side bar.
 | ||||
| 	void set_slicing_complete_large(bool large); | ||||
| 	// renders notifications in queue and deletes expired ones
 | ||||
| 	void render_notifications(GLCanvas3D& canvas, float overlay_width, float slope_width); | ||||
| 	// finds and closes all notifications of given type
 | ||||
| 	void close_notification_of_type(const NotificationType type); | ||||
| 	void dpi_changed(); | ||||
| 	// Which view is active? Plater or G-code preview? Hide warnings in G-code preview.
 | ||||
|     void set_in_preview(bool preview); | ||||
| 	// Move to left to avoid colision with variable layer height gizmo
 | ||||
| 	void set_move_from_overlay(bool move) { m_move_from_overlay = move; } | ||||
|  | @ -113,8 +122,8 @@ private: | |||
| 		NotificationLevel   level; | ||||
| 		const int           duration; | ||||
| 		const std::string   text1; | ||||
| 		const std::string   hypertext = std::string(); | ||||
| 		const std::string   text2     = std::string(); | ||||
| 		const std::string   hypertext; | ||||
| 		const std::string   text2; | ||||
| 	}; | ||||
| 
 | ||||
| 	// Cache of IDs to identify and reuse ImGUI windows.
 | ||||
|  | @ -190,6 +199,7 @@ private: | |||
| 
 | ||||
| 		const NotificationData m_data; | ||||
| 
 | ||||
| 		// For reusing ImGUI windows.
 | ||||
| 		NotificationIDProvider &m_id_provider; | ||||
| 		int              m_id { 0 }; | ||||
| 		bool			 m_initialized          { false }; | ||||
|  | @ -233,6 +243,7 @@ private: | |||
| 		//if multiline = true, notification is showing all lines(>2)
 | ||||
| 		bool             m_multiline            { false }; | ||||
| 		int              m_lines_count{ 1 }; | ||||
| 	    // Target for wxWidgets events sent by clicking on the hyperlink available at some notifications.
 | ||||
| 		wxEvtHandler*    m_evt_handler; | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -243,7 +254,7 @@ private: | |||
| 		void set_large(bool l); | ||||
| 		bool get_large() { return m_is_large; } | ||||
| 
 | ||||
| 		void set_print_info(std::string info); | ||||
| 		void set_print_info(const std::string &info); | ||||
| 	protected: | ||||
| 		virtual void render_text(ImGuiWrapper& imgui, | ||||
| 			                     const float win_size_x, const float win_size_y, | ||||
|  | @ -259,12 +270,7 @@ private: | |||
| 	{ | ||||
| 	public: | ||||
| 		SlicingWarningNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler) : PopNotification(n, id_provider, evt_handler) {} | ||||
| 		void         set_object_id(size_t id) { object_id = id; } | ||||
| 		const size_t get_object_id() { return object_id; } | ||||
| 		void         set_warning_step(int ws) { warning_step = ws; } | ||||
| 		const int    get_warning_step() { return warning_step; } | ||||
| 	protected: | ||||
| 		size_t object_id; | ||||
| 		ObjectID 	object_id; | ||||
| 		int    		warning_step; | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -274,8 +280,10 @@ private: | |||
| 	bool push_notification_data(std::unique_ptr<NotificationManager::PopNotification> notification, GLCanvas3D& canvas, int timestamp); | ||||
| 	//finds older notification of same type and moves it to the end of queue. returns true if found
 | ||||
| 	bool find_older(NotificationManager::PopNotification* notification); | ||||
| 	// Put the more important notifications to the bottom of the list.
 | ||||
| 	void sort_notifications(); | ||||
|     bool has_error_notification(); | ||||
| 	// If there is some error notification active, then the "Export G-code" notification after the slicing is finished is suppressed.
 | ||||
|     bool has_slicing_error_notification(); | ||||
| 
 | ||||
|     // Target for wxWidgets events sent by clicking on the hyperlink available at some notifications.
 | ||||
| 	wxEvtHandler*                m_evt_handler; | ||||
|  |  | |||
|  | @ -1714,7 +1714,8 @@ struct Plater::priv | |||
| 
 | ||||
| 	void clear_warnings(); | ||||
| 	void add_warning(const Slic3r::PrintStateBase::Warning &warning, size_t oid); | ||||
| 	void actualizate_warnings(const Model& model, size_t print_oid); | ||||
|     // Update notification manager with the current state of warnings produced by the background process (slicing).
 | ||||
| 	void actualize_slicing_warnings(const PrintBase &print); | ||||
| 	// Displays dialog window with list of warnings. 
 | ||||
| 	// Returns true if user clicks OK.
 | ||||
| 	// Returns true if current_warnings vector is empty without showning the dialog
 | ||||
|  | @ -2885,8 +2886,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool | |||
| 
 | ||||
| 	//actualizate warnings
 | ||||
| 	if (invalidated != Print::APPLY_STATUS_UNCHANGED) { | ||||
| 		actualizate_warnings(this->q->model(), this->background_process.current_print()->id().id); | ||||
| 		notification_manager->set_all_slicing_warnings_gray(true); | ||||
| 		actualize_slicing_warnings(*this->background_process.current_print()); | ||||
| 		show_warning_dialog = false; | ||||
| 		process_completed_with_error = false; | ||||
| 	} | ||||
|  | @ -3474,7 +3474,7 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) | |||
|         // Now process state.warnings.
 | ||||
| 		for (auto const& warning : state.warnings) { | ||||
| 			if (warning.current) { | ||||
| 				notification_manager->push_slicing_warning_notification(warning.message, false, *q->get_current_canvas3D(), object_id.id, warning_step); | ||||
| 				notification_manager->push_slicing_warning_notification(warning.message, false, *q->get_current_canvas3D(), object_id, warning_step); | ||||
| 				add_warning(warning, object_id.id); | ||||
| 			} | ||||
| 		} | ||||
|  | @ -3520,19 +3520,17 @@ void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, s | |||
| 	} | ||||
| 	current_warnings.emplace_back(std::pair<Slic3r::PrintStateBase::Warning, size_t>(warning, oid)); | ||||
| } | ||||
| void Plater::priv::actualizate_warnings(const Model& model, size_t print_oid) | ||||
| void Plater::priv::actualize_slicing_warnings(const PrintBase &print) | ||||
| { | ||||
|     if (model.objects.size() == 0) { | ||||
|     std::vector<ObjectID> ids = print.print_object_ids(); | ||||
|     if (ids.empty()) { | ||||
|         clear_warnings(); | ||||
|         return; | ||||
|     } | ||||
| 	std::vector<size_t> living_oids; | ||||
| 	living_oids.push_back(model.id().id); | ||||
| 	living_oids.push_back(print_oid); | ||||
| 	for (auto it = model.objects.begin(); it != model.objects.end(); ++it) { | ||||
| 		living_oids.push_back((*it)->id().id); | ||||
| 	} | ||||
| 	notification_manager->compare_warning_oids(living_oids); | ||||
|     ids.emplace_back(print.id()); | ||||
|     std::sort(ids.begin(), ids.end()); | ||||
| 	notification_manager->remove_slicing_warnings_of_released_objects(ids); | ||||
|     notification_manager->set_all_slicing_warnings_gray(true); | ||||
| } | ||||
| void Plater::priv::clear_warnings() | ||||
| { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik