mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Import/export of the Layers information to/from 3MF
This commit is contained in:
		
							parent
							
								
									f0f608f247
								
							
						
					
					
						commit
						4e0eb12ef6
					
				
					 1 changed files with 180 additions and 1 deletions
				
			
		|  | @ -33,6 +33,7 @@ const std::string RELATIONSHIPS_FILE = "_rels/.rels"; | |||
| const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config"; | ||||
| const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; | ||||
| const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; | ||||
| const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Slic3r_PE_layer_config_ranges.txt"; | ||||
| const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt"; | ||||
| 
 | ||||
| const char* MODEL_TAG = "model"; | ||||
|  | @ -331,6 +332,7 @@ namespace Slic3r { | |||
|         typedef std::map<int, ObjectMetadata> IdToMetadataMap; | ||||
|         typedef std::map<int, Geometry> IdToGeometryMap; | ||||
|         typedef std::map<int, std::vector<coordf_t>> IdToLayerHeightsProfileMap; | ||||
|         typedef std::map<int, t_layer_config_ranges> IdToLayerConfigRangesMap; | ||||
|         typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap; | ||||
| 
 | ||||
|         // Version of the 3mf file
 | ||||
|  | @ -347,6 +349,7 @@ namespace Slic3r { | |||
|         CurrentConfig m_curr_config; | ||||
|         IdToMetadataMap m_objects_metadata; | ||||
|         IdToLayerHeightsProfileMap m_layer_heights_profiles; | ||||
|         IdToLayerConfigRangesMap m_layer_config_ranges; | ||||
|         IdToSlaSupportPointsMap m_sla_support_points; | ||||
|         std::string m_curr_metadata_name; | ||||
|         std::string m_curr_characters; | ||||
|  | @ -365,6 +368,7 @@ namespace Slic3r { | |||
|         bool _load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config); | ||||
|         bool _extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||
|         void _extract_layer_heights_profile_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||
|         void _extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||
|         void _extract_sla_support_points_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); | ||||
|  | @ -476,6 +480,7 @@ namespace Slic3r { | |||
|         m_curr_config.volume_id = -1; | ||||
|         m_objects_metadata.clear(); | ||||
|         m_layer_heights_profiles.clear(); | ||||
|         m_layer_config_ranges.clear(); | ||||
|         m_sla_support_points.clear(); | ||||
|         m_curr_metadata_name.clear(); | ||||
|         m_curr_characters.clear(); | ||||
|  | @ -546,9 +551,14 @@ namespace Slic3r { | |||
| 
 | ||||
|                 if (boost::algorithm::iequals(name, LAYER_HEIGHTS_PROFILE_FILE)) | ||||
|                 { | ||||
|                     // extract slic3r lazer heights profile file
 | ||||
|                     // extract slic3r layer heights profile file
 | ||||
|                     _extract_layer_heights_profile_config_from_archive(archive, stat); | ||||
|                 } | ||||
|                 if (boost::algorithm::iequals(name, LAYER_CONFIG_RANGES_FILE)) | ||||
|                 { | ||||
|                     // extract slic3r layer config ranges file
 | ||||
|                     _extract_layer_config_ranges_from_archive(archive, stat); | ||||
|                 } | ||||
|                 else if (boost::algorithm::iequals(name, SLA_SUPPORT_POINTS_FILE)) | ||||
|                 { | ||||
|                     // extract sla support points file
 | ||||
|  | @ -592,6 +602,11 @@ namespace Slic3r { | |||
|             if (obj_layer_heights_profile != m_layer_heights_profiles.end()) | ||||
|                 model_object->layer_height_profile = obj_layer_heights_profile->second; | ||||
| 
 | ||||
|             // m_layer_config_ranges are indexed by a 1 based model object index.
 | ||||
|             IdToLayerConfigRangesMap::iterator obj_layer_config_ranges = m_layer_config_ranges.find(object.second + 1); | ||||
|             if (obj_layer_config_ranges != m_layer_config_ranges.end()) | ||||
|                 model_object->layer_config_ranges = obj_layer_config_ranges->second; | ||||
| 
 | ||||
|             // m_sla_support_points are indexed by a 1 based model object index.
 | ||||
|             IdToSlaSupportPointsMap::iterator obj_sla_support_points = m_sla_support_points.find(object.second + 1); | ||||
|             if (obj_sla_support_points != m_sla_support_points.end() && !obj_sla_support_points->second.empty()) { | ||||
|  | @ -769,6 +784,115 @@ namespace Slic3r { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void _3MF_Importer::_extract_layer_config_ranges_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 layer config ranges data to buffer"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (buffer.back() == '|') | ||||
|                 buffer.pop_back(); | ||||
| 
 | ||||
|             std::vector<std::string> objects; | ||||
|             boost::split(objects, buffer, boost::is_any_of("|"), boost::token_compress_off); | ||||
| 
 | ||||
|             for (std::string& object : objects) | ||||
|             { | ||||
|                 // delete all spaces
 | ||||
|                 boost::replace_all(object, " ", ""); | ||||
| 
 | ||||
|                 std::vector<std::string> object_data; | ||||
|                 boost::split(object_data, object, boost::is_any_of("*"), boost::token_compress_off); | ||||
|                 /* there should be at least one layer config range in the object 
 | ||||
|                  * object_data[0]       => object information | ||||
|                  * object_data[i>=1]    => range information | ||||
|                  */ | ||||
|                 if (object_data.size() < 2) { | ||||
|                     add_error("Error while reading object data"); | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 std::vector<std::string> object_data_id; | ||||
|                 boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off); | ||||
|                 if (object_data_id.size() != 2) { | ||||
|                     add_error("Error while reading object id"); | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 // get object information
 | ||||
|                 int object_id = std::atoi(object_data_id[1].c_str()); | ||||
|                 if (object_id == 0) { | ||||
|                     add_error("Found invalid object id"); | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 IdToLayerConfigRangesMap::iterator object_item = m_layer_config_ranges.find(object_id); | ||||
|                 if (object_item != m_layer_config_ranges.end()) { | ||||
|                     add_error("Found duplicated layer config range"); | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 t_layer_config_ranges config_ranges; | ||||
| 
 | ||||
|                 // get ranges information
 | ||||
|                 for (size_t i = 1; i < object_data.size(); ++i) | ||||
|                 { | ||||
|                     if (object_data[i].back() == '\n') | ||||
|                         object_data[i].pop_back(); | ||||
| 
 | ||||
|                     std::vector<std::string> range_data; | ||||
|                     boost::split(range_data, object_data[i], boost::is_any_of("\n"), boost::token_compress_off); | ||||
|                     /* There should be at least two options for layer config range
 | ||||
|                      * range_data[0]       => Z range information | ||||
|                      * range_data[i>=1]    => configuration for the range | ||||
|                      */ | ||||
|                     if (range_data.size() < 3) { | ||||
|                         add_error("Found invalid layer config range"); | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     std::vector<std::string> z_range_str; | ||||
|                     boost::split(z_range_str, range_data[0], boost::is_any_of("="), boost::token_compress_off); | ||||
|                     if (z_range_str.size() != 2) { | ||||
|                         add_error("Error while reading layer config range"); | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     std::vector<std::string> z_values; | ||||
|                     boost::split(z_values, z_range_str[1], boost::is_any_of(";"), boost::token_compress_off); | ||||
|                     if (z_values.size() != 2) { | ||||
|                         add_error("Found invalid layer config range"); | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     // get Z range information
 | ||||
|                     t_layer_height_range z_range = { (coordf_t)std::atof(z_values[0].c_str()) , (coordf_t)std::atof(z_values[1].c_str()) }; | ||||
|                     DynamicPrintConfig& config = config_ranges[z_range]; | ||||
| 
 | ||||
|                     // get configuration options for the range
 | ||||
|                     for (size_t j = 1; j < range_data.size(); ++j) | ||||
|                     { | ||||
|                         std::vector<std::string> key_val; | ||||
|                         boost::split(key_val, range_data[j], boost::is_any_of("="), boost::token_compress_off); | ||||
|                         if (key_val.size() != 2) { | ||||
|                             add_error("Error while reading config value"); | ||||
|                             continue; | ||||
|                         } | ||||
|                         config.set_deserialize(key_val[0], key_val[1]); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (!config_ranges.empty()) | ||||
|                     m_layer_config_ranges.insert(IdToLayerConfigRangesMap::value_type(object_id, config_ranges)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void _3MF_Importer::_extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) | ||||
|     { | ||||
|         if (stat.m_uncomp_size > 0) | ||||
|  | @ -1622,6 +1746,7 @@ namespace Slic3r { | |||
|         bool _add_mesh_to_object_stream(std::stringstream& stream, ModelObject& object, VolumeToOffsetsMap& volumes_offsets); | ||||
|         bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items); | ||||
|         bool _add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model); | ||||
|         bool _add_layer_config_ranges_file_to_archive(mz_zip_archive& archive, Model& model); | ||||
|         bool _add_sla_support_points_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); | ||||
|  | @ -1682,6 +1807,16 @@ namespace Slic3r { | |||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         // Adds layer config ranges file ("Metadata/Slic3r_PE_layer_config_ranges.txt").
 | ||||
|         // All layer height profiles of all ModelObjects are stored here, indexed by 1 based index of the ModelObject in Model.
 | ||||
|         // The index differes from the index of an object ID of an object instance of a 3MF file!
 | ||||
|         if (!_add_layer_config_ranges_file_to_archive(archive, model)) | ||||
|         { | ||||
|             close_zip_writer(&archive); | ||||
|             boost::filesystem::remove(filename); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         // Adds sla support points file ("Metadata/Slic3r_PE_sla_support_points.txt").
 | ||||
|         // All  sla support points of all ModelObjects are stored here, indexed by 1 based index of the ModelObject in Model.
 | ||||
|         // The index differes from the index of an object ID of an object instance of a 3MF file!
 | ||||
|  | @ -2012,6 +2147,50 @@ namespace Slic3r { | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     bool _3MF_Exporter::_add_layer_config_ranges_file_to_archive(mz_zip_archive& archive, Model& model) | ||||
|     { | ||||
|         std::string out = ""; | ||||
|         char buffer[1024]; | ||||
| 
 | ||||
|         unsigned int object_cnt = 0; | ||||
|         for (const ModelObject* object : model.objects) | ||||
|         { | ||||
|             object_cnt++; | ||||
|             const t_layer_config_ranges& ranges = object->layer_config_ranges; | ||||
|             if (!ranges.empty()) | ||||
|             { | ||||
|                 sprintf(buffer, "object_id=%d\n", object_cnt); | ||||
|                 out += buffer; | ||||
| 
 | ||||
|                 // Store the layer config ranges.
 | ||||
|                 for (const auto& range : ranges) | ||||
|                 { | ||||
|                     // store minX and maxZ
 | ||||
|                     sprintf(buffer, "*z_range = %f;%f\n", range.first.first, range.first.second); | ||||
|                     out += buffer; | ||||
| 
 | ||||
|                     // store range configuration
 | ||||
|                     const DynamicPrintConfig& config = range.second; | ||||
|                     for (const std::string& key : config.keys()) | ||||
|                         out += " " + key + " = " + config.serialize(key) + "\n"; | ||||
|                 } | ||||
|                  | ||||
|                 out += "|"; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (!out.empty()) | ||||
|         { | ||||
|             if (!mz_zip_writer_add_mem(&archive, LAYER_CONFIG_RANGES_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) | ||||
|             { | ||||
|                 add_error("Unable to add layer heights profile file to archive"); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     bool _3MF_Exporter::_add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model) | ||||
|     { | ||||
|         std::string out = ""; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka