mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Changed the G-code export and send to OctoPrint GUI code
to store the G-code next to the project file if it exists, and to process the project name with the PlaceholderParser.
This commit is contained in:
		
							parent
							
								
									e358dd9c01
								
							
						
					
					
						commit
						04397c7948
					
				
					 10 changed files with 55 additions and 31 deletions
				
			
		|  | @ -729,7 +729,7 @@ void GCode::_do_export(Print &print, FILE *file) | ||||||
|     // Prepare the helper object for replacing placeholders in custom G-code and output filename.
 |     // Prepare the helper object for replacing placeholders in custom G-code and output filename.
 | ||||||
|     m_placeholder_parser = print.placeholder_parser(); |     m_placeholder_parser = print.placeholder_parser(); | ||||||
|     m_placeholder_parser.update_timestamp(); |     m_placeholder_parser.update_timestamp(); | ||||||
|     print.update_object_placeholders(m_placeholder_parser.config_writable()); |     print.update_object_placeholders(m_placeholder_parser.config_writable(), ".gcode"); | ||||||
| 
 | 
 | ||||||
|     // Get optimal tool ordering to minimize tool switches of a multi-exruder print.
 |     // Get optimal tool ordering to minimize tool switches of a multi-exruder print.
 | ||||||
|     // For a print by objects, find the 1st printing object.
 |     // For a print by objects, find the 1st printing object.
 | ||||||
|  |  | ||||||
|  | @ -1875,12 +1875,12 @@ int Print::get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion | ||||||
| // Generate a recommended G-code output file name based on the format template, default extension, and template parameters
 | // Generate a recommended G-code output file name based on the format template, default extension, and template parameters
 | ||||||
| // (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics.
 | // (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics.
 | ||||||
| // Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before G-code is finalized).
 | // Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before G-code is finalized).
 | ||||||
| std::string Print::output_filename() const  | std::string Print::output_filename(const std::string &filename_base) const  | ||||||
| {  | {  | ||||||
|     // Set the placeholders for the data know first after the G-code export is finished.
 |     // Set the placeholders for the data know first after the G-code export is finished.
 | ||||||
|     // These values will be just propagated into the output file name.
 |     // These values will be just propagated into the output file name.
 | ||||||
|     DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); |     DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); | ||||||
|     return this->PrintBase::output_filename(m_config.output_filename_format.value, "gcode", &config); |     return this->PrintBase::output_filename(m_config.output_filename_format.value, ".gcode", filename_base, &config); | ||||||
| } | } | ||||||
| /*
 | /*
 | ||||||
| // Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
 | // Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
 | ||||||
|  |  | ||||||
|  | @ -351,7 +351,7 @@ public: | ||||||
|     bool                        has_wipe_tower() const; |     bool                        has_wipe_tower() const; | ||||||
|     const WipeTowerData&        wipe_tower_data() const { return m_wipe_tower_data; } |     const WipeTowerData&        wipe_tower_data() const { return m_wipe_tower_data; } | ||||||
| 
 | 
 | ||||||
| 	std::string                 output_filename() const override; | 	std::string                 output_filename(const std::string &filename_base = std::string()) const override; | ||||||
| 
 | 
 | ||||||
|     // Accessed by SupportMaterial
 |     // Accessed by SupportMaterial
 | ||||||
|     const PrintRegion*  get_region(size_t idx) const  { return m_regions[idx]; } |     const PrintRegion*  get_region(size_t idx) const  { return m_regions[idx]; } | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ namespace Slic3r | ||||||
| size_t PrintStateBase::g_last_timestamp = 0; | size_t PrintStateBase::g_last_timestamp = 0; | ||||||
| 
 | 
 | ||||||
| // Update "scale", "input_filename", "input_filename_base" placeholders from the current m_objects.
 | // Update "scale", "input_filename", "input_filename_base" placeholders from the current m_objects.
 | ||||||
| void PrintBase::update_object_placeholders(DynamicConfig &config) const | void PrintBase::update_object_placeholders(DynamicConfig &config, const std::string &default_ext) const | ||||||
| { | { | ||||||
|     // get the first input file name
 |     // get the first input file name
 | ||||||
|     std::string input_file; |     std::string input_file; | ||||||
|  | @ -40,25 +40,29 @@ void PrintBase::update_object_placeholders(DynamicConfig &config) const | ||||||
|     config.set_key_value("year", new ConfigOptionStrings(v_scale)); |     config.set_key_value("year", new ConfigOptionStrings(v_scale)); | ||||||
|     if (! input_file.empty()) { |     if (! input_file.empty()) { | ||||||
|         // get basename with and without suffix
 |         // get basename with and without suffix
 | ||||||
|         const std::string input_basename = boost::filesystem::path(input_file).filename().string(); |         const std::string input_filename = boost::filesystem::path(input_file).filename().string(); | ||||||
|         config.set_key_value("input_filename", new ConfigOptionString(input_basename)); |         const std::string input_filename_base = input_filename.substr(0, input_filename.find_last_of(".")); | ||||||
|         const std::string input_basename_base = input_basename.substr(0, input_basename.find_last_of(".")); |         config.set_key_value("input_filename", new ConfigOptionString(input_filename_base + default_ext)); | ||||||
|         config.set_key_value("input_filename_base", new ConfigOptionString(input_basename_base)); |         config.set_key_value("input_filename_base", new ConfigOptionString(input_filename_base)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Generate an output file name based on the format template, default extension, and template parameters
 | // Generate an output file name based on the format template, default extension, and template parameters
 | ||||||
| // (timestamps, object placeholders derived from the model, current placeholder prameters, print statistics - config_override)
 | // (timestamps, object placeholders derived from the model, current placeholder prameters, print statistics - config_override)
 | ||||||
| std::string PrintBase::output_filename(const std::string &format, const std::string &default_ext, const DynamicConfig *config_override) const | std::string PrintBase::output_filename(const std::string &format, const std::string &default_ext, const std::string &filename_base, const DynamicConfig *config_override) const | ||||||
| { | { | ||||||
|     DynamicConfig cfg; |     DynamicConfig cfg; | ||||||
|     if (config_override != nullptr) |     if (config_override != nullptr) | ||||||
|     	cfg = *config_override; |     	cfg = *config_override; | ||||||
|     PlaceholderParser::update_timestamp(cfg); |     PlaceholderParser::update_timestamp(cfg); | ||||||
|     this->update_object_placeholders(cfg); |     this->update_object_placeholders(cfg, default_ext); | ||||||
|  |     if (! filename_base.empty()) { | ||||||
|  | 		cfg.set_key_value("input_filename", new ConfigOptionString(filename_base + default_ext)); | ||||||
|  | 		cfg.set_key_value("input_filename_base", new ConfigOptionString(filename_base)); | ||||||
|  |     } | ||||||
|     try { |     try { | ||||||
| 		boost::filesystem::path filename = format.empty() ? | 		boost::filesystem::path filename = format.empty() ? | ||||||
| 			cfg.opt_string("input_filename_base") + "." + default_ext : | 			cfg.opt_string("input_filename_base") + default_ext : | ||||||
| 			this->placeholder_parser().process(format, 0, &cfg); | 			this->placeholder_parser().process(format, 0, &cfg); | ||||||
| 		if (filename.extension().empty()) | 		if (filename.extension().empty()) | ||||||
|         	filename = boost::filesystem::change_extension(filename, default_ext); |         	filename = boost::filesystem::change_extension(filename, default_ext); | ||||||
|  | @ -68,17 +72,17 @@ std::string PrintBase::output_filename(const std::string &format, const std::str | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string PrintBase::output_filepath(const std::string &path) const | std::string PrintBase::output_filepath(const std::string &path, const std::string &filename_base) const | ||||||
| { | { | ||||||
|     // if we were supplied no path, generate an automatic one based on our first object's input file
 |     // if we were supplied no path, generate an automatic one based on our first object's input file
 | ||||||
|     if (path.empty()) |     if (path.empty()) | ||||||
|         // get the first input file name
 |         // get the first input file name
 | ||||||
|         return (boost::filesystem::path(m_model.propose_export_file_name_and_path()).parent_path() / this->output_filename()).make_preferred().string(); |         return (boost::filesystem::path(m_model.propose_export_file_name_and_path()).parent_path() / this->output_filename(filename_base)).make_preferred().string(); | ||||||
|      |      | ||||||
|     // if we were supplied a directory, use it and append our automatically generated filename
 |     // if we were supplied a directory, use it and append our automatically generated filename
 | ||||||
|     boost::filesystem::path p(path); |     boost::filesystem::path p(path); | ||||||
|     if (boost::filesystem::is_directory(p)) |     if (boost::filesystem::is_directory(p)) | ||||||
|         return (p / this->output_filename()).make_preferred().string(); |         return (p / this->output_filename(filename_base)).make_preferred().string(); | ||||||
|      |      | ||||||
|     // if we were supplied a file which is not a directory, use it
 |     // if we were supplied a file which is not a directory, use it
 | ||||||
|     return path; |     return path; | ||||||
|  |  | ||||||
|  | @ -318,8 +318,10 @@ public: | ||||||
|     const PlaceholderParser&   placeholder_parser() const { return m_placeholder_parser; } |     const PlaceholderParser&   placeholder_parser() const { return m_placeholder_parser; } | ||||||
|     PlaceholderParser&         placeholder_parser() { return m_placeholder_parser; } |     PlaceholderParser&         placeholder_parser() { return m_placeholder_parser; } | ||||||
| 
 | 
 | ||||||
|     virtual std::string        output_filename() const = 0; |     virtual std::string        output_filename(const std::string &filename_base = std::string()) const = 0; | ||||||
|     std::string                output_filepath(const std::string &path) const; |     // If the filename_base is set, it is used as the input for the template processing. In that case the path is expected to be the directory (may be empty).
 | ||||||
|  |     // If filename_set is empty, than the path may be a file or directory. If it is a file, then the macro will not be processed.
 | ||||||
|  |     std::string                output_filepath(const std::string &path, const std::string &filename_base = std::string()) const; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	friend class PrintObjectBase; | 	friend class PrintObjectBase; | ||||||
|  | @ -334,9 +336,9 @@ protected: | ||||||
|     void                   throw_if_canceled() const { if (m_cancel_status) throw CanceledException(); } |     void                   throw_if_canceled() const { if (m_cancel_status) throw CanceledException(); } | ||||||
| 
 | 
 | ||||||
|     // To be called by this->output_filename() with the format string pulled from the configuration layer.
 |     // To be called by this->output_filename() with the format string pulled from the configuration layer.
 | ||||||
|     std::string            output_filename(const std::string &format, const std::string &default_ext, const DynamicConfig *config_override = nullptr) const; |     std::string            output_filename(const std::string &format, const std::string &default_ext, const std::string &filename_base, const DynamicConfig *config_override = nullptr) const; | ||||||
|     // Update "scale", "input_filename", "input_filename_base" placeholders from the current printable ModelObjects.
 |     // Update "scale", "input_filename", "input_filename_base" placeholders from the current printable ModelObjects.
 | ||||||
|     void                   update_object_placeholders(DynamicConfig &config) const; |     void                   update_object_placeholders(DynamicConfig &config, const std::string &default_ext) const; | ||||||
| 
 | 
 | ||||||
| 	Model                                   m_model; | 	Model                                   m_model; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -561,10 +561,10 @@ void SLAPrint::finalize() | ||||||
| // Generate a recommended output file name based on the format template, default extension, and template parameters
 | // Generate a recommended output file name based on the format template, default extension, and template parameters
 | ||||||
| // (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics.
 | // (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics.
 | ||||||
| // Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before the output is finalized).
 | // Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before the output is finalized).
 | ||||||
| std::string SLAPrint::output_filename() const | std::string SLAPrint::output_filename(const std::string &filename_base) const | ||||||
| { | { | ||||||
|     DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); |     DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); | ||||||
|     return this->PrintBase::output_filename(m_print_config.output_filename_format.value, "sl1", &config); |     return this->PrintBase::output_filename(m_print_config.output_filename_format.value, ".sl1", filename_base, &config); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| namespace { | namespace { | ||||||
|  |  | ||||||
|  | @ -402,7 +402,7 @@ public: | ||||||
|     // Extracted value from the configuration objects
 |     // Extracted value from the configuration objects
 | ||||||
|     Vec3d                       relative_correction() const; |     Vec3d                       relative_correction() const; | ||||||
| 
 | 
 | ||||||
| 	std::string                 output_filename() const override; | 	std::string                 output_filename(const std::string &filename_base = std::string()) const override; | ||||||
| 
 | 
 | ||||||
|     const SLAPrintStatistics&   print_statistics() const { return m_print_statistics; } |     const SLAPrintStatistics&   print_statistics() const { return m_print_statistics; } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -67,6 +67,14 @@ PrinterTechnology BackgroundSlicingProcess::current_printer_technology() const | ||||||
| 	return m_print->technology(); | 	return m_print->technology(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::filesystem::path &project_path) | ||||||
|  | { | ||||||
|  | 	assert(m_print != nullptr); | ||||||
|  |     if (project_path.empty()) | ||||||
|  |         return m_print->output_filepath(""); | ||||||
|  |     return m_print->output_filepath(project_path.parent_path().string(), project_path.stem().string()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // This function may one day be merged into the Print, but historically the print was separated
 | // This function may one day be merged into the Print, but historically the print was separated
 | ||||||
| // from the G-code generator.
 | // from the G-code generator.
 | ||||||
| void BackgroundSlicingProcess::process_fff() | void BackgroundSlicingProcess::process_fff() | ||||||
|  |  | ||||||
|  | @ -6,6 +6,8 @@ | ||||||
| #include <mutex> | #include <mutex> | ||||||
| #include <thread> | #include <thread> | ||||||
| 
 | 
 | ||||||
|  | #include <boost/filesystem.hpp> | ||||||
|  | 
 | ||||||
| #include <wx/event.h> | #include <wx/event.h> | ||||||
| 
 | 
 | ||||||
| #include "libslic3r/Print.hpp" | #include "libslic3r/Print.hpp" | ||||||
|  | @ -65,6 +67,9 @@ public: | ||||||
| 	const PrintBase*    current_print() const { return m_print; } | 	const PrintBase*    current_print() const { return m_print; } | ||||||
| 	const Print* 		fff_print() const { return m_fff_print; } | 	const Print* 		fff_print() const { return m_fff_print; } | ||||||
| 	const SLAPrint* 	sla_print() const { return m_sla_print; } | 	const SLAPrint* 	sla_print() const { return m_sla_print; } | ||||||
|  |     // Take the project path (if provided), extract the name of the project, run it through the macro processor and save it next to the project file.
 | ||||||
|  |     // If the project_path is empty, just run output_filepath().
 | ||||||
|  | 	std::string 		output_filepath_for_project(const boost::filesystem::path &project_path); | ||||||
| 
 | 
 | ||||||
| 	// Start the background processing. Returns false if the background processing was already running.
 | 	// Start the background processing. Returns false if the background processing was already running.
 | ||||||
| 	bool start(); | 	bool start(); | ||||||
|  |  | ||||||
|  | @ -5,9 +5,7 @@ | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <string> | #include <string> | ||||||
| #include <regex> | #include <regex> | ||||||
| #include <boost/algorithm/string/predicate.hpp> | #include <boost/algorithm/string.hpp> | ||||||
| #include <boost/algorithm/string/trim.hpp> |  | ||||||
| #include <boost/algorithm/string/replace.hpp> |  | ||||||
| #include <boost/optional.hpp> | #include <boost/optional.hpp> | ||||||
| #include <boost/filesystem/path.hpp> | #include <boost/filesystem/path.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -2971,9 +2969,16 @@ wxString Plater::priv::get_project_filename(const wxString& extension) const | ||||||
| void Plater::priv::set_project_filename(const wxString& filename) | void Plater::priv::set_project_filename(const wxString& filename) | ||||||
| { | { | ||||||
|     boost::filesystem::path full_path = into_path(filename); |     boost::filesystem::path full_path = into_path(filename); | ||||||
|     // remove extension
 |     boost::filesystem::path ext = full_path.extension(); | ||||||
|     while (full_path.has_extension()) |     if (boost::iequals(ext.string(), ".amf")) { | ||||||
|     { |         // Remove the first extension.
 | ||||||
|  |         full_path.replace_extension(""); | ||||||
|  |         // It may be ".zip.amf".
 | ||||||
|  |         if (boost::iequals(full_path.extension().string(), ".zip")) | ||||||
|  |             // Remove the 2nd extension.
 | ||||||
|  |             full_path.replace_extension(""); | ||||||
|  |     } else { | ||||||
|  |         // Remove just one extension.
 | ||||||
|         full_path.replace_extension(""); |         full_path.replace_extension(""); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -3492,7 +3497,7 @@ void Plater::export_gcode() | ||||||
| 		unsigned int state = this->p->update_restart_background_process(false, false); | 		unsigned int state = this->p->update_restart_background_process(false, false); | ||||||
| 		if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) | 		if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) | ||||||
| 			return; | 			return; | ||||||
|         default_output_file = this->p->background_process.current_print()->output_filepath(into_path(get_project_filename()).string()); |         default_output_file = this->p->background_process.output_filepath_for_project(into_path(get_project_filename(".3mf"))); | ||||||
|     } |     } | ||||||
|     catch (const std::exception &ex) { |     catch (const std::exception &ex) { | ||||||
|         show_error(this, ex.what()); |         show_error(this, ex.what()); | ||||||
|  | @ -3737,7 +3742,7 @@ void Plater::send_gcode() | ||||||
| 		unsigned int state = this->p->update_restart_background_process(false, false); | 		unsigned int state = this->p->update_restart_background_process(false, false); | ||||||
| 		if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) | 		if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) | ||||||
| 			return; | 			return; | ||||||
|         default_output_file = this->p->background_process.current_print()->output_filepath(into_path(get_project_filename(".3mf")).string()); |         default_output_file = this->p->background_process.output_filepath_for_project(into_path(get_project_filename(".3mf"))); | ||||||
|     } |     } | ||||||
|     catch (const std::exception &ex) { |     catch (const std::exception &ex) { | ||||||
|         show_error(this, ex.what()); |         show_error(this, ex.what()); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv