prusa3d / PrusaSlicer

G-code generator for 3D printers (RepRap, Makerbot, Ultimaker etc.)
https://www.prusa3d.com/prusaslicer/
GNU Affero General Public License v3.0
7.8k stars 1.94k forks source link

Allow different layer height for individual islands of one object #8223

Open jDavidnet opened 2 years ago

jDavidnet commented 2 years ago

Is your feature request related to a problem? Please describe. The tops and bottoms of curves appear to have lower resolution than the rest of the print, because with a static layer height the tops and bottom of curves are at steeper angles and get aliased differently for shallow angles. While printing Easter Eggs I noticed this acutely and started playing with the Height Range Modifier.

Describe the solution you'd like It would be nice for the tops ( and possibly bottoms ) of curved surfaces to globally ( or locally ) change the layer height to make the tops ( and possibly bottoms ) of curves smoother.

Describe how it would work It seems that the firmware has the ability to change layer height locally for multiple models on a single print, it also can change layer height dynamically for infill (and supports?) so it seems plausible for the firmware to discretely segment local regions, and then have a dynamic layer height for each of those regions within a tolerance.

Also, it seems like the math is in there for paint on enforcers to detect the angles of 'curved' surfaces, so you can automatically paint on support enforcers.

With some work and some settings it seems possible to dynamically scale the layer height for curved areas so you could say start at a .3mm layer height, and have the top of the curve at a .07mm layer height. ( say for a .4mm standard nozzle ).

For the Easter Eggs I printed I manually entered Height Range Modifiers for each egg as follows.

Range [00.00-57.50] -> .30mm
Range [57.50-58.00] -> .25mm
Range [58.00-59.00] -> .20mm
Range [59.00-60.00] -> .15mm
Range [60.00-61.00] -> .12mm
Range [61.00-62.00] -> .09mm
Range [62.00-66.00] -> .07mm

So over the course of 5-6mm I was able to better alias the top of the egg, and make it much, much smother, without drastically increasing overall print time.

Describe alternatives you've considered This can be experimented with manually and globally for a given object, but it would be neat to be able to process it algorithmically based on the local surfaces.

It would also be nice to be able to save object modifier macros, so I could say do this for one egg model, and then copy and paste it to other egg models.

Depending on the path tracing algorithm to generate the g-code, the easiest solution might be to just look a few layers below, and above the current layer, and detect the gradient slope, and adjust the layer height based on that slope. Then the algorithm might have a simpler slider from do nothing <-> aggressively optimize curves / slopes. or speed <-> resolve extra detail

Additional context As I get used to my Prusa MK3S+, I've been trying to optimize for speed and detail. Part of this is my desire to print both fine detail miniatures, miniature sets, and larger functional models for the home and holidays. I've noticed that if I manually change the layer height with the Height Range Modifier I can really start to approach SLA printers without the mess, toxicity, and waste. With the eggs, I was able to add only a few extra minutes of print time on a 1-2hr print to get the extra resolution where I needed it, but didn't have to double, triple, or more my print time like I would if I had set the whole project to the smaller layer height.

lukasmatena commented 2 years ago

I think you are talking about 'variable layer height' feature, which is in PrusaSlicer for ages. See e.g. https://www.youtube.com/watch?v=Z7eKL7AhzNg starting at 6:00. Is it not satisfactory?

jDavidnet commented 2 years ago

@lukasmatena, I was not aware of variable layer height, and will certainly use this feature in the future. However, what I'm suggesting would be even more local to a curve or slope than what variable layer height will support. variable layer height is still limited to being global for the object/ part, while, what I am suggesting would be more localized to individual slopes or curves. If I want to improve the layer height on some parts of a figurine or mini, then one part of the model might need more resolution or reduced layer height while other parts might be just fine with thicker layer lines.

If say a finger and the body of a figure would print in the same layer height, then as those are discrete sections it seems like the finger could print at a reduced layer height, and the body could print at a large layer height. I do understand however, how it might be difficult to say print the detail on a shirt button or buckle on that body and then print the rest of that section at a higher layer height, but that functionality could be reserved to a future time, or not at all, depending on how hard it is. At this time I think it makes sense to resolve discrete sections within a given layer and allow those sections to have different layer heights.

I just find that with a lot of my prints, there are discrete sections within a single part / model / object that could work nicely with a variable layer height for that localized region, while other parts of the print could have a larger layer height.

Take another example as well, say for instance that you are printing something that for the most part could be printed at .3mm or larger layer height, but then you have a few interface sections where you want tight tolerances, or say you have some threading that you want at .15mm. It would be nice to be able to say, print interface or these threads at .15mm, and print the rest of the object as fast as you can. With the variable layer height feature, any layers that have threads on them, would need to be printed in that layer height, vs. what I am suggesting where the threads might be auto detected ( or auto sectioned, of a sort ) and those regions would then only be locally printed in that layer height.

I think the baseline work is all there to do what I'm proposing, it just needs to be glued together in a new way,.

I suppose another possible interface for the variable height would be to use a greyscale paint functionality on the model, to manually paint on where you want more detailed layer heights, but that seems more manual than what I'm asking for. Maybe some people would prefer that. Maybe both would be cool. Maybe the greyscale surface map is a good way to preview what the automagic algorithm will do when it generates the gcode?

lukasmatena commented 2 years ago

@jDavidnet I'm not sure we understand each other.

If I want to improve the layer height on some parts of a figurine or mini, then one part of the model might need more resolution or reduced layer height while other parts might be just fine with thicker layer lines.

And that's exactly what current variable layer height feature does.

I suppose another possible interface for the variable height would be to use a greyscale paint functionality on the model, to manually paint on where you want more detailed layer heights

And that's exactly what current variable layer height feature does.

where the threads might be auto detected

And that's also something what current variable layer height feature allows - to set the layer heights adaptively.

Did you watch the video or tried it in PrusaSlicer? I don't think anything you suggest is missing.

neophyl commented 2 years ago

Lukas, I suspect the OP means within the model itself. Imagine a model that has a base and 2 columns. One column is plain and the other is covered in fine details. At the moment if you adjust the layers to pick up the fine detail on one column the same layer heights are used on the plain column too.

With a modifier you could theoretically define the plain column to have 0.3mm layers and the detailed column to use 0.1mm. Or with a paint on method as the OP suggested you could paint the detailed areas and those would define the layer height.

I can see why it would be difficult though as if a user placed a modifier that only covered one side of the detailed column then you would be printing different layer heights that connect to each other which could be problematic to say the least.

The paint on definition method would probably be better as you could make it define the whole of an individual island on that layer. That way at least the individual areas would be separate so you sidestep the different layer heights on connected areas.

lukasmatena commented 2 years ago

@neophyl Thanks. I read the third post more carefully now and you are probably right that I misunderstood it and focused too much on the original Easter egg example.

@jDavidnet It is fairly difficult. One object has certain layers, each has some thickness, but that's it. The backend does not support anything else. The supports can have different layering, but they are not exactly part of the object, so it does not really count. We may extend this some day, but it is not currently on the roadmap. There are much more pressing issues that are much easier to solve, so this has little priority, although it would definitely help in some cases.

jDavidnet commented 2 years ago

It sounds like we are on the same page now with the goal.

If I wanted to dig around the code to see how feasible it is, where would I look?

I actually think the paint on method is harder, but maybe not. I would think that an algorithmic exploration of the model might be better. Algorithmically, you could look at the slop given an x, y, x coordinate and as the slop approaches horizontal then you increase the layer height, and if you could average the slope across several layers and a grid of points then you 'smooth' out your calculation. The larger the averaging grid, the larger the details that the algorithm would optimize for. Basically, you would be computing a topological field of slopes across the model.

And then the second part is given a top down view of the model, slice it horizontally and detect discrete islands, or ellipses or blobs that don't touch. Maybe v1 would use a bounding box or bounding ellipse on the blob and then calculate if there is an intersection between the two? this would mean that at each layer you could see which columns exist, as @neophyl was saying.

I've been playing with variable layer height and it takes a lot of work to get something useful out of it on the model I'm trying to print. The slider doesn't seem properly balanced at all, and there is a weird bug where it will get stuck and will either fully smooth, fully add detail, or fully decrease detail.

I know this might not seem like a priority, but I really think this could help FDM compete with SLA printers in a big way, and PRUSA Slicer would be the first to implement a feature like this.

lukasmatena commented 2 years ago

If I wanted to dig around the code to see how feasible it is, where would I look?

Pretty much everywhere. Start in PrintObject class and its update_layer_height_profile method, then follow the data.

PRUSA Slicer would be the first to implement a feature like this.

I agree. Until then, PrusaSlicer is at least the only one who allows to print different objects with different (variable) layer heights. It makes a lot of things quite complex, even without what you suggest.

CaptainFalcon92 commented 1 year ago

Hello !

I join this thread because i would like to use such a feature too. I suggest renaming the issue to "Local variable layer height modifier" or something similar to avoid confusion.

I would myself like to apply a variable layer height modifier - but only to the boxed volume. Or this is not possible yet. Would be a banger though

image

EDIT: I also tried to use separated bodies but still one can't adjust layer height per body.

Dear prusa team, please consider this idea.

Thanks

jDavidnet commented 1 year ago

Captain Falcon, from your example, it's unclear why Adaptive Layer Height is insufficient. I am assuming there is a larger part with other objects on the Z axis?

I think a better picture might better demonstrate your point.

On Fri, May 12, 2023 at 3:46 AM CaptainFalcon92 @.***> wrote:

Hello !

I join this thread because i would like to use such a feature too. I suggest renaming the issue to "Local variable layer height modifier" or something similar to avoid confusion.

I would myself like to apply a variable layer height modifier - but only to the boxed volume. Or this is not possible yet. Would be a banger though

[image: image] https://user-images.githubusercontent.com/24324122/237949426-5e0db744-2727-47d2-8d83-2d1f2bdd2d58.png

Dear prusa team, please consider this idea.

Thanks

— Reply to this email directly, view it on GitHub https://github.com/prusa3d/PrusaSlicer/issues/8223#issuecomment-1545548359, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB5CFVQ3LOTOJ653CXD6M3XFYIJNANCNFSM5T5AOYDQ . You are receiving this because you were mentioned.Message ID: @.***>

-- -- -- Justin Kruger Software Consultant / Engineer - San Francisco, CA

--

http://jDavid.net http://www.linkedin.com/in/jdavid https://github.com/jDavidnet

@.***

CaptainFalcon92 commented 1 year ago

You're right. This picture may not be the best at illustrating the missed potential of a local variable height layer modifier.

Lets imagine a larger piece, such as this shown below. You could easily imagine how variable layer height is affecting the whole bed here, thus increasing print time significantly while being unnecessary for most of the part.

Some areas of a part might also not benefit from smooth layer transition, this will depend on whatever specific part you're printing. It is a matter of balance an manufacturing time efficiency, especially when printers are used less as figure-printing gimmick and more as actual engineering tools.

As an example, i poorly circled hypothetical areas i might like smooth while the rest would not be critical.

image

I can also bake an extreme case on purpose - that ultimately does not picture any of my own project - but still exacerbate the time loss to the extreme.

image

If one could indicate the volume that would be optimized using modifiers, we would get a formidable tool so far unseen.

image

Interestingly enough - as mentioned above by our friends - it appears that every fundamental brick for this feature exists independently in the slicer already (not saying this would be easy to implement);

If not for modifiers within a part, maybe at least allowing a per-body approach could help CAD designers mitigate the impact of unnecessarily optimizing filled volumes.

I can only assume we are not alone in our search for faster print time. I get it that running a voron with .8 nozzle is the fastest route to quick print, yet i believe optimizing the amount of work is an efficient approach. It would benefit Prusa's machines, which are work-horses more than sprinters.

That was an idea, i enjoyed reading other's people request about it. It comforted me in the idea that it would be a convenient feature of Prusa Slicer.