WIP: Refactored bridging flow from normal flow, new config value

'thick_bridges' to switch between the Slic3r vs. S3D/Cura/Ideamaker
way of printing 1st object layer over supports.
Simplified the PresetHints.
This commit is contained in:
Vojtech Bubnik 2021-03-08 13:44:00 +01:00
parent 1569dad5de
commit ceea9de8b8
21 changed files with 228 additions and 283 deletions

View file

@ -6,6 +6,12 @@
#include <boost/algorithm/string/predicate.hpp>
// Overlap factor of perimeter lines. Currently no overlap.
// #define HAS_PERIMETER_LINE_OVERLAP
#ifdef HAS_PERIMETER_LINE_OVERLAP
#define PERIMETER_LINE_OVERLAP_FACTOR 1.0
#endif
// Mark string for localization and translate.
#define L(s) Slic3r::I18N::translate(s)
@ -122,20 +128,13 @@ double Flow::extrusion_width(const std::string& opt_key, const ConfigOptionResol
// This constructor builds a Flow object from an extrusion width config setting
// and other context properties.
Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio)
Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height)
{
// we need layer height unless it's a bridge
if (height <= 0 && bridge_flow_ratio == 0)
if (height <= 0)
throw Slic3r::InvalidArgument("Invalid flow height supplied to new_from_config_width()");
float w;
if (bridge_flow_ratio > 0) {
// If bridge flow was requested, calculate the bridge width.
height = w = (bridge_flow_ratio == 1.) ?
// optimization to avoid sqrt()
nozzle_diameter :
sqrt(bridge_flow_ratio) * nozzle_diameter;
} else if (! width.percent && width.value == 0.) {
if (! width.percent && width.value == 0.) {
// If user left option to 0, calculate a sane default width.
w = auto_extrusion_width(role, nozzle_diameter);
} else {
@ -143,26 +142,23 @@ Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent
w = float(width.get_abs_value(height));
}
return Flow(w, height, nozzle_diameter, bridge_flow_ratio > 0);
return Flow(w, height, nozzle_diameter, false);
}
// This constructor builds a Flow object from a given centerline spacing.
Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge)
Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height)
{
// we need layer height unless it's a bridge
if (height <= 0 && !bridge)
if (height <= 0)
throw Slic3r::InvalidArgument("Invalid flow height supplied to new_from_spacing()");
// Calculate width from spacing.
// For normal extrusons, extrusion width is wider than the spacing due to the rounding and squishing of the extrusions.
// For bridge extrusions, the extrusions are placed with a tiny BRIDGE_EXTRA_SPACING gaps between the threads.
float width = float(bridge ?
(spacing - BRIDGE_EXTRA_SPACING) :
float width = float(
#ifdef HAS_PERIMETER_LINE_OVERLAP
(spacing + PERIMETER_LINE_OVERLAP_FACTOR * height * (1. - 0.25 * PI));
#else
(spacing + height * (1. - 0.25 * PI)));
#endif
return Flow(width, bridge ? width : height, nozzle_diameter, bridge);
return Flow(width, height, nozzle_diameter);
}
// This method returns the centerline spacing between two adjacent extrusions
@ -170,13 +166,13 @@ Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height,
float Flow::spacing() const
{
#ifdef HAS_PERIMETER_LINE_OVERLAP
if (this->bridge)
return this->width + BRIDGE_EXTRA_SPACING;
if (m_bridge)
return m_width + BRIDGE_EXTRA_SPACING;
// rectangle with semicircles at the ends
float min_flow_spacing = this->width - this->height * (1. - 0.25 * PI);
float res = this->width - PERIMETER_LINE_OVERLAP_FACTOR * (this->width - min_flow_spacing);
float min_flow_spacing = m_width - m_height * (1. - 0.25 * PI);
float res = m_width - PERIMETER_LINE_OVERLAP_FACTOR * (m_width - min_flow_spacing);
#else
float res = float(this->bridge ? (this->width + BRIDGE_EXTRA_SPACING) : (this->width - this->height * (1. - 0.25 * PI)));
float res = float(m_bridge ? (m_width + BRIDGE_EXTRA_SPACING) : (m_width - m_height * (1. - 0.25 * PI)));
#endif
// assert(res > 0.f);
if (res <= 0.f)
@ -189,10 +185,10 @@ float Flow::spacing() const
// this->spacing(other) shall return the same value as other.spacing(*this)
float Flow::spacing(const Flow &other) const
{
assert(this->height == other.height);
assert(this->bridge == other.bridge);
float res = float(this->bridge ?
0.5 * this->width + 0.5 * other.width + BRIDGE_EXTRA_SPACING :
assert(m_height == other.m_height);
assert(m_bridge == other.m_bridge);
float res = float(m_bridge ?
0.5 * m_width + 0.5 * other.m_width + BRIDGE_EXTRA_SPACING :
0.5 * this->spacing() + 0.5 * other.spacing());
// assert(res > 0.f);
if (res <= 0.f)
@ -203,11 +199,11 @@ float Flow::spacing(const Flow &other) const
// This method returns extrusion volume per head move unit.
double Flow::mm3_per_mm() const
{
float res = this->bridge ?
float res = m_bridge ?
// Area of a circle with dmr of this->width.
float((this->width * this->width) * 0.25 * PI) :
float((m_width * m_width) * 0.25 * PI) :
// Rectangle with semicircles at the ends. ~ h (w - 0.215 h)
float(this->height * (this->width - this->height * (1. - 0.25 * PI)));
float(m_height * (m_width - m_height * (1. - 0.25 * PI)));
//assert(res > 0.);
if (res <= 0.)
throw FlowErrorNegativeFlow();
@ -222,9 +218,7 @@ Flow support_material_flow(const PrintObject *object, float layer_height)
(object->config().support_material_extrusion_width.value > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
// if object->config().support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value),
// bridge_flow_ratio
0.f);
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value));
}
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
@ -235,9 +229,7 @@ Flow support_material_1st_layer_flow(const PrintObject *object, float layer_heig
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(width.value > 0) ? width : object->config().extrusion_width,
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
(layer_height > 0.f) ? layer_height : float(object->config().first_layer_height.get_abs_value(object->config().layer_height.value)),
// bridge_flow_ratio
0.f);
(layer_height > 0.f) ? layer_height : float(object->config().first_layer_height.get_abs_value(object->config().layer_height.value)));
}
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
@ -248,9 +240,7 @@ Flow support_material_interface_flow(const PrintObject *object, float layer_heig
(object->config().support_material_extrusion_width > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
// if object->config().support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_interface_extruder-1)),
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value),
// bridge_flow_ratio
0.f);
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value));
}
}