mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 10:17:55 -06:00
Reworked the "new" bridging to respect the bridge_flow_ratio
by maintaining extrusion spacing, but modifying the extrusion width and / or height.
This commit is contained in:
parent
8e27e355c2
commit
f01f02154c
12 changed files with 173 additions and 134 deletions
|
@ -6,12 +6,6 @@
|
|||
|
||||
#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)
|
||||
|
||||
|
@ -142,62 +136,82 @@ Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent
|
|||
w = float(width.get_abs_value(height));
|
||||
}
|
||||
|
||||
return Flow(w, height, nozzle_diameter, false);
|
||||
return Flow(w, height, rounded_rectangle_extrusion_spacing(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)
|
||||
// Adjust extrusion flow for new extrusion line spacing, maintaining the old spacing between extrusions.
|
||||
Flow Flow::with_spacing(float new_spacing) const
|
||||
{
|
||||
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.
|
||||
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, height, nozzle_diameter);
|
||||
Flow out = *this;
|
||||
if (m_bridge) {
|
||||
// Diameter of the rounded extrusion.
|
||||
assert(m_width == m_height);
|
||||
float gap = m_spacing - m_width;
|
||||
auto new_diameter = new_spacing - gap;
|
||||
out.m_width = out.m_height = new_diameter;
|
||||
} else {
|
||||
out.m_width += new_spacing - m_spacing;
|
||||
if (out.m_width < out.m_height)
|
||||
throw Slic3r::InvalidArgument("Invalid spacing supplied to Flow::with_spacing()");
|
||||
}
|
||||
out.m_spacing = new_spacing;
|
||||
return out;
|
||||
}
|
||||
|
||||
// This method returns the centerline spacing between two adjacent extrusions
|
||||
// having the same extrusion width (and other properties).
|
||||
float Flow::spacing() const
|
||||
// Adjust the width / height of a rounded extrusion model to reach the prescribed cross section area while maintaining extrusion spacing.
|
||||
Flow Flow::with_cross_section(float area_new) const
|
||||
{
|
||||
#ifdef HAS_PERIMETER_LINE_OVERLAP
|
||||
if (m_bridge)
|
||||
return m_width + BRIDGE_EXTRA_SPACING;
|
||||
// rectangle with semicircles at the ends
|
||||
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(m_bridge ? (m_width + BRIDGE_EXTRA_SPACING) : (m_width - m_height * (1. - 0.25 * PI)));
|
||||
#endif
|
||||
// assert(res > 0.f);
|
||||
if (res <= 0.f)
|
||||
throw FlowErrorNegativeSpacing();
|
||||
return res;
|
||||
assert(! m_bridge);
|
||||
assert(flow.width() >= flow.height());
|
||||
|
||||
// Adjust for bridge_flow_ratio, maintain the extrusion spacing.
|
||||
float area = this->mm3_per_mm();
|
||||
if (area_new > area + EPSILON) {
|
||||
// Increasing the flow rate.
|
||||
float new_full_spacing = area_new / m_height;
|
||||
if (new_full_spacing > m_spacing) {
|
||||
// Filling up the spacing without an air gap. Grow the extrusion in height.
|
||||
float height = area_new / m_spacing;
|
||||
return Flow(rounded_rectangle_extrusion_width_from_spacing(m_spacing, height), height, m_spacing, m_nozzle_diameter, false);
|
||||
} else {
|
||||
return this->with_width(rounded_rectangle_extrusion_width_from_spacing(area / m_height, m_height));
|
||||
}
|
||||
} else if (area_new < area - EPSILON) {
|
||||
// Decreasing the flow rate.
|
||||
float width_new = m_width - (area - area_new) / m_height;
|
||||
assert(width_dif > 0);
|
||||
if (width_new > m_height) {
|
||||
// Shrink the extrusion width.
|
||||
return this->with_width(width_new);
|
||||
} else {
|
||||
// Create a rounded extrusion.
|
||||
auto dmr = float(sqrt(area_new / M_PI));
|
||||
return Flow(dmr, dmr, m_spacing, m_nozzle_diameter, false);
|
||||
}
|
||||
} else
|
||||
return *this;
|
||||
}
|
||||
|
||||
// This method returns the centerline spacing between an extrusion using this
|
||||
// flow and another one using another flow.
|
||||
// this->spacing(other) shall return the same value as other.spacing(*this)
|
||||
float Flow::spacing(const Flow &other) const
|
||||
float Flow::rounded_rectangle_extrusion_spacing(float width, float height)
|
||||
{
|
||||
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)
|
||||
throw FlowErrorNegativeSpacing();
|
||||
return res;
|
||||
auto out = width - height * float(1. - 0.25 * PI);
|
||||
if (out <= 0.f)
|
||||
throw FlowErrorNegativeSpacing();
|
||||
return out;
|
||||
}
|
||||
|
||||
float Flow::rounded_rectangle_extrusion_width_from_spacing(float spacing, float height)
|
||||
{
|
||||
return float(spacing + height * (1. - 0.25 * PI));
|
||||
}
|
||||
|
||||
float Flow::bridge_extrusion_spacing(float dmr)
|
||||
{
|
||||
return dmr + BRIDGE_EXTRA_SPACING;
|
||||
}
|
||||
|
||||
// This method returns extrusion volume per head move unit.
|
||||
double Flow::mm3_per_mm() const
|
||||
double Flow::mm3_per_mm() const
|
||||
{
|
||||
float res = m_bridge ?
|
||||
// Area of a circle with dmr of this->width.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue