mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-21 06:21:16 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fe75c776d |
No files matched your search
@@ -9214,10 +9214,9 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string &path_d
|
||||
effective_height = static_cast<float>(m_sub_layer_height);
|
||||
}
|
||||
|
||||
// Effective extrusion length per distance unit = (filament_flow_ratio/cross_section) * mm3_per_mm / print flow ratio
|
||||
// m_writer.extruder()->e_per_mm3() below is (filament flow ratio / cross-sectional area)
|
||||
double e_per_mm = m_writer.filament()->e_per_mm3() * _mm3_per_mm;
|
||||
e_per_mm /= filament_flow_ratio;
|
||||
// _mm3_per_mm already includes the filament flow ratio, so convert it with the bare cross-section
|
||||
// rather than e_per_mm3(), which would apply the ratio a second time.
|
||||
double e_per_mm = _mm3_per_mm / m_writer.filament()->filament_crossection();
|
||||
|
||||
// set speed
|
||||
if (speed == -1) {
|
||||
|
||||
@@ -1882,6 +1882,23 @@ StringObjectException Print::validate(std::vector<StringObjectException> *warnin
|
||||
if (extruders.empty())
|
||||
return { L("No extrusions under current settings.") };
|
||||
|
||||
// A flow ratio of 0 would extrude nothing, and a nil one would write NaN extrusion lengths.
|
||||
{
|
||||
const std::vector<double> &flow_ratios = m_config.filament_flow_ratio.values;
|
||||
const std::vector<int> &self_index = m_config.filament_self_index.values;
|
||||
for (size_t column = 0; column < flow_ratios.size(); ++column) {
|
||||
// filament_self_index maps a column to its filament once the filament arrays hold one column per variant
|
||||
const unsigned int filament_id = self_index.size() == flow_ratios.size() ? self_index[column] - 1 : column;
|
||||
if (flow_ratios[column] > 0. || !std::binary_search(extruders.begin(), extruders.end(), filament_id))
|
||||
continue;
|
||||
StringObjectException err;
|
||||
// TRN %1% is the filament number as shown in the filament list, starting from 1.
|
||||
err.string = Slic3r::format(L("The flow ratio of filament %1% must be greater than 0."), filament_id + 1);
|
||||
err.opt_key = "filament_flow_ratio";
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// IDEX/IQEX: block multi-color in non-primary parallel modes when the active
|
||||
// configuration can't physically support it (no within-gantry toolchange path
|
||||
// or MMU lane sharing). See imex_multicolor_block_reason() for the full rule.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <catch2/catch_message.hpp>
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/GCodeReader.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/ModelArrange.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
@@ -89,6 +90,28 @@ TEST_CASE("The exclude object tolerance defaults to the former fixed 0.1 mm", "[
|
||||
Catch::Matchers::WithinAbs(0.1, 1e-9));
|
||||
}
|
||||
|
||||
TEST_CASE("The filament flow ratio scales the extruded length once", "[GCode]")
|
||||
{
|
||||
// Retraction off, so every positive relative E move is extrusion and scales with the ratio.
|
||||
auto extruded_length = [](double flow_ratio) {
|
||||
DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
|
||||
config.set_deserialize_strict({ { "use_relative_e_distances", "1" }, { "retraction_length", "0" }, { "wipe", "0" } });
|
||||
config.set_key_value("filament_flow_ratio", new ConfigOptionFloatsNullable{ flow_ratio });
|
||||
double total = 0.;
|
||||
GCodeReader reader;
|
||||
reader.parse_buffer(Test::slice({ Test::cube(20) }, config),
|
||||
[&](GCodeReader &, const GCodeReader::GCodeLine &line) {
|
||||
if ((line.cmd_is("G1") || line.cmd_is("G2") || line.cmd_is("G3")) && line.has_e() && line.e() > 0.f)
|
||||
total += line.e();
|
||||
});
|
||||
return total;
|
||||
};
|
||||
|
||||
const double full = extruded_length(1.);
|
||||
REQUIRE(full > 0.);
|
||||
CHECK_THAT(extruded_length(0.9) / full, Catch::Matchers::WithinRel(0.9, 1e-3));
|
||||
}
|
||||
|
||||
// Firmwares read the compatibility header lines (Anycubic's GoKlipper heats the bed with
|
||||
// first_layer_bed_temperature), so they must describe the filament the plate prints, not filament 1.
|
||||
TEST_CASE("The G-code header names the first layer temperatures of the filament the plate prints", "[GCode]")
|
||||
|
||||
@@ -547,6 +547,31 @@ TEST_CASE("Print::validate tolerates a null warnings pointer", "[Print][validate
|
||||
CHECK(err.string.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("Print::validate refuses a used filament with a flow ratio of 0", "[Print][validate][Regression]")
|
||||
{
|
||||
DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
|
||||
config.set_key_value("filament_flow_ratio", new ConfigOptionFloatsNullable{ 0. });
|
||||
|
||||
std::vector<StringObjectException> warnings;
|
||||
StringObjectException err = validate_cubes(config, warnings);
|
||||
|
||||
CHECK_FALSE(err.string.empty());
|
||||
CHECK_FALSE(err.is_warning);
|
||||
CHECK(err.opt_key == "filament_flow_ratio");
|
||||
}
|
||||
|
||||
TEST_CASE("Print::validate ignores a flow ratio of 0 on an unused filament", "[Print][validate]")
|
||||
{
|
||||
// The cube prints with filament 1, so filament 2's ratio is never used.
|
||||
DynamicPrintConfig config = multifilament_config(2, { { "filament_self_index", "1,2" } });
|
||||
config.set_key_value("filament_flow_ratio", new ConfigOptionFloatsNullable{ 1., 0. });
|
||||
|
||||
std::vector<StringObjectException> warnings;
|
||||
StringObjectException err = validate_cubes(config, warnings);
|
||||
|
||||
CHECK(err.string.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("Purge tower selection keeps ordinary printers on the classic path", "[Print][PurgeTower][Regression]")
|
||||
{
|
||||
DynamicPrintConfig config = multifilament_config(2, {
|
||||
|
||||
Reference in new issue
Block a user