mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' into lm_tm_hollowing
This commit is contained in:
		
						commit
						537260494d
					
				
					 185 changed files with 83280 additions and 4591 deletions
				
			
		|  | @ -52,6 +52,7 @@ const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights | |||
| const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Prusa_Slicer_layer_config_ranges.xml"; | ||||
| const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt"; | ||||
| const std::string SLA_DRAIN_HOLES_FILE = "Metadata/Slic3r_PE_sla_drain_holes.txt"; | ||||
| const std::string CUSTOM_GCODE_PER_HEIGHT_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_height.xml"; | ||||
| 
 | ||||
| const char* MODEL_TAG = "model"; | ||||
| const char* RESOURCES_TAG = "resources"; | ||||
|  | @ -421,6 +422,8 @@ namespace Slic3r { | |||
|         void _extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||
|         void _extract_sla_drain_holes_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||
| 
 | ||||
|         void _extract_custom_gcode_per_height_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||
| 
 | ||||
|         void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename); | ||||
|         bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model); | ||||
| 
 | ||||
|  | @ -635,6 +638,11 @@ namespace Slic3r { | |||
|                     // extract slic3r print config file
 | ||||
|                     _extract_print_config_from_archive(archive, stat, config, filename); | ||||
|                 } | ||||
|                 if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_HEIGHT_FILE)) | ||||
|                 { | ||||
|                     // extract slic3r layer config ranges file
 | ||||
|                     _extract_custom_gcode_per_height_from_archive(archive, stat); | ||||
|                 } | ||||
|                 else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) | ||||
|                 { | ||||
|                     // extract slic3r model config file
 | ||||
|  | @ -1155,6 +1163,43 @@ namespace Slic3r { | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     void _3MF_Importer::_extract_custom_gcode_per_height_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) | ||||
|     { | ||||
|         if (stat.m_uncomp_size > 0) | ||||
|         { | ||||
|             std::string buffer((size_t)stat.m_uncomp_size, 0); | ||||
|             mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0); | ||||
|             if (res == 0) { | ||||
|                 add_error("Error while reading custom Gcodes per height data to buffer"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             std::istringstream iss(buffer); // wrap returned xml to istringstream
 | ||||
|             pt::ptree main_tree; | ||||
|             pt::read_xml(iss, main_tree); | ||||
| 
 | ||||
|             if (main_tree.front().first != "custom_gcodes_per_height") | ||||
|                 return; | ||||
|             pt::ptree code_tree = main_tree.front().second; | ||||
| 
 | ||||
|             if (!m_model->custom_gcode_per_height.empty()) | ||||
|                 m_model->custom_gcode_per_height.clear(); | ||||
| 
 | ||||
|             for (const auto& code : code_tree) | ||||
|             { | ||||
|                 if (code.first != "code") | ||||
|                     continue; | ||||
|                 pt::ptree tree = code.second; | ||||
|                 double height       = tree.get<double>("<xmlattr>.height"); | ||||
|                 std::string gcode   = tree.get<std::string>("<xmlattr>.gcode"); | ||||
|                 int extruder        = tree.get<int>("<xmlattr>.extruder"); | ||||
|                 std::string color   = tree.get<std::string>("<xmlattr>.color"); | ||||
| 
 | ||||
|                 m_model->custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)) ; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void _3MF_Importer::_handle_start_model_xml_element(const char* name, const char** attributes) | ||||
|     { | ||||
|         if (m_xml_parser == nullptr) | ||||
|  | @ -1568,8 +1613,10 @@ namespace Slic3r { | |||
| 
 | ||||
|             if (m_check_version && (m_version > VERSION_3MF)) | ||||
|             { | ||||
|                 std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.")); | ||||
|                 throw version_error(msg.c_str()); | ||||
|                 // std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible."));
 | ||||
|                 // throw version_error(msg.c_str());
 | ||||
|                 const std::string msg = (boost::format(_(L("The selected 3mf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str(); | ||||
|                 throw version_error(msg); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1938,6 +1985,7 @@ namespace Slic3r { | |||
|         bool _add_sla_drain_holes_file_to_archive(mz_zip_archive& archive, Model& model); | ||||
|         bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config); | ||||
|         bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); | ||||
|         bool _add_custom_gcode_per_height_file_to_archive(mz_zip_archive& archive, Model& model); | ||||
|     }; | ||||
| 
 | ||||
| #if ENABLE_THUMBNAIL_GENERATOR | ||||
|  | @ -2048,6 +2096,15 @@ namespace Slic3r { | |||
|         } | ||||
|          | ||||
| 
 | ||||
|         // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_height.xml").
 | ||||
|         // All custom gcode per height of whole Model are stored here
 | ||||
|         if (!_add_custom_gcode_per_height_file_to_archive(archive, model)) | ||||
|         { | ||||
|             close_zip_writer(&archive); | ||||
|             boost::filesystem::remove(filename); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         // Adds slic3r print config file ("Metadata/Slic3r_PE.config").
 | ||||
|         // This file contains the content of FullPrintConfing / SLAFullPrintConfig.
 | ||||
|         if (config != nullptr) | ||||
|  | @ -2432,7 +2489,7 @@ namespace Slic3r { | |||
|         if (!tree.empty()) | ||||
|         { | ||||
|             std::ostringstream oss; | ||||
|             boost::property_tree::write_xml(oss, tree); | ||||
|             pt::write_xml(oss, tree); | ||||
|             out = oss.str(); | ||||
| 
 | ||||
|             // Post processing("beautification") of the output string for a better preview
 | ||||
|  | @ -2662,7 +2719,49 @@ namespace Slic3r { | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version) | ||||
| bool _3MF_Exporter::_add_custom_gcode_per_height_file_to_archive( mz_zip_archive& archive, Model& model) | ||||
| { | ||||
|     std::string out = ""; | ||||
| 
 | ||||
|     if (!model.custom_gcode_per_height.empty()) | ||||
|     { | ||||
|         pt::ptree tree; | ||||
|         pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); | ||||
| 
 | ||||
|         for (const Model::CustomGCode& code : model.custom_gcode_per_height) | ||||
|         { | ||||
|             pt::ptree& code_tree = main_tree.add("code", ""); | ||||
|             // store minX and maxZ
 | ||||
|             code_tree.put("<xmlattr>.height"    , code.height   ); | ||||
|             code_tree.put("<xmlattr>.gcode"     , code.gcode    ); | ||||
|             code_tree.put("<xmlattr>.extruder"  , code.extruder ); | ||||
|             code_tree.put("<xmlattr>.color"     , code.color    ); | ||||
|         }        | ||||
| 
 | ||||
|         if (!tree.empty()) | ||||
|         { | ||||
|             std::ostringstream oss; | ||||
|             boost::property_tree::write_xml(oss, tree); | ||||
|             out = oss.str(); | ||||
| 
 | ||||
|             // Post processing("beautification") of the output string
 | ||||
|             boost::replace_all(out, "><", ">\n<"); | ||||
|         } | ||||
|     }  | ||||
| 
 | ||||
|     if (!out.empty()) | ||||
|     { | ||||
|         if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_HEIGHT_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) | ||||
|         { | ||||
|             add_error("Unable to add custom Gcodes per height file to archive"); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version) | ||||
|     { | ||||
|         if ((path == nullptr) || (config == nullptr) || (model == nullptr)) | ||||
|             return false; | ||||
|  |  | |||
|  | @ -16,6 +16,10 @@ | |||
| 
 | ||||
| #include "AMF.hpp" | ||||
| 
 | ||||
| #include <boost/property_tree/ptree.hpp> | ||||
| #include <boost/property_tree/xml_parser.hpp> | ||||
| namespace pt = boost::property_tree; | ||||
| 
 | ||||
| #include <boost/filesystem/operations.hpp> | ||||
| #include <boost/algorithm/string.hpp> | ||||
| #include <boost/nowide/fstream.hpp> | ||||
|  | @ -147,6 +151,8 @@ struct AMFParserContext | |||
|         NODE_TYPE_MIRRORY,              // amf/constellation/instance/mirrory
 | ||||
|         NODE_TYPE_MIRRORZ,              // amf/constellation/instance/mirrorz
 | ||||
|         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_METADATA,             // anywhere under amf/*/metadata
 | ||||
|     }; | ||||
| 
 | ||||
|  | @ -227,7 +233,7 @@ struct AMFParserContext | |||
|     // Current instance allocated for an amf/constellation/instance subtree.
 | ||||
|     Instance                *m_instance; | ||||
|     // Generic string buffer for vertices, face indices, metadata etc.
 | ||||
|     std::string              m_value[3]; | ||||
|     std::string              m_value[4]; | ||||
|     // Pointer to config to update if config data are stored inside the amf file
 | ||||
|     DynamicPrintConfig      *m_config; | ||||
| 
 | ||||
|  | @ -268,6 +274,8 @@ void AMFParserContext::startElement(const char *name, const char **atts) | |||
|             } | ||||
|         } else if (strcmp(name, "constellation") == 0) { | ||||
|             node_type_new = NODE_TYPE_CONSTELLATION; | ||||
|         } else if (strcmp(name, "custom_gcodes_per_height") == 0) { | ||||
|             node_type_new = NODE_TYPE_CUSTOM_GCODE; | ||||
|         } | ||||
|         break; | ||||
|     case 2: | ||||
|  | @ -294,6 +302,13 @@ 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"); | ||||
|         } | ||||
|         break; | ||||
|     case 3: | ||||
|  | @ -616,6 +631,19 @@ void AMFParserContext::endElement(const char * /* name */) | |||
|         m_instance = nullptr; | ||||
|         break; | ||||
| 
 | ||||
|     case NODE_TYPE_GCODE_PER_HEIGHT: { | ||||
|         double height = 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_height.push_back(Model::CustomGCode(height, gcode, extruder, color)); | ||||
| 
 | ||||
|         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()); | ||||
|  | @ -884,8 +912,10 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi | |||
| 
 | ||||
|     if (check_version && (ctx.m_version > VERSION_AMF)) | ||||
|     { | ||||
|         std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.")); | ||||
|         throw std::runtime_error(msg.c_str()); | ||||
|         // std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible."));
 | ||||
|         // throw std::runtime_error(msg.c_str());
 | ||||
|         const std::string msg = (boost::format(_(L("The selected amf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str(); | ||||
|         throw std::runtime_error(msg); | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
|  | @ -1190,6 +1220,42 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) | |||
|         stream << instances; | ||||
|         stream << "  </constellation>\n"; | ||||
|     } | ||||
| 
 | ||||
|     if (!model->custom_gcode_per_height.empty()) | ||||
|     { | ||||
|         std::string out = ""; | ||||
|         pt::ptree tree; | ||||
| 
 | ||||
|         pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); | ||||
| 
 | ||||
|         for (const Model::CustomGCode& code : model->custom_gcode_per_height) | ||||
|         { | ||||
|             pt::ptree& code_tree = main_tree.add("code", ""); | ||||
|             // store minX and maxZ
 | ||||
|             code_tree.put("<xmlattr>.height", code.height); | ||||
|             code_tree.put("<xmlattr>.gcode", code.gcode); | ||||
|             code_tree.put("<xmlattr>.extruder", code.extruder); | ||||
|             code_tree.put("<xmlattr>.color", code.color); | ||||
|         } | ||||
| 
 | ||||
|         if (!tree.empty()) | ||||
|         { | ||||
|             std::ostringstream oss; | ||||
|             pt::write_xml(oss, tree); | ||||
|             out = oss.str(); | ||||
| 
 | ||||
|             int del_header_pos = out.find("<custom_gcodes_per_height"); | ||||
|             if (del_header_pos != std::string::npos) | ||||
|                 out.erase(out.begin(), out.begin() + del_header_pos); | ||||
| 
 | ||||
|             // Post processing("beautification") of the output string
 | ||||
|             boost::replace_all(out, "><code", ">\n  <code"); | ||||
|             boost::replace_all(out, "><", ">\n<"); | ||||
| 
 | ||||
|             stream << out << "\n"; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     stream << "</amf>\n"; | ||||
| 
 | ||||
|     std::string internal_amf_filename = boost::ireplace_last_copy(boost::filesystem::path(export_path).filename().string(), ".zip.amf", ".amf"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena