mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-07 08:49:06 +00:00
Updated Config Handling
This commit is contained in:
@@ -258,7 +258,11 @@ public class FilamentConfigFragment extends ProfileListFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResetConfig() {
|
protected void onResetConfig() {
|
||||||
currentConfig = new ConfigObject(Santoku.CONFIG.findFilament(Santoku.CONFIG.presets.get("filament")));
|
ConfigObject base = Santoku.CONFIG.findFilament(Santoku.CONFIG.presets.get("filament"));
|
||||||
|
if (base == null && Santoku.CONFIG.filamentConfigs != null && !Santoku.CONFIG.filamentConfigs.isEmpty()) {
|
||||||
|
base = Santoku.CONFIG.filamentConfigs.get(0);
|
||||||
|
}
|
||||||
|
currentConfig = base != null ? new ConfigObject(base) : ConfigObject.createCustomFilamentProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@@ -105,6 +106,29 @@ namespace Slic3r {
|
|||||||
gcode += '\n';
|
gcode += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string rewrite_simple_curly_placeholders_to_legacy(const std::string &templ)
|
||||||
|
{
|
||||||
|
// Convert {name} or {name[0]} to legacy [name] / [name_0].
|
||||||
|
// Only touches simple, standalone placeholders to avoid breaking control macros.
|
||||||
|
static const std::regex pattern(R"(\{([A-Za-z_][A-Za-z0-9_]*)(?:\[(\d+)\])?\})");
|
||||||
|
std::string out;
|
||||||
|
out.reserve(templ.size());
|
||||||
|
size_t last_pos = 0;
|
||||||
|
for (auto it = std::sregex_iterator(templ.begin(), templ.end(), pattern); it != std::sregex_iterator(); ++it) {
|
||||||
|
const std::smatch &m = *it;
|
||||||
|
out.append(templ, last_pos, m.position() - last_pos);
|
||||||
|
const std::string &name = m[1].str();
|
||||||
|
const std::string &idx = m[2].str();
|
||||||
|
if (! idx.empty())
|
||||||
|
out += "[" + name + "_" + idx + "]";
|
||||||
|
else
|
||||||
|
out += "[" + name + "]";
|
||||||
|
last_pos = m.position() + m.length();
|
||||||
|
}
|
||||||
|
out.append(templ, last_pos, std::string::npos);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// Return true if tch_prefix is found in custom_gcode
|
// Return true if tch_prefix is found in custom_gcode
|
||||||
static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std::string& tch_prefix, unsigned next_extruder)
|
static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std::string& tch_prefix, unsigned next_extruder)
|
||||||
{
|
{
|
||||||
@@ -1087,6 +1111,8 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
|
|
||||||
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
|
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
|
||||||
m_placeholder_parser_integration.parser = print.placeholder_parser();
|
m_placeholder_parser_integration.parser = print.placeholder_parser();
|
||||||
|
// Ensure all print config options are available for { } placeholder expressions.
|
||||||
|
m_placeholder_parser_integration.parser.apply_config(print.full_print_config());
|
||||||
m_placeholder_parser_integration.parser.update_timestamp();
|
m_placeholder_parser_integration.parser.update_timestamp();
|
||||||
m_placeholder_parser_integration.context.rng = std::mt19937(std::chrono::high_resolution_clock::now().time_since_epoch().count());
|
m_placeholder_parser_integration.context.rng = std::mt19937(std::chrono::high_resolution_clock::now().time_since_epoch().count());
|
||||||
// Enable passing global variables between PlaceholderParser invocations.
|
// Enable passing global variables between PlaceholderParser invocations.
|
||||||
@@ -1181,6 +1207,29 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
this->placeholder_parser().set("has_wipe_tower", has_wipe_tower);
|
this->placeholder_parser().set("has_wipe_tower", has_wipe_tower);
|
||||||
this->placeholder_parser().set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
|
this->placeholder_parser().set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
|
||||||
this->placeholder_parser().set("total_toolchanges", tool_ordering.toolchanges_count());
|
this->placeholder_parser().set("total_toolchanges", tool_ordering.toolchanges_count());
|
||||||
|
{
|
||||||
|
const DynamicPrintConfig &cfg = print.full_print_config();
|
||||||
|
if (const ConfigOption *opt = cfg.optptr("first_layer_temperature")) {
|
||||||
|
this->placeholder_parser().set("first_layer_temperature", opt->clone());
|
||||||
|
} else {
|
||||||
|
this->placeholder_parser().set("first_layer_temperature", new ConfigOptionInts(print.config().first_layer_temperature.values));
|
||||||
|
}
|
||||||
|
if (const ConfigOption *opt = cfg.optptr("temperature")) {
|
||||||
|
this->placeholder_parser().set("temperature", opt->clone());
|
||||||
|
} else {
|
||||||
|
this->placeholder_parser().set("temperature", new ConfigOptionInts(print.config().temperature.values));
|
||||||
|
}
|
||||||
|
if (const ConfigOption *opt = cfg.optptr("first_layer_bed_temperature")) {
|
||||||
|
this->placeholder_parser().set("first_layer_bed_temperature", opt->clone());
|
||||||
|
} else {
|
||||||
|
this->placeholder_parser().set("first_layer_bed_temperature", new ConfigOptionInts(print.config().first_layer_bed_temperature.values));
|
||||||
|
}
|
||||||
|
if (const ConfigOption *opt = cfg.optptr("chamber_temperature")) {
|
||||||
|
this->placeholder_parser().set("chamber_temperature", opt->clone());
|
||||||
|
} else {
|
||||||
|
this->placeholder_parser().set("chamber_temperature", new ConfigOptionInts(print.config().chamber_temperature.values));
|
||||||
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
const char *bed_type_label = (print.config().elegoolink_bed_type.value == ElegooBedType::PTE) ? "Side A" : "Side B";
|
const char *bed_type_label = (print.config().elegoolink_bed_type.value == ElegooBedType::PTE) ? "Side A" : "Side B";
|
||||||
this->placeholder_parser().set("curr_bed_type", new ConfigOptionString(bed_type_label));
|
this->placeholder_parser().set("curr_bed_type", new ConfigOptionString(bed_type_label));
|
||||||
@@ -1214,7 +1263,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
this->placeholder_parser().set("print_bed_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
this->placeholder_parser().set("print_bed_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
||||||
this->placeholder_parser().set("print_bed_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
this->placeholder_parser().set("print_bed_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
||||||
}
|
}
|
||||||
if (host_is_klipper) {
|
{
|
||||||
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
|
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
|
||||||
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
||||||
// It does NOT encompass user extrusions generated by custom G-code,
|
// It does NOT encompass user extrusions generated by custom G-code,
|
||||||
@@ -1224,59 +1273,64 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
pts->values.reserve(print.first_layer_convex_hull().size());
|
pts->values.reserve(print.first_layer_convex_hull().size());
|
||||||
for (const Point &pt : print.first_layer_convex_hull().points)
|
for (const Point &pt : print.first_layer_convex_hull().points)
|
||||||
pts->values.emplace_back(unscale(pt));
|
pts->values.emplace_back(unscale(pt));
|
||||||
BoundingBoxf bbox(pts->values);
|
BoundingBoxf first_layer_bbox(pts->values);
|
||||||
this->placeholder_parser().set("first_layer_print_convex_hull", pts.release());
|
this->placeholder_parser().set("first_layer_print_convex_hull", pts.release());
|
||||||
this->placeholder_parser().set("first_layer_print_min", new ConfigOptionFloats({ bbox.min.x(), bbox.min.y() }));
|
this->placeholder_parser().set("first_layer_print_min", new ConfigOptionFloats({ first_layer_bbox.min.x(), first_layer_bbox.min.y() }));
|
||||||
this->placeholder_parser().set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
this->placeholder_parser().set("first_layer_print_max", new ConfigOptionFloats({ first_layer_bbox.max.x(), first_layer_bbox.max.y() }));
|
||||||
this->placeholder_parser().set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
this->placeholder_parser().set("first_layer_print_size", new ConfigOptionFloats({ first_layer_bbox.size().x(), first_layer_bbox.size().y() }));
|
||||||
this->placeholder_parser().set("num_extruders", int(print.config().nozzle_diameter.values.size()));
|
this->placeholder_parser().set("num_extruders", int(print.config().nozzle_diameter.values.size()));
|
||||||
|
|
||||||
BoundingBoxf bed_bbox(print.config().bed_shape.values);
|
if (host_is_klipper) {
|
||||||
BoundingBoxf mesh_bbox = bbox;
|
BoundingBoxf bed_bbox(print.config().bed_shape.values);
|
||||||
if (bed_bbox.defined) {
|
BoundingBoxf mesh_bbox = first_layer_bbox;
|
||||||
const double margin = print.config().adaptive_bed_mesh_margin.value;
|
if (bed_bbox.defined) {
|
||||||
double min_x = bbox.min.x() - margin;
|
const double margin = print.config().adaptive_bed_mesh_margin.value;
|
||||||
double min_y = bbox.min.y() - margin;
|
double min_x = first_layer_bbox.min.x() - margin;
|
||||||
double max_x = bbox.max.x() + margin;
|
double min_y = first_layer_bbox.min.y() - margin;
|
||||||
double max_y = bbox.max.y() + margin;
|
double max_x = first_layer_bbox.max.x() + margin;
|
||||||
|
double max_y = first_layer_bbox.max.y() + margin;
|
||||||
|
|
||||||
min_x = std::max(min_x, bed_bbox.min.x());
|
min_x = std::max(min_x, bed_bbox.min.x());
|
||||||
min_y = std::max(min_y, bed_bbox.min.y());
|
min_y = std::max(min_y, bed_bbox.min.y());
|
||||||
max_x = std::min(max_x, bed_bbox.max.x());
|
max_x = std::min(max_x, bed_bbox.max.x());
|
||||||
max_y = std::min(max_y, bed_bbox.max.y());
|
max_y = std::min(max_y, bed_bbox.max.y());
|
||||||
|
|
||||||
const Vec2d limit_min = print.config().bed_mesh_limit_min.value;
|
const Vec2d limit_min = print.config().bed_mesh_limit_min.value;
|
||||||
const Vec2d limit_max = print.config().bed_mesh_limit_max.value;
|
const Vec2d limit_max = print.config().bed_mesh_limit_max.value;
|
||||||
if (limit_min.x() > -99998 || limit_min.y() > -99998) {
|
if (limit_min.x() > -99998 || limit_min.y() > -99998) {
|
||||||
min_x = std::max(min_x, limit_min.x());
|
min_x = std::max(min_x, limit_min.x());
|
||||||
min_y = std::max(min_y, limit_min.y());
|
min_y = std::max(min_y, limit_min.y());
|
||||||
}
|
}
|
||||||
if (limit_max.x() > -99998 || limit_max.y() > -99998) {
|
if (limit_max.x() > -99998 || limit_max.y() > -99998) {
|
||||||
max_x = std::min(max_x, limit_max.x());
|
max_x = std::min(max_x, limit_max.x());
|
||||||
max_y = std::min(max_y, limit_max.y());
|
max_y = std::min(max_y, limit_max.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_bbox.min = Vec2d(min_x, min_y);
|
||||||
|
mesh_bbox.max = Vec2d(max_x, max_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh_bbox.min = Vec2d(min_x, min_y);
|
adaptive_bed_mesh_min = mesh_bbox.min;
|
||||||
mesh_bbox.max = Vec2d(max_x, max_y);
|
adaptive_bed_mesh_max = mesh_bbox.max;
|
||||||
|
adaptive_bed_mesh_ready = true;
|
||||||
|
|
||||||
|
this->placeholder_parser().set("adaptive_bed_mesh_min", new ConfigOptionFloats({ mesh_bbox.min.x(), mesh_bbox.min.y() }));
|
||||||
|
this->placeholder_parser().set("adaptive_bed_mesh_max", new ConfigOptionFloats({ mesh_bbox.max.x(), mesh_bbox.max.y() }));
|
||||||
|
|
||||||
|
const Vec2d probe_dist = print.config().bed_mesh_probe_distance.value;
|
||||||
|
const double probe_dist_x = std::max(1.0, probe_dist.x());
|
||||||
|
const double probe_dist_y = std::max(1.0, probe_dist.y());
|
||||||
|
const int probe_count_x = std::max(3, int(std::ceil(mesh_bbox.size().x() / probe_dist_x)) + 1);
|
||||||
|
const int probe_count_y = std::max(3, int(std::ceil(mesh_bbox.size().y() / probe_dist_y)) + 1);
|
||||||
|
adaptive_probe_count_x = probe_count_x;
|
||||||
|
adaptive_probe_count_y = probe_count_y;
|
||||||
|
this->placeholder_parser().set("bed_mesh_probe_count", new ConfigOptionInts({ probe_count_x, probe_count_y }));
|
||||||
|
adaptive_bed_mesh_algo = (probe_count_x < 4 || probe_count_y < 4) ? "lagrange" : "bicubic";
|
||||||
|
this->placeholder_parser().set("bed_mesh_algo", new ConfigOptionString(adaptive_bed_mesh_algo));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
adaptive_bed_mesh_min = mesh_bbox.min;
|
{
|
||||||
adaptive_bed_mesh_max = mesh_bbox.max;
|
|
||||||
adaptive_bed_mesh_ready = true;
|
|
||||||
|
|
||||||
this->placeholder_parser().set("adaptive_bed_mesh_min", new ConfigOptionFloats({ mesh_bbox.min.x(), mesh_bbox.min.y() }));
|
|
||||||
this->placeholder_parser().set("adaptive_bed_mesh_max", new ConfigOptionFloats({ mesh_bbox.max.x(), mesh_bbox.max.y() }));
|
|
||||||
|
|
||||||
const Vec2d probe_dist = print.config().bed_mesh_probe_distance.value;
|
|
||||||
const double probe_dist_x = std::max(1.0, probe_dist.x());
|
|
||||||
const double probe_dist_y = std::max(1.0, probe_dist.y());
|
|
||||||
const int probe_count_x = std::max(3, int(std::ceil(mesh_bbox.size().x() / probe_dist_x)) + 1);
|
|
||||||
const int probe_count_y = std::max(3, int(std::ceil(mesh_bbox.size().y() / probe_dist_y)) + 1);
|
|
||||||
adaptive_probe_count_x = probe_count_x;
|
|
||||||
adaptive_probe_count_y = probe_count_y;
|
|
||||||
this->placeholder_parser().set("bed_mesh_probe_count", new ConfigOptionInts({ probe_count_x, probe_count_y }));
|
|
||||||
adaptive_bed_mesh_algo = (probe_count_x < 4 || probe_count_y < 4) ? "lagrange" : "bicubic";
|
|
||||||
this->placeholder_parser().set("bed_mesh_algo", new ConfigOptionString(adaptive_bed_mesh_algo));
|
|
||||||
// PlaceholderParser currently substitues non-existent vector values with the zero'th value, which is harmful in the case of "is_extruder_used[]"
|
// PlaceholderParser currently substitues non-existent vector values with the zero'th value, which is harmful in the case of "is_extruder_used[]"
|
||||||
// as Slicer may lie about availability of such non-existent extruder.
|
// as Slicer may lie about availability of such non-existent extruder.
|
||||||
// We rather sacrifice 256B of memory before we change the behavior of the PlaceholderParser, which should really only fill in the non-existent
|
// We rather sacrifice 256B of memory before we change the behavior of the PlaceholderParser, which should really only fill in the non-existent
|
||||||
@@ -1829,6 +1883,34 @@ std::string GCodeGenerator::placeholder_parser_process(
|
|||||||
}
|
}
|
||||||
catch (std::runtime_error &err)
|
catch (std::runtime_error &err)
|
||||||
{
|
{
|
||||||
|
// Retry with legacy placeholders for simple {name} / {name[idx]} patterns.
|
||||||
|
if (std::string(err.what()).find("Not a variable name") != std::string::npos) {
|
||||||
|
const std::string compat_templ = rewrite_simple_curly_placeholders_to_legacy(templ);
|
||||||
|
if (compat_templ != templ) {
|
||||||
|
ppi.update_from_gcodewriter(m_writer, m_print->wipe_tower_data());
|
||||||
|
std::string output = ppi.parser.process(compat_templ, current_extruder_id, config_override, &ppi.output_config, &ppi.context);
|
||||||
|
ppi.validate_output_vector_variables();
|
||||||
|
|
||||||
|
if (const std::vector<double> &pos = ppi.opt_position->values; ppi.position != pos) {
|
||||||
|
m_writer.update_position({ pos[0], pos[1], pos[2] });
|
||||||
|
this->last_position = this->gcode_to_point({ pos[0], pos[1] });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Extruder &e : m_writer.extruders()) {
|
||||||
|
unsigned int eid = e.id();
|
||||||
|
assert(eid < ppi.num_extruders);
|
||||||
|
if ( eid < ppi.num_extruders) {
|
||||||
|
if (! m_writer.config.use_relative_e_distances && ! is_approx(ppi.e_position[eid], ppi.opt_e_position->values[eid]))
|
||||||
|
const_cast<Extruder&>(e).set_position(ppi.opt_e_position->values[eid]);
|
||||||
|
if (! is_approx(ppi.e_retracted[eid], ppi.opt_e_retracted->values[eid]) ||
|
||||||
|
! is_approx(ppi.e_restart_extra[eid], ppi.opt_e_restart_extra->values[eid]))
|
||||||
|
const_cast<Extruder&>(e).set_retracted(ppi.opt_e_retracted->values[eid], ppi.opt_e_restart_extra->values[eid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Collect the names of failed template substitutions for error reporting.
|
// Collect the names of failed template substitutions for error reporting.
|
||||||
auto it = ppi.failed_templates.find(name);
|
auto it = ppi.failed_templates.find(name);
|
||||||
if (it == ppi.failed_templates.end())
|
if (it == ppi.failed_templates.end())
|
||||||
|
|||||||
@@ -1022,6 +1022,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
m_placeholder_parser.set("filament_preset", new_full_config.option("filament_settings_id")->clone());
|
m_placeholder_parser.set("filament_preset", new_full_config.option("filament_settings_id")->clone());
|
||||||
m_placeholder_parser.set("printer_preset", new_full_config.option("printer_settings_id")->clone());
|
m_placeholder_parser.set("printer_preset", new_full_config.option("printer_settings_id")->clone());
|
||||||
m_placeholder_parser.set("physical_printer_preset", new_full_config.option("physical_printer_settings_id")->clone());
|
m_placeholder_parser.set("physical_printer_preset", new_full_config.option("physical_printer_settings_id")->clone());
|
||||||
|
// Make all config options available to the PlaceholderParser.
|
||||||
|
m_placeholder_parser.apply_config(new_full_config);
|
||||||
// We want the filament overrides to be applied over their respective extruder parameters by the PlaceholderParser.
|
// We want the filament overrides to be applied over their respective extruder parameters by the PlaceholderParser.
|
||||||
// see "Placeholders do not respect filament overrides." GH issue #3649
|
// see "Placeholders do not respect filament overrides." GH issue #3649
|
||||||
m_placeholder_parser.apply_config(filament_overrides);
|
m_placeholder_parser.apply_config(filament_overrides);
|
||||||
|
|||||||
Reference in New Issue
Block a user