CuraEngine
CuraEngine copied to clipboard
Zig-zaggified zags should be stable
When "zig-zaggify infill" is enabled, the structure of where the zags connecting infill lines gets placed depends on the 2D geometry of the layer slice in such a way that it's unstable between layers. This leads to a situation where the parts of the outline that have an extra wall layer (from the infill zags) will invert at certain layers according to geometry, and will sometimes invert at every layer. These inversions not only weaken the part, but can lead to predictable underextrusion, in the following manner:
When a zag along the wall is printed where there was not one in the previous layer, it is entirely unsupported (essentially a bridge), and there is no backpressure at the nozzle from the previous layer. As such, it tends (especially with a bowden extruder, and especially with linear-advance/pressure-advance compensation, but I was able to reproduce it with LA disabled) to extrude more material than expected, leaving the next line to be underextruded. The extent is sufficient to affect the thickness/integrity of outer walls printed immediately after the infill.
Rather than creating connecting zags via a process specific to the geometry of the layer (or at least as an optional alternative), locations of zags should be chosen based entirely on the infill grid structure and x/y coordinates. Admittedly this is not an easy change, as it alters the optimization problem to be solved and may have cases that don't admit optimal solutions or even solutions meeting the current constraints. (For example it may preclude full zigzagification or require retracting already extruded zags.)
I don't have photos prepared now, but I can add some pics later if necessary to demonstrate the problem.
Hi @richfelker thank you. This is a known issue, but I have to defer this. Because it is very complex to solve and find the right solution. Hope you understand!
Nod, thanks for the quick response anyway! I'll see if I can dig up anything that would be useful in the mean time and post it here for the record. Do you know any workarounds that might help? Perhaps setting a very high infill overlap and printing infill after walls so it's extruded against the outer wall regardless?
Actually, that suggests a change that might go a long way towards solving the problem: print zags with very low line width, just enough to be a continuous proper extrusion rather than oozing, so that the pressure during them is very low. This might be something I can experiment with.
I'll do a bit more of a write-up because I know Richfelker will be interested ;) And perhaps it stimulates discussion/ideas.
We've looked into this before. When devising this algorithm I already foresaw this issue. There are small improvements we can theoretically make with some extra computational power but those are also very difficult to implement in practice due to multithreading.
Currently the algorithm to connect infill lines does the following:
- Start at an arbitrary point along the contour of the infill and go around the contour counter-clockwisely.
- Connect the first two intersections of the infill lines with the contour together.
- Don't connect the second and third intersections.
- Connect the third and fourth intersections, the fifth and sixth, and so on.
- When connecting two lines, first check if the lines are already connected through the other side of their lines. Each infill line becomes a polyline. Basically, don't create loops.
This issue arises when a new intersection is added or removed somewhere halfway through the contour. The rest of the contour then basically shifts by 1, causing most connections to flip over.
There is no way to 100% prevent this. A new intersection can always be added in a location that causes at least some zags to float in mid-air or lines to not be connected. Basically the best you can do is make as many zags as possible rest on zags of previous layers. There are two challenges with this:
- Which lines to connect on each side is a combinatoric problem. It grows very fast with the number of intersections. Brute-forcing it would be O(2^N) but there are of course quite some heuristics possible to make it more efficient. A simple heuristic would be to rotate the starting point and simply sample a number of them to see which of them make the most lines overlap. Trying 10 points would probably already reduce the problem significantly. At the cost of 10x as much processing power in this part of the slice of course, so it'll have to be seen how much that impacts the overall processing time. Aside from brute-forcing or sampling there may also be other ways to smartly reduce the number of computations but I don't think it's likely to get under O(N²). If you have a decent idea though I'd be all ears. It's a really interesting CompSci problem, actually.
- Perhaps a bigger problem is to know which lines are connected in the layer below. Two problems with that are that the layer below usually has a different shape, so you won't have the same number of intersections for a 1-on-1 mapping and they won't be in the same place either. You can't just look at slope and y-intersect either because the shape on that layer may be different so the connection won't always overlap, and also some infill patterns are 3D. What's more, layers in CuraEngine are generated asynchronously so you don't know yet what the previous layer did, only the shape of its infill, and you can't double-calculate the previous layer because its connections also depend on the layer beneath it, in turn. So the only way to do this is to have a pre-defined protocol, e.g. "at such and such coordinates you should prefer to connect two lines on the North side" but that is hard to devise with lines crossing in arbitrary directions at arbitrary positions. The Zigzag infill pattern uses such a predefined protocol to connect a certain side of the lines depending on their (rotated) Y coordinate.
The intent of this feature was to simply prevent interrupting the flow. While the bonus of getting a stronger part is nice, the fact that you get more consistent flow was the most important one to us. Even if the backpressure is reduced here and there, the flow is more consistent than when you travel.
Except for trying to align the zags on top of each other, there are also more print-process oriented solutions. I think the best one is to increase the Infill Overlap slightly, so that the infill gets printed a bit more into the outer wall. I think this is a good workaround for you.
The Zigzag infill pattern also has better guarantees than other infill patterns, but it alternates line directions by default (which you can alter with the Infill Angles setting).
I'll do a bit more of a write-up because I know Richfelker will be interested ;)
:-)
There is no way to 100% prevent this. A new intersection can always be added in a location that causes at least some zags to float in mid-air or lines to not be connected
I think this is right. My proposal was to have the decision determined by the infill grid position, e.g. for grid you can color each grid square according to parity and do connecting lines precisely where the wall goes through odd-parity squares. But I agree this creates situations where you'll have to make some non-connecting (travel) moves. I suspect you can optimize it down to very few in the common case, probably usually 0-2, but not always zero. I'm not sure which infill patterns admit such an approach though. Gyroid for example is inherently problematic because of the orientation switches, and I'm unsure whether it's workable for the triangular type patterns.
If an approach like the above works, it avoids having to be aware of previous layer line positions and the associated challenges for multithreading.
The intent of this feature was to simply prevent interrupting the flow. While the bonus of getting a stronger part is nice, the fact that you get more consistent flow was the most important one to us
This I understand, but in practice due to this issue, I've found that zig-zaggify-infill often doesn't just fail to make the part stronger, but makes it significantly weaker, sometimes causing complete failure of wall integrity in the layer after the flip.
Even if the backpressure is reduced here and there, the flow is more consistent than when you travel.
Flow is only consistent if you define flow as E-motor rate. The actual flow out of the nozzle is highly inconsistent due to lack of any backpressure.
I think the best one is to increase the Infill Overlap slightly, so that the infill gets printed a bit more into the outer wall. I think this is a good workaround for you.
I think this sounds promising too, but if the overlap is nontrivial, it will severely overextrude in narrow infill regions. That was my original motivation for not using infill overlap. Using a minimum infill area solves this for well-behaved shapes but not long thin ones, which will necessarily appear at one layer or another whenever you have a cylinder with axis parallel to the XY plane.
The Zigzag infill pattern also has better guarantees than other infill patterns, but it alternates line directions by default (which you can alter with the Infill Angles setting).
Thanks, will try. The alternating line direction basically means there's no infill layer bonding, but I forgot you can turn it off. Is there a reason triangles and cubic (the two best patterns, in my experience) can't be implemented just as repeating zigzag three times at 120 degree angle offset, ignoring (as they do now) the resulting self-intersection? Maybe the second and third would need to be offset inward by one/two line widths (resp) to avoid extruding coincident segments but it seems like it should work and solve the problem at the expense (and corresponding structural benefit) of more material.
Flow is only consistent if you define flow as E-motor rate. The actual flow out of the nozzle is highly inconsistent due to lack of any backpressure.
I meant flow out the nozzle. In our experience the flow out the nozzle is more consistent when you connect the infill lines than when you make travels. Our experience may be a bit different from yours because Ultimaker printers have Bowden tubes (so there's much more delay in the flow rate out the nozzle) and we tend to print with line widths slightly smaller than the nozzle size so the connections will be leaning a bit more on the walls.
Is there a reason triangles and cubic (the two best patterns, in my experience) can't be implemented just as repeating zigzag three times at 120 degree angle offset, ignoring (as they do now) the resulting self-intersection? Maybe the second and third would need to be offset inward by one/two line widths (resp) to avoid extruding coincident segments but it seems like it should work and solve the problem at the expense (and corresponding structural benefit) of more material.
The problem is indeed that you then get connections for basically the entire contour, much of which is overlapping from connections of different orientations in the same place. With triangular infill, as you can imagine, on average 150% of the contour will be connected. We recently tried (due to a slightly related story with Gradual Infill) to create multiple layers of connections, basically laying the connections next to each other instead of overlapping them. It didn't work out in the end. The connections will then not be attached to the walls at all any more because they are spaced away from the wall. So the ends of the infill lines don't attach to the walls any more and you get badness. This could also be "fixed" by making the connections wrap around the ends. This gets complicated real fast when you have multiple of these wrapped inside each other though (like the 3 orientations of triangular infill).
Confirmed that the problem goes away with pattern=zigzag. However the part of course has no strength against crushing perpendicular to the direction of the zigzag with this pattern. What if there were a pattern that behaved identicallly to zigzag except with a sinusoidal path for each (following the shape of the wall if it hit a wall along the way) crossing rather than straight line segments, so that consecutive paths across the infill region would always touch? Aside from solving the issue described here, I would expect it to be one of the strongest infill patterns, especially relative to speed - a lot like gyroid, but without the poor layer adhesion from each layer being largely overhang in a way that encourages delamination to spread as soon as it starts.
A bit like a full-honeycomb pattern, you mean?
With honeycomb it could work similarly to the zigzag pattern I reckon.
Yes, honeycomb is basically what I had in mind. A smooth one would be better for print speed and supporting solid layers on top, but a rigid one with 60 degree corners would give more strength. I don't immediately see a way to do honeycomb like this without doubled-up walls in one of the three angles, but that's probably great for part strength anyway.
Not a solution but may be interesting to anyone following this issue: switching from a bowden system to a direct drive extruder made the main problematic consequence of this issue go away entirely for me. Still I'd like to see this solved in case I'm using bowden printers again in the future and because solving it should produce significant improvement in part-strength-to-material ratio.