diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 4289026f86..caf425ca75 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -2613,7 +2613,7 @@ bool FffGcodeWriter::processInsets( roofing_mask.add(layer_part.outline); } } - return roofing_mask.offset(100); + return roofing_mask; }(); gcode_layer.setRoofingMask(roofing_mask); diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index b80251a715..894972259e 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -642,6 +642,8 @@ void LayerPlan::addPolygonsByOptimizer( static constexpr double max_non_bridge_line_volume = MM2INT(100); // limit to accumulated "volume" of non-bridge lines which is proportional to distance x extrusion rate +static int i = 0; + void LayerPlan::addWallLine( const Point2LL& p0, const Point2LL& p1, @@ -773,14 +775,54 @@ void LayerPlan::addWallLine( if (use_roofing_config) { - addExtrusionMove( - p1, - roofing_config, - SpaceFillType::Polygons, - flow, - width_factor, - spiralize, - 1.0_r); + // The line segment is wholly or partially in the roofing area. The line is intersected + // with the roofing area into line segments. Each line segment left in this intersection + // will be printed using the roofing config, all removed segments will be printed using + // the non_bridge_config. Since the original line segment was straight we can simply print + // to the first and last point of the intersected line segments alternating between + // roofing and non_bridge_config's. + Polygons line_polys; + line_polys.addLine(p0, p1); + constexpr bool restitch = false; // only a single line doesn't need stitching + auto has_area_above_poly_lines = roofing_mask_.intersectionPolyLines(line_polys, restitch); + + if (has_area_above_poly_lines.empty()) + { + addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + else + { + // reorder all the line segments so all lines start at p0 and end at p1 + for (auto& line_poly : has_area_above_poly_lines) + { + const Point2LL& line_p0 = line_poly.front(); + const Point2LL& line_p1 = line_poly.back(); + if (vSize2(line_p1 - p0) < vSize2(line_p0 - p0)) + { + std::reverse(line_poly.begin(), line_poly.end()); + } + } + std::sort(has_area_above_poly_lines.begin(), has_area_above_poly_lines.end(), [&](auto& a, auto& b) { return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); + + // add intersected line segments, alternating between roofing and non_bridge_config + for (const auto& line_poly : has_area_above_poly_lines) + { + // This is only relevant for the very fist iteration of the loop + // if the start of the line segment is already the same as p0 then no move is required + if (line_poly.front() != p0) + { + addExtrusionMove(line_poly.front(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + + addExtrusionMove(line_poly.back(), non_bridge_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + + // if the last point is not yet at p1 then add a move to p1 + if (has_area_above_poly_lines.back().back() != p1) + { + addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + } } else if (bridge_wall_mask_.empty()) {