Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Introduced option to control amount of internal bridging, fixing internal bridge missing for some sloped surfaces #3319

Merged
merged 20 commits into from
Jan 13, 2024

Conversation

igiannakas
Copy link
Contributor

@igiannakas igiannakas commented Dec 27, 2023

Updated below text with final ready for review implementation

Aiming to address issue #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:

  1. Models with arched top surfaces
  2. When lightning infill is used for curved top surface models
  3. When low density infill is used and especially with curved/slanted top surfaces

So updated the PR to convert this into an option:

Disabled (default) - Limited filtering - No filtering

  1. Disabled is the current behaviour and it is selected as the default value to maintain user experience continuity.
  2. 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. It is also enabled 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).
  3. No filtering adds internal bridges on all internal overhangs. It is very aggressive in creating internal bridges but this solves issues with very specific models with a specific angle of slanted top surface as seen below.

The above options can be controlled on a per-object basis, so if any particularly problematic objects exist in the build plate they can be enabled for them only.

In the image below you can see the limited filtering addressing the problematic slope but the regular shaped Voron cube being completely unaffected. With no filtering, there is excess bridging on the Voron cube. However it addresses the issue with the subsequent model (see further down).
image

No filtering for a challenging model:
image

Print test for the above model:
Left: Disabled - Right: No filtering
IMG_2749

Fixes #413

@igiannakas igiannakas changed the title ENH: Improve internal bridge detection for sloped surfaces ENH: fix internal bridge missing for some sloped surfaces Dec 28, 2023
@igiannakas
Copy link
Contributor Author

igiannakas commented Dec 28, 2023

@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 :)):
9ae24014-c927-4eec-a990-c79646da6466

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:
0aa379e3-8671-404b-ac20-556b3bb7d807
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):
image

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:

  1. 3 x spacing - this is constant
  2. 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);

3fa52cfa-bb95-43d7-822f-ee09d71f6c6f

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).

image

We could go even lower than that - say half spacing: (the black line)
516a5b78-d50c-4abc-ac7f-f62bd9d5d95f

In this case we finally get some bridging going on but that quickly deteriorates on subsequent layers
image

image

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.

image

image

So where does this leave us?

A few options depending on how much tweaking we leave to the user.

  1. We cannot use the area difference I think because of the above reasons (difference is proportional to the size of the polygon)
  2. 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
  3. Or we could give an on-off switch that sets the spacing to 1x or 3x (default).
  4. 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.
  5. 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.

@igiannakas
Copy link
Contributor Author

Updated some minor errata on the above analysis + submitted new code.

@neorm
Copy link

neorm commented Dec 29, 2023

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?
image
image
image
image

@neorm
Copy link

neorm commented Dec 29, 2023

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
image

@igiannakas
Copy link
Contributor Author

igiannakas commented Dec 29, 2023

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? :)

@igiannakas
Copy link
Contributor Author

Doing a print test with the below problem area only:
Slope print test.3mf.zip

image

Print speeds are reasonably fast and infill is very low - 6%, to show the issue if present and will revert back

@igiannakas
Copy link
Contributor Author

igiannakas commented Dec 29, 2023

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.

@igiannakas
Copy link
Contributor Author

igiannakas commented Dec 29, 2023

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:

image

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.

@igiannakas
Copy link
Contributor Author

igiannakas commented Dec 29, 2023

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:

IMG_2749

(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 SoftFever added this to the 1.9.1 milestone Dec 31, 2023
@igiannakas igiannakas marked this pull request as ready for review January 9, 2024 12:10
@igiannakas igiannakas force-pushed the ENH-Dont-filter-internal-bridges branch from 593eeb0 to e14783e Compare January 9, 2024 12:58
@igiannakas igiannakas changed the title ENH: fix internal bridge missing for some sloped surfaces ENH: Introduced option to control amount of internal bridging, fixing internal bridge missing for some sloped surfaces Jan 9, 2024
@igiannakas igiannakas changed the title ENH: Introduced option to control amount of internal bridging, fixing internal bridge missing for some sloped surfaces [Feature] Introduced option to control amount of internal bridging, fixing internal bridge missing for some sloped surfaces Jan 12, 2024
@SoftFever
Copy link
Owner

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. image

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.

@SoftFever SoftFever merged commit f7b92d9 into SoftFever:main Jan 13, 2024
12 checks passed
@igiannakas igiannakas deleted the ENH-Dont-filter-internal-bridges branch January 13, 2024 15:43
@igiannakas
Copy link
Contributor Author

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.

@martian099
Copy link

Great work, appreciate you guys! When will this be available in stable/alpha of orca slicer?

@igiannakas
Copy link
Contributor Author

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

@TinyMito
Copy link

@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!

compare

@igiannakas
Copy link
Contributor Author

@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!

compare

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

@borris345
Copy link

borris345 commented Apr 5, 2024

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

20240405_124728

@vgdh
Copy link
Contributor

vgdh commented Apr 5, 2024

WOW! internal bridges looks very well!

@igiannakas
Copy link
Contributor Author

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

20240405_124728

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.

@martian099
Copy link

martian099 commented Apr 5, 2024 via email

@igiannakas
Copy link
Contributor Author

I wish it was that simple… two things that prevent this from getting more user friendly:

  1. 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).

  2. 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…

@jrmhughes
Copy link

I am using this feature for the first time. It was very successful at fixing the issues I had in the top surface of my print but it didn't work for my model when I used a 0.08mm layer height.

I am using default settings for Bambu P1S, Generic PETG, 0.12mm Fine. The right hand one in the screenshots is 0.12mm layer height. The left is 0.08mm layer height. I have set 'Don't filter out small internal bridges (beta)' to 'No filtering'.
It worked as I expected with 'no filtering' or 'limited filtering' with 0.12mm layer height but not 0.08mm.

Can anyone explain why this is?

0.08mm layer height (left) and 0.12mm layer height (right)
Screenshot 1: Internal bridges were created on the slanted surface with the 0.12mm layer height but not the 0.08mm
Slant
Screenshot 2: Internal bridges were created with both layer heights for a couple of layers above and below the slanted surface (where the rounded corners are).
Above slant
Screenshot 3: The full model
Full model

@neorm
Copy link

neorm commented Sep 14, 2024

I agree, I'm very happy with the implementation. This way, I can handle these kinds of problems. Just wanted to say thank you, @igiannakas

@igiannakas
Copy link
Contributor Author

@neorm your welcome!! Hope it helps you ;)

@jrmhughes unfortunately it doesn’t work always when the layer height transition is too low compared to the slope. Try with filtering fully “disabled” and let’s see whether that makes any difference

@jrmhughes
Copy link

@igiannakas Thanks for replying. And thank you for all the work you've done improving orcaslicer.
The above screenshots were with '"No Filtering". If I set "don't filter out small internal bridges" to "disabled", no internal bridging is generated anywhere except the flat top (see screenshot below).
Only on roof

I did some more investigation and it seems that, as you say, the layer height is too small compared to the slope (which was 13.2 degrees). I created a table to show the limit of when it generates:
Test 4 table.pdf

I don't know if this was the right place to ask because it seems it's not to do with the filtering, but rather the creation of the bridging layers to begin with. Maybe I should create a feature request for adjusting the overlap width at which they generate because I like to use 0.08mm layer height for printing moulds but sometimes get a wavy surface on shallow angles. I don't know how it works though or whether that would be possible.

@igiannakas
Copy link
Contributor Author

Another way to deal with this is to slow down your internal solid infill. It ideal speed wise but setting your internal solid infill and inner walls to a more conservative speed should address the visual artefacts. And it will help with precision especially at 0.08 mm LH

@jrmhughes
Copy link

Thanks for the tip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Printing of slopes is missing the Bidge Layer
9 participants