From fd0b2547f2ba74cc1ffef13ec99ac840911c2967 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 27 Jan 2025 14:45:16 +0000 Subject: [PATCH] Add support for structured noise (perlin) fuzzy skin (#7678) * 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 --- cmake/modules/Findlibnoise.cmake | 15 +++++ deps/CMakeLists.txt | 1 + deps/libnoise/libnoise.cmake | 4 ++ src/libslic3r/CMakeLists.txt | 3 +- src/libslic3r/LayerRegion.cpp | 1 + src/libslic3r/PerimeterGenerator.cpp | 86 +++++++++++++++++++++------ src/libslic3r/PerimeterGenerator.hpp | 21 ++++++- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 60 +++++++++++++++++++ src/libslic3r/PrintConfig.hpp | 13 ++++ src/libslic3r/PrintObject.cpp | 4 ++ src/slic3r/CMakeLists.txt | 3 +- src/slic3r/GUI/ConfigManipulation.cpp | 7 ++- src/slic3r/GUI/Tab.cpp | 4 ++ 14 files changed, 200 insertions(+), 24 deletions(-) create mode 100644 cmake/modules/Findlibnoise.cmake create mode 100644 deps/libnoise/libnoise.cmake diff --git a/cmake/modules/Findlibnoise.cmake b/cmake/modules/Findlibnoise.cmake new file mode 100644 index 000000000..70a5da951 --- /dev/null +++ b/cmake/modules/Findlibnoise.cmake @@ -0,0 +1,15 @@ +find_path(LIBNOISE_INCLUDE_DIR libnoise/noise.h) +find_library(LIBNOISE_LIBRARY NAMES libnoise libnoise_static) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(libnoise DEFAULT_MSG + LIBNOISE_LIBRARY + LIBNOISE_INCLUDE_DIR +) + +if(libnoise_FOUND) + add_library(noise::noise STATIC IMPORTED) + set_target_properties(noise::noise PROPERTIES + IMPORTED_LOCATION "${LIBNOISE_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBNOISE_INCLUDE_DIR}" + ) +endif() \ No newline at end of file diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 88915369f..8b7dbe09e 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -293,6 +293,7 @@ include(MPFR/MPFR.cmake) include(CGAL/CGAL.cmake) include(NLopt/NLopt.cmake) +include(libnoise/libnoise.cmake) # I *think* 1.1 is used for *just* md5 hashing? diff --git a/deps/libnoise/libnoise.cmake b/deps/libnoise/libnoise.cmake new file mode 100644 index 000000000..0e19f2692 --- /dev/null +++ b/deps/libnoise/libnoise.cmake @@ -0,0 +1,4 @@ +orcaslicer_add_cmake_project(libnoise + URL https://github.com/SoftFever/Orca-deps-libnoise/archive/refs/tags/1.0.zip + URL_HASH SHA256=96ffd6cc47898dd8147aab53d7d1b1911b507d9dbaecd5613ca2649468afd8b6 +) \ No newline at end of file diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index ea08f39cf..7c673231e 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -550,7 +550,7 @@ set(OCCT_LIBS TKernel ) - +find_package(libnoise REQUIRED) target_link_libraries(libslic3r libnest2d admesh @@ -576,6 +576,7 @@ target_link_libraries(libslic3r JPEG::JPEG qoi opencv_world + noise::noise ) if(NOT WIN32) diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index ef5d325f5..60ba2721e 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -87,6 +87,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, const LayerRe &slices, &compatible_regions, this->layer()->height, + this->layer()->slice_z, this->flow(frPerimeter), ®ion_config, &this->layer()->object()->config(), diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 624a71090..1ad1e5b90 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -22,6 +22,7 @@ #include "libslic3r/AABBTreeLines.hpp" #include "Print.hpp" #include "Algorithm/LineSplit.hpp" +#include "libnoise/noise.h" static const int overhang_sampling_number = 6; static const double narrow_loop_length_threshold = 10; static const double min_degree_gap = 0.1; @@ -44,6 +45,14 @@ static double random_value() { return dist(gen); } +class UniformNoise: public noise::module::Module { + public: + UniformNoise(): Module (GetSourceModuleCount ()) {}; + + virtual int GetSourceModuleCount() const { return 0; } + virtual double GetValue(double x, double y, double z) const { return random_value() * 2 - 1; } +}; + // Hierarchy of perimeters. class PerimeterGeneratorLoop { public: @@ -66,9 +75,39 @@ public: bool is_internal_contour() const; }; +static std::unique_ptr get_noise_module(const FuzzySkinConfig& cfg) { + if (cfg.noise_type == NoiseType::Perlin) { + auto perlin_noise = noise::module::Perlin(); + perlin_noise.SetFrequency(1 / cfg.noise_scale); + perlin_noise.SetOctaveCount(cfg.noise_octaves); + perlin_noise.SetPersistence(cfg.noise_persistence); + return std::make_unique(perlin_noise); + } else if (cfg.noise_type == NoiseType::Billow) { + auto billow_noise = noise::module::Billow(); + billow_noise.SetFrequency(1 / cfg.noise_scale); + billow_noise.SetOctaveCount(cfg.noise_octaves); + billow_noise.SetPersistence(cfg.noise_persistence); + return std::make_unique(billow_noise); + } else if (cfg.noise_type == NoiseType::RidgedMulti) { + auto ridged_multi_noise = noise::module::RidgedMulti(); + ridged_multi_noise.SetFrequency(1 / cfg.noise_scale); + ridged_multi_noise.SetOctaveCount(cfg.noise_octaves); + return std::make_unique(ridged_multi_noise); + } else if (cfg.noise_type == NoiseType::Voronoi) { + auto voronoi_noise = noise::module::Voronoi(); + voronoi_noise.SetFrequency(1 / cfg.noise_scale); + voronoi_noise.SetDisplacement(1.0); + return std::make_unique(voronoi_noise); + } else { + return std::make_unique(); + } +} + // Thanks Cura developers for this function. -static void fuzzy_polyline(Points& poly, bool closed, const FuzzySkinConfig& cfg) +static void fuzzy_polyline(Points& poly, bool closed, coordf_t slice_z, const FuzzySkinConfig& cfg) { + std::unique_ptr noise = get_noise_module(cfg); + const double min_dist_between_points = cfg.point_distance * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value const double range_random_point_dist = cfg.point_distance / 2.; double dist_left_over = random_value() * (min_dist_between_points / 2.); // the distance to be traversed on the line before making the first new point @@ -90,8 +129,9 @@ static void fuzzy_polyline(Points& poly, bool closed, const FuzzySkinConfig& cfg for (; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + random_value() * range_random_point_dist) { - double r = random_value() * (cfg.thickness * 2.) - cfg.thickness; - out.emplace_back(*p0 + (p0p1 * (p0pa_dist / p0p1_size) + perp(p0p1).cast().normalized() * r).cast()); + Point pa = *p0 + (p0p1 * (p0pa_dist / p0p1_size)).cast(); + double r = noise->GetValue(unscale_(pa.x()), unscale_(pa.y()), slice_z) * cfg.thickness; + out.emplace_back(pa + (perp(p0p1).cast().normalized() * r).cast()); } dist_left_over = p0pa_dist - p0p1_size; p0 = &p1; @@ -108,8 +148,10 @@ static void fuzzy_polyline(Points& poly, bool closed, const FuzzySkinConfig& cfg } // Thanks Cura developers for this function. -static void fuzzy_extrusion_line(std::vector& ext_lines, const FuzzySkinConfig& cfg) +static void fuzzy_extrusion_line(std::vector& ext_lines, coordf_t slice_z, const FuzzySkinConfig& cfg) { + std::unique_ptr noise = get_noise_module(cfg); + const double min_dist_between_points = cfg.point_distance * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value const double range_random_point_dist = cfg.point_distance / 2.; double dist_left_over = random_value() * (min_dist_between_points / 2.); // the distance to be traversed on the line before making the first new point @@ -128,8 +170,9 @@ static void fuzzy_extrusion_line(std::vector& ext_li double p0p1_size = p0p1.norm(); double p0pa_dist = dist_left_over; for (; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + random_value() * range_random_point_dist) { - double r = random_value() * (cfg.thickness * 2.) - cfg.thickness; - out.emplace_back(p0->p + (p0p1 * (p0pa_dist / p0p1_size) + perp(p0p1).cast().normalized() * r).cast(), p1.w, p1.perimeter_index); + Point pa = p0->p + (p0p1 * (p0pa_dist / p0p1_size)).cast(); + double r = noise->GetValue(unscale_(pa.x()), unscale_(pa.y()), slice_z) * cfg.thickness; + out.emplace_back(pa + (perp(p0p1).cast().normalized() * r).cast(), p1.w, p1.perimeter_index); } dist_left_over = p0pa_dist - p0p1_size; p0 = &p1; @@ -544,7 +587,7 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime } fuzzified = loop.polygon; - fuzzy_polyline(fuzzified.points, true, config); + fuzzy_polyline(fuzzified.points, true, perimeter_generator.slice_z, config); return &fuzzified; } @@ -589,16 +632,17 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime // Fuzzy splitted polygon if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) { // The entire polygon is fuzzified - fuzzy_polyline(fuzzified.points, true, r.first); + fuzzy_polyline(fuzzified.points, true, perimeter_generator.slice_z, r.first); } else { Points segment; segment.reserve(splitted.size()); fuzzified.points.clear(); - const auto fuzzy_current_segment = [&segment, &fuzzified, &r]() { + const auto slice_z = perimeter_generator.slice_z; + const auto fuzzy_current_segment = [&segment, &fuzzified, &r, slice_z]() { fuzzified.points.push_back(segment.front()); const auto back = segment.back(); - fuzzy_polyline(segment, false, r.first); + fuzzy_polyline(segment, false, slice_z, r.first); fuzzified.points.insert(fuzzified.points.end(), segment.begin(), segment.end()); fuzzified.points.push_back(back); segment.clear(); @@ -970,6 +1014,8 @@ static void smooth_overhang_level(ExtrusionPaths &paths) static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& perimeter_generator, std::vector& pg_extrusions, bool &steep_overhang_contour, bool &steep_overhang_hole) { + const auto slice_z = perimeter_generator.slice_z; + // Detect steep overhangs bool overhangs_reverse = perimeter_generator.config->overhang_reverse && perimeter_generator.layer_id % 2 == 1; // Only calculate overhang degree on even (from GUI POV) layers @@ -989,7 +1035,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p const auto& config = regions.begin()->first; const bool fuzzify = should_fuzzify(config, perimeter_generator.layer_id, extrusion->inset_idx, is_contour); if (fuzzify) - fuzzy_extrusion_line(extrusion->junctions, config); + fuzzy_extrusion_line(extrusion.junctions, slice_z, config); } else { // Find all affective regions std::vector> fuzzified_regions; @@ -1011,19 +1057,19 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p // Fuzzy splitted extrusion if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) { // The entire polygon is fuzzified - fuzzy_extrusion_line(extrusion->junctions, r.first); + fuzzy_extrusion_line(extrusion.junctions, slice_z, r.first); } else { const auto current_ext = extrusion->junctions; std::vector segment; segment.reserve(current_ext.size()); extrusion->junctions.clear(); - const auto fuzzy_current_segment = [&segment, extrusion, &r]() { - extrusion->junctions.push_back(segment.front()); + const auto fuzzy_current_segment = [&segment, &extrusion, &r, slice_z]() { + extrusion.junctions.push_back(segment.front()); const auto back = segment.back(); - fuzzy_extrusion_line(segment, r.first); - extrusion->junctions.insert(extrusion->junctions.end(), segment.begin(), segment.end()); - extrusion->junctions.push_back(back); + fuzzy_extrusion_line(segment, slice_z, r.first); + extrusion.junctions.insert(extrusion.junctions.end(), segment.begin(), segment.end()); + extrusion.junctions.push_back(back); segment.clear(); }; @@ -1858,7 +1904,11 @@ static void group_region_by_fuzzify(PerimeterGenerator& g) region_config.fuzzy_skin, scaled(region_config.fuzzy_skin_thickness.value), scaled(region_config.fuzzy_skin_point_distance.value), - region_config.fuzzy_skin_first_layer + region_config.fuzzy_skin_first_layer, + region_config.fuzzy_skin_noise_type, + region_config.fuzzy_skin_scale, + region_config.fuzzy_skin_octaves, + region_config.fuzzy_skin_persistence }; auto& surfaces = regions[cfg]; for (const auto& surface : region->slices.surfaces) { diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp index 733920e31..0b79cc40c 100644 --- a/src/libslic3r/PerimeterGenerator.hpp +++ b/src/libslic3r/PerimeterGenerator.hpp @@ -16,10 +16,21 @@ struct FuzzySkinConfig coord_t thickness; coord_t point_distance; bool fuzzy_first_layer; + NoiseType noise_type; + double noise_scale; + int noise_octaves; + double noise_persistence; bool operator==(const FuzzySkinConfig& r) const { - return type == r.type && thickness == r.thickness && point_distance == r.point_distance && fuzzy_first_layer == r.fuzzy_first_layer; + return type == r.type + && thickness == r.thickness + && point_distance == r.point_distance + && fuzzy_first_layer == r.fuzzy_first_layer + && noise_type == r.noise_type + && noise_scale == r.noise_scale + && noise_octaves == r.noise_octaves + && noise_persistence == r.noise_persistence; } bool operator!=(const FuzzySkinConfig& r) const { return !(*this == r); } @@ -35,6 +46,10 @@ template<> struct hash boost::hash_combine(seed, std::hash{}(c.thickness)); boost::hash_combine(seed, std::hash{}(c.point_distance)); boost::hash_combine(seed, std::hash{}(c.fuzzy_first_layer)); + boost::hash_combine(seed, std::hash{}(c.noise_type)); + boost::hash_combine(seed, std::hash{}(c.noise_scale)); + boost::hash_combine(seed, std::hash{}(c.noise_octaves)); + boost::hash_combine(seed, std::hash{}(c.noise_persistence)); return seed; } }; @@ -51,6 +66,7 @@ public: const ExPolygons *lower_slices; double layer_height; int layer_id; + coordf_t slice_z; Flow perimeter_flow; Flow ext_perimeter_flow; Flow overhang_flow; @@ -83,6 +99,7 @@ public: const SurfaceCollection* slices, const LayerRegionPtrs *compatible_regions, double layer_height, + coordf_t slice_z, Flow flow, const PrintRegionConfig* config, const PrintObjectConfig* object_config, @@ -98,7 +115,7 @@ public: //BBS ExPolygons* fill_no_overlap) : slices(slices), compatible_regions(compatible_regions), upper_slices(nullptr), lower_slices(nullptr), layer_height(layer_height), - layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow), + slice_z(slice_z), layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow), overhang_flow(flow), solid_infill_flow(flow), config(config), object_config(object_config), print_config(print_config), m_spiral_vase(spiral_mode), diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index ce108b8b2..7ddb0884e 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -789,7 +789,7 @@ static std::vector s_Preset_print_options { "minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern","gap_fill_target", "ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing", "ironing_angle", "ironing_inset", "max_travel_detour_distance", - "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", + "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", "fuzzy_skin_noise_type", "fuzzy_skin_scale", "fuzzy_skin_octaves", "fuzzy_skin_persistence", "max_volumetric_extrusion_rate_slope", "max_volumetric_extrusion_rate_slope_segment_length","extrusion_rate_smoothing_external_perimeter_only", "inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed", "top_surface_speed", "support_speed", "support_object_xy_distance", "support_interface_speed", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b992fb237..03573d08b 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -123,6 +123,15 @@ static t_config_enum_values s_keys_map_FuzzySkinType { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FuzzySkinType) +static t_config_enum_values s_keys_map_NoiseType { + { "classic", int(NoiseType::Classic) }, + { "perlin", int(NoiseType::Perlin) }, + { "billow", int(NoiseType::Billow) }, + { "ridgedmulti", int(NoiseType::RidgedMulti) }, + { "voronoi", int(NoiseType::Voronoi) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NoiseType) + static t_config_enum_values s_keys_map_InfillPattern { { "concentric", ipConcentric }, { "zig-zag", ipRectilinear }, @@ -2632,6 +2641,57 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionBool(0)); + def = this->add("fuzzy_skin_noise_type", coEnum); + def->label = L("Fuzzy skin noise type"); + def->category = L("Others"); + def->tooltip = L("Noise type to use for fuzzy skin generation.\n" + "Classic: Classic uniform random noise.\n" + "Perlin: Perlin noise, which gives a more consistent texture.\n" + "Billow: Similar to perlin noise, but clumpier.\n" + "Ridged Multifractal: Ridged noise with sharp, jagged features. Creates marble-like textures.\n" + "Voronoi: Divides the surface into voronoi cells, and displaces each one by a random amount. Creates a patchwork texture."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("classic"); + def->enum_values.push_back("perlin"); + def->enum_values.push_back("billow"); + def->enum_values.push_back("ridgedmulti"); + def->enum_values.push_back("voronoi"); + def->enum_labels.push_back(L("Classic")); + def->enum_labels.push_back(L("Perlin")); + def->enum_labels.push_back(L("Billow")); + def->enum_labels.push_back(L("Ridged Multifractal")); + def->enum_labels.push_back(L("Voronoi")); + def->mode = comSimple; + def->set_default_value(new ConfigOptionEnum(NoiseType::Classic)); + + def = this->add("fuzzy_skin_scale", coFloat); + def->label = L("Fuzzy skin feature size"); + def->category = L("Others"); + def->tooltip = L("The base size of the coherent noise features, in mm. Higher values will result in larger features."); + def->sidetext = L("mm"); + def->min = 0.1; + def->max = 500; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1.0)); + + def = this->add("fuzzy_skin_octaves", coInt); + def->label = L("Fuzzy Skin Noise Octaves"); + def->category = L("Others"); + def->tooltip = L("The number of octaves of coherent noise to use. Higher values increase the detail of the noise, but also increase computation time."); + def->min = 1; + def->max = 10; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionInt(4)); + + def = this->add("fuzzy_skin_persistence", coFloat); + def->label = L("Fuzzy skin noise persistence"); + def->category = L("Others"); + def->tooltip = L("The decay rate for higher octaves of the coherent noise. Lower values will result in smoother noise."); + def->min = 0.01; + def->max = 1; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.5)); + def = this->add("filter_out_gap_fill", coFloat); def->label = L("Filter out tiny gaps"); def->category = L("Layers and Perimeters"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 88cc8438b..33a0e7eab 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -41,6 +41,14 @@ enum class FuzzySkinType { AllWalls, }; +enum class NoiseType { + Classic, + Perlin, + Billow, + RidgedMulti, + Voronoi, +}; + enum PrintHostType { htPrusaLink, htPrusaConnect, htOctoPrint, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS, htESP3D, htCrealityPrint, htObico, htFlashforge, htSimplyPrint }; @@ -402,6 +410,7 @@ static std::string get_bed_temp_1st_layer_key(const BedType type) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrinterTechnology) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeFlavor) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NoiseType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(InfillPattern) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(IroningType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SlicingMode) @@ -917,6 +926,10 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, fuzzy_skin_thickness)) ((ConfigOptionFloat, fuzzy_skin_point_distance)) ((ConfigOptionBool, fuzzy_skin_first_layer)) + ((ConfigOptionEnum, fuzzy_skin_noise_type)) + ((ConfigOptionFloat, fuzzy_skin_scale)) + ((ConfigOptionInt, fuzzy_skin_octaves)) + ((ConfigOptionFloat, fuzzy_skin_persistence)) ((ConfigOptionFloat, gap_infill_speed)) ((ConfigOptionInt, sparse_infill_filament)) ((ConfigOptionFloatOrPercent, sparse_infill_line_width)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 0c5d78de7..b76eaa457 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1117,6 +1117,10 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "fuzzy_skin_thickness" || opt_key == "fuzzy_skin_point_distance" || opt_key == "fuzzy_skin_first_layer" + || opt_key == "fuzzy_skin_noise_type" + || opt_key == "fuzzy_skin_scale" + || opt_key == "fuzzy_skin_octaves" + || opt_key == "fuzzy_skin_persistence" || opt_key == "detect_overhang_wall" || opt_key == "overhang_reverse" || opt_key == "overhang_reverse_internal_only" diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 10d3f3764..3de396c9d 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -616,7 +616,8 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SLIC3R_GUI_SOURCES}) encoding_check(libslic3r_gui) -target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto) +find_package(libnoise REQUIRED) +target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise) if (MSVC) target_link_libraries(libslic3r_gui Setupapi.lib) diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 44ed3da01..a376aa7f1 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -708,9 +708,14 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_line("support_interface_not_for_body",config->opt_int("support_interface_filament")&&!config->opt_int("support_filament")); bool has_fuzzy_skin = (config->opt_enum("fuzzy_skin") != FuzzySkinType::None); - for (auto el : { "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer"}) + for (auto el : { "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", "fuzzy_skin_noise_type"}) toggle_line(el, has_fuzzy_skin); + NoiseType fuzzy_skin_noise_type = config->opt_enum("fuzzy_skin_noise_type"); + toggle_line("fuzzy_skin_scale", has_fuzzy_skin && fuzzy_skin_noise_type != NoiseType::Classic); + toggle_line("fuzzy_skin_octaves", has_fuzzy_skin && fuzzy_skin_noise_type != NoiseType::Classic && fuzzy_skin_noise_type != NoiseType::Voronoi); + toggle_line("fuzzy_skin_persistence", has_fuzzy_skin && (fuzzy_skin_noise_type == NoiseType::Perlin || fuzzy_skin_noise_type == NoiseType::Billow)); + bool have_arachne = config->opt_enum("wall_generator") == PerimeterGeneratorType::Arachne; for (auto el : { "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "min_feature_size", "min_length_factor", "min_bead_width", "wall_distribution_count", "initial_layer_min_bead_width"}) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 78162dfb6..fea8908d7 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2352,8 +2352,12 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v optgroup->append_single_option_line("timelapse_type", "Timelapse"); optgroup->append_single_option_line("fuzzy_skin"); + optgroup->append_single_option_line("fuzzy_skin_noise_type"); optgroup->append_single_option_line("fuzzy_skin_point_distance"); optgroup->append_single_option_line("fuzzy_skin_thickness"); + optgroup->append_single_option_line("fuzzy_skin_scale"); + optgroup->append_single_option_line("fuzzy_skin_octaves"); + optgroup->append_single_option_line("fuzzy_skin_persistence"); optgroup->append_single_option_line("fuzzy_skin_first_layer"); optgroup = page->new_optgroup(L("G-code output"), L"param_gcode");