mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-09 07:56:24 -06:00
[FEATURE] Experimental small area flow compensation (#3334)
* [FEATURE] Experimental small area flow compensation This is a native implementation of the [Small Area Flow Compensation](https://github.com/Alexander-T-Moss/Small-Area-Flow-Comp) post-processor by Alexander Þór for OrcaSlicer. Quite often small areas of solid infill appear to be over-extruded, despite the rest of a print looking like it has a well-dialled-in EM/Flow. Currently, there isn't a good understanding of why this happens, so this is an attempt at a brute-force approach to treat the symptom. This feature modifies the flow of extrusion lines inversely proportional to the length of the extrusion line (the shorter the extrusion, the less flow it should have). Alexander Þór: Author of the original script implementation Weaslus: Proof Reader, Hypeman & pestered folks into making this * [TASK] Whitespace cleanup * [TASK] Add credits, format code, improve input labels * [TASK] Use multi-line textbox as input for flow model * [TASK] Toggle flow compensation per object * [TASK] Enable flow compensation for first layer --------- Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
b30efa727f
commit
82ead12cde
12 changed files with 1168 additions and 7 deletions
88
src/libslic3r/GCode/SmallAreaInfillFlowCompensator.cpp
Normal file
88
src/libslic3r/GCode/SmallAreaInfillFlowCompensator.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
// Modify the flow of extrusion lines inversely proportional to the length of
|
||||
// the extrusion line. When infill lines get shorter the flow rate will auto-
|
||||
// matically be reduced to mitigate the effect of small infill areas being
|
||||
// over-extruded.
|
||||
|
||||
// Based on original work by Alexander Þór licensed under the GPLv3:
|
||||
// https://github.com/Alexander-T-Moss/Small-Area-Flow-Comp
|
||||
|
||||
#include <math.h>
|
||||
#include <cstring>
|
||||
#include <cfloat>
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../PrintConfig.hpp"
|
||||
|
||||
#include "SmallAreaInfillFlowCompensator.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
bool nearly_equal(double a, double b)
|
||||
{
|
||||
return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
|
||||
}
|
||||
|
||||
SmallAreaInfillFlowCompensator::SmallAreaInfillFlowCompensator(const Slic3r::GCodeConfig& config)
|
||||
{
|
||||
for (auto& line : config.small_area_infill_flow_compensation_model.values) {
|
||||
std::istringstream iss(line);
|
||||
std::string value_str;
|
||||
double eLength = 0.0;
|
||||
|
||||
if (std::getline(iss, value_str, ',')) {
|
||||
try {
|
||||
eLength = std::stod(value_str);
|
||||
if (std::getline(iss, value_str, ',')) {
|
||||
eLengths.push_back(eLength);
|
||||
flowComps.push_back(std::stod(value_str));
|
||||
}
|
||||
} catch (...) {
|
||||
std::stringstream ss;
|
||||
ss << "Error parsing data point in small area infill compensation model:" << line << std::endl;
|
||||
|
||||
throw Slic3r::InvalidArgument(ss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < eLengths.size(); i++) {
|
||||
if (i == 0) {
|
||||
if (!nearly_equal(eLengths[i], 0.0)) {
|
||||
throw Slic3r::InvalidArgument("First extrusion length for small area infill compensation model must be 0");
|
||||
}
|
||||
} else {
|
||||
if (nearly_equal(eLengths[i], 0.0)) {
|
||||
throw Slic3r::InvalidArgument("Only the first extrusion length for small area infill compensation model can be 0");
|
||||
}
|
||||
if (eLengths[i] <= eLengths[i - 1]) {
|
||||
throw Slic3r::InvalidArgument("Extrusion lengths for subsequent points must be increasing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!flowComps.empty() && !nearly_equal(flowComps.back(), 1.0)) {
|
||||
throw Slic3r::InvalidArgument("Final compensation factor for small area infill flow compensation model must be 1.0");
|
||||
}
|
||||
|
||||
flowModel.set_points(eLengths, flowComps);
|
||||
}
|
||||
|
||||
double SmallAreaInfillFlowCompensator::flow_comp_model(const double line_length)
|
||||
{
|
||||
if (line_length == 0 || line_length > max_modified_length()) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return flowModel(line_length);
|
||||
}
|
||||
|
||||
double SmallAreaInfillFlowCompensator::modify_flow(const double line_length, const double dE, const ExtrusionRole role)
|
||||
{
|
||||
if (role == ExtrusionRole::erSolidInfill || role == ExtrusionRole::erTopSolidInfill || role == ExtrusionRole::erBottomSurface) {
|
||||
return dE * flow_comp_model(line_length);
|
||||
}
|
||||
|
||||
return dE;
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
Loading…
Add table
Add a link
Reference in a new issue