Skip to content

Conversation

Arachnid
Copy link
Contributor

@Arachnid Arachnid commented Dec 6, 2024

Description

Fixes #7467.

The existing fuzzy skin support does a good job of hiding printing artefacts, but uses a very naive algorithm based on randomly displacing points on the outside wall of an object. This means that there's no correlation between the displacements of vertically adjacent points, and this in turn gives the fuzzy skin a characteristic horizontal pattern that can accentuate rather than hide layer lines.

This PR adds libnoise, a library for creating structured noise, and uses it to enhance the fuzzy skin functionality with new options that have better aesthetics compared to the existing uniform random noise. Several noise algorithms are supported:

  • Perlin noise: A classic structured noise algorithm that creates spatially coherent noise.
  • Billow noise: A variation on perlin noise that has a more 'billowly' or cloud-like appearance.
  • Ridged Multifractal noise: Creates random ridgelike formations, or marble-like textures.
  • Voronoi: Divides space up into voronoi cells, and displaces each by a random amount. Creates a patchwork effect.

A number of parameters are provided to affect the output:

  • Feature size: Adjusts the size of the predominant features in the noise. In mm. Defaults to 1mm.
  • Octaves (all but Voronoi): Each noise algorithm uses several instances with decreasing feature size, and sums them. This controls how many instances are instantiated.
  • Persistence (Perlin, Billow only): Each octave contributes progressively less to the total. This controls the rate at which octaves' amplitude is reduced.

Existing parameters - depth and point distance - continue to be used in the expected manner.

Backwards-compatibility is provided for by having 'classic' as the default noise type when fuzzy skin is enabled.

I've included the library inline following the example of some other libraries used by Orca, as it's only available via download from Sourceforge via an interstitial. If there's a better way to do this, please let me know.

Screenshots/Recordings/Graphs

Screenshot from 2024-12-06 16-46-10

PXL_20241206_090346843 (1)
Bambulab Calibration Cube by prdak27.
0.2mm point distance, 0.2mm thickness.

PXL_20241206_090417016 (1)
0.2mm point distance, 0.2mm thickness.

PXL_20241206_090448835 (1)
PXL_20241206_154823381
Fuzzy Love Teddy Bear by SamActivity
Classic: 0.8mm point distance, 0.3mm thickness.
Voronoi: 0.2mm point distance, 0.2mm thickness, 5mm feature size
All others: 0.2mm point distance, 0.3mm thickness, 3mm feature size, 5 octaves, 0.66 persistence

@discip
Copy link
Contributor

discip commented Dec 7, 2024

@Arachnid
Thank you very much! 👍
Great, this is absolutely fantastic and contributes to Orca being the go to slicer!

I hope you don't mind: Here are some suggestions you might consider:

  1. Maybe you could reorder and rename the entries like this:

    • Structured skin
    • Noise type
    • Point distance
    • Amplitude
    • Feature size
    • Noise octaves
    • Noise persistence
    • Apply structure to first layer
  2. You may also want to hide irrelevant entries when a particular noise type is selected.

p.s.
Would it be possible to implement an option to use custom patterns (e.g. SVG) that define the structure of the skin? For example, something like a brick pattern.

@Arachnid
Copy link
Contributor Author

Arachnid commented Dec 8, 2024

I hope you don't mind: Here are some suggestions you might consider:

  1. Maybe you could reorder and rename the entries like this:

    • Structured skin
    • Noise type
    • Point distance
    • Amplitude
    • Feature size
    • Noise octaves
    • Noise persistence
    • Apply structure to first layer

I'm happy to consider it! I'd like to hear from the maintainers before renaming existing features, though - there may be concerns about confusion / backwards compatibility.

2. You may also want to hide irrelevant entries when a particular noise type is selected.

Already done!

p.s.
Would it be possible to implement an option to use custom patterns (e.g. SVG) that define the structure of the skin? For example, something like a brick pattern.

This is tricky. The existing noise library generates 3 dimensional noise, meaning we can get the value for any point just by querying it. Mapping a 2d object like an SVG to a surface is much more complex, and I'm afraid it's beyond my basic computational geometry skills!

@Arachnid
Copy link
Contributor Author

Arachnid commented Dec 9, 2024

Fixes #7467

@discip
Copy link
Contributor

discip commented Dec 9, 2024

@Arachnid

Fixes #7467

If you want the linked issue to be closed with the merge of this PR, you need to put it in the initial post via an edit. 😊

@Noisyfox
Copy link
Collaborator

Is it possible to add the libnoise as an external dep that can be downloaded as a zip during build?

@Arachnid
Copy link
Contributor Author

Is it possible to add the libnoise as an external dep that can be downloaded as a zip during build?

As far as I can tell, libnoise is only hosted on source forge, which has a browser interstitial for all downloads. I can try and bypass it for an automated download, but I was concerned that would be subject to breakage easily.

I can also delete irrelevant files such as docs, if that would help.

@Noisyfox
Copy link
Collaborator

I can also delete irrelevant files such as docs, if that would help.

Absolutely. Now my browser freezes as soon as I switch to the Files Changed tab

@discip
Copy link
Contributor

discip commented Dec 14, 2024

@Noisyfox
Could we please at least reorder the entries at this point?
I think the current order looks like it was patched together.

This is what I suggest to change in Tab.cpp:

2348        optgroup->append_single_option_line("fuzzy_skin");
2349        optgroup->append_single_option_line("fuzzy_skin_noise_type");
2350        optgroup->append_single_option_line("fuzzy_skin_point_distance");
2351        optgroup->append_single_option_line("fuzzy_skin_thickness");
2352        optgroup->append_single_option_line("fuzzy_skin_scale");
2353        optgroup->append_single_option_line("fuzzy_skin_octaves");
2354        optgroup->append_single_option_line("fuzzy_skin_persistence");
2355        optgroup->append_single_option_line("fuzzy_skin_first_layer");

Optionally line 2355 ("fuzzy_skin_first_layer") could be placed after 2349 ("fuzzy_skin_noise_type").

@Arachnid
While testing this very nice addition, I noticed that Multifractal and Billow are mixed up in the last image of the initial post. 😊

@Arachnid
Copy link
Contributor Author

I've reordered the options as suggested by @discip. I've also fixed the image - good catch.

I've also removed the docs folder to cut down on the number of files imported. Still happy to restructure it to download it at build time, if we have a good solution to the sourceforge hosting.

Copy link
Contributor

@discip discip left a comment

Choose a reason for hiding this comment

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

Great! 👍

Thank you!

@SeeTurtlee
Copy link

I've been playing with this for about a week now and its super cool! i was wondering however if it would be possible to add the option to apply fuzzy skin to the top layer? i know it's technically possible with https://github.com/TengerTechnologies/Fuzzyficator, but having it as an actual feature would be awesome!

@Arachnid
Copy link
Contributor Author

I've been playing with this for about a week now and its super cool! i was wondering however if it would be possible to add the option to apply fuzzy skin to the top layer? i know it's technically possible with https://github.com/TengerTechnologies/Fuzzyficator, but having it as an actual feature would be awesome!

Adding fuzzy skin to top surfaces is a whole different thing! I'd love to have it too, but I think it will require a separate pr reimplementing their hard work in C++.

@Arachnid
Copy link
Contributor Author

Arachnid commented Jan 7, 2025

@SoftFever Appreciate you have a lot going on, but I'd hugely appreciate it if you're able to give this a review.

} else {
const auto current_ext = extrusion.junctions;
std::vector<Arachne::ExtrusionJunction> segment;
segment.reserve(current_ext.size());
extrusion.junctions.clear();

const auto fuzzy_current_segment = [&segment, &extrusion, &r]() {
const auto fuzzy_current_segment = [&segment, extrusion, &r, slice_z]() {
Copy link
Contributor

@undingen undingen Jan 7, 2025

Choose a reason for hiding this comment

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

I'm getting a compile error here: because extrusion should IMHO be captured by reference like before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, fixed. I accidentally removed it when merging changes.

@undingen
Copy link
Contributor

undingen commented Jan 7, 2025

Very impressive results 💯
I tried taking this PR as a base for experimenting with using displacement map/texture for the surface - one thing I noticed: this code is still adding some additional noise by randomizing the line start position via random_value() and length. Not sure if this is on purpose I guess it does not really make a difference for the implemented noise sources but when I added a call to "checkboard" I seem to notice some of this random segments. Not sure if this should be removed if not in classic mode?!?

@Arachnid
Copy link
Contributor Author

Arachnid commented Jan 7, 2025

one thing I noticed: this code is still adding some additional noise by randomizing the line start position via random_value() and length. Not sure if this is on purpose I guess it does not really make a difference for the implemented noise sources but when I added a call to "checkboard" I seem to notice some of this random segments. Not sure if this should be removed if not in classic mode?!?

Good catch. I left it in because I didn't want to break legacy fuzzy skin, and leaving it as-is reduced the size of the diff, while not making a meaningful difference to the results with random noise. I can see how it would affect something more deterministic though!

@SoftFever
Copy link
Owner

@Arachnid
Thank you!
This is very nice.

Can we move the libnoise to third-party library (deps) so that we don't have to build it every time?
Please let me know if you need any help.

@SoftFever
Copy link
Owner

SoftFever commented Jan 26, 2025

I love it!
image

image

@Arachnid
Copy link
Contributor Author

@SoftFever Glad you like it! I'm happy to change how it's built, but I could use some advice on how. When I was looking at the process originally it looked like libraries in deps had to be downloaded as part of the build process, and the only download source for this library is sourceforge, with an interstitial page.

@SoftFever
Copy link
Owner

SoftFever commented Jan 26, 2025

@SoftFever Glad you like it! I'm happy to change how it's built, but I could use some advice on how. When I was looking at the process originally it looked like libraries in deps had to be downloaded as part of the build process, and the only download source for this library is sourceforge, with an interstitial page.

We can create a repo just like what we did for nanosvg and wxwidget.
No worries, let me help you move it

@SoftFever
Copy link
Owner

@Arachnid
I have move the libnoise to deps and have made the necessary change.
I need your help to allow me push my changes into your branch. If you are fine with it, you can enable it here: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork

Another option is that I can create another PR

@Arachnid
Copy link
Contributor Author

Amazing, thank you! Allow edits by maintainers is already ticked, so you should be able to push to my branch.

@SoftFever
Copy link
Owner

SoftFever commented Jan 26, 2025

Amazing, thank you! Allow edits by maintainers is already ticked, so you should be able to push to my branch.

Hmm I still can't push
but i found a way to get around it.
I raised an new PR to your branch. Please take a look :)

@Arachnid
Copy link
Contributor Author

Merged!

@SoftFever
Copy link
Owner

There are some compiler error after merging with main branch.
I will fix them in a new PR along with some CICD issues.
I'll merge this PR first as the main code logic looks good to me.

Thank you very much!

@SoftFever SoftFever merged commit fd0b254 into SoftFever:main Jan 27, 2025
10 of 16 checks passed
@Arachnid
Copy link
Contributor Author

Amazing. Thank you so much!

def->set_default_value(new ConfigOptionFloat(1.0));

def = this->add("fuzzy_skin_octaves", coInt);
def->label = L("Fuzzy Skin Noise Octaves");
Copy link
Contributor

Choose a reason for hiding this comment

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

@Arachnid
Hi. Skin has an uppercase S here, lower elsewhere.

@henrivdr
Copy link
Contributor

@Arachnid Can I recommend that the settings be moved to "Quality" , with it's own "Fuzzy skin" group and icon?
I think it deserves it's own group 👍
@SoftFever your thoughts? Not sure what the icon should look like :-)

@Arachnid
Copy link
Contributor Author

@henrivdr I think that makes a lot of sense. Happy to open a PR if @SoftFever agrees!

@igiannakas
Copy link
Contributor

@henrivdr I think that makes a lot of sense. Happy to open a PR if @SoftFever agrees!

Makes sense to have this as a separate group of settings now, from a usability perspective :)

Under ironing may be a good place to create a new section as ironing is already collapsed if not used and fuzzy skin would be equally collapsed.

@SoftFever
Copy link
Owner

That's a good suggestion to move it to its own group!
However, I hope it remains in the Other's tab for two reasons:

  1. People are getting used to finding the options here.
  2. I'm not entirely sure it fits within the Quality category, as that tab should, in principle, only contain options that affect surface quality or accuracy. While fuzzy skin represents aesthetic changes.

@igiannakas
Copy link
Contributor

Makes sense :)

@discip
Copy link
Contributor

discip commented Jan 28, 2025

2. I'm not entirely sure it fits within the Quality category, as that tab should, in principle, only contain options that affect surface quality or accuracy. While fuzzy skin represents aesthetic changes.

Absolutely agree!

@igiannakas
Copy link
Contributor

Just wanted to say a huge thank you for this - the new patterns look absolutely stunning!

IMG_5484

GiacomoGuaresi pushed a commit to gingeradditive/OrcaSlicer that referenced this pull request Feb 8, 2025
* Add support for perlin noise fuzzy skin

* Support multiple types of coherent noise

* Updated tooltips for more clarity.

* Reorder options as suggested by @discip

* Fix accidental removal of &

* Move libnoise to deps

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
@Zogar89
Copy link

Zogar89 commented May 5, 2025

Just wanted to say a huge thank you for this - the new patterns look absolutely stunning!

IMG_5484

Please, Could you share the options you used to achieve that finish?

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.

[Bounty: $250] Coherent noise fuzzy skin support
9 participants