Fixes to storing and loading configs from AMF/3MF.

This commit is contained in:
bubnikv 2018-11-07 14:57:50 +01:00
parent e529315ef9
commit 041de161a9
14 changed files with 53 additions and 67 deletions

View File

@ -189,7 +189,7 @@ inline void stl_normalize_vector(stl_normal &normal) {
if (length < 0.000000000001)
normal = stl_normal::Zero();
else
normal *= (1.0 / length);
normal *= float(1.0 / length);
}
inline bool stl_vertex_lower(const stl_vertex &a, const stl_vertex &b) {
return (a(0) != b(0)) ? (a(0) < b(0)) :

View File

@ -439,14 +439,16 @@ void ConfigBase::load_from_gcode_file(const std::string &file)
ifs.read(data.data(), data_length);
ifs.close();
load_from_gcode_string(data.data());
size_t key_value_pairs = load_from_gcode_string(data.data());
if (key_value_pairs < 80)
throw std::runtime_error((boost::format("Suspiciously low number of configuration values extracted from %1: %2") % file % key_value_pairs).str());
}
// Load the config keys from the given string.
void ConfigBase::load_from_gcode_string(const char* str)
size_t ConfigBase::load_from_gcode_string(const char* str)
{
if (str == nullptr)
return;
return 0;
// Walk line by line in reverse until a non-configuration key appears.
char *data_start = const_cast<char*>(str);
@ -497,11 +499,8 @@ void ConfigBase::load_from_gcode_string(const char* str)
}
end = start;
}
if (num_key_value_pairs < 90) {
char msg[80];
sprintf(msg, "Suspiciously low number of configuration values extracted: %d", num_key_value_pairs);
throw std::runtime_error(msg);
}
return num_key_value_pairs;
}
void ConfigBase::save(const std::string &file) const

View File

@ -1119,7 +1119,8 @@ public:
void load(const std::string &file);
void load_from_ini(const std::string &file);
void load_from_gcode_file(const std::string &file);
void load_from_gcode_string(const char* str);
// Returns number of key/value pairs extracted.
size_t load_from_gcode_string(const char* str);
void load(const boost::property_tree::ptree &tree);
void save(const std::string &file) const;

View File

@ -813,7 +813,7 @@ namespace Slic3r {
std::vector<Vec3f> sla_support_points;
for (unsigned int i=0; i<object_data_points.size(); i+=3)
sla_support_points.push_back(Vec3f(std::atof(object_data_points[i+0].c_str()), std::atof(object_data_points[i+1].c_str()), std::atof(object_data_points[i+2].c_str())));
sla_support_points.push_back(Vec3d(std::atof(object_data_points[i+0].c_str()), std::atof(object_data_points[i+1].c_str()), std::atof(object_data_points[i+2].c_str())).cast<float>());
if (!sla_support_points.empty())
m_sla_support_points.insert(IdToSlaSupportPointsMap::value_type(object_id, sla_support_points));
@ -1608,10 +1608,10 @@ namespace Slic3r {
IdToObjectDataMap m_objects_data;
public:
bool save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config);
bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config);
private:
bool _save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config);
bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config);
bool _add_content_types_file_to_archive(mz_zip_archive& archive);
bool _add_relationships_file_to_archive(mz_zip_archive& archive);
bool _add_model_file_to_archive(mz_zip_archive& archive, Model& model);
@ -1620,17 +1620,17 @@ namespace Slic3r {
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_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const Print& print);
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);
};
bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config)
bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config)
{
clear_errors();
return _save_model_to_file(filename, model, print, export_print_config);
return _save_model_to_file(filename, model, config);
}
bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config)
bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config)
{
mz_zip_archive archive;
mz_zip_zero_struct(&archive);
@ -1685,9 +1685,9 @@ namespace Slic3r {
}
// adds slic3r print config file
if (export_print_config)
if (config != nullptr)
{
if (!_add_print_config_file_to_archive(archive, print))
if (!_add_print_config_file_to_archive(archive, *config))
{
mz_zip_writer_end(&archive);
boost::filesystem::remove(filename);
@ -2017,13 +2017,15 @@ namespace Slic3r {
return true;
}
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const Print& print)
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config)
{
char buffer[1024];
sprintf(buffer, "; %s\n\n", header_slic3r_generated().c_str());
std::string out = buffer;
GCode::append_full_config(print, out);
for (const std::string &key : config.keys())
if (key != "compatible_printers")
out += "; " + key + " = " + config.serialize(key) + "\n";
if (!out.empty())
{
@ -2123,13 +2125,13 @@ namespace Slic3r {
return res;
}
bool store_3mf(const char* path, Model* model, Print* print, bool export_print_config)
bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config)
{
if ((path == nullptr) || (model == nullptr) || (print == nullptr))
if ((path == nullptr) || (model == nullptr))
return false;
_3MF_Exporter exporter;
bool res = exporter.save_model_to_file(path, *model, *print, export_print_config);
bool res = exporter.save_model_to_file(path, *model, config);
if (!res)
exporter.log_errors();

View File

@ -4,14 +4,14 @@
namespace Slic3r {
class Model;
class Print;
class DynamicPrintConfig;
// Load the content of a 3mf file into the given model and preset bundle.
extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model);
// Save the given model and the config data contained in the given Print into a 3mf file.
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
extern bool store_3mf(const char* path, Model* model, Print* print, bool export_print_config);
extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config);
}; // namespace Slic3r

View File

@ -834,9 +834,9 @@ bool load_amf(const char *path, DynamicPrintConfig *config, Model *model)
return false;
}
bool store_amf(const char *path, Model *model, Print* print, bool export_print_config)
bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config)
{
if ((path == nullptr) || (model == nullptr) || (print == nullptr))
if ((path == nullptr) || (model == nullptr))
return false;
// forces ".zip.amf" extension
@ -857,11 +857,13 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
stream << "<metadata type=\"cad\">Slic3r " << SLIC3R_VERSION << "</metadata>\n";
stream << "<metadata type=\"" << SLIC3RPE_AMF_VERSION << "\">" << VERSION_AMF << "</metadata>\n";
if (export_print_config)
if (config != nullptr)
{
std::string config = "\n";
GCode::append_full_config(*print, config);
stream << "<metadata type=\"" << SLIC3R_CONFIG_TYPE << "\">" << xml_escape(config) << "</metadata>\n";
std::string str_config = "\n";
for (const std::string &key : config->keys())
if (key != "compatible_printers")
str_config += "; " + key + " = " + config->serialize(key) + "\n";
stream << "<metadata type=\"" << SLIC3R_CONFIG_TYPE << "\">" << xml_escape(str_config) << "</metadata>\n";
}
for (const auto &material : model->materials) {

View File

@ -4,14 +4,14 @@
namespace Slic3r {
class Model;
class Print;
class DynamicPrintConfig;
// Load the content of an amf file into the given model and configuration.
extern bool load_amf(const char *path, DynamicPrintConfig *config, Model *model);
// Save the given model and the config data contained in the given Print into an amf file.
// Save the given model and the config data into an amf file.
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
extern bool store_amf(const char *path, Model *model, Print* print, bool export_print_config);
extern bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config);
}; // namespace Slic3r

View File

@ -58,7 +58,7 @@ inline Vec2d to_2d(const Vec3d &pt3) { return Vec2d (pt3(0), pt3(1)); }
inline Vec3d to_3d(const Vec2d &v, double z) { return Vec3d(v(0), v(1), z); }
inline Vec3f to_3d(const Vec2f &v, float z) { return Vec3f(v(0), v(1), z); }
inline Vec3i64 to_3d(const Vec2i64 &v, float z) { return Vec3i64(v(0), v(1), z); }
inline Vec3i64 to_3d(const Vec2i64 &v, float z) { return Vec3i64(int64_t(v(0)), int64_t(v(1)), int64_t(z)); }
inline Vec3crd to_3d(const Vec3crd &p, coord_t z) { return Vec3crd(p(0), p(1), z); }
inline Vec2d unscale(coord_t x, coord_t y) { return Vec2d(unscale<double>(x), unscale<double>(y)); }

View File

@ -186,7 +186,7 @@ int main(int argc, char **argv)
else
// Remove the previous extension and add .3mf extention.
outfile = outfile.substr(0, outfile.find_last_of('.')) + ".3mf";
store_3mf(outfile.c_str(), &model, nullptr, false);
store_3mf(outfile.c_str(), &model, nullptr);
boost::nowide::cout << "File file exported to " << outfile << std::endl;
} else if (cli_config.cut > 0) {
model.repair();

View File

@ -596,8 +596,7 @@ void MainFrame::load_config_file(wxString file/* = wxEmptyString*/)
// if (Slic3r::GUI::catch_error(this))
// return;
}
for (auto tab : m_options_tabs )
tab.second->load_current_preset();
wxGetApp().load_current_presets();
wxGetApp().app_config->update_config_dir(get_dir_name(file));
m_last_config = file;
}
@ -659,8 +658,7 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re
}
// Load the currently selected preset into the GUI, update the preset selection box.
for (auto tab : m_options_tabs)
tab.second->load_current_preset();
wxGetApp().load_current_presets();
const auto message = wxString::Format(_(L("%d presets successfully imported.")), presets_imported);
Slic3r::GUI::show_info(this, message, "Info");

View File

@ -1154,10 +1154,10 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path> &input_
{
DynamicPrintConfig config_loaded;
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, false);
// Based on the printer technology field found in the loaded config, select the base for the config,
PrinterTechnology printer_technology = Preset::printer_technology(config_loaded);
if (! config_loaded.empty()) {
config.apply(printer_technology == ptFFF ?
// Based on the printer technology field found in the loaded config, select the base for the config,
PrinterTechnology printer_technology = Preset::printer_technology(config_loaded);
config.apply(printer_technology == ptFFF ?
static_cast<const ConfigBase&>(FullPrintConfig::defaults()) :
static_cast<const ConfigBase&>(SLAFullPrintConfig::defaults()));
// and place the loaded config over the base.
@ -1167,8 +1167,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path> &input_
if (! config.empty()) {
Preset::normalize(config);
wxGetApp().preset_bundle->load_config_model(filename.string(), std::move(config));
for (const auto &kv : main_frame->options_tabs())
kv.second->load_current_preset();
wxGetApp().load_current_presets();
}
wxGetApp().app_config->update_config_dir(path.parent_path().string());
} else {
@ -2117,7 +2116,8 @@ void Plater::export_amf()
wxString path = dialog->GetPath();
auto path_cstr = path.c_str();
if (Slic3r::store_amf(path_cstr, &p->model, &p->print, dialog->get_checkbox_value())) {
DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config();
if (Slic3r::store_amf(path_cstr, &p->model, dialog->get_checkbox_value() ? &cfg : nullptr)) {
// Success
p->statusbar()->set_status_text(wxString::Format(_(L("AMF file exported to %s")), path));
} else {
@ -2136,7 +2136,8 @@ void Plater::export_3mf()
wxString path = dialog->GetPath();
auto path_cstr = path.c_str();
if (Slic3r::store_3mf(path_cstr, &p->model, &p->print, dialog->get_checkbox_value())) {
DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config();
if (Slic3r::store_3mf(path_cstr, &p->model, dialog->get_checkbox_value() ? &cfg : nullptr)) {
// Success
p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path));
} else {

View File

@ -618,18 +618,6 @@ void PresetBundle::load_config_file(const std::string &path)
}
}
void PresetBundle::load_config_string(const char* str, const char* source_filename)
{
if (str != nullptr)
{
DynamicPrintConfig config;
config.apply(FullPrintConfig::defaults());
config.load_from_gcode_string(str);
Preset::normalize(config);
load_config_file_config((source_filename == nullptr) ? "" : source_filename, true, std::move(config));
}
}
// Load a config file from a boost property_tree. This is a private method called from load_config_file.
void PresetBundle::load_config_file_config(const std::string &name_or_path, bool is_external, DynamicPrintConfig &&config)
{
@ -677,7 +665,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
compatible_printers_condition = compatible_printers_condition_values[idx];
if (is_external)
presets.load_external_preset(name_or_path, name,
config.opt_string((i_group == 0) ? ((printer_technology == ptFFF) ? "print_settings_id" : "sla_material_id") : "printer_settings_id", true),
config.opt_string((i_group == 0) ? ((printer_technology == ptFFF) ? "print_settings_id" : "sla_material_settings_id") : "printer_settings_id", true),
config);
else
presets.load_preset(presets.path_from_name(name), name, config).save();

View File

@ -84,11 +84,6 @@ public:
// If the file is loaded successfully, its print / filament / printer profiles will be activated.
void load_config_file(const std::string &path);
// Load an external config source containing the print, filament and printer presets.
// The given string must contain the full set of parameters (same as those exported to gcode).
// If the string is parsed successfully, its print / filament / printer profiles will be activated.
void load_config_string(const char* str, const char* source_filename = nullptr);
// Load a config bundle file, into presets and store the loaded presets into separate files
// of the local configuration directory.
// Load settings into the provided settings instance.

View File

@ -108,7 +108,7 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
m_widget_time->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
m_widget_volume->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
Bind(EVT_WIPE_TOWER_CHART_CHANGED,[this](wxCommandEvent&) {m_widget_volume->SetValue(m_chart->get_volume()); m_widget_time->SetValue(m_chart->get_time());} );
Refresh(this);
Refresh(true); // erase background
}
void RammingPanel::line_parameters_changed() {