Cura icon indicating copy to clipboard operation
Cura copied to clipboard

Infill is incorrect when Infill Layer Thickness is a multiple of Layer Height

Open GregValiant opened this issue 7 months ago • 8 comments

Cura Version

5.10.0

Operating System

Windows 10 Pro

Printer

Ender 3 Pro

Reproduction steps

Adjust the "Infill Layer Thickness to 2X Layer Height. Slice the model. Zoom in on the layers that should not have infill.

Actual results

Small dots of infill show up on layers that should have no infill. It appears that the nozzle is randomly traveling around with an occasional pause. It's actually traveling around to extrude small dots of infill. Image

With the Infill Layer Thickness at 3X Layer height there should be two layers with no infill separating the layer with infill but the dots are being printed. Image

Expected results

The small infill dots should not be there.

Add your .zip and screenshots here ⬇️

Project file with Gyroid infill. 20643 Infill problem.zip

See the UM Forum for some more discussion.

GregValiant avatar May 29 '25 03:05 GregValiant

It's also on Mac, could be a shared component between platforms

bbo-git avatar May 29 '25 05:05 bbo-git

@GregValiant It's similar to the ant trails caused when doing gradual infill step. If the connect infill lines is selected then the artifacts disappear.

I vaguely remember we had to accept this behavior happening and not just removing small infill areas generated as otherwise it would lead to very small gaps or thin models not getting the correct infill percentage. To properly resolve the issue we would have to do a bit of an overhaul on the engine, which is on the roadmap but not sure when we'll get to it. Keep the issue open for validation reference in future. It's not a won't do but it's a long wait as we've attempted to fix this behavior previously but we simply lack the data in the engine to address it properly without causing regressions.

HellAholic avatar May 29 '25 09:05 HellAholic

Ah! I remember now. It was the "Support Infill Layer Thickness" that had the same problem and enabling "Connect Support Infill Lines" was the workaround for it.

GregValiant avatar May 29 '25 10:05 GregValiant

Playing around with a fix for this on my source. The following removes almost all of the spurious infill lines. The ones that remain seem to be associated with skin regions. Something similar may work in UM Cura.

diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp
index 6755cba21..9bbabb014 100644
--- a/src/FffGcodeWriter.cpp
+++ b/src/FffGcodeWriter.cpp
@@ -1940,6 +1940,8 @@ bool FffGcodeWriter::processSingleLayerInfill(const SliceDataStorage& storage, L
             lightning_layer = &mesh.lightning_generator->getTreesForLayer(gcode_layer.getLayerNr());
         }
 
+        const size_t combined_infill_layers = std::max(uint64_t(1), round_divide(mesh.settings.get<coord_t>("infill_sparse_thickness"), std::max(mesh.settings.get<coord_t>("layer_height"), coord_t(1))));
+
         if (hasSkinEdgeSupport)
         {
             Polygons infill_below_skin_per_density = infill_below_skin.intersection(in_outline);
@@ -1952,7 +1954,6 @@ bool FffGcodeWriter::processSingleLayerInfill(const SliceDataStorage& storage, L
 
                 const auto skin_edge_support_line_distance = mesh.settings.get<coord_t>("skin_edge_support_line_distance");
 
-                const size_t combined_infill_layers = std::max(uint64_t(1), round_divide(mesh.settings.get<coord_t>("infill_sparse_thickness"), std::max(mesh.settings.get<coord_t>("layer_height"), coord_t(1))));
                 const bool fill_below_all_skin = mesh.settings.get<bool>("skin_edge_support_fill_below_all_skin");
                 const bool fill_below_skin = fill_below_all_skin || (combined_infill_layers > 1 || !infill_not_below_skin.empty());
 
@@ -2026,6 +2027,12 @@ bool FffGcodeWriter::processSingleLayerInfill(const SliceDataStorage& storage, L
         // especially on vertical surfaces
         in_outline.removeSmallAreas(minimum_small_area);
 
+        if (combined_infill_layers > 1 && !zig_zaggify_infill)
+        {
+            // remove extraneous infill lines that remain when using multi-layer infill
+            in_outline = in_outline.offset(-infill_line_width - 10).offset(infill_line_width);
+        }
+
         const size_t wall_line_count_here = (density_idx < last_idx) ? 0 : wall_line_count;
 
         Infill infill_comp(pattern, zig_zaggify_infill, connect_polygons, in_outline, outline_offset, infill_line_width,

smartavionics avatar May 30 '25 11:05 smartavionics

Looking into this further, the little infill lines that remain only occur where the outer walls are sloping inwards as the layer height increases (i.e. like a pyramid or cone). This is because the infill regions become smaller as height increases and so when the area of the thickened infill is subtracted from the infill areas on the layers below, there remains a thin region of infill. I'll think about a fix for this.

smartavionics avatar Jun 01 '25 07:06 smartavionics

Something like this, perhaps? ...

diff --git a/src/skin.cpp b/src/skin.cpp
index 56c0d8185..376b86f9b 100644
--- a/src/skin.cpp
+++ b/src/skin.cpp
@@ -805,10 +805,13 @@ void SkinInfillAreaComputation::combineInfillLayers(SliceMeshStorage& mesh)
                                 // of the lower layer with the same or higher density index
                                 max_lower_density_idx = lower_layer_part.infill_area_per_combine_per_density.size() - 1;
                             }
+                            // shrink/expand lower layer after thickened area has been removed to avoid generating thin infill areas underneath sloping walls
+                            const coord_t shrink_expand = (combine_count_here + 1) * 2 * mesh.settings.get<coord_t>("infill_line_width");
                             for (size_t lower_density_idx = density_idx; lower_density_idx <= max_lower_density_idx && lower_density_idx < lower_layer_part.infill_area_per_combine_per_density.size(); lower_density_idx++)
                             {
                                 std::vector<Polygons>& lower_infill_area_per_combine = lower_layer_part.infill_area_per_combine_per_density[lower_density_idx];
                                 lower_infill_area_per_combine[0] = lower_infill_area_per_combine[0].difference(intersection); // remove thickened area from lower (single thickness) layer
+                                lower_infill_area_per_combine[0] = lower_infill_area_per_combine[0].offset(-shrink_expand).offset(shrink_expand);
                             }
                         }
                     }

smartavionics avatar Jun 01 '25 09:06 smartavionics

The fix in skin.cpp also removes the lines that the fix in FffGcodeWriter.cpp removed so that first patch can be ignored.

smartavionics avatar Jun 01 '25 09:06 smartavionics

I've been playing with other things. I'll take a look in a bit.

GregValiant avatar Jun 02 '25 15:06 GregValiant