Ultimaker / Cura

3D printer / slicing GUI built on top of the Uranium framework
GNU Lesser General Public License v3.0
6.19k stars 2.08k forks source link

Allow support z distance to be smaller than layer height #6105

Closed nordurljosahvida closed 11 months ago

nordurljosahvida commented 5 years ago

Is your feature request related to a problem? Please describe. I always use support z-distances of between 0.1 and 0.15mm, I should be able to make a 0.3mm layer height print with supports that still are 0.15mm below the model, not be forced to a round-up to 0.3mm, which will make the first layer above supports crappy.

Describe the solution you'd like Allow smaller than layer height support z-distances, and instead of rounding up, make the entire single next layer lower and print every part of the model on that layer with a lower layer height so that the next layer, which will include the supported model area in addition to the non-supported model area, will be printed at the desired height above the support.

Affected users and/or printers Everyone

Additional context This would be groundbraking, especially in Cura where we don't have multiple processes like in simplify. Thanks.

nordurljosahvida commented 5 years ago

Also, am I correct in understanding that the raft z offset is in fact not rounded, but that an exact custom layer height of void is left between the raft and the model?

Ghostkeeper commented 5 years ago

This is harder than it seems. There is a circular dependency here so the proposed solution won't work. The circular dependency is this:

  1. First Cura will slice the object into cross sections (layers). These cross sections are generated at certain heights, normally spaced 1 layer height away from each other.
  2. Then Cura will figure out where the support needs to go, by looking at the difference between two adjacent layers and doing some tricks to join pieces of support from higher layers.
  3. It then finds, per this feature, that some layers between the top of the support and the actual support needed to have been smaller. This places all the layers at the top at a different Z coordinate.
  4. So it needs to re-slice all of the layers above the support.
  5. Because the layers at the new heights can be different, the areas that need to get supported are different as well, so it needs to re-calculate which layers have the lower thickness. And we're looping infinitely.

Apart from this, I'm also worried that changing the layer height across the entire print will result in terrible banding, because when the layer height changes you typically also want to adjust a whole lot of other settings and there is no way for Cura to know which settings to use then. You'd also have a big flow change there, which is why Adaptive Layers has a smoothing function to make sure there are no sudden layer height changes.

An alternative that can be considered is to have an entirely disparate set of layers for support. But this has other problems, not just with CuraEngine's architecture but also with preventing collisions when travelling across the support areas; we're then in a 3D space instead of simplifying collision checking to the 2D space of a layer.

So I'm rejecting this feature request. It is currently infeasible to implement Z distances that are not rounded to layers.

nordurljosahvida commented 5 years ago

@Ghostkeeper ok thanks for the explaination. How complex would it be to do the disparate set of layers solution? We could force z-hops with a height larger than the difference between final model layer height and final support layer height to overcome for it, so collisions would be fixed, right?

Separate question: am I correct in understanding that the raft z offset is in fact not rounded, but that an exact custom layer height of void is left between the raft and the model?

Thanks again

Ghostkeeper commented 5 years ago

How complex would it be to do the disparate set of layers solution? We could force z-hops with a height larger than the difference between final model layer height and final support layer height to overcome for it, so collisions would be fixed, right?

Z hops can leave a blob on the surface with some materials, so it's not a good solution to force that upon everyone.

The disparate set of layers is a difficult solution because of multiple reasons:

Separate question: am I correct in understanding that the raft z offset is in fact not rounded, but that an exact custom layer height of void is left between the raft and the model?

Yes! The raft air gap is not rounded and can be anything. The raft air gap also doesn't apply to supports (supports are allowed to stick to the raft), so in that case it behaves more or less as your feature request. One of the layers gets made thinner or thicker. In this case it was doable to write some exceptions as to where the Z coordinates of the layers land. This works because:

nordurljosahvida commented 5 years ago

very interesting thanks. you said that with a raft - indirectly - this acts more or less as my FR, so as a final question, may i ask you then:

IIUC, x many 0.2 layers for the raft will be printer, then a lower 0.15 layer of supports will be printed, then the first model layer and the second support layer will be printed at 0.2, and so on at 0.2. But at this point, will the first model layer and second support layer be exactly at the same Z height [since they're in the same layer]? if my supports have 0.2 [1 layer] support-to-model air gap, will the actual support-to-model gap be 0.2 or 0.15 as an indirect consequence of the raft air gap?

Thanks again

Ghostkeeper commented 5 years ago

You will get 0.2mm support-to-model gap, exactly 1 layer. Here's what it will print.

  1. A number of raft layers each with their own thickness settings.
  2. One layer of 0.15mm thickness only containing support during the raft-to-model air gap.
  3. A number of layers containing both model and support. The model and support layers are completely aligned at this point.
  4. At some point there will be 1 layer (0.2mm) gap between support and model.
  5. Model is printed on top of that.
Ghostkeeper commented 5 years ago

The disparate set of layers solution is technically feasible, but we don't consider it worth our time right now.

nordurljosahvida commented 5 years ago

@Ghostkeeper thanks both for your latest reply and you considering this, i was printing an extremely simple mechanical object at 0.4 layer height today but since a small area of it starts up off the ground and 0.4mm support z-distance would make the above surface collapse, i had to print the entire part at 0.2 layer height, or - as I did - switch over to simplify to actually meet the delivery deadline. Hope this can be implemented in the future. Thanks again!

dexx086 commented 4 years ago

Hi guys, I got to the same idea by having the need to get finer support Z distance, finer than mutiplicity of the current layer height.

I saw others struggling from this too: video In this video, the instructor has the support interface's top layer by being too close, or too far from the model, especially for thicker nozzles, and/or with 0.2< layer heights.

I saw other ideas (#6408) by setting a base offset, but I don't think either it would be a good way to offset the whole support structure's layers (placing them on different height Z plane for all the layers). And I agree with that too that reslicing the entire layer (affecting the model too) with a lower layer height just because of the support's interface layer is a no go.

However, I got to a different, hopefully more achievable solution in my mind.

My idea would be to have a different layer height only for the topmost interface layer of the support structure! Here's a draft picture about it. The green line is the thinner, topmost ('extra', see later) interface layer of the support. Red is the model. Light blue is the support's interface layers.

cura_support_z_thin

The reason I think it's a more achiavable way, is because it does not affect the model, not even the other layers of the support structure (or maybe the previous interface layer, see later). The only place it should take effect: when printing the topmost interface layer. At this point, the Z height should simply be lowered by the amount needed to have exactly the needed distance to the model.

For eg.: (weird by design) 0.15 Z-distance, with 0.20 layer height (so in this case we want a smaller gap than the layer height, as seen on the picture). Basically it means that 1 (full 0.2 height) layer is "skipped out" between model and support's interface, but we would need an EXTRA but thin LAYER that makes the exact height gap to the model. So, we need to print an EXTRA "remaining" (0.20-0.15) 0.05 height interface layer! This way, we will have exactly 0.15 gap between support and model.

Basically the workflow would remain the same (as I see): "skipping out" the rounded up numbers of layers (by multiplicity of the current layer height), but adding and EXTRA interface layer on top, to achieve the finer Z distance. And as the EXTRA layer is thinner than layer height, it should not make any trouble with any already printed layers. We just have to temporarily lower in Z distance (and of course to compensate flow to have the line width smaller too) to have the thinner EXTRA layer, and then go back to current, full 0.2 layer's Z position and continue as nothing special happened :)

Of course there are corner cases and things to consider:

What do you guys think about my idea? Does it look to be more achievable than formerly proposed solutions?

Ghostkeeper commented 4 years ago

Your new solution still has the same problem of disparate layer sets but limits the problem to only the layers just underneath overhang. On organic prints this is quite often still most of the layers. I agree it makes it simpler, but not simple enough that we'll increase the priority of this issue. It still requires us to build some system where there are extra layers in between the normal layers and work out the collisions with multiple layers.

will a 0.01 height layer be printable at all? Or by only a few printers?

No. Pretty much all plastic types have a minimum extrusion rate, where you just can't smear out the plastic that thin. Something to do with the surface tension and viscosity of the material. 10 microns is below this minimum for pretty much all FFF materials.

I think the minimum extra layer height is a better solution than reordering the layers, for complexity's sake.

All of these solutions also have the problem of changing the flow rate drastically. When you suddenly need to extrude 10% of the flow rate, you're going to overextrude for a few seconds. And when you go back to 100% flow rate you're going to underextrude for a few seconds.

dexx086 commented 4 years ago

Ok, thanks for your detailed response and considering my idea.

About the flow rate change: didn't really thought about that even this could cause some side effects. For bowden type extrusion systems it might happen, but I believe for direct drives it should not really cause any issues (and if the next line will be a support too, or inner wall/infill, it will not really count even if cause a very small overextrusion).

Although this little side effect could be left to the user to decide if he/she takes the possibility for such issue, however I think the real problem is not the flow rate change, but the thin layer's handling (collision handling) that you mentioned. Building some complex system for such solution could be painful. For such small thing maybe it's not even worth it, however could be a new brainstorm what other feature such system could be used for... maybe then it would be more worthy.

But I hope once there will be some solution to this to have finer control over the Z distance. Thanks again.

viper0078 commented 3 years ago

I'm glad to see someone else has similar ideas. I posted the same idea as dexx086 in #8848.

nordurljosahvida's idea has a feature that can be realized in Simplify3D (S3D). I use that feature when printing accuracy on the top surface of a support is important.

S3D allows you to change the print profile for each print height. In practice, multiple copies of a single profile are made and the height is automatically assigned to each one. You can then change parameters, such as the print pitch, in each profile. 無題222 無題333

By dividing the area around the contact surface of the support and the printed material, an optimal gap can be created. When using Raft, the optimal value for RaftAirGap on my printer is 0.12 to 0.13 mm.

When printing at a print pitch of 0.24mm, Z_Distance can be 0.24mm, which is twice as high as RaftAirGap. This will result in a rough underside of the printout. 無題0 24 Splitting the layer and making the pitch near the contact surface 0.12 mm allows you to print with the same quality as the raft placement surface. 無題0 12 Gray is printed with one profile (0.24mm pitch). Blue is printed with three profiles (0.12mm pitch near the support contact surface). DSC_1221 As you can see, controlling the distance of the support contact surface will significantly increase the print quality.

I often cite S3D as an example. Maybe you will be offended. S3D hasn't been updated for two years, not even a bug fix. S3D's support forums are in shambles, and many users have given up hope that there will be no more updates. So I have high hopes for Cura and hope that it will incorporate the good features of S3D. I spend quite a bit of time on this comment as well.

Please consider how to control the distance of support and printouts. Best regards

printingotb commented 3 years ago

Your new solution still has the same problem of disparate layer sets but limits the problem to only the layers just underneath overhang.

@Ghostkeeper Is this still the case if we do like this?: Using my suggestion with half layers #9019. (Using half layer heights will also prevent us from getting very small flow rates that can't be printed).

If we print at 0.2mm layer height and want a distance of 0.1mm, have Cura first calculate that as 0 distance in regards to calculating how to slice everything just like normal. So instead of rounding the Z-distance up, if this is active, round it down instead. Then when printing the support layer with a supposed 0 Z-distance to the model, "simply" tell Cura to print that support layer 0.1mm lower with half of the flow. Not changing the regular layer height for the rest of the model. I'm not a programmer but something like this:

Define variable allow_half_layer_Z = true ;true when the user has activated "allow half layers" Define variable half_layer_active = true ;true while printing within the 0 Z-distance layer Define variable half_layer_height = layer_height/2 ;(so 0.1mm in this example) Define variable half_layer_flow = flow / 2

If half_layer_active = true Z = Z - half_layer_height ;lower Z by half of a layer for the supposed 0 Z-distance support layer Flow = half_layer_flow ;reduce flow to 50% End if

And then restore it to normal once the support is finished for that layer.

Does this violate the engine?

The function is activated by a check-box "allow half layer z distance". An intuitive way would be to also be able to select Z-distance by number of layers in addition to the default mm input. #9155

Ghostkeeper commented 3 years ago

Your idea would help with the problem with flow rates going down to 10%, to a level where the nozzle just won't extrude reliably any more. All nozzles have a minimum layer height and if you're currently printing at least twice as much, halving the layer height is safe.

But whether the highest layer is exactly half the layer height or some other fraction, you'd have to keep this part of a layer aside. You'd want to print it not just at 50% flow, but also with the Z coordinate of the nozzle moved down. Everything on the main layer is currently printed at the Z coordinate of that layer, so either that architecture has to be changed or it'd have to be a separate layer. Having things on a separate layer is problematic for planning and collision checking. It's theoretically feasible, but difficult enough that we currently don't find it important enough to give it priority.

Viper's idea is something that would work for his model, but not for something more complex like this arc, where the Z distance applies pretty much everywhere: image

viper0078 commented 3 years ago

I often see that by presenting a specific shape pattern for an idea that negates it, the idea itself is no longer considered. This is very unfortunate. Is the option that Cura currently implements a perfect option that will work for all shapes? I don't think so. I often have a hard time finding the best option for the printed material I am creating. I try different patterns and find the best combination through trial and error. The ideas I have come up with are not theoretical. It's about the effect of actually getting a beautiful print, just like in the picture. If it is one of the options for printing parameters, I think it will be meaningful for users. Ghostkeeper has shown the shapes that don't work well in the diagram. It would be a shame if Cura's development policy is to implement only options that work perfectly for all shapes.

printingotb commented 3 years ago

I understand but I will keep hoping for something like this to become reality in the future :+1:

Out of curiosity if you have the time to answer: Could a plugin be written to modify the architecture if one had the knowledge and time? (I don't know how much of Cura that can be modified by a plugin?)

Or: If we use exactly one interface layer, can one write a post processing script that works something like this?

  1. It detects each of these lines ;TYPE:SUPPORT-INTERFACE
  2. Compares the Z-coordinate of that layer with the one before to calculate the current layer height.
  3. Divides that by two and insert a G0 Z coordinate = Z - the halved value.
  4. When it next encounters a ;TYPE: line that is not SUPPORT-INTERFACE, it inserts a G0 with the original Z-value to reset the Z-coordinate.

I haven't taken extrusion into account yet but I think I can figure that out.

Ghostkeeper commented 3 years ago

@viper0078 The current implementation creates logical output for all shapes. This is not necessarily perfect output for all shapes, but there is output and the output is reasonably logical to expect it to work okay, and easy to reason about why the output is the way it is.

We need to implement an algorithm that produces logical output for all shapes. If it's not logical, that's both a print quality problem and a user experience problem. In your case, we would frequently get bug reports like "I've set my layer height to 0.2mm, but Cura produces layers of 0.1mm instead, so Cura is broken." If people see that their layer height is greatly reduced and varies a lot, they will not think to blame one of the support settings for it because that's not logical. So they will not be able to fix the problem and they will not be able to print their model properly and/or not on time.

It's not Ultimaker's policy to reject all solutions that don't produce perfect results for all shapes. But for the user we do need to keep things logical. For your case it's easy enough to see that the layer height is reduced at the same height of an air gap, so the air gap is probably the cause. But for the general case most models have air gaps at all sorts of heights so most models will have a wrong layer height in large parts of the print and there is no way for the user to figure out what is causing that then unless they are already in the know.

Could a plugin be written to modify the architecture if one had the knowledge and time? (I don't know how much of Cura that can be modified by a plugin?)

Only Cura's front-end has a plug-in system. That means that plug-ins generally can't influence the slicing result much. Plug-ins can do a post-processing on the g-code. But there they get the g-code as a text file. So it's pretty much impossible to get the original shape of the model back or the shape of structures (e.g. support). You can't really create new slices (at different layer height) or different polygons. Things like adjusting coordinates or E values is possible. But it'll be hard to figure out which area is going to be filled with support on a different layer, to see which support lines are on top to see which should get reduced flow. Or to adjust travel moves to the newly optimal path

KimmoHop commented 3 years ago

In Prusa Slicer it looks like support layers are at their own layer Z values from the beginning, separate from object layer Z values. Objects do not need any special treatment nor recursive adjustments and their layer heights are not altered by the supports. Finally layers are printed starting from lowest Z, be it support or object. In PS it's also possible to set different layer height for each object, so it's not only support distance that gets benefits. I'd guess Prusa slicer manages multimaterial somehow, haven't tried because I don't have MMU (nor Prusa).

Making Cura engine do that, would it be more or less work than Arachne?

nallath commented 3 years ago

In Prusa Slicer it looks like support layers are at their own layer Z values from the beginning, separate from object layer Z values. Objects do not need any special treatment nor recursive adjustments and their layer heights are not altered by the supports. Finally layers are printed starting from lowest Z, be it support or object. In PS it's also possible to set different layer height for each object, so it's not only support distance that gets benefits. I'd guess Prusa slicer manages multimaterial somehow, haven't tried because I don't have MMU (nor Prusa).

Making Cura engine do that, would it be more or less work than Arachne?

I think it's more of a "we made certain choices in the start that are now biting us in the ass" kind of situation. The entire code kinda assumes that each thing printed on a layer has the same height (or at the very least; multiples of a layer).

It could be that there is a smart way of "breaking" this assumption within Cura, but I'm not really convinced that it's going to be easy and/ or maintainable (but by all means, i'd love to be proven wrong!). So as it stands, I think it's in the same-ish ballpark of amount of work as Arachne.

printingotb commented 3 years ago

But it'll be hard to figure out which area is going to be filled with support on a different layer, to see which support lines are on top...

Perhaps we are attacking the problem from the wrong direction. The support setting "Fan speed override" detects parts printed on top of support. So these areas are known to Cura. What if we also, or instead, reduce the flow of those same areas to simulate that these layers are printed at a lower layer height? (thus originating from the same Z-coordinate as the rest of the layer, eliminating the need for a split layer). At first I was thinking about using the bridge settings to lower flow but they seem to only be able to affect horizontal overhangs. And in it's current form does not apply on top of supports.

github-actions[bot] commented 1 year ago

Hi 👋, We are cleaning our list of issues to improve our focus. This feature request seems to be older than a year, which is at least three major Cura releases ago. It also received the label Deferred indicating that we did not have time to work on it back then and haven't found time to work on it since.

If this is still something that you think can improve how you and others use Cura, can you please leave a comment? We will have a fresh set of eyes to look at it.

If it has been resolved or don't need it to be improved anymore, you don't have to do anything, and this issue will be automatically closed in 14 days.

printingotb commented 1 year ago

Regardless how this can be solved, I really think this feature request would add value to Cura!

My attempt at a solution: I tried my hand at python and created a script that adjusts the actual Z-distance in the gcode.

It works like this: It goes through the gcode and registers when the line type changes to or from SUPPORT When it is within support, all Z-values are increased by a set amount that you define. (Except for the first layer for adhesion reasons). So you can slice with a 0.2mm layer height, set the Z-distance to 0.4mm and then use the script to move the support structure closer/upwards by for example 0.1mm. This gives a 0.3mm Z-distance. (The reason for not moving it downwards instead is to prevent the layers from overlapping, causing over extrusion and risk of knocking down the supports).

The script works in it's most basic form and I have tested the results finding that a support Z-distance of around 0.25-0.3mm works good at 0.2mm layer height. This gives much cleaner results than a distance of 0.4mm while still being able to be removed fairly easy.

While I made it work, I had some help from Chatgpt and Jelle but later I got stuck when trying to add things to it so the project was put on pause.

I'll see if I can take a look at the status of the script later and maybe someone can put the idea to good use.

In the following examples, I couldn't separate the support at 1 layer height distance. Just adding 0.05mm to the distance was enough: 333340403_594737839204567_7437722111580292749_n 333610959_1459937014414024_7114905106649364948_n 333721520_1232776810944322_4910850747777309824_n

genghisnico13 commented 1 year ago

We already have an Adaptive Layer function, wouldn't it be easier to modify its input to make it think the model has slopes on every layer with support interfaces so it reduces the layer height, increasing the resolution and getting closer to the set Z distance?

This is definitely only a mitigation, not a fix, and it works best on more functional models or models where the support interfaces are only on a few layers rather than organic ones but without knowledge of the code seems simpler to implement.

it would be nice to have a setting that's independent of the "Topography size" so if you want you can only use adaptive layers on the support interfaces.

MariMakes commented 1 year ago

Quick update from our side 👋

The new Cura 5.6 Beta, has an option to only enter values different from your layer height, which I believe should resolve this issue. Can you please try it out and let us know if it works for you? You can download it here. https://github.com/Ultimaker/Cura/releases/tag/5.6.0-beta.1

printingotb commented 12 months ago

Quick update from our side 👋

The new Cura 5.6 Beta, has an option to only enter values different from your layer height, which I believe should resolve this issue. Can you please try it out and let us know if it works for you? You can download it here. https://github.com/Ultimaker/Cura/releases/tag/5.6.0-beta.1

This is great, thank you! Testing this now. I have run into a few issues and will get back to you soon.

printingotb commented 12 months ago

17390

17391

17392

17393

github-actions[bot] commented 11 months ago

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.