mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Synchronized mode of color_print data to/from 3mf/amf
+ Code refactoring " CustomGCode extracted to separate namespace and file
This commit is contained in:
		
							parent
							
								
									3d9ac0ada1
								
							
						
					
					
						commit
						1ed313ab79
					
				
					 19 changed files with 247 additions and 132 deletions
				
			
		|  | @ -114,6 +114,8 @@ add_library(libslic3r STATIC | |||
|     Line.hpp | ||||
|     Model.cpp | ||||
|     Model.hpp | ||||
|     CustomGCode.cpp | ||||
|     CustomGCode.hpp | ||||
|     Arrange.hpp | ||||
|     Arrange.cpp | ||||
|     MotionPlanner.cpp | ||||
|  |  | |||
							
								
								
									
										72
									
								
								src/libslic3r/CustomGCode.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/libslic3r/CustomGCode.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | |||
| #include "CustomGCode.hpp" | ||||
| #include "Config.hpp" | ||||
| #include "GCode/PreviewData.hpp" | ||||
| #include "GCodeWriter.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| namespace CustomGCode { | ||||
| 
 | ||||
| // If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), 
 | ||||
| // and if CustomGCode::Info.gcodes is empty (there is no color print data available in a new format
 | ||||
| // then CustomGCode::Info.gcodes should be updated considering this option.
 | ||||
| extern void update_custom_gcode_per_print_z_from_config(Info& info, DynamicPrintConfig* config) | ||||
| { | ||||
| 	auto *colorprint_heights = config->option<ConfigOptionFloats>("colorprint_heights"); | ||||
|     if (colorprint_heights == nullptr) | ||||
|         return; | ||||
|     if (info.gcodes.empty() && ! colorprint_heights->values.empty()) { | ||||
| 		// Convert the old colorprint_heighs only if there is no equivalent data in a new format.
 | ||||
| 	    const std::vector<std::string>& colors = GCodePreviewData::ColorPrintColors(); | ||||
| 	    const auto& colorprint_values = colorprint_heights->values; | ||||
|         info.gcodes.clear(); | ||||
|         info.gcodes.reserve(colorprint_values.size()); | ||||
|         int i = 0; | ||||
|         for (auto val : colorprint_values) | ||||
|             info.gcodes.emplace_back(Item{ val, ColorChangeCode, 1, colors[(++i)%7] }); | ||||
| 
 | ||||
|         info.mode = SingleExtruder; | ||||
| 	} | ||||
| 
 | ||||
| 	// The "colorprint_heights" config value has been deprecated. At this point of time it has been converted
 | ||||
| 	// to a new format and therefore it shall be erased.
 | ||||
|     config->erase("colorprint_heights"); | ||||
| } | ||||
| 
 | ||||
| // If information for custom Gcode per print Z was imported from older Slicer, mode will be undefined.
 | ||||
| // So, we should set CustomGCode::Info.mode should be updated considering code values from items.
 | ||||
| extern void check_mode_for_custom_gcode_per_print_z(Info& info) | ||||
| { | ||||
|     if (info.mode != Undef) | ||||
|         return; | ||||
| 
 | ||||
|     bool is_single_extruder = true; | ||||
|     for (auto item : info.gcodes)  | ||||
|     { | ||||
|         if (item.gcode == ToolChangeCode) { | ||||
|             info.mode = MultiAsSingle; | ||||
|             return; | ||||
|         } | ||||
|         if (item.gcode == ColorChangeCode && item.extruder > 1) | ||||
|             is_single_extruder = false; | ||||
|     } | ||||
| 
 | ||||
|     info.mode = is_single_extruder ? SingleExtruder : MultiExtruder; | ||||
| } | ||||
| 
 | ||||
| // Return pairs of <print_z, 1-based extruder ID> sorted by increasing print_z from custom_gcode_per_print_z.
 | ||||
| // print_z corresponds to the first layer printed with the new extruder.
 | ||||
| std::vector<std::pair<double, unsigned int>> custom_tool_changes(const Info& custom_gcode_per_print_z, size_t num_extruders) | ||||
| { | ||||
|     std::vector<std::pair<double, unsigned int>> custom_tool_changes; | ||||
|     for (const Item& custom_gcode : custom_gcode_per_print_z.gcodes) | ||||
|         if (custom_gcode.gcode == ToolChangeCode) { | ||||
|             // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders
 | ||||
|             custom_tool_changes.emplace_back(custom_gcode.print_z, static_cast<unsigned int>(custom_gcode.extruder > num_extruders ? 1 : custom_gcode.extruder)); | ||||
|         } | ||||
|     return custom_tool_changes; | ||||
| } | ||||
| 
 | ||||
| } // namespace CustomGCode
 | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
							
								
								
									
										81
									
								
								src/libslic3r/CustomGCode.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/libslic3r/CustomGCode.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,81 @@ | |||
| #ifndef slic3r_CustomGCode_hpp_ | ||||
| #define slic3r_CustomGCode_hpp_ | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| class DynamicPrintConfig; | ||||
| 
 | ||||
| namespace CustomGCode { | ||||
| 
 | ||||
| struct Item | ||||
| { | ||||
|     bool operator<(const Item& rhs) const { return this->print_z < rhs.print_z; } | ||||
|     bool operator==(const Item& rhs) const | ||||
|     { | ||||
|         return (rhs.print_z   == this->print_z    ) && | ||||
|                (rhs.gcode     == this->gcode      ) && | ||||
|                (rhs.extruder  == this->extruder   ) && | ||||
|                (rhs.color     == this->color      ); | ||||
|     } | ||||
|     bool operator!=(const Item& rhs) const { return ! (*this == rhs); } | ||||
|      | ||||
|     double      print_z; | ||||
|     std::string gcode; | ||||
|     int         extruder;   // Informative value for ColorChangeCode and ToolChangeCode
 | ||||
|                             // "gcode" == ColorChangeCode   => M600 will be applied for "extruder" extruder
 | ||||
|                             // "gcode" == ToolChangeCode    => for whole print tool will be switched to "extruder" extruder
 | ||||
|     std::string color;      // if gcode is equal to PausePrintCode, 
 | ||||
|                             // this field is used for save a short message shown on Printer display 
 | ||||
| }; | ||||
| 
 | ||||
| enum Mode | ||||
| { | ||||
|     Undef, | ||||
|     SingleExtruder,   // Single extruder printer preset is selected
 | ||||
|     MultiAsSingle,    // Multiple extruder printer preset is selected, but 
 | ||||
|                       // this mode works just for Single extruder print 
 | ||||
|                       // (For all print from objects settings is used just one extruder) 
 | ||||
|     MultiExtruder     // Multiple extruder printer preset is selected
 | ||||
| }; | ||||
| 
 | ||||
| // string anlogue of custom_code_per_height mode
 | ||||
| static constexpr char SingleExtruderMode[] = "SingleExtruder"; | ||||
| static constexpr char MultiAsSingleMode [] = "MultiAsSingle"; | ||||
| static constexpr char MultiExtruderMode [] = "MultiExtruder"; | ||||
| 
 | ||||
| struct Info | ||||
| { | ||||
|     Mode mode = Undef; | ||||
|     std::vector<Item> gcodes; | ||||
| 
 | ||||
|     bool operator==(const Info& rhs) const | ||||
|     { | ||||
|         return  (rhs.mode   == this->mode   ) && | ||||
|                 (rhs.gcodes == this->gcodes ); | ||||
|     } | ||||
|     bool operator!=(const Info& rhs) const { return !(*this == rhs); } | ||||
| }; | ||||
| 
 | ||||
| // If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), 
 | ||||
| // and if CustomGCode::Info.gcodes is empty (there is no color print data available in a new format
 | ||||
| // then CustomGCode::Info.gcodes should be updated considering this option.
 | ||||
| extern void update_custom_gcode_per_print_z_from_config(Info& info, DynamicPrintConfig* config); | ||||
| 
 | ||||
| // If information for custom Gcode per print Z was imported from older Slicer, mode will be undefined.
 | ||||
| // So, we should set CustomGCode::Info.mode should be updated considering code values from items.
 | ||||
| extern void check_mode_for_custom_gcode_per_print_z(Info& info); | ||||
| 
 | ||||
| // Return pairs of <print_z, 1-based extruder ID> sorted by increasing print_z from custom_gcode_per_print_z.
 | ||||
| // print_z corresponds to the first layer printed with the new extruder.
 | ||||
| std::vector<std::pair<double, unsigned int>> custom_tool_changes(const Info& custom_gcode_per_print_z, size_t num_extruders); | ||||
| 
 | ||||
| } // namespace CustomGCode
 | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif /* slic3r_CustomGCode_hpp_ */ | ||||
|  | @ -1092,6 +1092,14 @@ namespace Slic3r { | |||
| 
 | ||||
|             for (const auto& code : code_tree) | ||||
|             { | ||||
|                 if (code.first == "mode") | ||||
|                 { | ||||
|                     pt::ptree tree = code.second; | ||||
|                     std::string mode = tree.get<std::string>("<xmlattr>.value"); | ||||
|                     m_model->custom_gcode_per_print_z.mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder : | ||||
|                                                              mode == CustomGCode::MultiAsSingleMode  ? CustomGCode::Mode::MultiAsSingle  : | ||||
|                                                              CustomGCode::Mode::MultiExtruder; | ||||
|                 } | ||||
|                 if (code.first != "code") | ||||
|                     continue; | ||||
|                 pt::ptree tree = code.second; | ||||
|  | @ -1100,7 +1108,7 @@ namespace Slic3r { | |||
|                 int extruder        = tree.get<int>         ("<xmlattr>.extruder"   ); | ||||
|                 std::string color   = tree.get<std::string> ("<xmlattr>.color"      ); | ||||
| 
 | ||||
|                 m_model->custom_gcode_per_print_z.gcodes.push_back(Model::CustomGCode{print_z, gcode, extruder, color}) ; | ||||
|                 m_model->custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, gcode, extruder, color}) ; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -2615,7 +2623,7 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv | |||
|         pt::ptree tree; | ||||
|         pt::ptree& main_tree = tree.add("custom_gcodes_per_print_z", ""); | ||||
| 
 | ||||
|         for (const Model::CustomGCode& code : model.custom_gcode_per_print_z.gcodes) | ||||
|         for (const CustomGCode::Item& code : model.custom_gcode_per_print_z.gcodes) | ||||
|         { | ||||
|             pt::ptree& code_tree = main_tree.add("code", ""); | ||||
|             // store minX and maxZ
 | ||||
|  | @ -2623,7 +2631,13 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv | |||
|             code_tree.put("<xmlattr>.gcode"     , code.gcode    ); | ||||
|             code_tree.put("<xmlattr>.extruder"  , code.extruder ); | ||||
|             code_tree.put("<xmlattr>.color"     , code.color    ); | ||||
|         }        | ||||
|         } | ||||
| 
 | ||||
|         pt::ptree& mode_tree = main_tree.add("mode", ""); | ||||
|         // store mode of a custom_gcode_per_print_z 
 | ||||
|         mode_tree.put("<xmlattr>.value", model.custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode : | ||||
|                                          model.custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle ?  CustomGCode::MultiAsSingleMode : | ||||
|                                          CustomGCode::MultiExtruderMode); | ||||
| 
 | ||||
|         if (!tree.empty()) | ||||
|         { | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ | |||
| #include "../Utils.hpp" | ||||
| #include "../I18N.hpp" | ||||
| #include "../Geometry.hpp" | ||||
| #include "../CustomGCode.hpp" | ||||
| 
 | ||||
| #include "AMF.hpp" | ||||
| 
 | ||||
|  | @ -156,6 +157,7 @@ struct AMFParserContext | |||
|         NODE_TYPE_PRINTABLE,            // amf/constellation/instance/mirrorz
 | ||||
|         NODE_TYPE_CUSTOM_GCODE,         // amf/custom_code_per_height
 | ||||
|         NODE_TYPE_GCODE_PER_HEIGHT,     // amf/custom_code_per_height/code
 | ||||
|         NODE_TYPE_CUSTOM_GCODE_MODE,    // amf/custom_code_per_height/mode
 | ||||
|         NODE_TYPE_METADATA,             // anywhere under amf/*/metadata
 | ||||
|     }; | ||||
| 
 | ||||
|  | @ -308,12 +310,18 @@ void AMFParserContext::startElement(const char *name, const char **atts) | |||
|             else | ||||
|                 this->stop(); | ||||
|         }  | ||||
|         else if (strcmp(name, "code") == 0 && m_path[1] == NODE_TYPE_CUSTOM_GCODE) { | ||||
|             node_type_new = NODE_TYPE_GCODE_PER_HEIGHT; | ||||
|             m_value[0] = get_attribute(atts, "height"); | ||||
|             m_value[1] = get_attribute(atts, "gcode"); | ||||
|             m_value[2] = get_attribute(atts, "extruder"); | ||||
|             m_value[3] = get_attribute(atts, "color"); | ||||
|         else if (m_path[1] == NODE_TYPE_CUSTOM_GCODE) { | ||||
|             if (strcmp(name, "code") == 0) { | ||||
|                 node_type_new = NODE_TYPE_GCODE_PER_HEIGHT; | ||||
|                 m_value[0] = get_attribute(atts, "print_z"); | ||||
|                 m_value[1] = get_attribute(atts, "gcode"); | ||||
|                 m_value[2] = get_attribute(atts, "extruder"); | ||||
|                 m_value[3] = get_attribute(atts, "color"); | ||||
|             } | ||||
|             else if (strcmp(name, "mode") == 0) { | ||||
|                 node_type_new = NODE_TYPE_CUSTOM_GCODE_MODE; | ||||
|                 m_value[0] = get_attribute(atts, "value"); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
|     case 3: | ||||
|  | @ -632,18 +640,29 @@ void AMFParserContext::endElement(const char * /* name */) | |||
|         break; | ||||
| 
 | ||||
|     case NODE_TYPE_GCODE_PER_HEIGHT: { | ||||
|         double height = double(atof(m_value[0].c_str())); | ||||
|         double print_z = double(atof(m_value[0].c_str())); | ||||
|         const std::string& gcode = m_value[1]; | ||||
|         int extruder = atoi(m_value[2].c_str()); | ||||
|         const std::string& color = m_value[3]; | ||||
| 
 | ||||
|         m_model.custom_gcode_per_print_z.gcodes.push_back(Model::CustomGCode{height, gcode, extruder, color}); | ||||
|         m_model.custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, gcode, extruder, color}); | ||||
| 
 | ||||
|         for (std::string& val: m_value) | ||||
|             val.clear(); | ||||
|         break; | ||||
|         } | ||||
| 
 | ||||
|     case NODE_TYPE_CUSTOM_GCODE_MODE: { | ||||
|         const std::string& mode = m_value[0]; | ||||
| 
 | ||||
|         m_model.custom_gcode_per_print_z.mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder : | ||||
|                                                 mode == CustomGCode::MultiAsSingleMode  ? CustomGCode::Mode::MultiAsSingle  : | ||||
|                                                                                           CustomGCode::Mode::MultiExtruder; | ||||
|         for (std::string& val: m_value) | ||||
|             val.clear(); | ||||
|         break; | ||||
|         } | ||||
| 
 | ||||
|     case NODE_TYPE_METADATA: | ||||
|         if ((m_config != nullptr) && strncmp(m_value[0].c_str(), SLIC3R_CONFIG_TYPE, strlen(SLIC3R_CONFIG_TYPE)) == 0) | ||||
|             m_config->load_from_gcode_string(m_value[1].c_str()); | ||||
|  | @ -1237,16 +1256,23 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) | |||
| 
 | ||||
|         pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); | ||||
| 
 | ||||
|         for (const Model::CustomGCode& code : model->custom_gcode_per_print_z.gcodes) | ||||
|         for (const CustomGCode::Item& code : model->custom_gcode_per_print_z.gcodes) | ||||
|         { | ||||
|             pt::ptree& code_tree = main_tree.add("code", ""); | ||||
|             // store minX and maxZ
 | ||||
|             // store custom_gcode_per_print_z gcodes information 
 | ||||
|             code_tree.put("<xmlattr>.print_z"   , code.print_z  ); | ||||
|             code_tree.put("<xmlattr>.gcode"     , code.gcode    ); | ||||
|             code_tree.put("<xmlattr>.extruder"  , code.extruder ); | ||||
|             code_tree.put("<xmlattr>.color"     , code.color    ); | ||||
|         } | ||||
| 
 | ||||
|         pt::ptree& mode_tree = main_tree.add("mode", ""); | ||||
|         // store mode of a custom_gcode_per_print_z 
 | ||||
|         mode_tree.put("<xmlattr>.value",  | ||||
|                       model->custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode :  | ||||
|                       model->custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle  ? | ||||
|                       CustomGCode::MultiAsSingleMode  : CustomGCode::MultiExtruderMode); | ||||
| 
 | ||||
|         if (!tree.empty()) | ||||
|         { | ||||
|             std::ostringstream oss; | ||||
|  | @ -1259,6 +1285,7 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) | |||
| 
 | ||||
|             // Post processing("beautification") of the output string
 | ||||
|             boost::replace_all(out, "><code", ">\n  <code"); | ||||
|             boost::replace_all(out, "><mode", ">\n  <mode"); | ||||
|             boost::replace_all(out, "><", ">\n<"); | ||||
| 
 | ||||
|             stream << out << "\n"; | ||||
|  |  | |||
|  | @ -1767,7 +1767,7 @@ namespace ProcessLayer | |||
| { | ||||
| 
 | ||||
|     static std::string emit_custom_gcode_per_print_z( | ||||
|     	const Model::CustomGCode 								*custom_gcode, | ||||
|     	const CustomGCode::Item 								*custom_gcode, | ||||
|         // ID of the first extruder printing this layer.
 | ||||
|         unsigned int                                             first_extruder_id, | ||||
| 		bool  											         single_material_print) | ||||
|  |  | |||
|  | @ -133,7 +133,7 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool | |||
| 		num_extruders > 1 && print.object_extruders().size() == 1) { | ||||
| 		// Printing a single extruder platter on a printer with more than 1 extruder (or single-extruder multi-material).
 | ||||
| 		// There may be custom per-layer tool changes available at the model.
 | ||||
| 		per_layer_extruder_switches = custom_tool_changes(print.model(), num_extruders); | ||||
| 		per_layer_extruder_switches = custom_tool_changes(print.model().custom_gcode_per_print_z, num_extruders); | ||||
| 	} | ||||
| 
 | ||||
|     // Collect extruders reuqired to print the layers.
 | ||||
|  | @ -462,7 +462,7 @@ void ToolOrdering::assign_custom_gcodes(const Print &print) | |||
| 	// Only valid for non-sequential print.
 | ||||
| 	assert(! print.config().complete_objects.value); | ||||
| 
 | ||||
| 	const Model::CustomGCodeInfo	&custom_gcode_per_print_z = print.model().custom_gcode_per_print_z; | ||||
| 	const CustomGCode::Info	&custom_gcode_per_print_z = print.model().custom_gcode_per_print_z; | ||||
| 	if (custom_gcode_per_print_z.gcodes.empty()) | ||||
| 		return; | ||||
| 
 | ||||
|  | @ -483,7 +483,7 @@ void ToolOrdering::assign_custom_gcodes(const Print &print) | |||
| 			// Custom G-codes were processed.
 | ||||
| 			break; | ||||
| 		// Some custom G-code is configured for this layer or a layer below.
 | ||||
| 		const Model::CustomGCode &custom_gcode = *custom_gcode_it; | ||||
| 		const CustomGCode::Item &custom_gcode = *custom_gcode_it; | ||||
| 		// print_z of the layer below the current layer.
 | ||||
| 		coordf_t print_z_below = 0.; | ||||
| 		if (auto it_lt_below = it_lt; ++ it_lt_below != m_layer_tools.rend()) | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ public: | |||
|     size_t                      wipe_tower_partitions = 0; | ||||
|     coordf_t 					wipe_tower_layer_height = 0.; | ||||
|     // Custom G-code (color change, extruder switch, pause) to be performed before this layer starts to print.
 | ||||
|     const Model::CustomGCode   *custom_gcode = nullptr; | ||||
|     const CustomGCode::Item    *custom_gcode = nullptr; | ||||
| 
 | ||||
|     WipingExtrusions& wiping_extrusions() { | ||||
|         m_wiping_extrusions.set_layer_tools_ptr(this); | ||||
|  |  | |||
|  | @ -126,7 +126,8 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c | |||
|     if (add_default_instances) | ||||
|         model.add_default_instances(); | ||||
| 
 | ||||
|     update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z.gcodes, config); | ||||
|     CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); | ||||
|     CustomGCode::check_mode_for_custom_gcode_per_print_z(model.custom_gcode_per_print_z); | ||||
| 
 | ||||
|     return model; | ||||
| } | ||||
|  | @ -163,7 +164,8 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig | |||
|     if (add_default_instances) | ||||
|         model.add_default_instances(); | ||||
| 
 | ||||
|     update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z.gcodes, config); | ||||
|     CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); | ||||
|     CustomGCode::check_mode_for_custom_gcode_per_print_z(model.custom_gcode_per_print_z); | ||||
| 
 | ||||
|     return model; | ||||
| } | ||||
|  | @ -1841,19 +1843,6 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon() const | |||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| // Return pairs of <print_z, 1-based extruder ID> sorted by increasing print_z from custom_gcode_per_print_z.
 | ||||
| // print_z corresponds to the first layer printed with the new extruder.
 | ||||
| std::vector<std::pair<double, unsigned int>> custom_tool_changes(const Model &model, size_t num_extruders) | ||||
| { | ||||
|     std::vector<std::pair<double, unsigned int>> custom_tool_changes; | ||||
|     for (const Model::CustomGCode &custom_gcode : model.custom_gcode_per_print_z.gcodes) | ||||
|         if (custom_gcode.gcode == ToolChangeCode) { | ||||
|             // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders
 | ||||
|             custom_tool_changes.emplace_back(custom_gcode.print_z, static_cast<unsigned int>(custom_gcode.extruder > num_extruders ? 1 : custom_gcode.extruder)); | ||||
|         } | ||||
|     return custom_tool_changes; | ||||
| } | ||||
| 
 | ||||
| // Test whether the two models contain the same number of ModelObjects with the same set of IDs
 | ||||
| // ordered in the same order. In that case it is not necessary to kill the background processing.
 | ||||
| bool model_object_list_equal(const Model &model_old, const Model &model_new) | ||||
|  | @ -1942,28 +1931,6 @@ extern bool model_has_advanced_features(const Model &model) | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| extern void update_custom_gcode_per_print_z_from_config(std::vector<Model::CustomGCode>& custom_gcode_per_print_z, DynamicPrintConfig* config) | ||||
| { | ||||
| 	auto *colorprint_heights = config->option<ConfigOptionFloats>("colorprint_heights"); | ||||
|     if (colorprint_heights == nullptr) | ||||
|         return; | ||||
| 
 | ||||
| 	if (custom_gcode_per_print_z.empty() && ! colorprint_heights->values.empty()) { | ||||
| 		// Convert the old colorprint_heighs only if there is no equivalent data in a new format.
 | ||||
| 	    const std::vector<std::string>& colors = GCodePreviewData::ColorPrintColors(); | ||||
| 	    const auto& colorprint_values = colorprint_heights->values; | ||||
|         custom_gcode_per_print_z.clear(); | ||||
|         custom_gcode_per_print_z.reserve(colorprint_values.size()); | ||||
|         int i = 0; | ||||
|         for (auto val : colorprint_values) | ||||
|             custom_gcode_per_print_z.emplace_back(Model::CustomGCode{ val, ColorChangeCode, 1, colors[(++i)%7] }); | ||||
| 	} | ||||
| 
 | ||||
| 	// The "colorprint_heights" config value has been deprecated. At this point of time it has been converted
 | ||||
| 	// to a new format and therefore it shall be erased.
 | ||||
|     config->erase("colorprint_heights"); | ||||
| } | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | ||||
| void check_model_ids_validity(const Model &model) | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
| #include "SLA/SLACommon.hpp" | ||||
| #include "TriangleMesh.hpp" | ||||
| #include "Arrange.hpp" | ||||
| #include "CustomGCode.hpp" | ||||
| 
 | ||||
| #include <map> | ||||
| #include <memory> | ||||
|  | @ -749,48 +750,7 @@ public: | |||
|     ModelWipeTower	    wipe_tower; | ||||
| 
 | ||||
|     // Extensions for color print
 | ||||
|     struct CustomGCode | ||||
|     { | ||||
|         bool operator<(const CustomGCode& rhs) const { return this->print_z < rhs.print_z; } | ||||
|         bool operator==(const CustomGCode& rhs) const | ||||
|         { | ||||
|             return (rhs.print_z   == this->print_z    ) &&  | ||||
|                    (rhs.gcode     == this->gcode      ) &&  | ||||
|                    (rhs.extruder  == this->extruder   ) &&  | ||||
|                    (rhs.color     == this->color      ); | ||||
|         } | ||||
|         bool operator!=(const CustomGCode& rhs) const { return ! (*this == rhs); } | ||||
|          | ||||
|         double      print_z; | ||||
|         std::string gcode; | ||||
|         int         extruder;   // Informative value for ColorChangeCode and ToolChangeCode
 | ||||
|                                 // "gcode" == ColorChangeCode   => M600 will be applied for "extruder" extruder
 | ||||
|                                 // "gcode" == ToolChangeCode    => for whole print tool will be switched to "extruder" extruder
 | ||||
|         std::string color;      // if gcode is equal to PausePrintCode, 
 | ||||
|                                 // this field is used for save a short message shown on Printer display 
 | ||||
|     }; | ||||
|      | ||||
|     struct CustomGCodeInfo | ||||
|     { | ||||
|         enum MODE | ||||
|         { | ||||
|             SingleExtruder,   // single extruder printer preset is selected
 | ||||
|             MultiAsSingle,    // multiple extruder printer preset is selected, but 
 | ||||
|                               // this mode works just for Single extruder print 
 | ||||
|                               // (For all print from objects settings is used just one extruder) 
 | ||||
|             MultiExtruder     // multiple extruder printer preset is selected
 | ||||
|         } mode; | ||||
|          | ||||
|         std::vector<CustomGCode> gcodes; | ||||
| 
 | ||||
|         bool operator==(const CustomGCodeInfo& rhs) const | ||||
|         { | ||||
|             return  (rhs.mode   == this->mode   ) && | ||||
|                     (rhs.gcodes == this->gcodes ); | ||||
|         } | ||||
|         bool operator!=(const CustomGCodeInfo& rhs) const { return !(*this == rhs); } | ||||
|     }  | ||||
|     custom_gcode_per_print_z; | ||||
|     CustomGCode::Info custom_gcode_per_print_z; | ||||
|      | ||||
|     // Default constructor assigns a new ID to the model.
 | ||||
|     Model() { assert(this->id().valid()); } | ||||
|  | @ -872,10 +832,6 @@ private: | |||
| #undef OBJECTBASE_DERIVED_COPY_MOVE_CLONE | ||||
| #undef OBJECTBASE_DERIVED_PRIVATE_COPY_MOVE | ||||
| 
 | ||||
| // Return pairs of <print_z, 1-based extruder ID> sorted by increasing print_z from custom_gcode_per_print_z.
 | ||||
| // print_z corresponds to the first layer printed with the new extruder.
 | ||||
| extern std::vector<std::pair<double, unsigned int>> custom_tool_changes(const Model &model, size_t num_extruders); | ||||
| 
 | ||||
| // Test whether the two models contain the same number of ModelObjects with the same set of IDs
 | ||||
| // ordered in the same order. In that case it is not necessary to kill the background processing.
 | ||||
| extern bool model_object_list_equal(const Model &model_old, const Model &model_new); | ||||
|  | @ -893,10 +849,6 @@ extern bool model_volume_list_changed(const ModelObject &model_object_old, const | |||
| extern bool model_has_multi_part_objects(const Model &model); | ||||
| // If the model has advanced features, then it cannot be processed in simple mode.
 | ||||
| extern bool model_has_advanced_features(const Model &model); | ||||
| // If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), 
 | ||||
| // and if model.custom_gcode_per_print_z is empty (there is no color print data available in a new format
 | ||||
| // then model.custom_gcode_per_print_z should be updated considering this option.
 | ||||
| extern void update_custom_gcode_per_print_z_from_config(std::vector<Model::CustomGCode>& custom_gcode_per_print_z, DynamicPrintConfig* config); | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | ||||
|  |  | |||
|  | @ -491,7 +491,7 @@ static bool layer_height_ranges_equal(const t_layer_config_ranges &lr1, const t_ | |||
| } | ||||
| 
 | ||||
| // Returns true if va == vb when all CustomGCode items that are not ToolChangeCode are ignored.
 | ||||
| static bool custom_per_printz_gcodes_tool_changes_differ(const std::vector<Model::CustomGCode> &va, const std::vector<Model::CustomGCode> &vb) | ||||
| static bool custom_per_printz_gcodes_tool_changes_differ(const std::vector<CustomGCode::Item> &va, const std::vector<CustomGCode::Item> &vb) | ||||
| { | ||||
| 	auto it_a = va.begin(); | ||||
| 	auto it_b = vb.begin(); | ||||
|  |  | |||
|  | @ -892,7 +892,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | |||
|                                                                 std::vector<float>& colors, | ||||
|                                                                 std::vector<std::string>& cp_legend_items) | ||||
| { | ||||
|     std::vector<Model::CustomGCode> custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; | ||||
|     std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; | ||||
| 
 | ||||
|     const int extruders_cnt = wxGetApp().extruders_edited_cnt(); | ||||
|     if (extruders_cnt == 1)  | ||||
|  | @ -2410,7 +2410,7 @@ void GLCanvas3D::load_sla_preview() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<Model::CustomGCode>& color_print_values) | ||||
| void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values) | ||||
| { | ||||
|     const Print *print = this->fff_print(); | ||||
|     if (print == nullptr) | ||||
|  | @ -5245,7 +5245,7 @@ void GLCanvas3D::_load_print_toolpaths() | |||
|     volume->indexed_vertex_array.finalize_geometry(m_initialized); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<Model::CustomGCode>& color_print_values) | ||||
| void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values) | ||||
| { | ||||
|     std::vector<float> tool_colors = _parse_colors(str_tool_colors); | ||||
| 
 | ||||
|  | @ -5259,7 +5259,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|         const std::vector<float>*    tool_colors; | ||||
|         bool                         is_single_material_print; | ||||
|         int                          extruders_cnt; | ||||
|         const std::vector<Model::CustomGCode>*   color_print_values; | ||||
|         const std::vector<CustomGCode::Item>*   color_print_values; | ||||
| 
 | ||||
|         static const float*          color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
 | ||||
|         static const float*          color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
 | ||||
|  | @ -5274,7 +5274,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|         // For coloring by a color_print(M600), return a parsed color.
 | ||||
|         bool                         color_by_color_print() const { return color_print_values!=nullptr; } | ||||
|         const size_t                 color_print_color_idx_by_layer_idx(const size_t layer_idx) const { | ||||
|             const Model::CustomGCode value{layers[layer_idx]->print_z + EPSILON, "", 0, ""}; | ||||
|             const CustomGCode::Item value{layers[layer_idx]->print_z + EPSILON, "", 0, ""}; | ||||
|             auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); | ||||
|             return (it - color_print_values->begin()) % number_tools(); | ||||
|         } | ||||
|  | @ -5284,7 +5284,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|             const coordf_t print_z = layers[layer_idx]->print_z; | ||||
| 
 | ||||
|             auto it = std::find_if(color_print_values->begin(), color_print_values->end(), | ||||
|                 [print_z](const Model::CustomGCode& code) | ||||
|                 [print_z](const CustomGCode::Item& code) | ||||
|                 { return fabs(code.print_z - print_z) < EPSILON; }); | ||||
|             if (it != color_print_values->end()) | ||||
|             { | ||||
|  | @ -5305,7 +5305,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             const Model::CustomGCode value{print_z + EPSILON, "", 0, ""}; | ||||
|             const CustomGCode::Item value{print_z + EPSILON, "", 0, ""}; | ||||
|             it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); | ||||
|             while (it != color_print_values->begin()) | ||||
|             { | ||||
|  | @ -5325,7 +5325,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|         } | ||||
| 
 | ||||
|     private: | ||||
|         int get_m600_color_idx(std::vector<Model::CustomGCode>::const_iterator it) const  | ||||
|         int get_m600_color_idx(std::vector<CustomGCode::Item>::const_iterator it) const | ||||
|         { | ||||
|             int shift = 0; | ||||
|             while (it != color_print_values->begin()) { | ||||
|  | @ -5336,7 +5336,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|             return extruders_cnt + shift; | ||||
|         } | ||||
| 
 | ||||
|         int get_color_idx_for_tool_change(std::vector<Model::CustomGCode>::const_iterator it, const int extruder) const  | ||||
|         int get_color_idx_for_tool_change(std::vector<CustomGCode::Item>::const_iterator it, const int extruder) const | ||||
|         { | ||||
|             const int current_extruder = it->extruder == 0 ? extruder : it->extruder; | ||||
|             if (number_tools() == extruders_cnt + 1) // there is no one "M600"
 | ||||
|  | @ -5352,7 +5352,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|             return std::min<int>(extruders_cnt - 1, std::max<int>(current_extruder - 1, 0)); | ||||
|         } | ||||
| 
 | ||||
|         int get_color_idx_for_color_change(std::vector<Model::CustomGCode>::const_iterator it, const int extruder) const  | ||||
|         int get_color_idx_for_color_change(std::vector<CustomGCode::Item>::const_iterator it, const int extruder) const | ||||
|         { | ||||
|             if (extruders_cnt == 1) | ||||
|                 return get_m600_color_idx(it); | ||||
|  |  | |||
|  | @ -557,7 +557,7 @@ public: | |||
| 
 | ||||
|     void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors); | ||||
|     void load_sla_preview(); | ||||
|     void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<Model::CustomGCode>& color_print_values); | ||||
|     void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values); | ||||
|     void bind_event_handlers(); | ||||
|     void unbind_event_handlers(); | ||||
| 
 | ||||
|  | @ -720,7 +720,7 @@ private: | |||
|     // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
 | ||||
|     // one for perimeters, one for infill and one for supports.
 | ||||
|     void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, | ||||
|                                       const std::vector<Model::CustomGCode>& color_print_values); | ||||
|                                       const std::vector<CustomGCode::Item>& color_print_values); | ||||
|     // Create 3D thick extrusion lines for wipe tower extrusions
 | ||||
|     void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors); | ||||
| 
 | ||||
|  |  | |||
|  | @ -633,7 +633,7 @@ static int find_close_layer_idx(const std::vector<double>& zs, double &z, double | |||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| void Preview::check_slider_values(std::vector<Model::CustomGCode>& ticks_from_model, | ||||
| void Preview::check_slider_values(std::vector<CustomGCode::Item>& ticks_from_model, | ||||
|                                   const std::vector<double>& layers_z) | ||||
| { | ||||
|     // All ticks that would end up outside the slider range should be erased.
 | ||||
|  | @ -641,7 +641,7 @@ void Preview::check_slider_values(std::vector<Model::CustomGCode>& ticks_from_mo | |||
|     // this function is e.g. not called when the last object is deleted
 | ||||
|     unsigned int old_size = ticks_from_model.size(); | ||||
|     ticks_from_model.erase(std::remove_if(ticks_from_model.begin(), ticks_from_model.end(), | ||||
|                      [layers_z](Model::CustomGCode val) | ||||
|                      [layers_z](CustomGCode::Item val) | ||||
|         { | ||||
|             auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.print_z - DoubleSlider::epsilon()); | ||||
|             return it == layers_z.end(); | ||||
|  | @ -669,7 +669,7 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee | |||
|     // Detect and set manipulation mode for double slider
 | ||||
|     update_double_slider_mode(); | ||||
| 
 | ||||
|     Model::CustomGCodeInfo &ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; | ||||
|     CustomGCode::Info &ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; | ||||
|     check_slider_values(ticks_info_from_model.gcodes, layers_z); | ||||
| 
 | ||||
|     m_slider->SetSliderValues(layers_z); | ||||
|  | @ -830,7 +830,7 @@ void Preview::load_print_as_fff(bool keep_z_range) | |||
|     bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); | ||||
|     // Collect colors per extruder.
 | ||||
|     std::vector<std::string> colors; | ||||
|     std::vector<Model::CustomGCode> color_print_values = {}; | ||||
|     std::vector<CustomGCode::Item> color_print_values = {}; | ||||
|     // set color print values, if it si selected "ColorPrint" view type
 | ||||
|     if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) | ||||
|     { | ||||
|  |  | |||
|  | @ -155,7 +155,7 @@ private: | |||
| 
 | ||||
|     // Create/Update/Reset double slider on 3dPreview
 | ||||
|     void create_double_slider(); | ||||
|     void check_slider_values(std::vector<Model::CustomGCode> &ticks_from_model, | ||||
|     void check_slider_values(std::vector<CustomGCode::Item> &ticks_from_model, | ||||
|                              const std::vector<double> &layers_z); | ||||
|     void reset_double_slider(); | ||||
|     void update_double_slider(const std::vector<double>& layers_z, bool keep_z_range = false); | ||||
|  |  | |||
|  | @ -5423,7 +5423,7 @@ std::vector<std::string> Plater::get_colors_for_color_print() const | |||
|     std::vector<std::string> colors = get_extruder_colors_from_plater_config(); | ||||
|     colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size()); | ||||
| 
 | ||||
|     for (const Model::CustomGCode& code : p->model.custom_gcode_per_print_z.gcodes) | ||||
|     for (const CustomGCode::Item& code : p->model.custom_gcode_per_print_z.gcodes) | ||||
|         if (code.gcode == ColorChangeCode) | ||||
|             colors.emplace_back(code.color); | ||||
| 
 | ||||
|  |  | |||
|  | @ -884,7 +884,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool | |||
|         // 4) Load the project config values (the per extruder wipe matrix etc).
 | ||||
|         this->project_config.apply_only(config, s_project_options); | ||||
| 
 | ||||
|         update_custom_gcode_per_print_z_from_config(GUI::wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes, &this->project_config); | ||||
|         update_custom_gcode_per_print_z_from_config(GUI::wxGetApp().plater()->model().custom_gcode_per_print_z, &this->project_config); | ||||
| 
 | ||||
|         break; | ||||
|     } | ||||
|  |  | |||
|  | @ -2531,10 +2531,10 @@ double DoubleSlider::get_double_value(const SelectedSlider& selection) | |||
|     return m_values[selection == ssLower ? m_lower_value : m_higher_value]; | ||||
| } | ||||
| 
 | ||||
| using t_custom_code = Slic3r::Model::CustomGCode; | ||||
| Slic3r::Model::CustomGCodeInfo DoubleSlider::GetTicksValues() const | ||||
| using t_custom_code = Slic3r::CustomGCode::Item; | ||||
| Slic3r::CustomGCode::Info DoubleSlider::GetTicksValues() const | ||||
| { | ||||
|     Slic3r::Model::CustomGCodeInfo custom_gcode_per_print_z; | ||||
|     Slic3r::CustomGCode::Info custom_gcode_per_print_z; | ||||
|     std::vector<t_custom_code>& values = custom_gcode_per_print_z.gcodes; | ||||
| 
 | ||||
|     const int val_size = m_values.size(); | ||||
|  | @ -2550,7 +2550,7 @@ Slic3r::Model::CustomGCodeInfo DoubleSlider::GetTicksValues() const | |||
|     return custom_gcode_per_print_z; | ||||
| } | ||||
| 
 | ||||
| void DoubleSlider::SetTicksValues(const Slic3r::Model::CustomGCodeInfo& custom_gcode_per_print_z) | ||||
| void DoubleSlider::SetTicksValues(const Slic3r::CustomGCode::Info& custom_gcode_per_print_z) | ||||
| { | ||||
|     if (m_values.empty()) | ||||
|     { | ||||
|  |  | |||
|  | @ -782,7 +782,7 @@ public: | |||
|         const wxString& name = wxEmptyString); | ||||
|     ~DoubleSlider() {} | ||||
| 
 | ||||
|     using t_mode = Slic3r::Model::CustomGCodeInfo::MODE; | ||||
|     using t_mode = Slic3r::CustomGCode::Mode; | ||||
| 
 | ||||
|     /* For exporting GCode in GCodeWriter is used XYZF_NUM(val) = PRECISION(val, 3) for XYZ values. 
 | ||||
|      * So, let use same value as a permissible error for layer height. | ||||
|  | @ -810,8 +810,8 @@ public: | |||
|     void SetKoefForLabels(const double koef)                { m_label_koef = koef; } | ||||
|     void SetSliderValues(const std::vector<double>& values) { m_values = values; } | ||||
|     void ChangeOneLayerLock(); | ||||
|     Slic3r::Model::CustomGCodeInfo  GetTicksValues() const; | ||||
|     void                            SetTicksValues(const Slic3r::Model::CustomGCodeInfo &custom_gcode_per_print_z); | ||||
|     Slic3r::CustomGCode::Info   GetTicksValues() const; | ||||
|     void                        SetTicksValues(const Slic3r::CustomGCode::Info &custom_gcode_per_print_z); | ||||
|     void EnableTickManipulation(bool enable = true) { m_is_enabled_tick_manipulation = enable; } | ||||
|     void DisableTickManipulation()                  { EnableTickManipulation(false); } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka