WIP: G-code find / replace using a new gcode_substitutions PrintConfig
parameter.
This commit is contained in:
parent
c54b8908dd
commit
658f01b64b
@ -98,6 +98,8 @@ add_library(libslic3r STATIC
|
||||
GCode/ThumbnailData.hpp
|
||||
GCode/CoolingBuffer.cpp
|
||||
GCode/CoolingBuffer.hpp
|
||||
GCode/FindReplace.cpp
|
||||
GCode/FindReplace.hpp
|
||||
GCode/PostProcessor.cpp
|
||||
GCode/PostProcessor.hpp
|
||||
# GCode/PressureEqualizer.cpp
|
||||
|
@ -1155,6 +1155,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
m_enable_extrusion_role_markers = false;
|
||||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
|
||||
if (! print.config().gcode_substitutions.values.empty())
|
||||
m_find_replace = make_unique<GCodeFindReplace>(print.config());
|
||||
|
||||
// Write information on the generator.
|
||||
file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
||||
|
||||
@ -1560,13 +1563,21 @@ void GCode::process_layers(
|
||||
[&cooling_buffer = *this->m_cooling_buffer.get()](GCode::LayerResult in) -> std::string {
|
||||
return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush);
|
||||
});
|
||||
const auto find_replace = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&self = *this->m_find_replace.get()](std::string s) -> std::string {
|
||||
return self.process_layer(std::move(s));
|
||||
});
|
||||
const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&output_stream](std::string s) { output_stream.write(s); }
|
||||
);
|
||||
|
||||
// The pipeline elements are joined using const references, thus no copying is performed.
|
||||
if (m_spiral_vase)
|
||||
if (m_spiral_vase && m_find_replace)
|
||||
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
|
||||
else if (m_spiral_vase)
|
||||
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
|
||||
else if (m_find_replace)
|
||||
tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
|
||||
else
|
||||
tbb::parallel_pipeline(12, generator & cooling & output);
|
||||
}
|
||||
@ -1603,13 +1614,21 @@ void GCode::process_layers(
|
||||
[&cooling_buffer = *this->m_cooling_buffer.get()](GCode::LayerResult in)->std::string {
|
||||
return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush);
|
||||
});
|
||||
const auto find_replace = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&self = *this->m_find_replace.get()](std::string s) -> std::string {
|
||||
return self.process_layer(std::move(s));
|
||||
});
|
||||
const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&output_stream](std::string s) { output_stream.write(s); }
|
||||
);
|
||||
|
||||
// The pipeline elements are joined using const references, thus no copying is performed.
|
||||
if (m_spiral_vase)
|
||||
if (m_spiral_vase && m_find_replace)
|
||||
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
|
||||
else if (m_spiral_vase)
|
||||
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
|
||||
else if (m_find_replace)
|
||||
tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
|
||||
else
|
||||
tbb::parallel_pipeline(12, generator & cooling & output);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "PrintConfig.hpp"
|
||||
#include "GCode/AvoidCrossingPerimeters.hpp"
|
||||
#include "GCode/CoolingBuffer.hpp"
|
||||
#include "GCode/FindReplace.hpp"
|
||||
#include "GCode/SpiralVase.hpp"
|
||||
#include "GCode/ToolOrdering.hpp"
|
||||
#include "GCode/WipeTower.hpp"
|
||||
@ -393,6 +394,7 @@ private:
|
||||
|
||||
std::unique_ptr<CoolingBuffer> m_cooling_buffer;
|
||||
std::unique_ptr<SpiralVase> m_spiral_vase;
|
||||
std::unique_ptr<GCodeFindReplace> m_find_replace;
|
||||
#ifdef HAS_PRESSURE_EQUALIZER
|
||||
std::unique_ptr<PressureEqualizer> m_pressure_equalizer;
|
||||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
|
71
src/libslic3r/GCode/FindReplace.cpp
Normal file
71
src/libslic3r/GCode/FindReplace.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "FindReplace.hpp"
|
||||
#include "../Utils.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
GCodeFindReplace::GCodeFindReplace(const PrintConfig &print_config)
|
||||
{
|
||||
const std::vector<std::string> &subst = print_config.gcode_substitutions.values;
|
||||
|
||||
if ((subst.size() % 3) != 0)
|
||||
throw RuntimeError("Invalid length of gcode_substitutions parameter");
|
||||
|
||||
m_substitutions.reserve(subst.size() / 3);
|
||||
for (size_t i = 0; i < subst.size(); i += 3) {
|
||||
boost::regex pattern;
|
||||
try {
|
||||
pattern.assign(subst[i]);
|
||||
} catch (const std::exception &ex) {
|
||||
throw RuntimeError(std::string("Invalid gcode_substitutions parameter, failed to compile regular expression: ") + ex.what());
|
||||
}
|
||||
m_substitutions.push_back({ std::move(pattern), subst[i + 1] });
|
||||
}
|
||||
}
|
||||
|
||||
class ToStringIterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using value_type = void;
|
||||
using difference_type = void;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
|
||||
ToStringIterator(std::string &data) : m_data(&data) {}
|
||||
|
||||
ToStringIterator& operator=(const char val) {
|
||||
size_t needs = m_data->size() + 1;
|
||||
if (m_data->capacity() < needs)
|
||||
m_data->reserve(next_highest_power_of_2(needs));
|
||||
m_data->push_back(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ToStringIterator& operator*() { return *this; }
|
||||
ToStringIterator& operator++() { return *this; }
|
||||
ToStringIterator operator++(int) { return *this; }
|
||||
|
||||
private:
|
||||
std::string *m_data;
|
||||
};
|
||||
|
||||
std::string GCodeFindReplace::process_layer(const std::string &ain)
|
||||
{
|
||||
std::string out;
|
||||
const std::string *in = &ain;
|
||||
std::string temp;
|
||||
temp.reserve(in->size());
|
||||
|
||||
for (const Substitution &substitution : m_substitutions) {
|
||||
temp.clear();
|
||||
temp.reserve(in->size());
|
||||
boost::regex_replace(ToStringIterator(temp), in->begin(), in->end(),
|
||||
substitution.pattern, substitution.format, boost::match_default | boost::format_all);
|
||||
std::swap(out, temp);
|
||||
in = &out;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
26
src/libslic3r/GCode/FindReplace.hpp
Normal file
26
src/libslic3r/GCode/FindReplace.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef slic3r_FindReplace_hpp_
|
||||
#define slic3r_FindReplace_hpp_
|
||||
|
||||
#include "../PrintConfig.hpp"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCodeFindReplace {
|
||||
public:
|
||||
GCodeFindReplace(const PrintConfig &print_config);
|
||||
|
||||
std::string process_layer(const std::string &gcode);
|
||||
|
||||
private:
|
||||
struct Substitution {
|
||||
boost::regex pattern;
|
||||
std::string format;
|
||||
};
|
||||
std::vector<Substitution> m_substitutions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // slic3r_FindReplace_hpp_
|
@ -1357,6 +1357,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(0));
|
||||
|
||||
def = this->add("gcode_substitutions", coStrings);
|
||||
def->label = L("G-code substitutions");
|
||||
def->tooltip = L("Find / replace patterns in G-code lines and substitute them.");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionStrings());
|
||||
|
||||
def = this->add("high_current_on_filament_swap", coBool);
|
||||
def->label = L("High extruder current on filament swap");
|
||||
def->tooltip = L("It may be beneficial to increase the extruder motor current during the filament exchange"
|
||||
|
@ -641,6 +641,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, gcode_comments))
|
||||
((ConfigOptionEnum<GCodeFlavor>, gcode_flavor))
|
||||
((ConfigOptionBool, gcode_label_objects))
|
||||
((ConfigOptionStrings, gcode_substitutions))
|
||||
((ConfigOptionString, layer_gcode))
|
||||
((ConfigOptionFloat, max_print_speed))
|
||||
((ConfigOptionFloat, max_volumetric_speed))
|
||||
|
Loading…
Reference in New Issue
Block a user