The new ExtrusionRole implementation newly supports both "Bridging"
and "External" attributes at the same time. PerimeterGenerator was updated to make use of it and set "External" attribute for overhang perimeters.
This commit is contained in:
parent
50bb164263
commit
ca0c83d914
@ -13,9 +13,10 @@ namespace Slic3r {
|
||||
GCodeExtrusionRole extrusion_role_to_gcode_extrusion_role(ExtrusionRole role)
|
||||
{
|
||||
if (role == ExtrusionRole::None) return GCodeExtrusionRole::None;
|
||||
if (role == ExtrusionRole::Perimeter) return GCodeExtrusionRole::Perimeter;
|
||||
if (role == ExtrusionRole::ExternalPerimeter) return GCodeExtrusionRole::ExternalPerimeter;
|
||||
if (role == ExtrusionRole::OverhangPerimeter) return GCodeExtrusionRole::OverhangPerimeter;
|
||||
if (role.is_perimeter()) {
|
||||
return role.is_bridge() ? GCodeExtrusionRole::OverhangPerimeter :
|
||||
role.is_external() ? GCodeExtrusionRole::ExternalPerimeter : GCodeExtrusionRole::Perimeter;
|
||||
}
|
||||
if (role == ExtrusionRole::InternalInfill) return GCodeExtrusionRole::InternalInfill;
|
||||
if (role == ExtrusionRole::SolidInfill) return GCodeExtrusionRole::SolidInfill;
|
||||
if (role == ExtrusionRole::TopSolidInfill) return GCodeExtrusionRole::TopSolidInfill;
|
||||
|
@ -2631,7 +2631,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, const std::string_view descr
|
||||
}
|
||||
|
||||
// make a little move inwards before leaving loop
|
||||
if (paths.back().role() == ExtrusionRole::ExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
|
||||
if (paths.back().role().is_external_perimeter() && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
|
||||
// detect angle between last and first segment
|
||||
// the side depends on the original winding order of the polygon (left for contours, right for holes)
|
||||
//FIXME improve the algorithm in case the loop is tiny.
|
||||
@ -2877,7 +2877,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||
} else if (path.role() == ExtrusionRole::ExternalPerimeter) {
|
||||
speed = m_config.get_abs_value("external_perimeter_speed");
|
||||
} else if (path.role().is_bridge()) {
|
||||
assert(path.role() == ExtrusionRole::OverhangPerimeter || path.role() == ExtrusionRole::BridgeInfill);
|
||||
assert(path.role().is_perimeter() || path.role() == ExtrusionRole::BridgeInfill);
|
||||
speed = m_config.get_abs_value("bridge_speed");
|
||||
} else if (path.role() == ExtrusionRole::InternalInfill) {
|
||||
speed = m_config.get_abs_value("infill_speed");
|
||||
|
@ -114,7 +114,7 @@ ExtrusionMultiPath PerimeterGenerator::thick_polyline_to_multi_path(const ThickP
|
||||
}
|
||||
|
||||
const double w = fmax(line.a_width, line.b_width);
|
||||
const Flow new_flow = (role == ExtrusionRole::OverhangPerimeter && flow.bridge()) ? flow : flow.with_width(unscale<float>(w) + flow.height() * float(1. - 0.25 * PI));
|
||||
const Flow new_flow = (role.is_bridge() && flow.bridge()) ? flow : flow.with_width(unscale<float>(w) + flow.height() * float(1. - 0.25 * PI));
|
||||
if (path.polyline.points.empty()) {
|
||||
path.polyline.append(line.a);
|
||||
path.polyline.append(line.b);
|
||||
@ -292,9 +292,9 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
||||
for (const PerimeterGeneratorLoop &loop : loops) {
|
||||
bool is_external = loop.is_external();
|
||||
|
||||
ExtrusionRole role = ExtrusionRole::None;
|
||||
ExtrusionLoopRole loop_role;
|
||||
role = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||
ExtrusionRole role_normal = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||
ExtrusionRole role_overhang = role_normal | ExtrusionRoleModifier::Bridge;
|
||||
if (loop.is_internal_contour()) {
|
||||
// Note that we set loop role to ContourInternalPerimeter
|
||||
// also when loop is both internal and external (i.e.
|
||||
@ -321,7 +321,7 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
||||
extrusion_paths_append(
|
||||
paths,
|
||||
intersection_pl({ polygon }, lower_slices_polygons_clipped),
|
||||
role,
|
||||
role_normal,
|
||||
is_external ? params.ext_mm3_per_mm : params.mm3_per_mm,
|
||||
is_external ? params.ext_perimeter_flow.width() : params.perimeter_flow.width(),
|
||||
float(params.layer_height));
|
||||
@ -332,7 +332,7 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
||||
extrusion_paths_append(
|
||||
paths,
|
||||
diff_pl({ polygon }, lower_slices_polygons_clipped),
|
||||
ExtrusionRole::OverhangPerimeter,
|
||||
role_overhang,
|
||||
params.mm3_per_mm_overhang,
|
||||
params.overhang_flow.width(),
|
||||
params.overhang_flow.height());
|
||||
@ -341,7 +341,7 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
||||
// We allow polyline reversal because Clipper may have randomly reversed polylines during clipping.
|
||||
chain_and_reorder_extrusion_paths(paths, &paths.front().first_point());
|
||||
} else {
|
||||
ExtrusionPath path(role);
|
||||
ExtrusionPath path(role_normal);
|
||||
path.polyline = polygon.split_at_first_point();
|
||||
path.mm3_per_mm = is_external ? params.ext_mm3_per_mm : params.mm3_per_mm;
|
||||
path.width = is_external ? params.ext_perimeter_flow.width() : params.perimeter_flow.width();
|
||||
@ -503,7 +503,8 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
||||
continue;
|
||||
|
||||
const bool is_external = extrusion->inset_idx == 0;
|
||||
ExtrusionRole role = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||
ExtrusionRole role_normal = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||
ExtrusionRole role_overhang = role_normal | ExtrusionRoleModifier::Bridge;
|
||||
|
||||
if (pg_extrusion.fuzzify)
|
||||
fuzzy_extrusion_line(*extrusion, scaled<float>(params.config.fuzzy_skin_thickness.value), scaled<float>(params.config.fuzzy_skin_point_dist.value));
|
||||
@ -541,13 +542,13 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
||||
}
|
||||
|
||||
// get non-overhang paths by intersecting this loop with the grown lower slices
|
||||
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctIntersection), role,
|
||||
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctIntersection), role_normal,
|
||||
is_external ? params.ext_perimeter_flow : params.perimeter_flow);
|
||||
|
||||
// get overhang paths by checking what parts of this loop fall
|
||||
// outside the grown lower slices (thus where the distance between
|
||||
// the loop centerline and original lower slices is >= half nozzle diameter
|
||||
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctDifference), ExtrusionRole::OverhangPerimeter,
|
||||
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctDifference), role_overhang,
|
||||
params.overhang_flow);
|
||||
|
||||
// Reapply the nearest point search for starting point.
|
||||
@ -568,7 +569,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
||||
for (const ExtrusionPath &path : paths) {
|
||||
++point_occurrence[path.polyline.first_point()].occurrence;
|
||||
++point_occurrence[path.polyline.last_point()].occurrence;
|
||||
if (path.role() == ExtrusionRole::OverhangPerimeter) {
|
||||
if (path.role().is_bridge()) {
|
||||
point_occurrence[path.polyline.first_point()].is_overhang = true;
|
||||
point_occurrence[path.polyline.last_point()].is_overhang = true;
|
||||
}
|
||||
@ -588,7 +589,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
||||
chain_and_reorder_extrusion_paths(paths, &start_point);
|
||||
}
|
||||
} else {
|
||||
extrusion_paths_append(paths, *extrusion, role, is_external ? params.ext_perimeter_flow : params.perimeter_flow);
|
||||
extrusion_paths_append(paths, *extrusion, role_normal, is_external ? params.ext_perimeter_flow : params.perimeter_flow);
|
||||
}
|
||||
|
||||
// Append paths to collection.
|
||||
|
@ -58,9 +58,7 @@ public:
|
||||
bool is_external_perimeter() const
|
||||
{
|
||||
assert(origin_entity != nullptr);
|
||||
//FIXME origin_entity->role() == ExtrusionRole::OverhangPerimeter is not quite right.
|
||||
// rather use origin_entity->role().is_external_perimeter()
|
||||
return origin_entity->role() == ExtrusionRole::ExternalPerimeter || origin_entity->role() == ExtrusionRole::OverhangPerimeter;
|
||||
return origin_entity->role().is_external_perimeter();
|
||||
}
|
||||
|
||||
Vec2f a;
|
||||
|
@ -36,6 +36,12 @@ public:
|
||||
// Combine with another enum_bitmask of the same type.
|
||||
constexpr enum_bitmask operator|(enum_bitmask<option_type> t) const { return enum_bitmask(m_bits | t.m_bits); }
|
||||
|
||||
// Set the bit corresponding to the given option.
|
||||
constexpr void operator|=(option_type t) { m_bits = enum_bitmask(m_bits | mask_value(t)); }
|
||||
|
||||
// Combine with another enum_bitmask of the same type.
|
||||
constexpr void operator|=(enum_bitmask<option_type> t) { m_bits = enum_bitmask(m_bits | t.m_bits); }
|
||||
|
||||
// Get the value of the bit corresponding to the given option.
|
||||
constexpr bool operator&(option_type t) const { return m_bits & mask_value(t); }
|
||||
constexpr bool has(option_type t) const { return m_bits & mask_value(t); }
|
||||
|
Loading…
Reference in New Issue
Block a user