Merge branch 'master_250' (NO CONFLICTS FIXED):

CONFLICT (content): Merge conflict in resources/profiles/PrusaResearch.idx
CONFLICT (content): Merge conflict in resources/profiles/PrusaResearch.ini
CONFLICT (content): Merge conflict in src/libslic3r/CMakeLists.txt
CONFLICT (content): Merge conflict in src/libslic3r/Fill/Fill.cpp
CONFLICT (content): Merge conflict in src/libslic3r/GCode.cpp
CONFLICT (content): Merge conflict in src/libslic3r/GCode.hpp
CONFLICT (content): Merge conflict in src/libslic3r/GCode/GCodeProcessor.cpp
CONFLICT (content): Merge conflict in src/libslic3r/GCode/GCodeProcessor.hpp
CONFLICT (content): Merge conflict in src/libslic3r/GCode/SeamPlacer.cpp
CONFLICT (content): Merge conflict in src/libslic3r/GCode/SeamPlacer.hpp
CONFLICT (add/add): Merge conflict in src/libslic3r/Geometry/Curves.hpp
CONFLICT (content): Merge conflict in src/libslic3r/PerimeterGenerator.cpp
CONFLICT (content): Merge conflict in src/libslic3r/Point.hpp
CONFLICT (content): Merge conflict in src/libslic3r/PrintConfig.hpp
CONFLICT (content): Merge conflict in src/slic3r/GUI/ConfigWizard.cpp
CONFLICT (content): Merge conflict in src/slic3r/GUI/GCodeViewer.cpp
CONFLICT (content): Merge conflict in src/slic3r/GUI/GLCanvas3D.cpp
CONFLICT (content): Merge conflict in src/slic3r/GUI/GUI_App.cpp
CONFLICT (content): Merge conflict in src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
CONFLICT (content): Merge conflict in src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
CONFLICT (content): Merge conflict in src/slic3r/Utils/FixModelByWin10.cpp
CONFLICT (modify/delete): t/perimeters.t deleted in HEAD and modified in master_250.  Version master_250 of t/perimeters.t left in tree.
CONFLICT (content): Merge conflict in tests/fff_print/CMakeLists.txt
CONFLICT (content): Merge conflict in tests/fff_print/test_fill.cpp
CONFLICT (content): Merge conflict in version.inc
CONFLICT (modify/delete): xs/xsp/PerimeterGenerator.xsp deleted in HEAD and modified in master_250.  Version master_250 of xs/xsp/PerimeterGenerator.xsp left in tree.
This commit is contained in:
Lukas Matena 2022-06-29 14:34:55 +02:00
commit b61714bb3e
152 changed files with 86092 additions and 45493 deletions
src/libslic3r

View file

@ -3,7 +3,6 @@
#include "GCode.hpp"
#include "Exception.hpp"
#include "ExtrusionEntity.hpp"
#include "EdgeGrid.hpp"
#include "Geometry/ConvexHull.hpp"
#include "GCode/PrintExtents.hpp"
#include "GCode/Thumbnails.hpp"
@ -1106,14 +1105,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (print.config().spiral_vase.value)
m_spiral_vase = make_unique<SpiralVase>(print.config());
#ifdef HAS_PRESSURE_EQUALIZER
if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 ||
print.config().max_volumetric_extrusion_rate_slope_negative.value > 0)
m_pressure_equalizer = make_unique<PressureEqualizer>(&print.config());
m_pressure_equalizer = make_unique<PressureEqualizer>(print.config());
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
#else /* HAS_PRESSURE_EQUALIZER */
m_enable_extrusion_role_markers = false;
#endif /* HAS_PRESSURE_EQUALIZER */
// Write information on the generator.
file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str());
@ -1299,7 +1295,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
print.throw_if_canceled();
// Collect custom seam data from all objects.
m_seam_placer.init(print);
std::function<void(void)> throw_if_canceled_func = [&print]() { print.throw_if_canceled();};
m_seam_placer.init(print, throw_if_canceled_func);
if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming)) {
// Set initial extruder only after custom start G-code.
@ -1352,10 +1349,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
// and export G-code into file.
this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file);
#ifdef HAS_PRESSURE_EQUALIZER
if (m_pressure_equalizer)
file.write(m_pressure_equalizer->process("", true));
#endif /* HAS_PRESSURE_EQUALIZER */
++ finished_objects;
// Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
// Reset it when starting another object from 1st layer.
@ -1412,10 +1405,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
// and export G-code into file.
this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file);
#ifdef HAS_PRESSURE_EQUALIZER
if (m_pressure_equalizer)
file.write(m_pressure_equalizer->process("", true));
#endif /* HAS_PRESSURE_EQUALIZER */
if (m_wipe_tower)
// Purge the extruder, pull out the active filament.
file.write(m_wipe_tower->finalize(*this));
@ -1528,11 +1517,18 @@ void GCode::process_layers(
{
// The pipeline is variable: The vase mode filter is optional.
size_t layer_to_print_idx = 0;
const auto generator = tbb::make_filter<void, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[this, &print, &tool_ordering, &print_object_instances_ordering, &layers_to_print, &layer_to_print_idx](tbb::flow_control& fc) -> GCode::LayerResult {
if (layer_to_print_idx == layers_to_print.size()) {
fc.stop();
return {};
const auto generator = tbb::make_filter<void, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[this, &print, &tool_ordering, &print_object_instances_ordering, &layers_to_print, &layer_to_print_idx](tbb::flow_control& fc) -> LayerResult {
if (layer_to_print_idx >= layers_to_print.size()) {
if ((!m_pressure_equalizer && layer_to_print_idx == layers_to_print.size()) || (m_pressure_equalizer && layer_to_print_idx == (layers_to_print.size() + 1))) {
fc.stop();
return {};
} else {
// Pressure equalizer need insert empty input. Because it returns one layer back.
// Insert NOP (no operation) layer;
++layer_to_print_idx;
return LayerResult::make_nop_layer_result();
}
} else {
const std::pair<coordf_t, std::vector<LayerToPrint>>& layer = layers_to_print[layer_to_print_idx++];
const LayerTools& layer_tools = tool_ordering.tools_for_layer(layer.first);
@ -1542,17 +1538,27 @@ void GCode::process_layers(
return this->process_layer(print, layer.second, layer_tools, &layer == &layers_to_print.back(), &print_object_instances_ordering, size_t(-1));
}
});
const auto spiral_vase = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&spiral_vase = *this->m_spiral_vase.get()](GCode::LayerResult in) -> GCode::LayerResult {
const auto spiral_vase = tbb::make_filter<LayerResult, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&spiral_vase = *this->m_spiral_vase](LayerResult in) -> LayerResult {
if (in.nop_layer_result)
return in;
spiral_vase.enable(in.spiral_vase_enable);
return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush };
return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush};
});
const auto cooling = tbb::make_filter<GCode::LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&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 pressure_equalizer = tbb::make_filter<LayerResult, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&pressure_equalizer = *this->m_pressure_equalizer](LayerResult in) -> LayerResult {
return pressure_equalizer.process_layer(std::move(in));
});
const auto cooling = tbb::make_filter<LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&cooling_buffer = *this->m_cooling_buffer](LayerResult in) -> std::string {
if (in.nop_layer_result)
return in.gcode;
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 {
[&self = *this->m_find_replace](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,
@ -1565,14 +1571,22 @@ void GCode::process_layers(
// The pipeline elements are joined using const references, thus no copying is performed.
output_stream.find_replace_supress();
if (m_spiral_vase && m_find_replace)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
if (m_spiral_vase && m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase && m_find_replace)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
else if (m_spiral_vase && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & output);
else if (m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
else if (m_find_replace)
tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
else if (m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & output);
else
tbb::parallel_pipeline(12, generator & cooling & output);
tbb::parallel_pipeline(12, generator & cooling & output);
output_stream.find_replace_enable();
}
@ -1588,28 +1602,43 @@ void GCode::process_layers(
{
// The pipeline is variable: The vase mode filter is optional.
size_t layer_to_print_idx = 0;
const auto generator = tbb::make_filter<void, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[this, &print, &tool_ordering, &layers_to_print, &layer_to_print_idx, single_object_idx](tbb::flow_control& fc) -> GCode::LayerResult {
if (layer_to_print_idx == layers_to_print.size()) {
fc.stop();
return {};
const auto generator = tbb::make_filter<void, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[this, &print, &tool_ordering, &layers_to_print, &layer_to_print_idx, single_object_idx](tbb::flow_control& fc) -> LayerResult {
if (layer_to_print_idx >= layers_to_print.size()) {
if ((!m_pressure_equalizer && layer_to_print_idx == layers_to_print.size()) || (m_pressure_equalizer && layer_to_print_idx == (layers_to_print.size() + 1))) {
fc.stop();
return {};
} else {
// Pressure equalizer need insert empty input. Because it returns one layer back.
// Insert NOP (no operation) layer;
++layer_to_print_idx;
return LayerResult::make_nop_layer_result();
}
} else {
LayerToPrint &layer = layers_to_print[layer_to_print_idx ++];
print.throw_if_canceled();
return this->process_layer(print, { std::move(layer) }, tool_ordering.tools_for_layer(layer.print_z()), &layer == &layers_to_print.back(), nullptr, single_object_idx);
}
});
const auto spiral_vase = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&spiral_vase = *this->m_spiral_vase.get()](GCode::LayerResult in)->GCode::LayerResult {
const auto spiral_vase = tbb::make_filter<LayerResult, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&spiral_vase = *this->m_spiral_vase](LayerResult in)->LayerResult {
if (in.nop_layer_result)
return in;
spiral_vase.enable(in.spiral_vase_enable);
return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush };
});
const auto cooling = tbb::make_filter<GCode::LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&cooling_buffer = *this->m_cooling_buffer.get()](GCode::LayerResult in)->std::string {
const auto pressure_equalizer = tbb::make_filter<LayerResult, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&pressure_equalizer = *this->m_pressure_equalizer](LayerResult in) -> LayerResult {
return pressure_equalizer.process_layer(std::move(in));
});
const auto cooling = tbb::make_filter<LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&cooling_buffer = *this->m_cooling_buffer](LayerResult in)->std::string {
if (in.nop_layer_result)
return in.gcode;
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 {
[&self = *this->m_find_replace](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,
@ -1622,14 +1651,22 @@ void GCode::process_layers(
// The pipeline elements are joined using const references, thus no copying is performed.
output_stream.find_replace_supress();
if (m_spiral_vase && m_find_replace)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
if (m_spiral_vase && m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase && m_find_replace)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
else if (m_spiral_vase && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & output);
else if (m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
else if (m_find_replace)
tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
else if (m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & output);
else
tbb::parallel_pipeline(12, generator & cooling & output);
tbb::parallel_pipeline(12, generator & cooling & output);
output_stream.find_replace_enable();
}
@ -2056,7 +2093,7 @@ namespace Skirt {
// In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated.
// For multi-material prints, this routine minimizes extruder switches by gathering extruder specific extrusion paths
// and performing the extruder specific extrusions together.
GCode::LayerResult GCode::process_layer(
LayerResult GCode::process_layer(
const Print &print,
// Set of object & print layers of the same PrintObject and with the same print_z.
const std::vector<LayerToPrint> &layers,
@ -2087,7 +2124,7 @@ GCode::LayerResult GCode::process_layer(
}
}
const Layer &layer = (object_layer != nullptr) ? *object_layer : *support_layer;
GCode::LayerResult result { {}, layer.id(), false, last_layer };
LayerResult result { {}, layer.id(), false, last_layer, false};
if (layer_tools.extruders.empty())
// Nothing to extrude.
return result;
@ -2470,13 +2507,11 @@ GCode::LayerResult GCode::process_layer(
// Flush the cooling buffer at each object layer or possibly at the last layer, even if it contains just supports (This should not happen).
object_layer || last_layer);
#ifdef HAS_PRESSURE_EQUALIZER
// Apply pressure equalization if enabled;
// printf("G-code before filter:\n%s\n", gcode.c_str());
if (m_pressure_equalizer)
gcode = m_pressure_equalizer->process(gcode.c_str(), false);
// printf("G-code after filter:\n%s\n", out.c_str());
#endif /* HAS_PRESSURE_EQUALIZER */
file.write(gcode);
#endif
@ -2578,6 +2613,7 @@ std::string GCode::change_layer(coordf_t print_z)
return gcode;
}
<<<<<<< HEAD
static const auto comment_perimeter = "perimeter"sv;
// Comparing string_view pointer & length for speed.
static inline bool comment_is_perimeter(const std::string_view comment) {
@ -2585,6 +2621,9 @@ static inline bool comment_is_perimeter(const std::string_view comment) {
}
std::string GCode::extrude_loop(ExtrusionLoop loop, const std::string_view description, double speed)
=======
std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed)
>>>>>>> master_250
{
// get a copy; don't modify the orientation of the original loop object otherwise
// next copies (if any) would not detect the correct orientation
@ -2595,11 +2634,21 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, const std::string_view descr
// find the point of the loop that is closest to the current extruder position
// or randomize if requested
Point last_pos = this->last_pos();
<<<<<<< HEAD
if (! m_config.spiral_vase && comment_is_perimeter(description)) {
assert(m_layer != nullptr);
m_seam_placer.place_seam(m_layer, loop, m_config.external_perimeters_first, this->last_pos());
} else
loop.split_at(last_pos, false);
=======
if (! m_config.spiral_vase && description == "perimeter") {
assert(m_layer != nullptr);
m_seam_placer.place_seam(m_layer, loop, m_config.external_perimeters_first, this->last_pos());
} else
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
// thus empty path segments will not be produced by G-code export.
loop.split_at(last_pos, false, scaled<double>(0.0015));
>>>>>>> master_250
// clip the path to avoid the extruder to get exactly on the first point of the loop;
// if polyline was shorter than the clipping distance we'd get a null polyline, so
@ -2686,7 +2735,11 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, const std::s
return gcode;
}
<<<<<<< HEAD
std::string GCode::extrude_entity(const ExtrusionEntity &entity, const std::string_view description, double speed)
=======
std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string description, double speed)
>>>>>>> master_250
{
if (const ExtrusionPath* path = dynamic_cast<const ExtrusionPath*>(&entity))
return this->extrude_path(*path, description, speed);
@ -2721,7 +2774,11 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
m_config.apply(print.get_print_region(&region - &by_region.front()).config());
for (const ExtrusionEntity* ee : region.perimeters)
<<<<<<< HEAD
gcode += this->extrude_entity(*ee, comment_perimeter, -1.);
=======
gcode += this->extrude_entity(*ee, "perimeter", -1.);
>>>>>>> master_250
}
return gcode;
}