Import/export of the Layers information to/from 3MF
This commit is contained in:
parent
f0f608f247
commit
4e0eb12ef6
@ -33,6 +33,7 @@ const std::string RELATIONSHIPS_FILE = "_rels/.rels";
|
|||||||
const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config";
|
const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config";
|
||||||
const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.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_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 std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt";
|
||||||
|
|
||||||
const char* MODEL_TAG = "model";
|
const char* MODEL_TAG = "model";
|
||||||
@ -331,6 +332,7 @@ namespace Slic3r {
|
|||||||
typedef std::map<int, ObjectMetadata> IdToMetadataMap;
|
typedef std::map<int, ObjectMetadata> IdToMetadataMap;
|
||||||
typedef std::map<int, Geometry> IdToGeometryMap;
|
typedef std::map<int, Geometry> IdToGeometryMap;
|
||||||
typedef std::map<int, std::vector<coordf_t>> IdToLayerHeightsProfileMap;
|
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;
|
typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap;
|
||||||
|
|
||||||
// Version of the 3mf file
|
// Version of the 3mf file
|
||||||
@ -347,6 +349,7 @@ namespace Slic3r {
|
|||||||
CurrentConfig m_curr_config;
|
CurrentConfig m_curr_config;
|
||||||
IdToMetadataMap m_objects_metadata;
|
IdToMetadataMap m_objects_metadata;
|
||||||
IdToLayerHeightsProfileMap m_layer_heights_profiles;
|
IdToLayerHeightsProfileMap m_layer_heights_profiles;
|
||||||
|
IdToLayerConfigRangesMap m_layer_config_ranges;
|
||||||
IdToSlaSupportPointsMap m_sla_support_points;
|
IdToSlaSupportPointsMap m_sla_support_points;
|
||||||
std::string m_curr_metadata_name;
|
std::string m_curr_metadata_name;
|
||||||
std::string m_curr_characters;
|
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 _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);
|
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_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_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);
|
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_curr_config.volume_id = -1;
|
||||||
m_objects_metadata.clear();
|
m_objects_metadata.clear();
|
||||||
m_layer_heights_profiles.clear();
|
m_layer_heights_profiles.clear();
|
||||||
|
m_layer_config_ranges.clear();
|
||||||
m_sla_support_points.clear();
|
m_sla_support_points.clear();
|
||||||
m_curr_metadata_name.clear();
|
m_curr_metadata_name.clear();
|
||||||
m_curr_characters.clear();
|
m_curr_characters.clear();
|
||||||
@ -546,9 +551,14 @@ namespace Slic3r {
|
|||||||
|
|
||||||
if (boost::algorithm::iequals(name, LAYER_HEIGHTS_PROFILE_FILE))
|
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);
|
_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))
|
else if (boost::algorithm::iequals(name, SLA_SUPPORT_POINTS_FILE))
|
||||||
{
|
{
|
||||||
// extract 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())
|
if (obj_layer_heights_profile != m_layer_heights_profiles.end())
|
||||||
model_object->layer_height_profile = obj_layer_heights_profile->second;
|
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.
|
// 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);
|
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()) {
|
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)
|
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)
|
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_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_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_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_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_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_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data);
|
||||||
@ -1682,6 +1807,16 @@ namespace Slic3r {
|
|||||||
return false;
|
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").
|
// 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.
|
// 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!
|
// 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;
|
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)
|
bool _3MF_Exporter::_add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model)
|
||||||
{
|
{
|
||||||
std::string out = "";
|
std::string out = "";
|
||||||
|
Loading…
Reference in New Issue
Block a user