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

new z-dither branch which implements feature described in issue #9388 #10391

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

LRaiz
Copy link

@LRaiz LRaiz commented Apr 18, 2023

I implemented the z-dithering algorithm that halves the layer stairstep effect on low-slopped surfaces. See #9388 for the description of the idea. A new checkmark in the Advanced group of the Print Setting tab allows you to turn it on or off. Turning it on introduces additional thin layers at the periphery of regular layers. These layers are added not for the entire slice area but only where the surface slope is sufficiently low to accommodate nozzle passage at half-layer height. It makes the resulting surface with details rivaling the details of the surface printed with half-layer height but without a significant increase in print time. I expect that turning this option on in many cases will negate the necessity to have multiple layer height ranges. I also hope that it will allow increasing default layer height and thus speed up printing. On the other hand, it may necessitate fine-tuning other printing parameters. Consider it to be an experimental feature.

I have tested the implementation on several examples, but given its nature, further testing is required; it may also necessitate tuning some aspects of the resulting g-code (e.g. speed or width).

@LRaiz
Copy link
Author

LRaiz commented Apr 20, 2023

This pull request probably needs to remove the Overhangs label, just as it was removed on originating issue #9388. On the other hand, it may need to have the "feature request" label added.

@mirlang
Copy link

mirlang commented Apr 20, 2023

was eager to try this, but it gives tons of errors in compilation :/

@LRaiz
Copy link
Author

LRaiz commented Apr 20, 2023

In my limited tests, prints with z-dithering turned on showed the expected decrease in layer stairstep appearance. The geometric aspects of the new feature were working fine. However, the surface smoothness at the corners connecting z-dithering layers with nominal layers was not as good as I had hoped. Some tuning of z-dithered paths or their g-code parameters appears necessary to address smoothness at such corners.

@LRaiz
Copy link
Author

LRaiz commented Apr 20, 2023

@mirlang I didn't see any errors in my Windows environment. Are you on Windows? Make sure to fetch everything from the origin and build the master branch first. Use supplied build script as described in https://github.com/prusa3d/PrusaSlicer/blob/master/doc/How%20to%20build%20-%20Windows.md Then switch to the z-dither branch and build.

@mirlang
Copy link

mirlang commented Apr 20, 2023

Are you on Windows?

no, sry, I'm using linux... my c++ abilities are not that great, but those errors indicate missing includes oder variable definitions - i downloaded the diff of this pull request from github instead of cloning your repo, maybe something went wrong here (will try tomorrow) - alpha6 without this patch builds fine

errors from log:

/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:64:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:71:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:76:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:82:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:90:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:107:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:117:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:125:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:130:11: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:132:5: error: ‘indexed_triangle_set’ has not been declared
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/TriangleMeshSlicer.hpp:133:5: error: ‘indexed_triangle_set’ has not been declared
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.hpp:21:24: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.hpp:35:40: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:14:24: error: ‘indexed_triangle_set’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:29:17: error: ‘stl_vertex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:29:27: error: template argument 1 is invalid
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:29:27: error: template argument 2 is invalid
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:29:55: error: request for member ‘vertices’ in ‘mesh’, which is of non-class type ‘const int’
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:31:24: error: found ‘:’ in nested-name-specifier, expected ‘::’
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:31:22: error: ‘v’ has not been declared
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:33:36: error: expected initializer before ‘(’ token
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:33:36: error: could not convert ‘candidate_zs’ from ‘std::vector<float>’ to ‘bool’
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:33:36: error: expected ‘;’ before ‘(’ token
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:33:42: error: expected ‘)’ before ‘;’ token
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:39:9: error: ‘candidate_zs’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:44:5: error: ‘candidate_zs’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:56:31: error: request for member ‘indices’ in ‘mesh’, which is of non-class type ‘const int’
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:57:15: error: ‘stl_triangle_vertex_indices’ does not name a type
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:58:19: error: expected ‘;’ before ‘vertex’
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:61:21: error: ‘vertex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:125:21: error: ‘diff_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:129:38: error: ‘diff_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:134:21: error: ‘diff_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:138:38: error: ‘diff_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:143:35: error: ‘intersection_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:145:35: error: ‘intersection_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:147:35: error: ‘intersection_ex’ was not declared in this scope
/var/tmp/portage/media-gfx/prusaslicer-2.6.0_alpha6/work/PrusaSlicer-version_2.6.0-alpha6/src/libslic3r/ZDither.cpp:154:35: error: ‘error’ was not declared in this scope; did you mean ‘perror’?

@LRaiz
Copy link
Author

LRaiz commented Apr 21, 2023

It looks like you don’t have right base. I suspect your master branch would not compile either. Consult Linux instructions how to install and build in README.md

@vovodroid
Copy link
Contributor

vovodroid commented May 18, 2023

Hi Leonid!

I updated your code to latest beta2, resolved conflicts, removed various whitespaces and tabulation changes (probably your IDE has auto format enabled), and made code style more Prusa like.

Feel free to take branch https://github.com/vovodroidprusa/PrusaSlicer/tree/z-dither-LRaiz and update PR basing on it.

Most astonishing that it still works )))

vovodroid added a commit to vovodroid/PrusaSlicer that referenced this pull request May 21, 2023
@LRaiz
Copy link
Author

LRaiz commented May 22, 2023 via email

@vovodroid
Copy link
Contributor

for all changed files I removed trailing whitespaces and replaced tabs with spaces.

This adds a lot of "noise" when you compare PR to master, and causes endless conflicts in the future. Actually https://github.com/prusa3d/PrusaSlicer/wiki/Contribution-guidelines says

Don't do anything not directly related to that. Do not fix comment-typos in all files that you see, don't unify whitespace usage,

@LRaiz
Copy link
Author

LRaiz commented May 22, 2023 via email

@vovodroid
Copy link
Contributor

Unfortunately I did not come across the contribution guidelines earlier. -

No problem, just check my code that it didn't broke desired functionality.

@LRaiz
Copy link
Author

LRaiz commented May 22, 2023 via email

vovodroid added a commit to vovodroid/PrusaSlicer that referenced this pull request May 22, 2023
vovodroid added a commit to vovodroid/PrusaSlicer that referenced this pull request May 23, 2023
@LRaiz
Copy link
Author

LRaiz commented May 23, 2023

I committed @vovodroid changes and some additional by myself to LRaiz/PrusaSlicer z-dither branch. Some comment lines are taken from the master branch instead of the @vovodroid version.

@@ -296,6 +302,7 @@ void PrintObject::prepare_infill()
// Decide what surfaces are to be filled.
// Here the stTop / stBottomBridge / stBottom infill is turned to just stInternal if zero top / bottom infill layers are configured.
// Also tiny stInternal surfaces are turned to stInternalSolid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just empty string, could be removed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.
The change was delayed because I was looking into failures of fff_print_tests built with debug (but not release). Turns out that master branch behaves exactly the same, so I stopped checking.

@vovodroid
Copy link
Contributor

vovodroid commented May 25, 2023

Extruder advanced parameters on the printer settings tab default to min_layer_height = 0.07 and max_layer_height = 0.25

Yes, it's hardcoded, but it's not universal limit. Imagine someone printing with 0.6 nozzle and wood or carbon filament. I'm not sure you can go 0.07 and especially less. The same applies to small nozzles, like 0.2. It wouldn't be good print 0.3 layer with such nozzle.

  • All layer height restrictions are imposed by the master branch

But master branch does take into account min_layer_height, for example in variable layers. Nevertheless users expect that slicer never goes beyond min/max limits, that's the meaning of these values.

So I would suggest to check layer height and split base layer in such way, that no min limit is violated.

@LRaiz
Copy link
Author

LRaiz commented May 25, 2023 via email

@vovodroid
Copy link
Contributor

vovodroid commented May 25, 2023

Such limitations are not currently enforced by master.

Though master allows setting layer height out of min limit (but anyway limits maximum to nozzle diameter), but variable layers do respect these limits.

@vovodroid
Copy link
Contributor

Hi, z-dither option sometimes causes overhangs to be printed in the air (project attached):
image

Without z-dither:
image

Body.zip

@LRaiz
Copy link
Author

LRaiz commented May 28, 2023 via email

LRaiz added 5 commits June 1, 2023 11:51
1. Check and filter out tiny areas made during z-dithering
2. Prefer to use better bahaving classic perimeters for dithered layers
3. Computed dithered overhangs only if support is enabled
4. Turning support on/off in the presence of z-dithering requires reslicing
   in order to account for potential change in number of layers.
5. Accounted for dithered layers effect on skirt-height handling by GCode.
@LRaiz
Copy link
Author

LRaiz commented Jun 24, 2023

Commit 7f1f6bd addresses the issue pointed out by @vovodroid and contains a number of additional fixes/enhancements.
There is still one remaining question. It is not clear to me how beneficial z-dithering would be for handling overhangs. For now, I limited the creation of dithered overhangs only to prints that generate support. I expect testing to show if it is sufficient or if a separate config switch is needed.

@vovodroid
Copy link
Contributor

It is not clear to me how beneficial z-dithering would be for handling overhangs.

Decreasing layer height is good for overhangs as it increases line overlap.

@LRaiz
Copy link
Author

LRaiz commented Jun 25, 2023 via email

@vovodroid
Copy link
Contributor

They are supported only by support structure.

Why? I'm talking about overhangs, not bridges.

By a way, latest commit looks quite good!

@LRaiz
Copy link
Author

LRaiz commented Jun 28, 2023

The illustration included in the original issue #9388 makes it apparent that dithered layers on downward-facing surfaces do not overlap regular layers below and thus need a support structure to keep them from falling.

@vovodroid
Copy link
Contributor

Z-dither breaks support for attached STL, especially organic:

image

S10eCase.zip

@LRaiz
Copy link
Author

LRaiz commented Jul 5, 2023

I do not see indications that the problem reported by @vovodroid is related to z-dithering. When I run master branch using debug executable and select organic support, the executable generates an assert error.
Assert
I guess this issue is better reported to Prusa developers. I also suggest including parameter configuration to assure that the problem is reproduced. On the other hand z-dither RelWithDebug executable does not assert but makes support trees taller than object. Crazy.
Capture

By the way, for my print parameters, I got no indication that support was needed, and g-code without support was computed fine with z-dither.

@vovodroid
Copy link
Contributor

But without Z-dithering it's ok:

image

@LRaiz
Copy link
Author

LRaiz commented Jul 6, 2023

My result using RelWithDebug with no dithering is very different. The difference must be attributable to the difference in other printing parameters since @vovodroid did not provide his Config. Still, the fact that without z-dithering, Debug executable asserts using the same set of parameters indicates that newly released organic supports still have some issues to iron out. These issues need to be addressed before the z-dithering investigation.
Capture

@vovodroid
Copy link
Contributor

Here is attached project with z-dither enabled:

image

S10eCase-zdither.zip

// arachne width averaging is not so good for thin areas of dithered layers becuase it results in routh attachment/seams of
// dithered layers to non-dithered (regular) layers. On the other hand for very narrow dithered layers classic algothim
// sometimes makes no perimeters at all and in this case we better employ arachne algorithm (even if user selected classic).
if (!use_arachne || dithered_layer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better not to switch Arachne/Classic calls order, neither reformat parameter list, as it causes problem with further merges.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While changing the formatting of parameters could be done and is not a big deal, the alternative to switching Arachne/Classic calls order was considered and turned out to be much worse.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even restore format will be good, as I had problem in merging another PR over dithering. But what is problem with call order? Aren't two calls mutually exclusive? I guess this

if (dithered_layer && m_perimeters.empty() || !dithered_layer && use_arachne)
       PerimeterGenerator::process_arachne(
.........
else
       PerimeterGenerator::process_classic(

should work, or do I miss something?

Copy link
Author

@LRaiz LRaiz Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For dithered layers, Classic paths connect to adjacent non-dithers layers much better than Arachne. This is because Classic tends to create closed perimeter loops, while for narrow regions, Arachne may produce open contours. On the other hand, at times, Classic produces nothing, while Arachne is still capable of making open perimeters. My code for dithered layers attempts to use Classic first, then if Classic fails, use Arachne. Observe m_perimeters.empty() as a check for Classic failure and two if statements as opposed to if/else.

The change in formatting was made by Visual Studio while complying with .clang-format. I will restore the original formatting and attempt to improve the comment describing the logic of the changed code.

LRaiz and others added 4 commits July 12, 2023 14:21
1. Check and filter out tiny areas made during z-dithering
2. Prefer to use better bahaving classic perimeters for dithered layers
3. Computed dithered overhangs only if support is enabled
4. Turning support on/off in the presence of z-dithering requires reslicing
   in order to account for potential change in number of layers.
5. Accounted for dithered layers effect on skirt-height handling by GCode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants