OrcaSlicer
OrcaSlicer copied to clipboard
ENH: fix internal bridge missing for some sloped surfaces
Aiming to address issue https://github.com/SoftFever/OrcaSlicer/issues/413 and corresponding development backlog item
By default Orca and all the Slic3r derivatives implement filtering to remove areas where internal bridging may be unnecessary as the infill is thought to be supported adequately from the sparse infill below.
However that is not always the case, especially for:
- Models with arched top surfaces
- When lightning infill is used for curved top surface models
- When low density infill is used and especially with curved/slanted top surfaces
Examples:
Unsupported solid infill edges when using lightning
Solid infill printing in mid aid when using low density infill (adaptive cubic)
Solid infill printing in mid air when using low density infill (grid)
Weirdness here...
Even more weirdness :)
This can result in pillowing of top surfaces and unnecessary increase in the density of the infill to enable a good quality top surface, especially as the solid infill is printed fast.
This option removes the filtering and enables internal bridging to be created in problematic areas like the above.
Beautifully supported solid infill below (fully or partly)
Option is located here:
Filtering is disabled by default when lightning infill is used as this is particularly problematic. (and personally I've ruined a few silk PLA models because of this and had to significantly increase lightning infill % to get it to work well :( )
@SoftFever Thank you for this comment above, its been fantastic in pushing me to explore this further (and dont be lazy just disabling it completely.)
I'm sharing all of the analysis I've done below for your reading, incl some recommendations.
Analysis
I've implemented part of the above proposed code and graphed the polygons so we can see it visually what is going on (I'm a visual person and need to see the math :)):
The above is at layer 147 of the attached 3MF : Dyson fuss.3mf.zip
At layer 147 (1 indexed) the unsupported_area_original has 8 polygons. There are 2 big polygons (the ones you see) and the rest are the tiny ones that appear like dots in the graph on the left hand side (I think a couple are not even drawn as they are too small).
Now if I filter out the tiny ones:
We can see the original polygon and the clipped polygon.
Original
auto unsupported_area_original = diff(unsupported_area, lower_layer_solids);
Clipped / New:
lower_layer_solids = shrink(lower_layer_solids, 1 * spacing);
lower_layer_solids = expand(lower_layer_solids, (1 + 3) * spacing);
unsupported_area = shrink(unsupported_area, 3 * spacing);
unsupported_area = diff(unsupported_area, lower_layer_solid
The below is the slice (bridge is generated as I didn't turn off the option to do remove the filtering - this is the original unsupported):
What you're proposing above is to take the delta region between the Original and New polygons (including all the tiny original ones) and if the area of that delta region is over a specific threshold then replace the New polygon with the Original polygon, reverting the shrinking.
Here is where my potentially questionable memory of math from my Computer science classes 22 years ago comes in.
While this will work if the threshold is set low enough, the delta area between the two is a function of:
- 3 x spacing - this is constant
- The size of the polygon. Larger polygons will reduce in terms of surface area much more compared to smaller ones
So setting a threshold area as a filtering mechanism won't necessarily work. We could do it as a % but then this is already kind of known because we always shrink by 3 x spacing. (I think).
What we could do is shrink the polygon by less - not 3x spacing but say 1x spacing in which case we get this shrinkage:
unsupported_area = shrink(unsupported_area, 1 * spacing);
But this doesnt help as the region that would trigger the bridge on the left is clipped more (this is with 1x spacing). (you can see it as the distance from the original polygon on the left compared to the red dotted line is proportionally larger).
We could go even lower than that - say half spacing: (the black line)
In this case we finally get some bridging going on but that quickly deteriorates on subsequent layers
That is now because of the clipping from the lower_layer_solids that are expanded by 3 x spacing (3x + 1x from the previous shrinkage).
lower_layer_solids = expand(lower_layer_solids, (1 + 3) * spacing);
If I reduce the expansion of the lower_layer_solids to 1 x spacing and leave the unsupported area clipped by 1 x spacing I get good bridges again:
lower_layer_solids = expand(lower_layer_solids, 1 * spacing);
unsupported_area = shrink(unsupported_area, 1 * spacing);
Bingo, we've found our culprit! The artificial expansion by 3x unsupported perimeters of the lower layer solids kills bridging here. Ιt fills it that small region with solid infill as it thinks its supported by a lower solid region and fills the rest with sparse infill as we haven't hit the distance/number of layers to the top surface yet.
So its not the thin but long issue that was considered but rather a special case where due to the angle of the slope we are having an unsupported area that is filtered out as supported because of the 3x spacing, with the rest also not being unsupported as its not infill yet - its sparse infill.
So the bridge infill is therefore, never generated.
So where does this leave us?
A few options depending on how much tweaking we leave to the user.
- We cannot use the area difference I think because of the above reasons (difference is proportional to the size of the polygon)
- We can either give the user a spacing option that is a % between 0-100 which is then multiplied with the 3*spacing to control that filtering
- Or we could give an on-off switch that sets the spacing to 1x or 3x (default).
- Or we could limit the spacing tweak only to the lower_layer_solids. I haven't done that here as wanting to be safe, but this is something to explore. In this scenario it works equally well to leave the unsupported_area spacing untouched but only change the lower_layer_solids expansion.
- Or do we not even make it an option and just adjust the default values to be a bit more conservative? (1x spacing). The more I think about it the more I am just leaning towards this, as I can't see the downside.
I've implemented number 3 in the latest code push. But equally can do (4) but need more models to try it on.
Updated some minor errata on the above analysis + submitted new code.
Ok, I have checked some of the generated G-code. Some of it looks a bit weird sometimes, is there a way to make it a bit more uniform?
Also, I tested it with a part where the slope is increasing. Around layer 25, it stops making the bridge layers, and when it prints these small lines, they tend to curl upwards as they cool down. That's when it becomes a problem.
Bambu_Lab_Trash_-Small-_Thickness_1mm.zip
The downside to removing the filtering is that you may get small sections that are not that uniform. This is dependant on the model geometry unfortunately and is a tradeoff to be made - more bridging with some small artefacts or reduced bridging with none. Think this is making the case to have this as an option for the user.
I haven't found a way to trigger bridging on your second scenario, even when removing completely all filtering. The reason for this is that its a single perimeter width that is unsupported, which doesnt "count" as an unsupported region large enough to trigger bridging.
Theoretically it shouldn't affect print quality as the vast majority of the surface is supported underneath. Kind of like printing small overhangs. This can be mitigated by ensuring enough top layers are present as this will push those small overhangs down and not be visible to the outside.
I think this needs now print tests to verify.....
Unless Softfever has another idea on this? :)
Doing a print test with the below problem area only: Slope print test.3mf.zip
Print speeds are reasonably fast and infill is very low - 6%, to show the issue if present and will revert back
Printer go brrrrr :D
https://youtube.com/shorts/Xh_-R8LBpao?si=sqjdzbnGvdOtyuyP
I can see every so slight curling up in the layers without support. Will try to find where I can fix this, but I'm not holding my breath. Part so far looks OK, even though I can see it possibly having an issue higher up.
So turns out you're absolutely correct - the top surface looked like poop because of the curling.
I've extended the removal of the filtering even further resulting in this:
While this option doesn't "break" anything, it does mean that it creates very conservative internal bridges, increasing print time. And in some cases unnecessarily so. Hence why this now must be an option and not on by default.
I'll be pushing a new build for testing.
New build is up. @neorm please test when you can, ideally also with a real print, if possible.
Flagged option as experimental and updated tooltip with the warning that it may unnecessarily create internal bridges over small overhanging solid infill regions. However, it does have a use case like the above example:
(ignore the slight perimeter under extrusion - I had pushed my flow rate a tad too low).
Clearly it makes a big difference in this particular scenario. However it's a bit ham fisted approach that could be refined further to not be for example so sensitive with internal overhangs that are way way too small.
So I'm not 100% happy with it. It works but it's way too conservative. I tried to refine it further by playing with the expansion values in the if statement that is now ignored when this option is enabled but failed miserably. Maybe a fresh pair of eyes on this can help :)
For now its a working version that could help with this specific issue (and enabled only for models that really need it) so its still worth it but not comfortable to always have it enabled, like I'd like as it is too conservative and extends print times with out a good reason in most "usual" models.
@SoftFever I'll make a further change to this PR this week. I want to introduce a drop down for this option that controls the level of filtering. 1. Disabled - the as is V1.9 code 2. Limited filtering - would be the PR as it was submitted a couple of weeks ago - where it works for partly slanted surfaces but not all slanted surfaces 3. No filtering - would be this PR as it is now
I'll be making the changes this week and I'll resubmit. The reasoning is that I want to enable this option in my own personal profiles to address slightly slanted surfaces but I am not a fan of the complete lack of filtering as this PR stands right now. I can see the need for no filtering on some difficult models, so it's valid to keep it, but I dont want to be throwing bridges everywhere if a less aggressive option can work for the model.
@SoftFever I'll make a further change to this PR this week. I want to introduce a drop down for this option that controls the level of filtering. 1. Disabled - the as is V1.9 code 2. Limited filtering - would be the PR as it was submitted a couple of weeks ago - where it works for partly slanted surfaces but not all slanted surfaces 3. No filtering - would be this PR as it is now
I'll be making the changes this week and I'll resubmit. The reasoning is that I want to enable this option in my own personal profiles for slanted surfaces but I am not a fan of the complete lack of filtering as this PR stands right now. I can see the need for no filtering on some difficult models, so its valid to keep it, but I dont want to be throwing bridges everywhere if a less aggressive option can work for the model.
Noted. 👍
Looks very promising! Good job!
So updated the PR to convert this into an option:
Disabled (default) - Limited filtering - No filtering
Limited filtering addresses the majority of the slanted top surface issues without creating unnecessary internal bridges and is what I'll pick as my default. No filtering is very aggressive in creating internal bridges but this solves issues with very specific models with slanted top surfaces as seen above.
Submitting as ready for review and I'll update the top post with the final implementation.
So updated the PR to convert this into an option:
Disabled (default) - Limited filtering - No filtering Limited filtering addresses the majority of the slanted top surface issues without creating unnecessary internal bridges and is what I'll pick as my default. No filtering is very aggressive in creating internal bridges but this solves issues with very specific models with slanted top surfaces as seen above.
Submitting as ready for review and I'll update the top post with the final implementation.
Thanks for the great work! I messed with a few models and agree that the 'limited' option seems most reasonable from the g-code preview, even though it slightly increases printing time. I'm not sure how much difference it will make to the actual print for most 'common' models, but I totally agree with you on keeping the current default behavior.
Fantastic 👌🏻 thank you!
I’ve set the limited option as my default for my custom profiles and will be test driving this going forward. Maybe we revisit the default when more data is available.
Great work, appreciate you guys! When will this be available in stable/alpha of orca slicer?
Great work, appreciate you guys! When will this be available in stable/alpha of orca slicer?
Yeap it’s in the nightly release here: https://github.com/SoftFever/OrcaSlicer/releases/tag/nightly-builds
@igiannakas I just want to chip in saying this is an awesome work and thank you. Not just solved slope in an angle surface artifact, but there are instances just 20 degree straight slope can see the improvement by having no filtering set. It works like a charm!
@igiannakas I just want to chip in saying this is an awesome work and thank you. Not just solved slope in an angle surface artifact, but there are instances just 20 degree straight slope can see the improvement by having no filtering set. It works like a charm!
Your welcome! Personally I have set my profile to limited filtering as this works great for most cases with the odd exception needing none, and equally the odd exception needing this feature disabled. Big improvement in sloped surfaces over the past few months I’ve been using this
no filtering works great on this model attached but with limited is poor. any help? i dont like how much extra time and filament it uses so hopefully this will help you improve it! this is one of best features added just need get some testing and tuning. i stopped the test early because it was quite obvious it was going to be perfect with it turned on compared to before.
model used https://www.dropbox.com/scl/fi/oynw87altq5yma6vqscdy/gradient-test.3mf?rlkey=61qcutklydx4wm7yvnxfnooft&dl=0
WOW! internal bridges looks very well!
no filtering works great on this model attached but with limited is poor. any help? i dont like how much extra time and filament it uses so hopefully this will help you improve it! this is one of best features added just need get some testing and tuning. i stopped the test early because it was quite obvious it was going to be perfect with it turned on compared to before.
model used https://www.dropbox.com/scl/fi/oynw87altq5yma6vqscdy/gradient-test.3mf?rlkey=61qcutklydx4wm7yvnxfnooft&dl=0
Not much that can be done really - for models like this is why I implemented the no filtering option. It’s a trade off- more print time but better quality.
That's a huge difference in print quality! Yeah I noticed that too that no filtering consumes way too much filament and time, and unnecessary in most but not all cases. I have two comments
-
If there's a way to automatically decide no filtering vs limited filtering, that would be great, so we don't need to experiment and this will give us ease of mind. Users don't even need to worry about this toggle if it's automatic selection
-
Instead of relying solely on internal bridges, I'd recommend slowing down the internal overhangs like how we slow down the external overhangs. This could remove need for internal bridges in lots of cases.
On Fri, Apr 5, 2024, 7:56 AM borris345 @.***> wrote:
no filtering works great on this model attached but with limited is poor. any help? i dont like how much extra time and filament it uses so hopefully this will help you improve it! this is one of best features added just need get some testing and tuning.
model used https://www.dropbox.com/scl/fi/oynw87altq5yma6vqscdy/gradient-test.3mf?rlkey=61qcutklydx4wm7yvnxfnooft&dl=0
20240405_124728.jpg (view on web) https://github.com/SoftFever/OrcaSlicer/assets/27918951/d990ebb1-2512-42ae-832e-4c06b6d31b87
— Reply to this email directly, view it on GitHub https://github.com/SoftFever/OrcaSlicer/pull/3319#issuecomment-2039613809, or unsubscribe https://github.com/notifications/unsubscribe-auth/AS7LXLFROMSNOZX2VVV3N53Y32GOHAVCNFSM6AAAAABBE3EDO2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZZGYYTGOBQHE . You are receiving this because you commented.Message ID: @.***>
I wish it was that simple… two things that prevent this from getting more user friendly:
-
The slicer doesn’t understand internal overhangs. When slicing a model the internal sparse infill is considered as a support surface hence it doesn’t consider overhanging perimeters as overhanging, because they are facing into a “solid”. For all intents and purposes the inside of the model is “solid” hence it cannot overhang if that makes sense. That is a limitation of the current code base and will need significant rewrite for that to change - which has wider consequences (among others, it will increase the difficulty in porting features from Prusa, Bambu and Superslicer).
-
The slicer makes a tradeoff between supporting all internal surfaces or applying some filtering to remove the need for too many bridges. That filtering is quite complicated as shown in the study earlier in this thread. And in some edge cases it removes too much of the internal bridge, hence where this option comes in. If there was a way to automate this and make it transparent I would have done it already :(. The best tradeoff is to use limited filtering that would cover the large majority of scenarios. For models with sharp slanted surfaces inspect the sliced file and judge whether you’ll want more internal bridges or not. Then apply them manually.
I did try setting this more automatically but it cannot be done with the current code base without some significant rework of the bridging code which would introduce the potential for more issues coming up.
This is also the reason why none of the other 3 slicers using the same code base have fixed this…