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

Displacement map applied during slicing (resolves #8649) #13854

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ build-linux/*
deps/build-linux/*
**/.DS_Store
**/.idea/
/deps/
19 changes: 19 additions & 0 deletions src/libslic3r/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

namespace Slic3r {

std::map<std::string, png::BackendPng> config_images;
png::BackendPng no_image; // A non-loaded image (IsOK() should always be false) for avoiding returning nullptr.

// Escape \n, \r and backslash
std::string escape_string_cstyle(const std::string &str)
{
Expand Down Expand Up @@ -460,6 +463,22 @@ void ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys
} else
my_opt->set(other_opt);
}
// ConfigOption *path_opt = this->option("fuzzy_skin_displacement_map", false); // tries to use deleted = operator?
// std::string path_opt = "/home/owner/Maps/wall/Bricks076A_1K-JPG/Bricks076A_1K_Displacement-512-RGBA.png"; // this->option("fuzzy_skin_displacement_map", false)->value;
// dynamic_cast<std::string>(*this->option("fuzzy_skin_displacement_map"))->value;
/*
if (path_opt != nullptr) {
std::string this_displacement_map_path = path_opt;
if (this_displacement_map_path != displacement_img.GetPath()) {
if (this_displacement_map_path != "") {
this->m_displacement_img.LoadFile(this_displacement_map_path);
}
else {
m_displacement_img.Destroy();
}
}
}
*/
}

// Are the two configs equal? Ignoring options not present in both configs.
Expand Down
46 changes: 46 additions & 0 deletions src/libslic3r/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "clonable_ptr.hpp"
#include "Exception.hpp"
#include "Point.hpp"
#include "PNGReadWrite.hpp" // ideally some kind of cache or interface (IBackendImage or something) would be used instead of BackendPng directly.

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
Expand Down Expand Up @@ -81,6 +82,10 @@ extern bool unescape_strings_cstyle(const std::string &str, std::vector<

extern std::string escape_ampersand(const std::string& str);

extern std::map<std::string, png::BackendPng> config_images;
// ^ consider: std::map<std::string, shared_ptr<BackendPng>> config_images; // use `new` and pointers but let delete get called automatically
extern png::BackendPng no_image; // A non-loaded image (IsOK() should always be false) for avoiding returning nullptr.

namespace ConfigHelpers {
inline bool looks_like_enum_value(std::string value)
{
Expand Down Expand Up @@ -2065,9 +2070,50 @@ class ConfigBase : public ConfigOptionResolver

static size_t load_from_gcode_string_legacy(ConfigBase& config, const char* str, ConfigSubstitutionContext& substitutions);

/*!
Get a pointer to the displacement map. The return is always non-null.
If the param is false but the function was not properly called on the main thread
beforehand with true, an exception will be raised (It will appear in the GUI, but it
is an implementation error and should be fixed before release).

@param opt_key_str The string equivalent to the opt_key that will also be used as the
caching key in config_images.
@param main_thread If true, the call must be made outside of a multithreading context.
In threads should be called with false to avoid multithreading issues,
by forcing an exception if not already loaded.
*/
const png::BackendPng* opt_image(std::string opt_key_str, bool main_thread) const {
// ConfigOption* path_opt = this->option("fuzzy_skin_displacement_map", false);
// if (path_opt == nullptr) {
// return &no_image;
// }
// std::string path = dynamic_cast<std::string>(path_opt->get()); // incorrect?
const std::string& path = this->opt_string(opt_key_str).empty()
? std::string("") // print_config_def.get("fuzzy_skin_displacement_map")->get_default_value<ConfigOptionString>()->value
: this->opt_string(opt_key_str);
if (path == "") {
return &no_image;
}

auto pos = config_images.find(path); // std::map<string, png::BackendImage>::const_iterator pos =
if (pos == config_images.end()) {
if (!main_thread) {
throw ConfigurationError(opt_key_str + " has a new value."
" opt_image(\"" + opt_key_str + "\", true) must"
" be accessed within the main thread first to preload it"
" (This is a problem with implementation not a runtime error).");
// return nullptr;
}
config_images[path] = png::BackendPng();
config_images[path].LoadFile(path);
}
// else Some other function should clear config_images cache in case the same image file changed on storage.
return &config_images[path];
}
private:
// Set a configuration value from a string.
bool set_deserialize_raw(const t_config_option_key& opt_key_src, const std::string& value, ConfigSubstitutionContext& substitutions, bool append);
// png::BackendPng m_displacement_img; //!< This must be loaded from fuzzy_skin_displacement_map (see apply_config; Using a cached image accessed by the option key may be better).
};

// Configuration store with dynamic number of configuration values.
Expand Down
3 changes: 2 additions & 1 deletion src/libslic3r/Layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ void Layer::make_perimeters()
&& config.infill_overlap == other_config.infill_overlap
&& config.fuzzy_skin == other_config.fuzzy_skin
&& config.fuzzy_skin_thickness == other_config.fuzzy_skin_thickness
&& config.fuzzy_skin_point_dist == other_config.fuzzy_skin_point_dist)
&& config.fuzzy_skin_point_dist == other_config.fuzzy_skin_point_dist
&& config.fuzzy_skin_displacement_map == other_config.fuzzy_skin_displacement_map)
{
other_layerm->perimeters.clear();
other_layerm->fills.clear();
Expand Down
6 changes: 4 additions & 2 deletions src/libslic3r/LayerRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,12 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
&slices,
this->layer()->height,
this->flow(frPerimeter),
&region_config,
&this->layer()->object()->config(),
&region_config, // PrintRegionConfig*
// &this->layer()->object()->config(), // PrintObjectConfig*
this->layer()->object(), // PrintObject*
&print_config,
spiral_vase,
this->layer()->print_z,

// output:
&this->perimeters,
Expand Down
Loading