mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-16 20:25:54 +08:00
Export to prusa:
* now the .3mf contains the modified config compatible with purusaslicer * now the superslicer settings are stored in their own file. Note: projects saved with this version will transfer only prusa settings back to older superslicer version.
This commit is contained in:
parent
8f3e0b6fb4
commit
3799d533cc
@ -1648,7 +1648,11 @@ protected:
|
|||||||
// Both opt_key and value may be modified by handle_legacy().
|
// Both opt_key and value may be modified by handle_legacy().
|
||||||
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
||||||
// handle_legacy() is called internally by set_deserialize().
|
// handle_legacy() is called internally by set_deserialize().
|
||||||
virtual void handle_legacy(t_config_option_key &/*opt_key*/, std::string &/*value*/) const {}
|
virtual void handle_legacy(t_config_option_key&/*opt_key*/, std::string&/*value*/) const {}
|
||||||
|
// Verify whether the opt_key has to be converted or isn't present int prusaslicer
|
||||||
|
// Both opt_key and value may be modified by to_prusa().
|
||||||
|
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by to_prusa().
|
||||||
|
virtual void to_prusa(t_config_option_key&/*opt_key*/, std::string&/*value*/) const {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using ConfigOptionResolver::option;
|
using ConfigOptionResolver::option;
|
||||||
|
@ -48,8 +48,10 @@ const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format
|
|||||||
const std::string CONTENT_TYPES_FILE = "[Content_Types].xml";
|
const std::string CONTENT_TYPES_FILE = "[Content_Types].xml";
|
||||||
const std::string RELATIONSHIPS_FILE = "_rels/.rels";
|
const std::string RELATIONSHIPS_FILE = "_rels/.rels";
|
||||||
const std::string THUMBNAIL_FILE = "Metadata/thumbnail.png";
|
const std::string THUMBNAIL_FILE = "Metadata/thumbnail.png";
|
||||||
const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config";
|
const std::string PRINT_CONFIG_FILE = "Metadata/SuperSlicer.config";
|
||||||
const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config";
|
const std::string MODEL_CONFIG_FILE = "Metadata/SuperSlicer_model.config";
|
||||||
|
const std::string PRINT_PRUSA_CONFIG_FILE = "Metadata/Slic3r_PE.config";
|
||||||
|
const std::string MODEL_PRUSA_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/Prusa_Slicer_layer_config_ranges.xml";
|
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_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt";
|
||||||
@ -615,6 +617,7 @@ namespace Slic3r {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we then loop again the entries to read other files stored in the archive
|
// we then loop again the entries to read other files stored in the archive
|
||||||
|
bool print_config_parsed = false, model_config_parsed = false;
|
||||||
for (mz_uint i = 0; i < num_entries; ++i)
|
for (mz_uint i = 0; i < num_entries; ++i)
|
||||||
{
|
{
|
||||||
if (mz_zip_reader_file_stat(&archive, i, &stat))
|
if (mz_zip_reader_file_stat(&archive, i, &stat))
|
||||||
@ -646,6 +649,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
// extract slic3r print config file
|
// extract slic3r print config file
|
||||||
_extract_print_config_from_archive(archive, stat, config, filename);
|
_extract_print_config_from_archive(archive, stat, config, filename);
|
||||||
|
print_config_parsed = true;
|
||||||
}
|
}
|
||||||
if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_PRINT_Z_FILE))
|
if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_PRINT_Z_FILE))
|
||||||
{
|
{
|
||||||
@ -653,6 +657,32 @@ namespace Slic3r {
|
|||||||
_extract_custom_gcode_per_print_z_from_archive(archive, stat);
|
_extract_custom_gcode_per_print_z_from_archive(archive, stat);
|
||||||
}
|
}
|
||||||
else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE))
|
else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE))
|
||||||
|
{
|
||||||
|
// extract slic3r model config file
|
||||||
|
if (!_extract_model_config_from_archive(archive, stat, model))
|
||||||
|
{
|
||||||
|
close_zip_reader(&archive);
|
||||||
|
add_error("Archive does not contain a valid model config");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
model_config_parsed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//parsed prusa files if superslicer not found
|
||||||
|
for (mz_uint i = 0; i < num_entries; ++i)
|
||||||
|
{
|
||||||
|
if (mz_zip_reader_file_stat(&archive, i, &stat))
|
||||||
|
{
|
||||||
|
std::string name(stat.m_filename);
|
||||||
|
std::replace(name.begin(), name.end(), '\\', '/');
|
||||||
|
|
||||||
|
//TODO use special methods to convert them better?
|
||||||
|
if (!print_config_parsed && boost::algorithm::iequals(name, PRINT_PRUSA_CONFIG_FILE))
|
||||||
|
{
|
||||||
|
// extract slic3r print config file
|
||||||
|
_extract_print_config_from_archive(archive, stat, config, filename);
|
||||||
|
} else if (!model_config_parsed && boost::algorithm::iequals(name, MODEL_PRUSA_CONFIG_FILE))
|
||||||
{
|
{
|
||||||
// extract slic3r model config file
|
// extract slic3r model config file
|
||||||
if (!_extract_model_config_from_archive(archive, stat, model))
|
if (!_extract_model_config_from_archive(archive, stat, model))
|
||||||
@ -2661,13 +2691,13 @@ namespace Slic3r {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config)
|
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig& config)
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
sprintf(buffer, "; %s\n\n", header_slic3r_generated().c_str());
|
sprintf(buffer, "; %s\n\n", header_slic3r_generated().c_str());
|
||||||
std::string out = buffer;
|
std::string out = buffer;
|
||||||
|
|
||||||
for (const std::string &key : config.keys())
|
for (const std::string& key : config.keys())
|
||||||
if (key != "compatible_printers")
|
if (key != "compatible_printers")
|
||||||
out += "; " + key + " = " + config.opt_serialize(key) + "\n";
|
out += "; " + key + " = " + config.opt_serialize(key) + "\n";
|
||||||
|
|
||||||
@ -2680,18 +2710,44 @@ namespace Slic3r {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add prusa print config
|
||||||
|
out = buffer;
|
||||||
|
|
||||||
|
for (std::string key : config.keys())
|
||||||
|
if (key != "compatible_printers") {
|
||||||
|
std::string value = config.opt_serialize(key);
|
||||||
|
config.to_prusa(key, value);
|
||||||
|
if(!key.empty())
|
||||||
|
out += "; " + key + " = " + value + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!out.empty())
|
||||||
|
{
|
||||||
|
if (!mz_zip_writer_add_mem(&archive, PRINT_PRUSA_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
|
||||||
|
{
|
||||||
|
add_error("Unable to add prusa print config file to archive");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data)
|
bool _3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data)
|
||||||
{
|
{
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
|
std::stringstream stream_prusa;
|
||||||
// Store mesh transformation in full precision, as the volumes are stored transformed and they need to be transformed back
|
// Store mesh transformation in full precision, as the volumes are stored transformed and they need to be transformed back
|
||||||
// when loaded as accurately as possible.
|
// when loaded as accurately as possible.
|
||||||
stream << std::setprecision(std::numeric_limits<double>::max_digits10);
|
stream << std::setprecision(std::numeric_limits<double>::max_digits10);
|
||||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||||
stream << "<" << CONFIG_TAG << ">\n";
|
stream << "<" << CONFIG_TAG << ">\n";
|
||||||
|
|
||||||
|
stream_prusa << std::setprecision(std::numeric_limits<double>::max_digits10);
|
||||||
|
stream_prusa << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||||
|
stream_prusa << "<" << CONFIG_TAG << ">\n";
|
||||||
|
|
||||||
|
|
||||||
for (const IdToObjectDataMap::value_type& obj_metadata : objects_data)
|
for (const IdToObjectDataMap::value_type& obj_metadata : objects_data)
|
||||||
{
|
{
|
||||||
const ModelObject* obj = obj_metadata.second.object;
|
const ModelObject* obj = obj_metadata.second.object;
|
||||||
@ -2699,15 +2755,18 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
// Output of instances count added because of github #3435, currently not used by PrusaSlicer
|
// Output of instances count added because of github #3435, currently not used by PrusaSlicer
|
||||||
stream << " <" << OBJECT_TAG << " " << ID_ATTR << "=\"" << obj_metadata.first << "\" " << INSTANCESCOUNT_ATTR << "=\"" << obj->instances.size() << "\">\n";
|
stream << " <" << OBJECT_TAG << " " << ID_ATTR << "=\"" << obj_metadata.first << "\" " << INSTANCESCOUNT_ATTR << "=\"" << obj->instances.size() << "\">\n";
|
||||||
|
stream_prusa << " <" << OBJECT_TAG << " " << ID_ATTR << "=\"" << obj_metadata.first << "\" " << INSTANCESCOUNT_ATTR << "=\"" << obj->instances.size() << "\">\n";
|
||||||
|
|
||||||
// stores object's name
|
// stores object's name
|
||||||
if (!obj->name.empty())
|
if (!obj->name.empty()) {
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << xml_escape(obj->name) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << xml_escape(obj->name) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << xml_escape(obj->name) << "\"/>\n";
|
||||||
|
}
|
||||||
|
|
||||||
// stores object's config data
|
// stores object's config data
|
||||||
for (const std::string& key : obj->config.keys())
|
for (const std::string& key : obj->config.keys()) {
|
||||||
{
|
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << obj->config.opt_serialize(key) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << obj->config.opt_serialize(key) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << obj->config.opt_serialize(key) << "\"/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ModelVolume* volume : obj_metadata.second.object->volumes)
|
for (const ModelVolume* volume : obj_metadata.second.object->volumes)
|
||||||
@ -2722,20 +2781,30 @@ namespace Slic3r {
|
|||||||
stream << " <" << VOLUME_TAG << " ";
|
stream << " <" << VOLUME_TAG << " ";
|
||||||
stream << FIRST_TRIANGLE_ID_ATTR << "=\"" << it->second.first_triangle_id << "\" ";
|
stream << FIRST_TRIANGLE_ID_ATTR << "=\"" << it->second.first_triangle_id << "\" ";
|
||||||
stream << LAST_TRIANGLE_ID_ATTR << "=\"" << it->second.last_triangle_id << "\">\n";
|
stream << LAST_TRIANGLE_ID_ATTR << "=\"" << it->second.last_triangle_id << "\">\n";
|
||||||
|
stream_prusa << " <" << VOLUME_TAG << " ";
|
||||||
|
stream_prusa << FIRST_TRIANGLE_ID_ATTR << "=\"" << it->second.first_triangle_id << "\" ";
|
||||||
|
stream_prusa << LAST_TRIANGLE_ID_ATTR << "=\"" << it->second.last_triangle_id << "\">\n";
|
||||||
|
|
||||||
// stores volume's name
|
// stores volume's name
|
||||||
if (!volume->name.empty())
|
if (!volume->name.empty()) {
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n";
|
||||||
|
}
|
||||||
|
|
||||||
// stores volume's modifier field (legacy, to support old slicers)
|
// stores volume's modifier field (legacy, to support old slicers)
|
||||||
if (volume->is_modifier())
|
if (volume->is_modifier()) {
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MODIFIER_KEY << "\" " << VALUE_ATTR << "=\"1\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MODIFIER_KEY << "\" " << VALUE_ATTR << "=\"1\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MODIFIER_KEY << "\" " << VALUE_ATTR << "=\"1\"/>\n";
|
||||||
|
}
|
||||||
// stores volume's type (overrides the modifier field above)
|
// stores volume's type (overrides the modifier field above)
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " <<
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " <<
|
||||||
VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n";
|
VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " <<
|
||||||
|
VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n";
|
||||||
|
|
||||||
// stores volume's local matrix
|
// stores volume's local matrix
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MATRIX_KEY << "\" " << VALUE_ATTR << "=\"";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MATRIX_KEY << "\" " << VALUE_ATTR << "=\"";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MATRIX_KEY << "\" " << VALUE_ATTR << "=\"";
|
||||||
Transform3d matrix = volume->get_matrix() * volume->source.transform.get_matrix();
|
Transform3d matrix = volume->get_matrix() * volume->source.transform.get_matrix();
|
||||||
for (int r = 0; r < 4; ++r)
|
for (int r = 0; r < 4; ++r)
|
||||||
{
|
{
|
||||||
@ -2744,9 +2813,13 @@ namespace Slic3r {
|
|||||||
stream << matrix(r, c);
|
stream << matrix(r, c);
|
||||||
if ((r != 3) || (c != 3))
|
if ((r != 3) || (c != 3))
|
||||||
stream << " ";
|
stream << " ";
|
||||||
|
stream_prusa << matrix(r, c);
|
||||||
|
if ((r != 3) || (c != 3))
|
||||||
|
stream_prusa << " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stream << "\"/>\n";
|
stream << "\"/>\n";
|
||||||
|
stream_prusa << "\"/>\n";
|
||||||
|
|
||||||
// stores volume's source data
|
// stores volume's source data
|
||||||
if (!volume->source.input_file.empty())
|
if (!volume->source.input_file.empty())
|
||||||
@ -2758,24 +2831,39 @@ namespace Slic3r {
|
|||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_X_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(0) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_X_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(0) << "\"/>\n";
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_Y_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(1) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_Y_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(1) << "\"/>\n";
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_Z_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(2) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_Z_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(2) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_FILE_KEY << "\" " << VALUE_ATTR << "=\"" << input_file << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OBJECT_ID_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.object_idx << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_VOLUME_ID_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.volume_idx << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_X_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(0) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_Y_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(1) << "\"/>\n";
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << SOURCE_OFFSET_Z_KEY << "\" " << VALUE_ATTR << "=\"" << volume->source.mesh_offset(2) << "\"/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// stores volume's config data
|
// stores volume's config data
|
||||||
for (const std::string& key : volume->config.keys())
|
for (std::string key : volume->config.keys())
|
||||||
{
|
{
|
||||||
|
//superslicer config
|
||||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n";
|
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n";
|
||||||
|
//now the prusa config
|
||||||
|
std::string value = volume->config.opt_serialize(key);
|
||||||
|
volume->config.to_prusa(key, value);
|
||||||
|
if (!key.empty())
|
||||||
|
stream_prusa << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << value << "\"/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
stream << " </" << VOLUME_TAG << ">\n";
|
stream << " </" << VOLUME_TAG << ">\n";
|
||||||
|
stream_prusa << " </" << VOLUME_TAG << ">\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream << " </" << OBJECT_TAG << ">\n";
|
stream << " </" << OBJECT_TAG << ">\n";
|
||||||
|
stream_prusa << " </" << OBJECT_TAG << ">\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream << "</" << CONFIG_TAG << ">\n";
|
stream << "</" << CONFIG_TAG << ">\n";
|
||||||
|
stream_prusa << "</" << CONFIG_TAG << ">\n";
|
||||||
|
|
||||||
std::string out = stream.str();
|
std::string out = stream.str();
|
||||||
|
|
||||||
@ -2785,6 +2873,13 @@ namespace Slic3r {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out = stream_prusa.str();
|
||||||
|
if (!mz_zip_writer_add_mem(&archive, MODEL_PRUSA_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
|
||||||
|
{
|
||||||
|
add_error("Unable to add prusa model config file to archive");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4943,6 +4943,214 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value, const DynamicConfig& all_conf) {
|
||||||
|
|
||||||
|
std::unordered_set<std::string> to_remove_keys = {
|
||||||
|
"thumbnails_color",
|
||||||
|
"thumbnails_custom_color",
|
||||||
|
"thumbnails_with_bed",
|
||||||
|
"thumbnails_with_support",
|
||||||
|
"allow_empty_layers",
|
||||||
|
"avoid_crossing_not_first_layer",
|
||||||
|
"top_fan_speed",
|
||||||
|
"over_bridge_flow_ratio",
|
||||||
|
"bridge_overlap",
|
||||||
|
"bridge_speed_internal",
|
||||||
|
"brim_inside_holes",
|
||||||
|
"brim_width_interior",
|
||||||
|
"brim_ears",
|
||||||
|
"brim_ears_max_angle",
|
||||||
|
"brim_ears_pattern",
|
||||||
|
"brim_offset",
|
||||||
|
"chamber_temperature",
|
||||||
|
"complete_objects_one_skirt",
|
||||||
|
"complete_objects_sort",
|
||||||
|
"top_fill_pattern",
|
||||||
|
"solid_fill_pattern",
|
||||||
|
"enforce_full_fill_volume",
|
||||||
|
"external_infill_margin",
|
||||||
|
"bridged_infill_margin",
|
||||||
|
"external_perimeter_cut_corners",
|
||||||
|
"external_perimeter_fan_speed",
|
||||||
|
"external_perimeter_overlap",
|
||||||
|
"perimeter_overlap",
|
||||||
|
"perimeter_bonding",
|
||||||
|
"external_perimeters_vase",
|
||||||
|
"external_perimeters_nothole",
|
||||||
|
"external_perimeters_hole",
|
||||||
|
"perimeter_loop",
|
||||||
|
"perimeter_loop_seam",
|
||||||
|
"extra_perimeters_overhangs",
|
||||||
|
"extra_perimeters_odd_layers",
|
||||||
|
"only_one_perimeter_top",
|
||||||
|
"extruder_temperature_offset",
|
||||||
|
"extruder_fan_offset",
|
||||||
|
"print_extrusion_multiplier",
|
||||||
|
"filament_max_speed",
|
||||||
|
"filament_max_wipe_tower_speed",
|
||||||
|
"filament_enable_toolchange_temp",
|
||||||
|
"filament_use_fast_skinnydip",
|
||||||
|
"filament_enable_toolchange_part_fan",
|
||||||
|
"filament_toolchange_part_fan_speed",
|
||||||
|
"filament_use_skinnydip",
|
||||||
|
"filament_melt_zone_pause",
|
||||||
|
"filament_cooling_zone_pause",
|
||||||
|
"filament_dip_insertion_speed",
|
||||||
|
"filament_dip_extraction_speed",
|
||||||
|
"filament_toolchange_temp",
|
||||||
|
"filament_skinnydip_distance",
|
||||||
|
"filament_shrink",
|
||||||
|
"fill_angle_increment",
|
||||||
|
"fill_top_flow_ratio",
|
||||||
|
"fill_top_flow_ratio",
|
||||||
|
"first_layer_flow_ratio",
|
||||||
|
"fill_smooth_width",
|
||||||
|
"fill_smooth_distribution",
|
||||||
|
"first_layer_infill_speed",
|
||||||
|
"gap_fill",
|
||||||
|
"gap_fill_min_area",
|
||||||
|
"gap_fill_overlap",
|
||||||
|
"infill_dense",
|
||||||
|
"infill_connection",
|
||||||
|
"infill_dense_algo",
|
||||||
|
"feature_gcode",
|
||||||
|
"exact_last_layer_height",
|
||||||
|
"fan_speedup_time",
|
||||||
|
"fan_speedup_overhangs",
|
||||||
|
"fan_kickstart",
|
||||||
|
"machine_max_acceleration_travel",
|
||||||
|
"max_speed_reduction",
|
||||||
|
"min_length",
|
||||||
|
"min_width_top_surface",
|
||||||
|
"printhost_apikey",
|
||||||
|
"printhost_cafile",
|
||||||
|
"print_host",
|
||||||
|
"overhangs_speed",
|
||||||
|
"overhangs_width_speed",
|
||||||
|
"overhangs_reverse",
|
||||||
|
"overhangs_reverse_threshold",
|
||||||
|
"no_perimeter_unsupported_algo",
|
||||||
|
"support_material_solid_first_layer",
|
||||||
|
"print_retract_length",
|
||||||
|
"retract_lift_first_layer",
|
||||||
|
"retract_lift_top",
|
||||||
|
"seam_angle_cost",
|
||||||
|
"seam_travel_cost",
|
||||||
|
"skirt_extrusion_width",
|
||||||
|
"small_perimeter_min_length",
|
||||||
|
"small_perimeter_max_length",
|
||||||
|
"curve_smoothing_angle_convex",
|
||||||
|
"curve_smoothing_angle_concave",
|
||||||
|
"curve_smoothing_precision",
|
||||||
|
"curve_smoothing_cutoff_dist",
|
||||||
|
"model_precision",
|
||||||
|
"support_material_contact_distance_type",
|
||||||
|
"support_material_contact_distance_bottom",
|
||||||
|
"support_material_interface_pattern",
|
||||||
|
"print_temperature",
|
||||||
|
"print_retract_lift",
|
||||||
|
"thin_perimeters",
|
||||||
|
"thin_perimeters_all",
|
||||||
|
"thin_walls_min_width",
|
||||||
|
"thin_walls_overlap",
|
||||||
|
"thin_walls_merge",
|
||||||
|
"thin_walls_speed",
|
||||||
|
"time_estimation_compensation",
|
||||||
|
"tool_name",
|
||||||
|
"wipe_advanced",
|
||||||
|
"wipe_advanced_nozzle_melted_volume",
|
||||||
|
"filament_wipe_advanced_pigment",
|
||||||
|
"wipe_advanced_multiplier",
|
||||||
|
"wipe_advanced_algo",
|
||||||
|
"wipe_tower_brim",
|
||||||
|
"wipe_extra_perimeter",
|
||||||
|
"xy_inner_size_compensation",
|
||||||
|
"hole_size_compensation",
|
||||||
|
"hole_size_threshold",
|
||||||
|
"hole_to_polyhole",
|
||||||
|
"z_step",
|
||||||
|
"milling_cutter",
|
||||||
|
"milling_diameter",
|
||||||
|
"milling_offset",
|
||||||
|
"milling_z_offset",
|
||||||
|
"milling_z_lift",
|
||||||
|
"milling_toolchange_start_gcode",
|
||||||
|
"milling_toolchange_end_gcode",
|
||||||
|
"milling_post_process",
|
||||||
|
"milling_extra_size",
|
||||||
|
"milling_after_z",
|
||||||
|
"milling_speed"
|
||||||
|
|
||||||
|
};
|
||||||
|
//looks if it's to be removed, or have to be transformed
|
||||||
|
if (to_remove_keys.find(opt_key) != to_remove_keys.end()) {
|
||||||
|
opt_key = "";
|
||||||
|
value = "";
|
||||||
|
} else if (opt_key.find("_pattern") != std::string::npos) {
|
||||||
|
if ("smooth" == value || "smoothtriple" == value || "smoothhilbert" == value || "rectiwithperimeter" == value || "scatteredrectilinear" == value || "rectilineargapfill" == value || "sawtooth" == value) {
|
||||||
|
value = "rectilinear";
|
||||||
|
} else if ( "concentricgapfill" == value) {
|
||||||
|
value = "concentric";
|
||||||
|
}
|
||||||
|
} else if ("seam_position" == opt_key) {
|
||||||
|
if ("seam_travel_cost" == value || "near" == value || "hidden" == value) {
|
||||||
|
value = "nearest";
|
||||||
|
}
|
||||||
|
} else if ("first_layer_size_compensation" == opt_key) {
|
||||||
|
opt_key = "elefant_foot_compensation";
|
||||||
|
if (!value.empty()) {
|
||||||
|
if (value[0] == '-') {
|
||||||
|
value = value.substr(1);
|
||||||
|
} else {
|
||||||
|
value = "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("elephant_foot_min_width" == opt_key) {
|
||||||
|
opt_key = "elefant_foot_min_width";
|
||||||
|
} else if("first_layer_acceleration" == opt_key || "infill_acceleration" == opt_key || "bridge_acceleration" == opt_key || "default_acceleration" == opt_key || "overhangs_speed" == opt_key || "perimeter_acceleration" == opt_key){
|
||||||
|
if (value.find("%") != std::string::npos)
|
||||||
|
value = "0";
|
||||||
|
} else if ("gap_fill_speed" == opt_key && all_conf.has("gap_fill") && !all_conf.option<ConfigOptionBool>("gap_fill")->value) {
|
||||||
|
value = "0";
|
||||||
|
} else if ("bridge_flow_ratio" == opt_key && all_conf.has("bridge_flow_ratio")) {
|
||||||
|
value = boost::lexical_cast<std::string>(all_conf.option<ConfigOptionPercent>("bridge_flow_ratio")->get_abs_value(1));
|
||||||
|
} else if ("overhangs_width" == opt_key) {
|
||||||
|
opt_key = "overhangs";
|
||||||
|
if (value != "0")
|
||||||
|
value = "1";
|
||||||
|
} else if ("support_material_contact_distance_top" == opt_key) {
|
||||||
|
opt_key = "support_material_contact_distance";
|
||||||
|
//default : get the top value or 0.2 if a %
|
||||||
|
if (value.find("%") != std::string::npos)
|
||||||
|
value = "0.2";
|
||||||
|
try { //avoid most useless cheks and multiple corners cases with this try catch
|
||||||
|
SupportZDistanceType dist_type = all_conf.option<ConfigOptionEnum<SupportZDistanceType>>("support_material_contact_distance_type")->value;
|
||||||
|
if (SupportZDistanceType::zdNone == dist_type) {
|
||||||
|
value = "0";
|
||||||
|
} else {
|
||||||
|
double val = all_conf.option<ConfigOptionFloatOrPercent>("support_material_contact_distance_top")->get_abs_value(all_conf.option<ConfigOptionFloats>("nozzle_diameter")->values.front());
|
||||||
|
if (SupportZDistanceType::zdFilament == dist_type) { // not exact but good enough effort
|
||||||
|
val += all_conf.option<ConfigOptionFloats>("nozzle_diameter")->values.front();
|
||||||
|
val -= all_conf.get_abs_value("layer_height");
|
||||||
|
}
|
||||||
|
value = boost::lexical_cast<std::string>(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
}
|
||||||
|
} else if ("gcode_flavor" == opt_key) {
|
||||||
|
if ("reprap" == value)
|
||||||
|
value = "reprapfirmware";
|
||||||
|
else if ("sprinter" == value)
|
||||||
|
value = "reprap";
|
||||||
|
else if ("lerdge" == value)
|
||||||
|
value = "marlin";
|
||||||
|
else if ("klipper" == value)
|
||||||
|
value = "reprap";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const PrintConfigDef print_config_def;
|
const PrintConfigDef print_config_def;
|
||||||
|
|
||||||
DynamicPrintConfig DynamicPrintConfig::full_print_config()
|
DynamicPrintConfig DynamicPrintConfig::full_print_config()
|
||||||
|
@ -364,7 +364,8 @@ class PrintConfigDef : public ConfigDef
|
|||||||
public:
|
public:
|
||||||
PrintConfigDef();
|
PrintConfigDef();
|
||||||
|
|
||||||
static void handle_legacy(t_config_option_key &opt_key, std::string &value);
|
static void handle_legacy(t_config_option_key& opt_key, std::string& value);
|
||||||
|
static void to_prusa(t_config_option_key& opt_key, std::string& value, const DynamicConfig& all_conf);
|
||||||
|
|
||||||
// Array options growing with the number of extruders
|
// Array options growing with the number of extruders
|
||||||
const std::vector<std::string>& extruder_option_keys() const { return m_extruder_option_keys; }
|
const std::vector<std::string>& extruder_option_keys() const { return m_extruder_option_keys; }
|
||||||
@ -435,6 +436,9 @@ public:
|
|||||||
// handle_legacy() is called internally by set_deserialize().
|
// handle_legacy() is called internally by set_deserialize().
|
||||||
void handle_legacy(t_config_option_key &opt_key, std::string &value) const override
|
void handle_legacy(t_config_option_key &opt_key, std::string &value) const override
|
||||||
{ PrintConfigDef::handle_legacy(opt_key, value); }
|
{ PrintConfigDef::handle_legacy(opt_key, value); }
|
||||||
|
|
||||||
|
void to_prusa(t_config_option_key& opt_key, std::string& value) const override
|
||||||
|
{ PrintConfigDef::to_prusa(opt_key, value, *this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class StaticPrintConfig : public StaticConfig
|
class StaticPrintConfig : public StaticConfig
|
||||||
@ -1860,6 +1864,8 @@ public:
|
|||||||
// Not thread safe! Should not be called from other than the main thread!
|
// Not thread safe! Should not be called from other than the main thread!
|
||||||
void touch() { m_timestamp = ++ s_last_timestamp; }
|
void touch() { m_timestamp = ++ s_last_timestamp; }
|
||||||
|
|
||||||
|
void to_prusa(t_config_option_key& opt_key, std::string& value) const
|
||||||
|
{ m_data.to_prusa(opt_key, value); }
|
||||||
private:
|
private:
|
||||||
friend class cereal::access;
|
friend class cereal::access;
|
||||||
template<class Archive> void serialize(Archive& ar) { ar(m_timestamp); ar(m_data); }
|
template<class Archive> void serialize(Archive& ar) { ar(m_timestamp); ar(m_data); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user