Merge remote-tracking branch 'remotes/origin/amf_activate_existing_presets'
This commit is contained in:
commit
210eeff160
@ -22,6 +22,7 @@ xs/src/slic3r/GUI/UpdateDialogs.cpp
|
||||
xs/src/slic3r/GUI/WipeTowerDialog.cpp
|
||||
xs/src/slic3r/Utils/OctoPrint.cpp
|
||||
xs/src/slic3r/Utils/PresetUpdater.cpp
|
||||
xs/src/libslic3r/Print.cpp
|
||||
xs/src/libslic3r/PrintConfig.cpp
|
||||
xs/src/libslic3r/GCode/PreviewData.cpp
|
||||
lib/Slic3r/GUI.pm
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Escape \n, \r and backslash
|
||||
std::string escape_string_cstyle(const std::string &str)
|
||||
{
|
||||
// Allocate a buffer twice the input string length,
|
||||
@ -28,9 +29,15 @@ std::string escape_string_cstyle(const std::string &str)
|
||||
char *outptr = out.data();
|
||||
for (size_t i = 0; i < str.size(); ++ i) {
|
||||
char c = str[i];
|
||||
if (c == '\n' || c == '\r') {
|
||||
if (c == '\r') {
|
||||
(*outptr ++) = '\\';
|
||||
(*outptr ++) = 'r';
|
||||
} else if (c == '\n') {
|
||||
(*outptr ++) = '\\';
|
||||
(*outptr ++) = 'n';
|
||||
} else if (c == '\\') {
|
||||
(*outptr ++) = '\\';
|
||||
(*outptr ++) = '\\';
|
||||
} else
|
||||
(*outptr ++) = c;
|
||||
}
|
||||
@ -69,7 +76,10 @@ std::string escape_strings_cstyle(const std::vector<std::string> &strs)
|
||||
if (c == '\\' || c == '"') {
|
||||
(*outptr ++) = '\\';
|
||||
(*outptr ++) = c;
|
||||
} else if (c == '\n' || c == '\r') {
|
||||
} else if (c == '\r') {
|
||||
(*outptr ++) = '\\';
|
||||
(*outptr ++) = 'r';
|
||||
} else if (c == '\n') {
|
||||
(*outptr ++) = '\\';
|
||||
(*outptr ++) = 'n';
|
||||
} else
|
||||
@ -84,6 +94,7 @@ std::string escape_strings_cstyle(const std::vector<std::string> &strs)
|
||||
return std::string(out.data(), outptr - out.data());
|
||||
}
|
||||
|
||||
// Unescape \n, \r and backslash
|
||||
bool unescape_string_cstyle(const std::string &str, std::string &str_out)
|
||||
{
|
||||
std::vector<char> out(str.size(), 0);
|
||||
@ -94,8 +105,12 @@ bool unescape_string_cstyle(const std::string &str, std::string &str_out)
|
||||
if (++ i == str.size())
|
||||
return false;
|
||||
c = str[i];
|
||||
if (c == 'n')
|
||||
if (c == 'r')
|
||||
(*outptr ++) = '\r';
|
||||
else if (c == 'n')
|
||||
(*outptr ++) = '\n';
|
||||
else
|
||||
(*outptr ++) = c;
|
||||
} else
|
||||
(*outptr ++) = c;
|
||||
}
|
||||
@ -134,7 +149,9 @@ bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &o
|
||||
if (++ i == str.size())
|
||||
return false;
|
||||
c = str[i];
|
||||
if (c == 'n')
|
||||
if (c == 'r')
|
||||
c = '\r';
|
||||
else if (c == 'n')
|
||||
c = '\n';
|
||||
}
|
||||
buf.push_back(c);
|
||||
@ -188,7 +205,10 @@ void ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys
|
||||
throw UnknownOptionException(opt_key);
|
||||
}
|
||||
const ConfigOption *other_opt = other.option(opt_key);
|
||||
if (other_opt != nullptr)
|
||||
if (other_opt == nullptr) {
|
||||
// The key was not found in the source config, therefore it will not be initialized!
|
||||
// printf("Not found, therefore not initialized: %s\n", opt_key.c_str());
|
||||
} else
|
||||
my_opt->set(other_opt);
|
||||
}
|
||||
}
|
||||
|
@ -291,6 +291,8 @@ public:
|
||||
ConfigOptionFloats() : ConfigOptionVector<double>() {}
|
||||
explicit ConfigOptionFloats(size_t n, double value) : ConfigOptionVector<double>(n, value) {}
|
||||
explicit ConfigOptionFloats(std::initializer_list<double> il) : ConfigOptionVector<double>(std::move(il)) {}
|
||||
explicit ConfigOptionFloats(const std::vector<double> &vec) : ConfigOptionVector<double>(vec) {}
|
||||
explicit ConfigOptionFloats(std::vector<double> &&vec) : ConfigOptionVector<double>(std::move(vec)) {}
|
||||
|
||||
static ConfigOptionType static_type() { return coFloats; }
|
||||
ConfigOptionType type() const override { return static_type(); }
|
||||
|
@ -1411,15 +1411,22 @@ void GCode::apply_print_config(const PrintConfig &print_config)
|
||||
|
||||
void GCode::append_full_config(const Print& print, std::string& str)
|
||||
{
|
||||
const StaticPrintConfig *configs[] = { &print.config, &print.default_object_config, &print.default_region_config };
|
||||
const StaticPrintConfig *configs[] = { static_cast<const GCodeConfig*>(&print.config), &print.default_object_config, &print.default_region_config };
|
||||
for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++i) {
|
||||
const StaticPrintConfig *cfg = configs[i];
|
||||
for (const std::string &key : cfg->keys())
|
||||
{
|
||||
if (key != "compatible_printers")
|
||||
str += "; " + key + " = " + cfg->serialize(key) + "\n";
|
||||
}
|
||||
}
|
||||
const DynamicConfig &full_config = print.placeholder_parser.config();
|
||||
for (const char *key : {
|
||||
"print_settings_id", "filament_settings_id", "printer_settings_id",
|
||||
"printer_model", "printer_variant", "default_print_profile", "default_filament_profile",
|
||||
"compatible_printers_condition_cummulative", "inherits_cummulative" }) {
|
||||
const ConfigOption *opt = full_config.option(key);
|
||||
if (opt != nullptr)
|
||||
str += std::string("; ") + key + " = " + opt->serialize() + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void GCode::set_extruders(const std::vector<unsigned int> &extruder_ids)
|
||||
|
@ -2,7 +2,12 @@
|
||||
#include "PreviewData.hpp"
|
||||
#include <float.h>
|
||||
#include <wx/intl.h>
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include <I18N.hpp>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
//! macro used to mark string used at localization,
|
||||
#define L(s) (s)
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -405,7 +410,7 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
|
||||
items.reserve(last_valid - first_valid + 1);
|
||||
for (unsigned int i = (unsigned int)first_valid; i <= (unsigned int)last_valid; ++i)
|
||||
{
|
||||
items.emplace_back(_CHB(extrusion.role_names[i].c_str()).data(), extrusion.role_colors[i]);
|
||||
items.emplace_back(Slic3r::I18N::translate(extrusion.role_names[i]), extrusion.role_colors[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -436,13 +441,9 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
|
||||
items.reserve(tools_colors_count);
|
||||
for (unsigned int i = 0; i < tools_colors_count; ++i)
|
||||
{
|
||||
char buf[MIN_BUF_LENGTH_FOR_L];
|
||||
sprintf(buf, _CHB(L("Extruder %d")), i + 1);
|
||||
|
||||
GCodePreviewData::Color color;
|
||||
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + i * 4), 4 * sizeof(float));
|
||||
|
||||
items.emplace_back(buf, color);
|
||||
items.emplace_back((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str(), color);
|
||||
}
|
||||
|
||||
break;
|
||||
|
18
xs/src/libslic3r/I18N.hpp
Normal file
18
xs/src/libslic3r/I18N.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef slic3r_I18N_hpp_
|
||||
#define slic3r_I18N_hpp_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace I18N {
|
||||
typedef std::string (*translate_fn_type)(const char*);
|
||||
extern translate_fn_type translate_fn;
|
||||
inline void set_translate_callback(translate_fn_type fn) { translate_fn = fn; }
|
||||
inline std::string translate(const std::string &s) { return (translate_fn == nullptr) ? s : (*translate_fn)(s.c_str()); }
|
||||
inline std::string translate(const char *ptr) { return (translate_fn == nullptr) ? std::string(ptr) : (*translate_fn)(ptr); }
|
||||
} // namespace I18N
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_I18N_hpp_ */
|
@ -4,6 +4,7 @@
|
||||
#include "Extruder.hpp"
|
||||
#include "Flow.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "SupportMaterial.hpp"
|
||||
#include "GCode/WipeTowerPrusaMM.hpp"
|
||||
#include <algorithm>
|
||||
@ -11,6 +12,10 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
//! macro used to mark string used at localization,
|
||||
//! return same string
|
||||
#define L(s) Slic3r::I18N::translate(s)
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
template class PrintState<PrintStep, psCount>;
|
||||
@ -523,7 +528,7 @@ std::string Print::validate() const
|
||||
print_volume.min.z = -1e10;
|
||||
for (PrintObject *po : this->objects) {
|
||||
if (!print_volume.contains(po->model_object()->tight_bounding_box(false)))
|
||||
return "Some objects are outside of the print volume.";
|
||||
return L("Some objects are outside of the print volume.");
|
||||
}
|
||||
|
||||
if (this->config.complete_objects) {
|
||||
@ -550,7 +555,7 @@ std::string Print::validate() const
|
||||
Polygon p = convex_hull;
|
||||
p.translate(copy);
|
||||
if (! intersection(convex_hulls_other, p).empty())
|
||||
return "Some objects are too close; your extruder will collide with them.";
|
||||
return L("Some objects are too close; your extruder will collide with them.");
|
||||
polygons_append(convex_hulls_other, p);
|
||||
}
|
||||
}
|
||||
@ -565,7 +570,7 @@ std::string Print::validate() const
|
||||
// it will be printed as last one so its height doesn't matter.
|
||||
object_height.pop_back();
|
||||
if (! object_height.empty() && object_height.back() > scale_(this->config.extruder_clearance_height.value))
|
||||
return "Some objects are too tall and cannot be printed without extruder collisions.";
|
||||
return L("Some objects are too tall and cannot be printed without extruder collisions.");
|
||||
}
|
||||
} // end if (this->config.complete_objects)
|
||||
|
||||
@ -575,27 +580,22 @@ std::string Print::validate() const
|
||||
total_copies_count += object->copies().size();
|
||||
// #4043
|
||||
if (total_copies_count > 1 && ! this->config.complete_objects.value)
|
||||
return "The Spiral Vase option can only be used when printing a single object.";
|
||||
return L("The Spiral Vase option can only be used when printing a single object.");
|
||||
if (this->regions.size() > 1)
|
||||
return "The Spiral Vase option can only be used when printing single material objects.";
|
||||
return L("The Spiral Vase option can only be used when printing single material objects.");
|
||||
}
|
||||
|
||||
if (this->config.single_extruder_multi_material) {
|
||||
for (size_t i=1; i<this->config.nozzle_diameter.values.size(); ++i)
|
||||
if (this->config.nozzle_diameter.values[i] != this->config.nozzle_diameter.values[i-1])
|
||||
return "All extruders must have the same diameter for single extruder multimaterial printer.";
|
||||
return L("All extruders must have the same diameter for single extruder multimaterial printer.");
|
||||
}
|
||||
|
||||
if (this->has_wipe_tower() && ! this->objects.empty()) {
|
||||
#if 0
|
||||
for (auto dmr : this->config.nozzle_diameter.values)
|
||||
if (std::abs(dmr - 0.4) > EPSILON)
|
||||
return "The Wipe Tower is currently only supported for the 0.4mm nozzle diameter.";
|
||||
#endif
|
||||
if (this->config.gcode_flavor != gcfRepRap && this->config.gcode_flavor != gcfMarlin)
|
||||
return "The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors.";
|
||||
return L("The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors.");
|
||||
if (! this->config.use_relative_e_distances)
|
||||
return "The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).";
|
||||
return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
|
||||
SlicingParameters slicing_params0 = this->objects.front()->slicing_parameters();
|
||||
|
||||
const PrintObject* tallest_object = this->objects.front(); // let's find the tallest object
|
||||
@ -607,13 +607,13 @@ std::string Print::validate() const
|
||||
SlicingParameters slicing_params = object->slicing_parameters();
|
||||
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
|
||||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
|
||||
return "The Wipe Tower is only supported for multiple objects if they have equal layer heigths";
|
||||
return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths");
|
||||
if (slicing_params.raft_layers() != slicing_params0.raft_layers())
|
||||
return "The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers";
|
||||
return L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers");
|
||||
if (object->config.support_material_contact_distance != this->objects.front()->config.support_material_contact_distance)
|
||||
return "The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance";
|
||||
return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance");
|
||||
if (! equal_layering(slicing_params, slicing_params0))
|
||||
return "The Wipe Tower is only supported for multiple objects if they are sliced equally.";
|
||||
return L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
|
||||
bool was_layer_height_profile_valid = object->layer_height_profile_valid;
|
||||
object->update_layer_height_profile();
|
||||
object->layer_height_profile_valid = was_layer_height_profile_valid;
|
||||
@ -637,13 +637,8 @@ std::string Print::validate() const
|
||||
failed = true;
|
||||
|
||||
if (failed)
|
||||
return "The Wipe tower is only supported if all objects have the same layer height profile";
|
||||
return L("The Wipe tower is only supported if all objects have the same layer height profile");
|
||||
}
|
||||
|
||||
/*for (size_t i = 5; i < object->layer_height_profile.size(); i += 2)
|
||||
if (object->layer_height_profile[i-1] > slicing_params.object_print_z_min + EPSILON &&
|
||||
std::abs(object->layer_height_profile[i] - object->config.layer_height) > EPSILON)
|
||||
return "The Wipe Tower is currently only supported with constant Z layer spacing. Layer editing is not allowed.";*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,7 +646,7 @@ std::string Print::validate() const
|
||||
// find the smallest nozzle diameter
|
||||
std::vector<unsigned int> extruders = this->extruders();
|
||||
if (extruders.empty())
|
||||
return "The supplied settings will cause an empty print.";
|
||||
return L("The supplied settings will cause an empty print.");
|
||||
|
||||
std::vector<double> nozzle_diameters;
|
||||
for (unsigned int extruder_id : extruders)
|
||||
@ -661,7 +656,7 @@ std::string Print::validate() const
|
||||
unsigned int total_extruders_count = this->config.nozzle_diameter.size();
|
||||
for (const auto& extruder_idx : extruders)
|
||||
if ( extruder_idx >= total_extruders_count )
|
||||
return "One or more object were assigned an extruder that the printer does not have.";
|
||||
return L("One or more object were assigned an extruder that the printer does not have.");
|
||||
|
||||
for (PrintObject *object : this->objects) {
|
||||
if ((object->config.support_material_extruder == -1 || object->config.support_material_interface_extruder == -1) &&
|
||||
@ -670,13 +665,13 @@ std::string Print::validate() const
|
||||
// will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles
|
||||
// are of the same diameter.
|
||||
if (nozzle_diameters.size() > 1)
|
||||
return "Printing with multiple extruders of differing nozzle diameters. "
|
||||
return L("Printing with multiple extruders of differing nozzle diameters. "
|
||||
"If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), "
|
||||
"all nozzles have to be of the same diameter.";
|
||||
"all nozzles have to be of the same diameter.");
|
||||
}
|
||||
|
||||
// validate first_layer_height
|
||||
double first_layer_height = object->config.get_abs_value("first_layer_height");
|
||||
double first_layer_height = object->config.get_abs_value(L("first_layer_height"));
|
||||
double first_layer_min_nozzle_diameter;
|
||||
if (object->config.raft_layers > 0) {
|
||||
// if we have raft layers, only support material extruder is used on first layer
|
||||
@ -691,11 +686,11 @@ std::string Print::validate() const
|
||||
first_layer_min_nozzle_diameter = min_nozzle_diameter;
|
||||
}
|
||||
if (first_layer_height > first_layer_min_nozzle_diameter)
|
||||
return "First layer height can't be greater than nozzle diameter";
|
||||
return L("First layer height can't be greater than nozzle diameter");
|
||||
|
||||
// validate layer_height
|
||||
if (object->config.layer_height.value > min_nozzle_diameter)
|
||||
return "Layer height can't be greater than nozzle diameter";
|
||||
return L("Layer height can't be greater than nozzle diameter");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1212,7 +1207,7 @@ std::string Print::output_filename()
|
||||
try {
|
||||
return this->placeholder_parser.process(this->config.output_filename_format.value, 0);
|
||||
} catch (std::runtime_error &err) {
|
||||
throw std::runtime_error(std::string("Failed processing of the output_filename_format template.\n") + err.what());
|
||||
throw std::runtime_error(L("Failed processing of the output_filename_format template.") + "\n" + err.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include "PrintConfig.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
@ -11,7 +14,7 @@ namespace Slic3r {
|
||||
|
||||
//! macro used to mark string used at localization,
|
||||
//! return same string
|
||||
#define L(s) s
|
||||
#define L(s) Slic3r::I18N::translate(s)
|
||||
|
||||
PrintConfigDef::PrintConfigDef()
|
||||
{
|
||||
@ -151,6 +154,11 @@ PrintConfigDef::PrintConfigDef()
|
||||
"with the active printer profile.");
|
||||
def->default_value = new ConfigOptionString();
|
||||
|
||||
// The following value is to be stored into the project file (AMF, 3MF, Config ...)
|
||||
// and it contains a sum of "compatible_printers_condition" values over the print and filament profiles.
|
||||
def = this->add("compatible_printers_condition_cummulative", coStrings);
|
||||
def->default_value = new ConfigOptionStrings();
|
||||
|
||||
def = this->add("complete_objects", coBool);
|
||||
def->label = L("Complete individual objects");
|
||||
def->tooltip = L("When printing multiple objects or copies, this feature will complete "
|
||||
@ -821,7 +829,12 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->tooltip = L("Name of the profile, from which this profile inherits.");
|
||||
def->full_width = true;
|
||||
def->height = 50;
|
||||
def->default_value = new ConfigOptionString("");
|
||||
def->default_value = new ConfigOptionString();
|
||||
|
||||
// The following value is to be stored into the project file (AMF, 3MF, Config ...)
|
||||
// and it contains a sum of "inherits" values over the print and filament profiles.
|
||||
def = this->add("inherits_cummulative", coStrings);
|
||||
def->default_value = new ConfigOptionStrings();
|
||||
|
||||
def = this->add("interface_shells", coBool);
|
||||
def->label = L("Interface shells");
|
||||
@ -853,6 +866,85 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(0.3);
|
||||
|
||||
{
|
||||
struct AxisDefault {
|
||||
std::string name;
|
||||
std::vector<double> max_feedrate;
|
||||
std::vector<double> max_acceleration;
|
||||
std::vector<double> max_jerk;
|
||||
};
|
||||
std::vector<AxisDefault> axes {
|
||||
// name, max_feedrate, max_acceleration, max_jerk
|
||||
{ "x", { 200., 200. }, { 1000., 1000. }, { 10., 10. } },
|
||||
{ "y", { 200., 200. }, { 1000., 1000. }, { 10., 10. } },
|
||||
{ "z", { 12., 12. }, { 200., 200. }, { 0.4, 0.4 } },
|
||||
{ "e", { 120., 120. }, { 5000., 5000. }, { 2.5, 2.5 } }
|
||||
};
|
||||
for (const AxisDefault &axis : axes) {
|
||||
std::string axis_upper = boost::to_upper_copy<std::string>(axis.name);
|
||||
// Add the machine feedrate limits for XYZE axes. (M203)
|
||||
def = this->add("machine_max_feedrate_" + axis.name, coFloats);
|
||||
def->label = (boost::format(L("Maximum feedrate %1%")) % axis_upper).str();
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = (boost::format(L("Maximum feedrate of the %1% axis")) % axis_upper).str();
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(axis.max_feedrate);
|
||||
// Add the machine acceleration limits for XYZE axes (M201)
|
||||
def = this->add("machine_max_acceleration_" + axis.name, coFloats);
|
||||
def->label = (boost::format(L("Maximum acceleration %1%")) % axis_upper).str();
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = (boost::format(L("Maximum acceleration of the %1% axis")) % axis_upper).str();
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(axis.max_acceleration);
|
||||
// Add the machine jerk limits for XYZE axes (M205)
|
||||
def = this->add("machine_max_jerk_" + axis.name, coFloats);
|
||||
def->label = (boost::format(L("Maximum jerk %1%")) % axis_upper).str();
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = (boost::format(L("Maximum jerk of the %1% axis")) % axis_upper).str();
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(axis.max_jerk);
|
||||
}
|
||||
}
|
||||
|
||||
// M205 S... [mm/sec]
|
||||
def = this->add("machine_min_extruding_rate", coFloats);
|
||||
def->label = L("Minimum feedrate when extruding");
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = L("Minimum feedrate when extruding") + " (M205 S)";
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(0., 0.);
|
||||
|
||||
// M205 T... [mm/sec]
|
||||
def = this->add("machine_min_travel_rate", coFloats);
|
||||
def->label = L("Minimum travel feedrate");
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = L("Minimum travel feedrate") + " (M205 T)";
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(0., 0.);
|
||||
|
||||
// M204 S... [mm/sec^2]
|
||||
def = this->add("machine_max_acceleration_extruding", coFloats);
|
||||
def->label = L("Maximum acceleration when extruding");
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = L("Maximum acceleration when extruding") + " (M204 S)";
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(1250., 1250.);
|
||||
|
||||
// M204 T... [mm/sec^2]
|
||||
def = this->add("machine_max_acceleration_retracting", coFloats);
|
||||
def->label = L("Maximum acceleration when retracting");
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = L("Maximum acceleration when retracting") + " (M204 T)";
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloats(1250., 1250.);
|
||||
|
||||
def = this->add("max_fan_speed", coInts);
|
||||
def->label = L("Max");
|
||||
def->tooltip = L("This setting represents the maximum speed of your fan.");
|
||||
@ -2198,6 +2290,7 @@ std::string FullPrintConfig::validate()
|
||||
// Declare the static caches for each StaticPrintConfig derived class.
|
||||
StaticPrintConfig::StaticCache<class Slic3r::PrintObjectConfig> PrintObjectConfig::s_cache_PrintObjectConfig;
|
||||
StaticPrintConfig::StaticCache<class Slic3r::PrintRegionConfig> PrintRegionConfig::s_cache_PrintRegionConfig;
|
||||
StaticPrintConfig::StaticCache<class Slic3r::MachineEnvelopeConfig> MachineEnvelopeConfig::s_cache_MachineEnvelopeConfig;
|
||||
StaticPrintConfig::StaticCache<class Slic3r::GCodeConfig> GCodeConfig::s_cache_GCodeConfig;
|
||||
StaticPrintConfig::StaticCache<class Slic3r::PrintConfig> PrintConfig::s_cache_PrintConfig;
|
||||
StaticPrintConfig::StaticCache<class Slic3r::HostConfig> HostConfig::s_cache_HostConfig;
|
||||
|
@ -455,6 +455,56 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class MachineEnvelopeConfig : public StaticPrintConfig
|
||||
{
|
||||
STATIC_PRINT_CONFIG_CACHE(MachineEnvelopeConfig)
|
||||
public:
|
||||
// M201 X... Y... Z... E... [mm/sec^2]
|
||||
ConfigOptionFloats machine_max_acceleration_x;
|
||||
ConfigOptionFloats machine_max_acceleration_y;
|
||||
ConfigOptionFloats machine_max_acceleration_z;
|
||||
ConfigOptionFloats machine_max_acceleration_e;
|
||||
// M203 X... Y... Z... E... [mm/sec]
|
||||
ConfigOptionFloats machine_max_feedrate_x;
|
||||
ConfigOptionFloats machine_max_feedrate_y;
|
||||
ConfigOptionFloats machine_max_feedrate_z;
|
||||
ConfigOptionFloats machine_max_feedrate_e;
|
||||
// M204 S... [mm/sec^2]
|
||||
ConfigOptionFloats machine_max_acceleration_extruding;
|
||||
// M204 T... [mm/sec^2]
|
||||
ConfigOptionFloats machine_max_acceleration_retracting;
|
||||
// M205 X... Y... Z... E... [mm/sec]
|
||||
ConfigOptionFloats machine_max_jerk_x;
|
||||
ConfigOptionFloats machine_max_jerk_y;
|
||||
ConfigOptionFloats machine_max_jerk_z;
|
||||
ConfigOptionFloats machine_max_jerk_e;
|
||||
// M205 T... [mm/sec]
|
||||
ConfigOptionFloats machine_min_travel_rate;
|
||||
// M205 S... [mm/sec]
|
||||
ConfigOptionFloats machine_min_extruding_rate;
|
||||
|
||||
protected:
|
||||
void initialize(StaticCacheBase &cache, const char *base_ptr)
|
||||
{
|
||||
OPT_PTR(machine_max_acceleration_x);
|
||||
OPT_PTR(machine_max_acceleration_y);
|
||||
OPT_PTR(machine_max_acceleration_z);
|
||||
OPT_PTR(machine_max_acceleration_e);
|
||||
OPT_PTR(machine_max_feedrate_x);
|
||||
OPT_PTR(machine_max_feedrate_y);
|
||||
OPT_PTR(machine_max_feedrate_z);
|
||||
OPT_PTR(machine_max_feedrate_e);
|
||||
OPT_PTR(machine_max_acceleration_extruding);
|
||||
OPT_PTR(machine_max_acceleration_retracting);
|
||||
OPT_PTR(machine_max_jerk_x);
|
||||
OPT_PTR(machine_max_jerk_y);
|
||||
OPT_PTR(machine_max_jerk_z);
|
||||
OPT_PTR(machine_max_jerk_e);
|
||||
OPT_PTR(machine_min_travel_rate);
|
||||
OPT_PTR(machine_min_extruding_rate);
|
||||
}
|
||||
};
|
||||
|
||||
// This object is mapped to Perl as Slic3r::Config::GCode.
|
||||
class GCodeConfig : public StaticPrintConfig
|
||||
{
|
||||
@ -566,7 +616,7 @@ protected:
|
||||
};
|
||||
|
||||
// This object is mapped to Perl as Slic3r::Config::Print.
|
||||
class PrintConfig : public GCodeConfig
|
||||
class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig
|
||||
{
|
||||
STATIC_PRINT_CONFIG_CACHE_DERIVED(PrintConfig)
|
||||
PrintConfig() : GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); }
|
||||
@ -642,6 +692,7 @@ protected:
|
||||
PrintConfig(int) : GCodeConfig(1) {}
|
||||
void initialize(StaticCacheBase &cache, const char *base_ptr)
|
||||
{
|
||||
this->MachineEnvelopeConfig::initialize(cache, base_ptr);
|
||||
this->GCodeConfig::initialize(cache, base_ptr);
|
||||
OPT_PTR(avoid_crossing_perimeters);
|
||||
OPT_PTR(bed_shape);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "Utils.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include <locale>
|
||||
#include <ctime>
|
||||
@ -123,6 +124,9 @@ const std::string& localization_dir()
|
||||
return g_local_dir;
|
||||
}
|
||||
|
||||
// Translate function callback, to call wxWidgets translate function to convert non-localized UTF8 string to a localized one.
|
||||
Slic3r::I18N::translate_fn_type Slic3r::I18N::translate_fn = nullptr;
|
||||
|
||||
static std::string g_data_dir;
|
||||
|
||||
void set_data_dir(const std::string &dir)
|
||||
|
@ -56,9 +56,9 @@
|
||||
|
||||
#include "../Utils/PresetUpdater.hpp"
|
||||
#include "../Config/Snapshot.hpp"
|
||||
#include "libslic3r/I18N.hpp"
|
||||
#include "3DScene.hpp"
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
#if __APPLE__
|
||||
@ -150,9 +150,13 @@ void update_label_colours_from_appconfig()
|
||||
}
|
||||
}
|
||||
|
||||
static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); }
|
||||
|
||||
void set_wxapp(wxApp *app)
|
||||
{
|
||||
g_wxApp = app;
|
||||
// Let the libslic3r know the callback, which will translate messages on demand.
|
||||
Slic3r::I18N::set_translate_callback(libslic3r_translate_callback);
|
||||
init_label_colours();
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,14 @@ class PresetUpdater;
|
||||
class DynamicPrintConfig;
|
||||
class TabIface;
|
||||
|
||||
#define _(s) Slic3r::translate((s))
|
||||
inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); }
|
||||
inline wxString translate(const wchar_t *s) { return wxGetTranslation(s); }
|
||||
inline wxString translate(const std::string &s) { return wxGetTranslation(wxString(s.c_str(), wxConvUTF8)); }
|
||||
inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_str()); }
|
||||
#define _(s) Slic3r::GUI::I18N::translate((s))
|
||||
|
||||
namespace GUI { namespace I18N {
|
||||
inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); }
|
||||
inline wxString translate(const wchar_t *s) { return wxGetTranslation(s); }
|
||||
inline wxString translate(const std::string &s) { return wxGetTranslation(wxString(s.c_str(), wxConvUTF8)); }
|
||||
inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_str()); }
|
||||
} }
|
||||
|
||||
// !!! If you needed to translate some wxString,
|
||||
// !!! please use _(L(string))
|
||||
|
@ -234,12 +234,12 @@ std::string Preset::label() const
|
||||
|
||||
bool Preset::is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const
|
||||
{
|
||||
auto *condition = dynamic_cast<const ConfigOptionString*>(this->config.option("compatible_printers_condition"));
|
||||
auto &condition = this->compatible_printers_condition();
|
||||
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(this->config.option("compatible_printers"));
|
||||
bool has_compatible_printers = compatible_printers != nullptr && ! compatible_printers->values.empty();
|
||||
if (! has_compatible_printers && condition != nullptr && ! condition->value.empty()) {
|
||||
if (! has_compatible_printers && ! condition.empty()) {
|
||||
try {
|
||||
return PlaceholderParser::evaluate_boolean_expression(condition->value, active_printer.config, extra_config);
|
||||
return PlaceholderParser::evaluate_boolean_expression(condition, active_printer.config, extra_config);
|
||||
} catch (const std::runtime_error &err) {
|
||||
//FIXME in case of an error, return "compatible with everything".
|
||||
printf("Preset::is_compatible_with_printer - parsing error of compatible_printers_condition %s:\n%s\n", active_printer.name.c_str(), err.what());
|
||||
@ -424,7 +424,87 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string
|
||||
{
|
||||
DynamicPrintConfig cfg(this->default_preset().config);
|
||||
cfg.apply_only(config, cfg.keys(), true);
|
||||
return this->load_preset(path, name, std::move(cfg));
|
||||
return this->load_preset(path, name, std::move(cfg), select);
|
||||
}
|
||||
|
||||
static bool profile_print_params_same(const DynamicPrintConfig &cfg1, const DynamicPrintConfig &cfg2)
|
||||
{
|
||||
t_config_option_keys diff = cfg1.diff(cfg2);
|
||||
// Following keys are used by the UI, not by the slicing core, therefore they are not important
|
||||
// when comparing profiles for equality. Ignore them.
|
||||
for (const char *key : { "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"print_settings_id", "filament_settings_id", "printer_settings_id",
|
||||
"printer_model", "printer_variant", "default_print_profile", "default_filament_profile" })
|
||||
diff.erase(std::remove(diff.begin(), diff.end(), key), diff.end());
|
||||
// Preset with the same name as stored inside the config exists.
|
||||
return diff.empty();
|
||||
}
|
||||
|
||||
// Load a preset from an already parsed config file, insert it into the sorted sequence of presets
|
||||
// and select it, losing previous modifications.
|
||||
// In case
|
||||
Preset& PresetCollection::load_external_preset(
|
||||
// Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
|
||||
const std::string &path,
|
||||
// Name of the profile, derived from the source file name.
|
||||
const std::string &name,
|
||||
// Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
|
||||
const std::string &original_name,
|
||||
// Config to initialize the preset from.
|
||||
const DynamicPrintConfig &config,
|
||||
// Select the preset after loading?
|
||||
bool select)
|
||||
{
|
||||
// Load the preset over a default preset, so that the missing fields are filled in from the default preset.
|
||||
DynamicPrintConfig cfg(this->default_preset().config);
|
||||
cfg.apply_only(config, cfg.keys(), true);
|
||||
// Is there a preset already loaded with the name stored inside the config?
|
||||
std::deque<Preset>::iterator it = this->find_preset_internal(original_name);
|
||||
if (it != m_presets.end() && it->name == original_name && profile_print_params_same(it->config, cfg)) {
|
||||
// The preset exists and it matches the values stored inside config.
|
||||
if (select)
|
||||
this->select_preset(it - m_presets.begin());
|
||||
return *it;
|
||||
}
|
||||
// Update the "inherits" field.
|
||||
std::string &inherits = Preset::inherits(cfg);
|
||||
if (it != m_presets.end() && inherits.empty()) {
|
||||
// There is a profile with the same name already loaded. Should we update the "inherits" field?
|
||||
if (it->vendor == nullptr)
|
||||
inherits = it->inherits();
|
||||
else
|
||||
inherits = it->name;
|
||||
}
|
||||
// The external preset does not match an internal preset, load the external preset.
|
||||
std::string new_name;
|
||||
for (size_t idx = 0;; ++ idx) {
|
||||
std::string suffix;
|
||||
if (original_name.empty()) {
|
||||
if (idx > 0)
|
||||
suffix = " (" + std::to_string(idx) + ")";
|
||||
} else {
|
||||
if (idx == 0)
|
||||
suffix = " (" + original_name + ")";
|
||||
else
|
||||
suffix = " (" + original_name + "-" + std::to_string(idx) + ")";
|
||||
}
|
||||
new_name = name + suffix;
|
||||
it = this->find_preset_internal(new_name);
|
||||
if (it == m_presets.end() || it->name != new_name)
|
||||
// Unique profile name. Insert a new profile.
|
||||
break;
|
||||
if (profile_print_params_same(it->config, cfg)) {
|
||||
// The preset exists and it matches the values stored inside config.
|
||||
if (select)
|
||||
this->select_preset(it - m_presets.begin());
|
||||
return *it;
|
||||
}
|
||||
// Form another profile name.
|
||||
}
|
||||
// Insert a new profile.
|
||||
Preset &preset = this->load_preset(path, new_name, std::move(cfg), select);
|
||||
preset.is_external = true;
|
||||
return preset;
|
||||
}
|
||||
|
||||
Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select)
|
||||
@ -460,7 +540,7 @@ void PresetCollection::save_current_preset(const std::string &new_name)
|
||||
} else {
|
||||
// Creating a new preset.
|
||||
Preset &preset = *m_presets.insert(it, m_edited_preset);
|
||||
std::string &inherits = preset.config.opt_string("inherits", true);
|
||||
std::string &inherits = preset.inherits();
|
||||
std::string old_name = preset.name;
|
||||
preset.name = new_name;
|
||||
preset.file = this->path_from_name(new_name);
|
||||
@ -475,7 +555,6 @@ void PresetCollection::save_current_preset(const std::string &new_name)
|
||||
// Inherited from a user preset. Just maintain the "inherited" flag,
|
||||
// meaning it will inherit from either the system preset, or the inherited user preset.
|
||||
}
|
||||
preset.inherits = inherits;
|
||||
preset.is_default = false;
|
||||
preset.is_system = false;
|
||||
preset.is_external = false;
|
||||
@ -513,20 +592,20 @@ bool PresetCollection::load_bitmap_default(const std::string &file_name)
|
||||
|
||||
const Preset* PresetCollection::get_selected_preset_parent() const
|
||||
{
|
||||
auto *inherits = dynamic_cast<const ConfigOptionString*>(this->get_edited_preset().config.option("inherits"));
|
||||
if (inherits == nullptr || inherits->value.empty())
|
||||
return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; // nullptr;
|
||||
const Preset* preset = this->find_preset(inherits->value, false);
|
||||
const std::string &inherits = this->get_edited_preset().inherits();
|
||||
if (inherits.empty())
|
||||
return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
|
||||
const Preset* preset = this->find_preset(inherits, false);
|
||||
return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset;
|
||||
}
|
||||
|
||||
const Preset* PresetCollection::get_preset_parent(const Preset& child) const
|
||||
{
|
||||
auto *inherits = dynamic_cast<const ConfigOptionString*>(child.config.option("inherits"));
|
||||
if (inherits == nullptr || inherits->value.empty())
|
||||
const std::string &inherits = child.inherits();
|
||||
if (inherits.empty())
|
||||
// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
|
||||
return nullptr;
|
||||
const Preset* preset = this->find_preset(inherits->value, false);
|
||||
const Preset* preset = this->find_preset(inherits, false);
|
||||
return (preset == nullptr/* || preset->is_default */|| preset->is_external) ? nullptr : preset;
|
||||
}
|
||||
|
||||
@ -763,7 +842,7 @@ std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, c
|
||||
// The "compatible_printers" option key is handled differently from the others:
|
||||
// It is not mandatory. If the key is missing, it means it is compatible with any printer.
|
||||
// If the key exists and it is empty, it means it is compatible with no printer.
|
||||
std::initializer_list<const char*> optional_keys { "compatible_printers", "compatible_printers_condition" };
|
||||
std::initializer_list<const char*> optional_keys { "compatible_printers" };
|
||||
for (auto &opt_key : optional_keys) {
|
||||
if (reference->config.has(opt_key) != edited->config.has(opt_key))
|
||||
changed.emplace_back(opt_key);
|
||||
@ -772,17 +851,6 @@ std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, c
|
||||
return changed;
|
||||
}
|
||||
|
||||
std::vector<std::string> PresetCollection::system_equal_options() const
|
||||
{
|
||||
const Preset *edited = &this->get_edited_preset();
|
||||
const Preset *reference = this->get_selected_preset_parent();
|
||||
std::vector<std::string> equal;
|
||||
if (edited != nullptr && reference != nullptr) {
|
||||
equal = reference->config.equal(edited->config);
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
|
||||
// Select a new preset. This resets all the edits done to the currently selected preset.
|
||||
// If the preset with index idx does not exist, a first visible preset is selected.
|
||||
Preset& PresetCollection::select_preset(size_t idx)
|
||||
|
@ -113,9 +113,6 @@ public:
|
||||
// or a Configuration file bundling the Print + Filament + Printer presets (in that case is_external and possibly is_system will be true),
|
||||
// or it could be a G-code (again, is_external will be true).
|
||||
std::string file;
|
||||
// A user profile may inherit its settings either from a system profile, or from a user profile.
|
||||
// A system profile shall never derive from any other profile, as the system profile hierarchy is being flattened during loading.
|
||||
std::string inherits;
|
||||
// If this is a system profile, then there should be a vendor data available to display at the UI.
|
||||
const VendorProfile *vendor = nullptr;
|
||||
|
||||
@ -142,6 +139,16 @@ public:
|
||||
bool is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const;
|
||||
bool is_compatible_with_printer(const Preset &active_printer) const;
|
||||
|
||||
// Returns the name of the preset, from which this preset inherits.
|
||||
static std::string& inherits(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("inherits", true)->value; }
|
||||
std::string& inherits() { return Preset::inherits(this->config); }
|
||||
const std::string& inherits() const { return Preset::inherits(const_cast<Preset*>(this)->config); }
|
||||
|
||||
// Returns the "compatible_printers_condition".
|
||||
static std::string& compatible_printers_condition(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("compatible_printers_condition", true)->value; }
|
||||
std::string& compatible_printers_condition() { return Preset::compatible_printers_condition(this->config); }
|
||||
const std::string& compatible_printers_condition() const { return Preset::compatible_printers_condition(const_cast<Preset*>(this)->config); }
|
||||
|
||||
// Mark this preset as compatible if it is compatible with active_printer.
|
||||
bool update_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config);
|
||||
|
||||
@ -200,6 +207,18 @@ public:
|
||||
Preset& load_preset(const std::string &path, const std::string &name, const DynamicPrintConfig &config, bool select = true);
|
||||
Preset& load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select = true);
|
||||
|
||||
Preset& load_external_preset(
|
||||
// Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
|
||||
const std::string &path,
|
||||
// Name of the profile, derived from the source file name.
|
||||
const std::string &name,
|
||||
// Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
|
||||
const std::string &original_name,
|
||||
// Config to initialize the preset from.
|
||||
const DynamicPrintConfig &config,
|
||||
// Select the preset after loading?
|
||||
bool select = true);
|
||||
|
||||
// Save the preset under a new name. If the name is different from the old one,
|
||||
// a new preset is stored into the list of presets.
|
||||
// All presets are marked as not modified and the new preset is activated.
|
||||
@ -312,8 +331,6 @@ public:
|
||||
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
|
||||
std::vector<std::string> current_different_from_parent_options(const bool is_printer_type = false) const
|
||||
{ return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), is_printer_type); }
|
||||
// Compare the content of get_selected_preset() with get_selected_preset_parent() configs, return the list of keys where they equal.
|
||||
std::vector<std::string> system_equal_options() const;
|
||||
|
||||
// Update the choice UI from the list of presets.
|
||||
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
|
||||
@ -349,9 +366,10 @@ private:
|
||||
PresetCollection(const PresetCollection &other);
|
||||
PresetCollection& operator=(const PresetCollection &other);
|
||||
|
||||
// Find a preset in the sorted list of presets.
|
||||
// Find a preset position in the sorted list of presets.
|
||||
// The "-- default -- " preset is always the first, so it needs
|
||||
// to be handled differently.
|
||||
// If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name.
|
||||
std::deque<Preset>::iterator find_preset_internal(const std::string &name)
|
||||
{
|
||||
Preset key(m_type, name);
|
||||
|
@ -52,26 +52,37 @@ PresetBundle::PresetBundle() :
|
||||
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
|
||||
// The following keys are handled by the UI, they do not have a counterpart in any StaticPrintConfig derived classes,
|
||||
// therefore they need to be handled differently. As they have no counterpart in StaticPrintConfig, they are not being
|
||||
// initialized based on PrintConfigDef(), but to empty values (zeros, empty vectors, empty strings).
|
||||
//
|
||||
// "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
// "print_settings_id", "filament_settings_id", "printer_settings_id",
|
||||
// "printer_vendor", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile"
|
||||
|
||||
// Create the ID config keys, as they are not part of the Static print config classes.
|
||||
this->prints.default_preset().config.opt_string("print_settings_id", true);
|
||||
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values.assign(1, std::string());
|
||||
this->printers.default_preset().config.opt_string("printer_settings_id", true);
|
||||
// "compatible printers" are not mandatory yet.
|
||||
//FIXME Rename "compatible_printers" and "compatible_printers_condition", as they are defined in both print and filament profiles,
|
||||
// therefore they are clashing when generating a a config file, G-code or AMF/3MF.
|
||||
// this->filaments.default_preset().config.optptr("compatible_printers", true);
|
||||
// this->filaments.default_preset().config.optptr("compatible_printers_condition", true);
|
||||
// this->prints.default_preset().config.optptr("compatible_printers", true);
|
||||
// this->prints.default_preset().config.optptr("compatible_printers_condition", true);
|
||||
// Create the "printer_vendor", "printer_model" and "printer_variant" keys.
|
||||
this->prints.default_preset().config.optptr("print_settings_id", true);
|
||||
this->prints.default_preset().compatible_printers_condition();
|
||||
this->prints.default_preset().inherits();
|
||||
|
||||
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values = { "" };
|
||||
this->filaments.default_preset().compatible_printers_condition();
|
||||
this->filaments.default_preset().inherits();
|
||||
|
||||
this->printers.default_preset().config.optptr("printer_settings_id", true);
|
||||
this->printers.default_preset().config.optptr("printer_vendor", true);
|
||||
this->printers.default_preset().config.optptr("printer_model", true);
|
||||
this->printers.default_preset().config.optptr("printer_variant", true);
|
||||
// Load the default preset bitmaps.
|
||||
this->printers.default_preset().config.optptr("default_print_profile", true);
|
||||
this->printers.default_preset().config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
|
||||
this->printers.default_preset().inherits();
|
||||
|
||||
// Load the default preset bitmaps.
|
||||
this->prints .load_bitmap_default("cog.png");
|
||||
this->filaments.load_bitmap_default("spool.png");
|
||||
this->printers .load_bitmap_default("printer_empty.png");
|
||||
this->load_compatible_bitmaps();
|
||||
|
||||
// Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above.
|
||||
this->prints .select_preset(0);
|
||||
this->filaments.select_preset(0);
|
||||
@ -372,9 +383,16 @@ DynamicPrintConfig PresetBundle::full_config() const
|
||||
|
||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(out.option("nozzle_diameter"));
|
||||
size_t num_extruders = nozzle_diameter->values.size();
|
||||
// Collect the "compatible_printers_condition" and "inherits" values over all presets (print, filaments, printers) into a single vector.
|
||||
std::vector<std::string> compatible_printers_condition;
|
||||
std::vector<std::string> inherits;
|
||||
compatible_printers_condition.emplace_back(this->prints.get_edited_preset().compatible_printers_condition());
|
||||
inherits .emplace_back(this->prints.get_edited_preset().inherits());
|
||||
|
||||
if (num_extruders <= 1) {
|
||||
out.apply(this->filaments.get_edited_preset().config);
|
||||
compatible_printers_condition.emplace_back(this->filaments.get_edited_preset().compatible_printers_condition());
|
||||
inherits .emplace_back(this->filaments.get_edited_preset().inherits());
|
||||
} else {
|
||||
// Retrieve filament presets and build a single config object for them.
|
||||
// First collect the filament configurations based on the user selection of this->filament_presets.
|
||||
@ -384,11 +402,15 @@ DynamicPrintConfig PresetBundle::full_config() const
|
||||
filament_configs.emplace_back(&this->filaments.find_preset(filament_preset_name, true)->config);
|
||||
while (filament_configs.size() < num_extruders)
|
||||
filament_configs.emplace_back(&this->filaments.first_visible().config);
|
||||
for (const DynamicPrintConfig *cfg : filament_configs) {
|
||||
compatible_printers_condition.emplace_back(Preset::compatible_printers_condition(*const_cast<DynamicPrintConfig*>(cfg)));
|
||||
inherits .emplace_back(Preset::inherits(*const_cast<DynamicPrintConfig*>(cfg)));
|
||||
}
|
||||
// Option values to set a ConfigOptionVector from.
|
||||
std::vector<const ConfigOption*> filament_opts(num_extruders, nullptr);
|
||||
// loop through options and apply them to the resulting config.
|
||||
for (const t_config_option_key &key : this->filaments.default_preset().config.keys()) {
|
||||
if (key == "compatible_printers" || key == "compatible_printers_condition")
|
||||
if (key == "compatible_printers")
|
||||
continue;
|
||||
// Get a destination option.
|
||||
ConfigOption *opt_dst = out.option(key, false);
|
||||
@ -406,9 +428,13 @@ DynamicPrintConfig PresetBundle::full_config() const
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME These two value types clash between the print and filament profiles. They should be renamed.
|
||||
// Don't store the "compatible_printers_condition" for the printer profile, there is none.
|
||||
inherits.emplace_back(this->printers.get_edited_preset().inherits());
|
||||
|
||||
// These two value types clash between the print and filament profiles. They should be renamed.
|
||||
out.erase("compatible_printers");
|
||||
out.erase("compatible_printers_condition");
|
||||
out.erase("inherits");
|
||||
|
||||
static const char *keys[] = { "perimeter", "infill", "solid_infill", "support_material", "support_material_interface" };
|
||||
for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); ++ i) {
|
||||
@ -418,6 +444,25 @@ DynamicPrintConfig PresetBundle::full_config() const
|
||||
opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_extruders));
|
||||
}
|
||||
|
||||
out.option<ConfigOptionString >("print_settings_id", true)->value = this->prints.get_selected_preset().name;
|
||||
out.option<ConfigOptionStrings>("filament_settings_id", true)->values = this->filament_presets;
|
||||
out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset().name;
|
||||
|
||||
// Serialize the collected "compatible_printers_condition" and "inherits" fields.
|
||||
// There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored.
|
||||
// The vector will not be stored if all fields are empty strings.
|
||||
auto add_if_some_non_empty = [&out](std::vector<std::string> &&values, const std::string &key) {
|
||||
bool nonempty = false;
|
||||
for (const std::string &v : values)
|
||||
if (! v.empty()) {
|
||||
nonempty = true;
|
||||
break;
|
||||
}
|
||||
if (nonempty)
|
||||
out.set_key_value(key, new ConfigOptionStrings(std::move(values)));
|
||||
};
|
||||
add_if_some_non_empty(std::move(compatible_printers_condition), "compatible_printers_condition_cummulative");
|
||||
add_if_some_non_empty(std::move(inherits), "inherits_cummulative");
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -496,6 +541,18 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
||||
}
|
||||
}
|
||||
|
||||
size_t num_extruders = std::min(config.option<ConfigOptionFloats>("nozzle_diameter" )->values.size(),
|
||||
config.option<ConfigOptionFloats>("filament_diameter")->values.size());
|
||||
// Make a copy of the "compatible_printers_condition_cummulative" and "inherits_cummulative" vectors, which
|
||||
// accumulate values over all presets (print, filaments, printers).
|
||||
// These values will be distributed into their particular presets when loading.
|
||||
std::vector<std::string> compatible_printers_condition_values = std::move(config.option<ConfigOptionStrings>("compatible_printers_condition_cummulative", true)->values);
|
||||
std::vector<std::string> inherits_values = std::move(config.option<ConfigOptionStrings>("inherits_cummulative", true)->values);
|
||||
std::string &compatible_printers_condition = Preset::compatible_printers_condition(config);
|
||||
std::string &inherits = Preset::inherits(config);
|
||||
compatible_printers_condition_values.resize(num_extruders + 2, std::string());
|
||||
inherits_values.resize(num_extruders + 2, std::string());
|
||||
|
||||
// 1) Create a name from the file name.
|
||||
// Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles.
|
||||
std::string name = is_external ? boost::filesystem::path(name_or_path).filename().string() : name_or_path;
|
||||
@ -504,24 +561,31 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
||||
// First load the print and printer presets.
|
||||
for (size_t i_group = 0; i_group < 2; ++ i_group) {
|
||||
PresetCollection &presets = (i_group == 0) ? this->prints : this->printers;
|
||||
Preset &preset = presets.load_preset(is_external ? name_or_path : presets.path_from_name(name), name, config);
|
||||
if (is_external)
|
||||
preset.is_external = true;
|
||||
// Split the "compatible_printers_condition" and "inherits" values one by one from a single vector to the print & printer profiles.
|
||||
size_t idx = (i_group == 0) ? 0 : num_extruders + 1;
|
||||
inherits = inherits_values[idx];
|
||||
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) ? "print_settings_id" : "printer_settings_id", true),
|
||||
config);
|
||||
else
|
||||
preset.save();
|
||||
presets.load_preset(presets.path_from_name(name), name, config).save();
|
||||
}
|
||||
|
||||
// 3) Now load the filaments. If there are multiple filament presets, split them and load them.
|
||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
|
||||
auto *filament_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("filament_diameter"));
|
||||
size_t num_extruders = std::min(nozzle_diameter->values.size(), filament_diameter->values.size());
|
||||
auto old_filament_profile_names = config.option<ConfigOptionStrings>("filament_settings_id", true);
|
||||
old_filament_profile_names->values.resize(num_extruders, std::string());
|
||||
config.option<ConfigOptionStrings>("default_filament_profile", true)->values.resize(num_extruders, std::string());
|
||||
|
||||
if (num_extruders <= 1) {
|
||||
Preset &preset = this->filaments.load_preset(
|
||||
is_external ? name_or_path : this->filaments.path_from_name(name), name, config);
|
||||
// Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
|
||||
inherits = inherits_values[1];
|
||||
compatible_printers_condition = compatible_printers_condition_values[1];
|
||||
if (is_external)
|
||||
preset.is_external = true;
|
||||
this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config);
|
||||
else
|
||||
preset.save();
|
||||
this->filaments.load_preset(this->filaments.path_from_name(name), name, config).save();
|
||||
this->filament_presets.clear();
|
||||
this->filament_presets.emplace_back(name);
|
||||
} else {
|
||||
@ -543,21 +607,30 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
||||
// Load the configs into this->filaments and make them active.
|
||||
this->filament_presets.clear();
|
||||
for (size_t i = 0; i < configs.size(); ++ i) {
|
||||
char suffix[64];
|
||||
if (i == 0)
|
||||
suffix[0] = 0;
|
||||
else
|
||||
sprintf(suffix, " (%d)", i);
|
||||
std::string new_name = name + suffix;
|
||||
DynamicPrintConfig &cfg = configs[i];
|
||||
// Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
|
||||
cfg.opt_string("compatible_printers_condition", true) = compatible_printers_condition_values[i + 1];
|
||||
cfg.opt_string("inherits", true) = inherits_values[i + 1];
|
||||
// Load all filament presets, but only select the first one in the preset dialog.
|
||||
Preset &preset = this->filaments.load_preset(
|
||||
is_external ? name_or_path : this->filaments.path_from_name(new_name),
|
||||
new_name, std::move(configs[i]), i == 0);
|
||||
Preset *loaded = nullptr;
|
||||
if (is_external)
|
||||
preset.is_external = true;
|
||||
else
|
||||
preset.save();
|
||||
this->filament_presets.emplace_back(new_name);
|
||||
loaded = &this->filaments.load_external_preset(name_or_path, name,
|
||||
(i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "",
|
||||
std::move(cfg), i == 0);
|
||||
else {
|
||||
// Used by the config wizard when creating a custom setup.
|
||||
// Therefore this block should only be called for a single extruder.
|
||||
char suffix[64];
|
||||
if (i == 0)
|
||||
suffix[0] = 0;
|
||||
else
|
||||
sprintf(suffix, "%d", i);
|
||||
std::string new_name = name + suffix;
|
||||
loaded = &this->filaments.load_preset(this->filaments.path_from_name(new_name),
|
||||
new_name, std::move(cfg), i == 0);
|
||||
loaded->save();
|
||||
}
|
||||
this->filament_presets.emplace_back(loaded->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ protected:
|
||||
std::vector<std::string> m_reload_dependent_tabs = {};
|
||||
enum OptStatus { osSystemValue = 1, osInitValue = 2 };
|
||||
std::map<std::string, int> m_options_list;
|
||||
int m_opt_status_value;
|
||||
int m_opt_status_value = 0;
|
||||
|
||||
t_icon_descriptions m_icon_descriptions = {};
|
||||
|
||||
|
@ -74,13 +74,13 @@
|
||||
static StaticPrintConfig* new_GCodeConfig()
|
||||
%code{% RETVAL = new GCodeConfig(); %};
|
||||
static StaticPrintConfig* new_PrintConfig()
|
||||
%code{% RETVAL = new PrintConfig(); %};
|
||||
%code{% RETVAL = static_cast<GCodeConfig*>(new PrintConfig()); %};
|
||||
static StaticPrintConfig* new_PrintObjectConfig()
|
||||
%code{% RETVAL = new PrintObjectConfig(); %};
|
||||
static StaticPrintConfig* new_PrintRegionConfig()
|
||||
%code{% RETVAL = new PrintRegionConfig(); %};
|
||||
static StaticPrintConfig* new_FullPrintConfig()
|
||||
%code{% RETVAL = static_cast<PrintObjectConfig*>(new FullPrintConfig()); %};
|
||||
%code{% RETVAL = static_cast<GCodeConfig*>(new FullPrintConfig()); %};
|
||||
~StaticPrintConfig();
|
||||
bool has(t_config_option_key opt_key);
|
||||
SV* as_hash()
|
||||
@ -119,7 +119,7 @@
|
||||
auto config = new FullPrintConfig();
|
||||
try {
|
||||
config->load(path);
|
||||
RETVAL = static_cast<PrintObjectConfig*>(config);
|
||||
RETVAL = static_cast<GCodeConfig*>(config);
|
||||
} catch (std::exception& e) {
|
||||
delete config;
|
||||
croak("Error extracting configuration from %s:\n%s\n", path, e.what());
|
||||
|
@ -133,7 +133,7 @@ _constant()
|
||||
~Print();
|
||||
|
||||
Ref<StaticPrintConfig> config()
|
||||
%code%{ RETVAL = &THIS->config; %};
|
||||
%code%{ RETVAL = static_cast<GCodeConfig*>(&THIS->config); %};
|
||||
Ref<StaticPrintConfig> default_object_config()
|
||||
%code%{ RETVAL = &THIS->default_object_config; %};
|
||||
Ref<StaticPrintConfig> default_region_config()
|
||||
|
Loading…
Reference in New Issue
Block a user