Add TD effective alpha correction
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
namespace Slic3r {
|
||||
namespace {
|
||||
|
||||
constexpr float TD_EFFECTIVE_ALPHA_DENSITY_SCALE = 0.6761904762f;
|
||||
constexpr float TD_EFFECTIVE_ALPHA_PASS_DENSITY = 0.05f;
|
||||
constexpr float TD_EFFECTIVE_ALPHA_WHITE_DENSITY = 0.35f;
|
||||
|
||||
float clamp01(float value)
|
||||
{
|
||||
if (!std::isfinite(value))
|
||||
@@ -189,6 +193,11 @@ std::array<float, 3> color_solver_v2_axis_weights(const std::array<float, 3> &ta
|
||||
};
|
||||
}
|
||||
|
||||
uint8_t stack_role_index(ColorSolverStackComponentRole role)
|
||||
{
|
||||
return uint8_t(std::clamp(int(role), int(ColorSolverStackComponentRole::Generic), int(ColorSolverStackComponentRole::White)));
|
||||
}
|
||||
|
||||
int build_color_solver_kd_tree(const std::vector<float> &coords,
|
||||
std::vector<ColorSolverCandidateSet::KdNode> &nodes,
|
||||
std::vector<uint32_t> &indices,
|
||||
@@ -429,24 +438,9 @@ ColorSolverNearestResult nearest_color_solver_candidates_perceptual(const Candid
|
||||
return result;
|
||||
}
|
||||
|
||||
std::array<float, 3> beer_lambert_rgb_transmission(const std::array<float, 3> &srgb_color, float scalar_transmission)
|
||||
std::array<float, 3> transmission_from_density_bias(const std::array<float, 3> &density_bias, float scalar_transmission)
|
||||
{
|
||||
const float transmission = std::clamp(std::isfinite(scalar_transmission) ? scalar_transmission : 0.5f, 1e-4f, 0.9999f);
|
||||
const std::array<float, 3> linear = srgb_to_linear_color(srgb_color);
|
||||
const float min_channel = std::min({ linear[0], linear[1], linear[2] });
|
||||
const float max_channel = std::max({ linear[0], linear[1], linear[2] });
|
||||
const float saturation = max_channel > 1e-4f ? std::clamp((max_channel - min_channel) / max_channel, 0.f, 1.f) : 0.f;
|
||||
const float strength = 0.75f * saturation;
|
||||
if (strength <= 1e-4f)
|
||||
return { transmission, transmission, transmission };
|
||||
|
||||
const float luminance = std::clamp(linear_luminance(linear), 0.02f, 0.98f);
|
||||
std::array<float, 3> density_bias;
|
||||
for (size_t channel = 0; channel < 3; ++channel) {
|
||||
const float channel_level = std::max(linear[channel], 0.02f);
|
||||
density_bias[channel] = std::pow(std::clamp(luminance / channel_level, 0.25f, 4.f), strength);
|
||||
}
|
||||
|
||||
auto weighted_transmission = [&density_bias, transmission](float scale) {
|
||||
return 0.2126f * std::pow(transmission, density_bias[0] * scale) +
|
||||
0.7152f * std::pow(transmission, density_bias[1] * scale) +
|
||||
@@ -472,6 +466,56 @@ std::array<float, 3> beer_lambert_rgb_transmission(const std::array<float, 3> &s
|
||||
};
|
||||
}
|
||||
|
||||
std::array<float, 3> rgb_density_bias(const std::array<float, 3> &srgb_color, float strength_scale)
|
||||
{
|
||||
const std::array<float, 3> linear = srgb_to_linear_color(srgb_color);
|
||||
const float min_channel = std::min({ linear[0], linear[1], linear[2] });
|
||||
const float max_channel = std::max({ linear[0], linear[1], linear[2] });
|
||||
const float saturation = max_channel > 1e-4f ? std::clamp((max_channel - min_channel) / max_channel, 0.f, 1.f) : 0.f;
|
||||
const float strength = std::clamp(strength_scale, 0.f, 2.f) * saturation;
|
||||
if (strength <= 1e-4f)
|
||||
return { 1.f, 1.f, 1.f };
|
||||
|
||||
const float luminance = std::clamp(linear_luminance(linear), 0.02f, 0.98f);
|
||||
std::array<float, 3> density_bias;
|
||||
for (size_t channel = 0; channel < 3; ++channel) {
|
||||
const float channel_level = std::max(linear[channel], 0.02f);
|
||||
density_bias[channel] = std::pow(std::clamp(luminance / channel_level, 0.25f, 4.f), strength);
|
||||
}
|
||||
return density_bias;
|
||||
}
|
||||
|
||||
std::array<float, 3> beer_lambert_rgb_transmission(const std::array<float, 3> &srgb_color, float scalar_transmission)
|
||||
{
|
||||
return transmission_from_density_bias(rgb_density_bias(srgb_color, 0.75f), scalar_transmission);
|
||||
}
|
||||
|
||||
std::array<float, 3> td_effective_alpha_density_bias(const std::array<float, 3> &srgb_color,
|
||||
ColorSolverStackComponentRole role)
|
||||
{
|
||||
switch (role) {
|
||||
case ColorSolverStackComponentRole::Cyan:
|
||||
return { 1.f, TD_EFFECTIVE_ALPHA_PASS_DENSITY, TD_EFFECTIVE_ALPHA_PASS_DENSITY };
|
||||
case ColorSolverStackComponentRole::Magenta:
|
||||
return { TD_EFFECTIVE_ALPHA_PASS_DENSITY, 1.f, TD_EFFECTIVE_ALPHA_PASS_DENSITY };
|
||||
case ColorSolverStackComponentRole::Yellow:
|
||||
return { TD_EFFECTIVE_ALPHA_PASS_DENSITY, TD_EFFECTIVE_ALPHA_PASS_DENSITY, 1.f };
|
||||
case ColorSolverStackComponentRole::Black:
|
||||
return { 1.f, 1.f, 1.f };
|
||||
case ColorSolverStackComponentRole::White:
|
||||
return { TD_EFFECTIVE_ALPHA_WHITE_DENSITY, TD_EFFECTIVE_ALPHA_WHITE_DENSITY, TD_EFFECTIVE_ALPHA_WHITE_DENSITY };
|
||||
default:
|
||||
return rgb_density_bias(srgb_color, 0.85f);
|
||||
}
|
||||
}
|
||||
|
||||
std::array<float, 3> td_effective_alpha_transmission(const std::array<float, 3> &srgb_color,
|
||||
float scalar_transmission,
|
||||
ColorSolverStackComponentRole role)
|
||||
{
|
||||
return transmission_from_density_bias(td_effective_alpha_density_bias(srgb_color, role), scalar_transmission);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_ordered_stack_beer_lambert_rgb(const std::vector<std::array<float, 3>> &colors_with_background,
|
||||
const std::vector<uint16_t> &surface_to_deep,
|
||||
const std::vector<float> &layer_opacities,
|
||||
@@ -520,17 +564,76 @@ std::array<float, 3> mix_ordered_stack_beer_lambert_rgb(const std::vector<std::a
|
||||
return linear_to_srgb_color(accumulated);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_ordered_stack_td_effective_alpha(
|
||||
const std::vector<std::array<float, 3>> &colors_with_background,
|
||||
const std::vector<uint16_t> &surface_to_deep,
|
||||
const std::vector<float> &layer_opacities,
|
||||
float surface_scatter,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
if (colors_with_background.empty() || surface_to_deep.empty())
|
||||
return colors_with_background.empty() ? std::array<float, 3>{ { 0.f, 0.f, 0.f } } : colors_with_background.back();
|
||||
|
||||
const size_t component_count = colors_with_background.size() - 1;
|
||||
std::array<float, 3> accumulated { 0.f, 0.f, 0.f };
|
||||
std::array<float, 3> remaining { 1.f, 1.f, 1.f };
|
||||
bool surface_layer = true;
|
||||
const float safe_surface_scatter =
|
||||
std::clamp(std::isfinite(surface_scatter) ? surface_scatter : 0.f, 0.f, 0.5f);
|
||||
for (uint16_t component_idx : surface_to_deep) {
|
||||
if (size_t(component_idx) >= component_count)
|
||||
continue;
|
||||
const float opacity =
|
||||
size_t(component_idx) < layer_opacities.size() && std::isfinite(layer_opacities[size_t(component_idx)]) ?
|
||||
std::clamp(layer_opacities[size_t(component_idx)], 1e-4f, 0.9999f) :
|
||||
0.5f;
|
||||
const float scalar_transmission = std::pow(1.f - opacity, TD_EFFECTIVE_ALPHA_DENSITY_SCALE);
|
||||
const ColorSolverStackComponentRole role =
|
||||
size_t(component_idx) < component_roles.size() ?
|
||||
component_roles[size_t(component_idx)] :
|
||||
ColorSolverStackComponentRole::Generic;
|
||||
std::array<float, 3> transmission =
|
||||
td_effective_alpha_transmission(colors_with_background[size_t(component_idx)], scalar_transmission, role);
|
||||
if (surface_layer) {
|
||||
for (float &channel_transmission : transmission) {
|
||||
const float channel_opacity = std::clamp(safe_surface_scatter + (1.f - safe_surface_scatter) * (1.f - channel_transmission),
|
||||
1e-4f,
|
||||
0.9999f);
|
||||
channel_transmission = 1.f - channel_opacity;
|
||||
}
|
||||
surface_layer = false;
|
||||
}
|
||||
const std::array<float, 3> layer_linear = srgb_to_linear_color(colors_with_background[size_t(component_idx)]);
|
||||
for (size_t channel = 0; channel < 3; ++channel) {
|
||||
const float channel_opacity = 1.f - transmission[channel];
|
||||
accumulated[channel] += remaining[channel] * channel_opacity * layer_linear[channel];
|
||||
remaining[channel] *= transmission[channel];
|
||||
}
|
||||
if (std::max({ remaining[0], remaining[1], remaining[2] }) <= 1e-5f)
|
||||
break;
|
||||
}
|
||||
|
||||
const std::array<float, 3> background_linear = srgb_to_linear_color(colors_with_background.back());
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
accumulated[channel] += remaining[channel] * background_linear[channel];
|
||||
return linear_to_srgb_color(accumulated);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_ordered_stack_with_buffers(const std::vector<std::array<float, 3>> &colors_with_background,
|
||||
std::vector<float> &weights,
|
||||
const std::vector<uint16_t> &surface_to_deep,
|
||||
const std::vector<float> &layer_opacities,
|
||||
ColorSolverMixModel mix_model,
|
||||
float surface_scatter,
|
||||
bool beer_lambert_rgb_correction)
|
||||
bool beer_lambert_rgb_correction,
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
if (colors_with_background.empty() || surface_to_deep.empty())
|
||||
return colors_with_background.empty() ? std::array<float, 3>{ { 0.f, 0.f, 0.f } } : colors_with_background.back();
|
||||
|
||||
if (td_effective_alpha_correction)
|
||||
return mix_ordered_stack_td_effective_alpha(colors_with_background, surface_to_deep, layer_opacities, surface_scatter, component_roles);
|
||||
if (beer_lambert_rgb_correction)
|
||||
return mix_ordered_stack_beer_lambert_rgb(colors_with_background, surface_to_deep, layer_opacities, surface_scatter);
|
||||
|
||||
@@ -728,7 +831,9 @@ void append_ordered_stack_candidate(ColorSolverOrderedStackCandidateSet &c
|
||||
ColorSolverMixModel mix_model,
|
||||
int simulated_stack_depth,
|
||||
float surface_scatter,
|
||||
bool beer_lambert_rgb_correction)
|
||||
bool beer_lambert_rgb_correction,
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
std::vector<uint16_t> simulated_surface_to_deep;
|
||||
const std::vector<uint16_t> *mix_stack = &surface_to_deep;
|
||||
@@ -737,7 +842,15 @@ void append_ordered_stack_candidate(ColorSolverOrderedStackCandidateSet &c
|
||||
mix_stack = &simulated_surface_to_deep;
|
||||
}
|
||||
const std::array<float, 3> mixed =
|
||||
mix_ordered_stack_with_buffers(colors_with_background, weights, *mix_stack, layer_opacities, mix_model, surface_scatter, beer_lambert_rgb_correction);
|
||||
mix_ordered_stack_with_buffers(colors_with_background,
|
||||
weights,
|
||||
*mix_stack,
|
||||
layer_opacities,
|
||||
mix_model,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
component_roles);
|
||||
const std::array<float, 3> perceptual = oklab_from_srgb(mixed);
|
||||
candidates.rgbs.emplace_back(mixed[0]);
|
||||
candidates.rgbs.emplace_back(mixed[1]);
|
||||
@@ -813,7 +926,9 @@ std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array
|
||||
const std::array<float, 3> &background_rgb,
|
||||
ColorSolverMixModel mix_model,
|
||||
float surface_scatter,
|
||||
bool beer_lambert_rgb_correction)
|
||||
bool beer_lambert_rgb_correction,
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
if (component_colors.empty() || surface_to_deep.empty())
|
||||
return background_rgb;
|
||||
@@ -827,7 +942,9 @@ std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array
|
||||
layer_opacities,
|
||||
mix_model,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction);
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
component_roles);
|
||||
}
|
||||
|
||||
std::array<float, 3> color_solver_oklab_from_srgb(const std::array<float, 3> &rgb)
|
||||
@@ -962,7 +1079,9 @@ std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std
|
||||
size_t candidate_limit,
|
||||
size_t stack_item_limit,
|
||||
float surface_scatter,
|
||||
bool beer_lambert_rgb_correction)
|
||||
bool beer_lambert_rgb_correction,
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
std::ostringstream key;
|
||||
key << component_colors.size();
|
||||
@@ -975,6 +1094,15 @@ std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std
|
||||
std::clamp(std::isfinite(surface_scatter) ? surface_scatter : 0.f, 0.f, 0.5f);
|
||||
key << "|ss" << int(std::lround(safe_surface_scatter * 1000000.f));
|
||||
key << "|bl" << (beer_lambert_rgb_correction ? 1 : 0);
|
||||
key << "|ea" << (td_effective_alpha_correction ? 1 : 0);
|
||||
if (td_effective_alpha_correction) {
|
||||
key << "|role";
|
||||
for (size_t idx = 0; idx < component_colors.size(); ++idx) {
|
||||
const ColorSolverStackComponentRole role =
|
||||
idx < component_roles.size() ? component_roles[idx] : ColorSolverStackComponentRole::Generic;
|
||||
key << ',' << int(stack_role_index(role));
|
||||
}
|
||||
}
|
||||
key << "|bg"
|
||||
<< int(std::lround(clamp01(background_rgb[0]) * 65535.f)) << ','
|
||||
<< int(std::lround(clamp01(background_rgb[1]) * 65535.f)) << ','
|
||||
@@ -1006,7 +1134,9 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
size_t candidate_limit,
|
||||
size_t stack_item_limit,
|
||||
float surface_scatter,
|
||||
bool beer_lambert_rgb_correction)
|
||||
bool beer_lambert_rgb_correction,
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
ColorSolverOrderedStackCandidateSet candidates;
|
||||
int simulated_depth = simulated_stack_depth > 0 ? simulated_stack_depth : stack_depth;
|
||||
@@ -1045,7 +1175,9 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
mix_model,
|
||||
simulated_depth,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction);
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
component_roles);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1094,7 +1226,9 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
mix_model,
|
||||
simulated_depth,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction);
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
component_roles);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1122,7 +1256,9 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
size_t candidate_limit,
|
||||
size_t stack_item_limit,
|
||||
float surface_scatter,
|
||||
bool beer_lambert_rgb_correction)
|
||||
bool beer_lambert_rgb_correction,
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles)
|
||||
{
|
||||
const std::string key =
|
||||
color_solver_ordered_stack_candidate_cache_key(component_colors,
|
||||
@@ -1134,7 +1270,9 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
candidate_limit,
|
||||
stack_item_limit,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction);
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
component_roles);
|
||||
auto it = cache.find(key);
|
||||
if (it != cache.end())
|
||||
return it->second;
|
||||
@@ -1149,7 +1287,9 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
candidate_limit,
|
||||
stack_item_limit,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction)).first->second;
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
component_roles)).first->second;
|
||||
}
|
||||
|
||||
std::vector<uint16_t> solve_color_solver_ordered_stack_for_target(
|
||||
|
||||
@@ -44,6 +44,16 @@ enum class ColorSolverMode : int
|
||||
V2 = 1
|
||||
};
|
||||
|
||||
enum class ColorSolverStackComponentRole : uint8_t
|
||||
{
|
||||
Generic = 0,
|
||||
Cyan = 1,
|
||||
Magenta = 2,
|
||||
Yellow = 3,
|
||||
Black = 4,
|
||||
White = 5
|
||||
};
|
||||
|
||||
struct ColorSolverCandidateSet {
|
||||
struct KdNode {
|
||||
uint32_t candidate_idx { 0 };
|
||||
@@ -112,7 +122,9 @@ std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array
|
||||
const std::array<float, 3> &background_rgb,
|
||||
ColorSolverMixModel mix_model,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false);
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {});
|
||||
std::array<float, 3> color_solver_oklab_from_srgb(const std::array<float, 3> &rgb);
|
||||
std::array<float, 3> color_solver_srgb_from_oklab(const std::array<float, 3> &oklab);
|
||||
|
||||
@@ -139,7 +151,9 @@ std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std
|
||||
size_t candidate_limit = 0,
|
||||
size_t stack_item_limit = 0,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false);
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {});
|
||||
ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<float> &layer_opacities,
|
||||
@@ -150,7 +164,9 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
size_t candidate_limit = 0,
|
||||
size_t stack_item_limit = 0,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false);
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {});
|
||||
const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates(
|
||||
ColorSolverOrderedStackCandidateCache &cache,
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
@@ -162,7 +178,9 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
size_t candidate_limit = 0,
|
||||
size_t stack_item_limit = 0,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false);
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {});
|
||||
std::vector<uint16_t> solve_color_solver_ordered_stack_for_target(
|
||||
const ColorSolverOrderedStackCandidateSet &candidates,
|
||||
const std::array<float, 3> &target_rgb,
|
||||
|
||||
@@ -507,6 +507,7 @@ struct TopSurfaceImageRegionPlan {
|
||||
bool contoning_td_adjustment_enabled = TextureMappingZone::DefaultTopSurfaceContoningTdAdjustmentEnabled;
|
||||
bool contoning_surface_scatter_enabled = TextureMappingZone::DefaultTopSurfaceContoningSurfaceScatterEnabled;
|
||||
bool contoning_beer_lambert_rgb_correction_enabled = TextureMappingZone::DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled;
|
||||
bool contoning_td_effective_alpha_correction_enabled = TextureMappingZone::DefaultTopSurfaceContoningTdEffectiveAlphaCorrectionEnabled;
|
||||
int contoning_generic_solver_mix_model = TextureMappingZone::DefaultGenericSolverMixModel;
|
||||
int contoning_flat_surface_infill_mode = TextureMappingZone::SlicerDefaultTopSurfaceContoningFlatSurfaceInfillMode;
|
||||
};
|
||||
@@ -1176,6 +1177,7 @@ struct TopSurfaceImageContoningStackPlanKey {
|
||||
bool td_adjustment { false };
|
||||
bool surface_scatter { false };
|
||||
bool beer_lambert_rgb_correction { false };
|
||||
bool td_effective_alpha_correction { false };
|
||||
int mix_model { TextureMappingZone::DefaultGenericSolverMixModel };
|
||||
|
||||
bool operator<(const TopSurfaceImageContoningStackPlanKey &rhs) const
|
||||
@@ -1207,6 +1209,7 @@ struct TopSurfaceImageContoningStackPlanKey {
|
||||
td_adjustment,
|
||||
surface_scatter,
|
||||
beer_lambert_rgb_correction,
|
||||
td_effective_alpha_correction,
|
||||
mix_model) <
|
||||
std::tie(rhs.source_layer,
|
||||
rhs.source_layer_id,
|
||||
@@ -1235,6 +1238,7 @@ struct TopSurfaceImageContoningStackPlanKey {
|
||||
rhs.td_adjustment,
|
||||
rhs.surface_scatter,
|
||||
rhs.beer_lambert_rgb_correction,
|
||||
rhs.td_effective_alpha_correction,
|
||||
rhs.mix_model);
|
||||
}
|
||||
};
|
||||
@@ -2640,6 +2644,7 @@ static TopSurfaceImageContoningStackPlanKey top_surface_image_contoning_stack_pl
|
||||
key.td_adjustment = plan.contoning_td_adjustment_enabled;
|
||||
key.surface_scatter = plan.contoning_surface_scatter_enabled;
|
||||
key.beer_lambert_rgb_correction = plan.contoning_beer_lambert_rgb_correction_enabled;
|
||||
key.td_effective_alpha_correction = plan.contoning_td_effective_alpha_correction_enabled;
|
||||
key.mix_model = plan.contoning_generic_solver_mix_model;
|
||||
return key;
|
||||
}
|
||||
@@ -3306,8 +3311,12 @@ static std::vector<TopSurfaceImageRegionPlan> top_surface_image_region_plans(
|
||||
plan.contoning_td_adjustment_enabled = zone->top_surface_contoning_td_adjustment_enabled;
|
||||
plan.contoning_surface_scatter_enabled =
|
||||
plan.contoning_td_adjustment_enabled && zone->top_surface_contoning_surface_scatter_enabled;
|
||||
plan.contoning_td_effective_alpha_correction_enabled =
|
||||
plan.contoning_td_adjustment_enabled && zone->top_surface_contoning_td_effective_alpha_correction_enabled;
|
||||
plan.contoning_beer_lambert_rgb_correction_enabled =
|
||||
plan.contoning_td_adjustment_enabled && zone->top_surface_contoning_beer_lambert_rgb_correction_enabled;
|
||||
plan.contoning_td_adjustment_enabled &&
|
||||
!plan.contoning_td_effective_alpha_correction_enabled &&
|
||||
zone->top_surface_contoning_beer_lambert_rgb_correction_enabled;
|
||||
plan.contoning_generic_solver_mix_model =
|
||||
std::clamp(zone->generic_solver_mix_model,
|
||||
int(TextureMappingZone::GenericSolverPigmentPainter),
|
||||
|
||||
@@ -1164,6 +1164,7 @@ bool TextureMappingZone::operator==(const TextureMappingZone &rhs) const
|
||||
top_surface_contoning_td_adjustment_enabled == rhs.top_surface_contoning_td_adjustment_enabled &&
|
||||
top_surface_contoning_surface_scatter_enabled == rhs.top_surface_contoning_surface_scatter_enabled &&
|
||||
top_surface_contoning_beer_lambert_rgb_correction_enabled == rhs.top_surface_contoning_beer_lambert_rgb_correction_enabled &&
|
||||
top_surface_contoning_td_effective_alpha_correction_enabled == rhs.top_surface_contoning_td_effective_alpha_correction_enabled &&
|
||||
compact_offset_mode == rhs.compact_offset_mode &&
|
||||
use_legacy_fixed_color_mode == rhs.use_legacy_fixed_color_mode &&
|
||||
high_speed_image_texture_sampling == rhs.high_speed_image_texture_sampling &&
|
||||
@@ -1572,6 +1573,8 @@ std::string TextureMappingManager::serialize_entries()
|
||||
zone.top_surface_contoning_surface_scatter_enabled;
|
||||
texture["top_surface_contoning_beer_lambert_rgb_correction_enabled"] =
|
||||
zone.top_surface_contoning_beer_lambert_rgb_correction_enabled;
|
||||
texture["top_surface_contoning_td_effective_alpha_correction_enabled"] =
|
||||
zone.top_surface_contoning_td_effective_alpha_correction_enabled;
|
||||
texture["compact_offset_mode"] = zone.compact_offset_mode;
|
||||
texture["use_legacy_fixed_color_mode"] = zone.use_legacy_fixed_color_mode;
|
||||
texture["high_speed_image_texture_sampling"] = true;
|
||||
@@ -1880,6 +1883,9 @@ void TextureMappingManager::load_entries(const std::string &serialized,
|
||||
zone.top_surface_contoning_beer_lambert_rgb_correction_enabled =
|
||||
texture.value("top_surface_contoning_beer_lambert_rgb_correction_enabled",
|
||||
TextureMappingZone::DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled);
|
||||
zone.top_surface_contoning_td_effective_alpha_correction_enabled =
|
||||
texture.value("top_surface_contoning_td_effective_alpha_correction_enabled",
|
||||
TextureMappingZone::DefaultTopSurfaceContoningTdEffectiveAlphaCorrectionEnabled);
|
||||
zone.apply_top_surface_contoning_experimental_defaults();
|
||||
zone.compact_offset_mode = texture.value("compact_offset_mode", TextureMappingZone::DefaultCompactOffsetMode);
|
||||
zone.use_legacy_fixed_color_mode =
|
||||
|
||||
@@ -70,6 +70,51 @@ bool black_role_component(int filament_color_mode, size_t component_idx, size_t
|
||||
}
|
||||
}
|
||||
|
||||
ColorSolverStackComponentRole cmy_component_role(int filament_color_mode, size_t component_idx, size_t component_count)
|
||||
{
|
||||
switch (std::clamp(filament_color_mode,
|
||||
int(TextureMappingZone::FilamentColorAny),
|
||||
int(TextureMappingZone::FilamentColorRGBKW))) {
|
||||
case int(TextureMappingZone::FilamentColorCMY):
|
||||
if (component_count == 3) {
|
||||
if (component_idx == 0)
|
||||
return ColorSolverStackComponentRole::Cyan;
|
||||
if (component_idx == 1)
|
||||
return ColorSolverStackComponentRole::Magenta;
|
||||
if (component_idx == 2)
|
||||
return ColorSolverStackComponentRole::Yellow;
|
||||
}
|
||||
break;
|
||||
case int(TextureMappingZone::FilamentColorCMYK):
|
||||
if (component_count == 4) {
|
||||
if (component_idx == 0)
|
||||
return ColorSolverStackComponentRole::Cyan;
|
||||
if (component_idx == 1)
|
||||
return ColorSolverStackComponentRole::Magenta;
|
||||
if (component_idx == 2)
|
||||
return ColorSolverStackComponentRole::Yellow;
|
||||
if (component_idx == 3)
|
||||
return ColorSolverStackComponentRole::Black;
|
||||
}
|
||||
break;
|
||||
case int(TextureMappingZone::FilamentColorCMYW):
|
||||
if (component_count == 4) {
|
||||
if (component_idx == 0)
|
||||
return ColorSolverStackComponentRole::Cyan;
|
||||
if (component_idx == 1)
|
||||
return ColorSolverStackComponentRole::Magenta;
|
||||
if (component_idx == 2)
|
||||
return ColorSolverStackComponentRole::Yellow;
|
||||
if (component_idx == 3)
|
||||
return ColorSolverStackComponentRole::White;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ColorSolverStackComponentRole::Generic;
|
||||
}
|
||||
|
||||
bool is_black_color_filament(const PrintConfig &config, unsigned int component_id)
|
||||
{
|
||||
ColorRGB color;
|
||||
@@ -270,6 +315,15 @@ std::optional<std::array<float, 3>> texture_mapping_contoning_component_colors(
|
||||
return out.front();
|
||||
}
|
||||
|
||||
std::vector<ColorSolverStackComponentRole> texture_mapping_contoning_component_roles(const TextureMappingZone &zone,
|
||||
size_t component_count)
|
||||
{
|
||||
std::vector<ColorSolverStackComponentRole> roles(component_count, ColorSolverStackComponentRole::Generic);
|
||||
for (size_t idx = 0; idx < component_count; ++idx)
|
||||
roles[idx] = cmy_component_role(zone.filament_color_mode, idx, component_count);
|
||||
return roles;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> texture_mapping_contoning_components_bottom_to_top(
|
||||
const TextureMappingZone &zone,
|
||||
const PrintConfig &config,
|
||||
@@ -353,8 +407,12 @@ TextureMappingContoningSolver::TextureMappingContoningSolver(const TextureMappin
|
||||
{
|
||||
m_mix_model = color_solver_mix_model_from_index(zone.generic_solver_mix_model);
|
||||
m_td_adjustment_enabled = zone.top_surface_contoning_td_adjustment_enabled;
|
||||
m_td_effective_alpha_correction_enabled =
|
||||
m_td_adjustment_enabled && zone.top_surface_contoning_td_effective_alpha_correction_enabled;
|
||||
m_beer_lambert_rgb_correction_enabled =
|
||||
m_td_adjustment_enabled && zone.top_surface_contoning_beer_lambert_rgb_correction_enabled;
|
||||
m_td_adjustment_enabled &&
|
||||
!m_td_effective_alpha_correction_enabled &&
|
||||
zone.top_surface_contoning_beer_lambert_rgb_correction_enabled;
|
||||
m_layer_height_mm = std::isfinite(layer_height_mm) && layer_height_mm > 0.f ? layer_height_mm : 0.2f;
|
||||
if (!std::isfinite(m_layer_height_mm) || m_layer_height_mm <= 0.f)
|
||||
m_layer_height_mm = 0.2f;
|
||||
@@ -370,6 +428,7 @@ TextureMappingContoningSolver::TextureMappingContoningSolver(const TextureMappin
|
||||
m_component_ids.clear();
|
||||
if (m_component_ids.empty())
|
||||
return;
|
||||
m_component_roles = texture_mapping_contoning_component_roles(zone, m_component_ids.size());
|
||||
|
||||
m_component_luminance.reserve(m_component_ids.size());
|
||||
for (const unsigned int id : m_component_ids)
|
||||
@@ -488,7 +547,9 @@ std::optional<std::array<float, 3>> TextureMappingContoningSolver::stack_rgb(
|
||||
m_background_rgb,
|
||||
m_mix_model,
|
||||
m_surface_scatter,
|
||||
m_beer_lambert_rgb_correction_enabled);
|
||||
m_beer_lambert_rgb_correction_enabled,
|
||||
m_td_effective_alpha_correction_enabled,
|
||||
m_component_roles);
|
||||
}
|
||||
|
||||
void TextureMappingContoningSolver::arrange_stack_for_light_path(std::vector<unsigned int> &bottom_to_top,
|
||||
@@ -589,7 +650,9 @@ TextureMappingContoningStack TextureMappingContoningSolver::solve(const std::arr
|
||||
MAX_TD_ORDERED_CONTONING_CANDIDATES,
|
||||
MAX_TD_ORDERED_CONTONING_STACK_ITEMS,
|
||||
m_surface_scatter,
|
||||
m_beer_lambert_rgb_correction_enabled);
|
||||
m_beer_lambert_rgb_correction_enabled,
|
||||
m_td_effective_alpha_correction_enabled,
|
||||
m_component_roles);
|
||||
}
|
||||
const std::vector<uint16_t> surface_to_deep =
|
||||
solve_color_solver_ordered_stack_for_target(*ordered_candidates, target_rgb, ColorSolverMode::V2);
|
||||
|
||||
@@ -69,6 +69,8 @@ private:
|
||||
ColorSolverMixModel m_mix_model { ColorSolverMixModel::PigmentPainter };
|
||||
bool m_td_adjustment_enabled { false };
|
||||
bool m_beer_lambert_rgb_correction_enabled { false };
|
||||
bool m_td_effective_alpha_correction_enabled { false };
|
||||
std::vector<ColorSolverStackComponentRole> m_component_roles;
|
||||
mutable std::map<int, std::vector<Candidate>> m_candidates_by_depth;
|
||||
mutable std::shared_ptr<ColorSolverOrderedStackCandidateCache> m_ordered_candidate_cache { std::make_shared<ColorSolverOrderedStackCandidateCache>() };
|
||||
mutable std::shared_ptr<std::mutex> m_ordered_candidate_cache_mutex { std::make_shared<std::mutex>() };
|
||||
@@ -85,6 +87,8 @@ bool texture_mapping_contoning_normal_eligible(float normal_z, float threshold_d
|
||||
std::optional<std::array<float, 3>> texture_mapping_contoning_component_colors(const PrintConfig &config,
|
||||
const std::vector<unsigned int> &component_ids,
|
||||
std::vector<std::array<float, 3>> &out);
|
||||
std::vector<ColorSolverStackComponentRole> texture_mapping_contoning_component_roles(const TextureMappingZone &zone,
|
||||
size_t component_count);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/TextureMapping.hpp"
|
||||
#include "libslic3r/TextureMappingContoning.hpp"
|
||||
#include "libslic3r/ColorSolver.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -96,6 +97,7 @@ struct TexturePreviewSimulationSettings
|
||||
bool contoning_flat_surface_pattern_blend = false;
|
||||
bool contoning_flat_surface_td_adjustment = false;
|
||||
bool contoning_flat_surface_beer_lambert_rgb_correction = false;
|
||||
bool contoning_flat_surface_td_effective_alpha_correction = false;
|
||||
int contoning_flat_surface_pattern_filaments = TextureMappingZone::DefaultTopSurfaceContoningPatternFilaments;
|
||||
bool simulate_top_surface_lod = false;
|
||||
float top_surface_lod_pitch_mm = 0.f;
|
||||
@@ -106,6 +108,7 @@ struct TexturePreviewSimulationSettings
|
||||
float minimum_visibility_offset_factor = 0.f;
|
||||
std::vector<unsigned int> component_ids;
|
||||
std::vector<std::array<float, 3>> component_colors;
|
||||
std::vector<ColorSolverStackComponentRole> component_roles;
|
||||
std::vector<float> component_strength_factors;
|
||||
std::vector<float> component_minimum_offset_factors;
|
||||
std::vector<size_t> semantic_component_indices;
|
||||
@@ -2522,7 +2525,9 @@ std::array<float, 3> contoning_flat_surface_rgb_for_texture_preview(
|
||||
settings.contoning_flat_surface_background_rgb,
|
||||
color_solver_mix_model_from_index(settings.generic_solver_mix_model),
|
||||
settings.contoning_flat_surface_surface_scatter,
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction);
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction,
|
||||
settings.contoning_flat_surface_td_effective_alpha_correction,
|
||||
settings.component_roles);
|
||||
}
|
||||
}
|
||||
if (!candidates.empty()) {
|
||||
@@ -2679,7 +2684,11 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
|
||||
zone->top_surface_contoning_active() && zone->top_surface_contoning_td_adjustment_enabled;
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction =
|
||||
settings.contoning_flat_surface_td_adjustment &&
|
||||
!zone->top_surface_contoning_td_effective_alpha_correction_enabled &&
|
||||
zone->top_surface_contoning_beer_lambert_rgb_correction_enabled;
|
||||
settings.contoning_flat_surface_td_effective_alpha_correction =
|
||||
settings.contoning_flat_surface_td_adjustment &&
|
||||
zone->top_surface_contoning_td_effective_alpha_correction_enabled;
|
||||
settings.contoning_flat_surface_surface_scatter =
|
||||
settings.contoning_flat_surface_td_adjustment &&
|
||||
zone->top_surface_contoning_surface_scatter_enabled ?
|
||||
@@ -2696,6 +2705,7 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
|
||||
settings.component_ids = TextureMappingManager::effective_texture_component_ids(*zone, num_physical, physical_colors);
|
||||
if (settings.component_ids.empty())
|
||||
return std::nullopt;
|
||||
settings.component_roles = texture_mapping_contoning_component_roles(*zone, settings.component_ids.size());
|
||||
settings.simulate_top_surface_lod =
|
||||
texture_preview_simulate_top_surface_lod() &&
|
||||
zone->top_surface_image_printing_enabled;
|
||||
@@ -2739,6 +2749,7 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
|
||||
if (settings.contoning_flat_surface_layer_opacities.size() != settings.component_colors.size()) {
|
||||
settings.contoning_flat_surface_td_adjustment = false;
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction = false;
|
||||
settings.contoning_flat_surface_td_effective_alpha_correction = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2779,6 +2790,7 @@ size_t texture_preview_simulation_signature(const ModelVolume &model_volume,
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_pattern_blend ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_td_adjustment ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_beer_lambert_rgb_correction ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_td_effective_alpha_correction ? 1 : 0));
|
||||
if (settings.contoning_flat_surface_quantization) {
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_pattern_filaments));
|
||||
mix(std::hash<int>{}(settings.simulate_top_surface_lod ? 1 : 0));
|
||||
@@ -2790,6 +2802,9 @@ size_t texture_preview_simulation_signature(const ModelVolume &model_volume,
|
||||
mix(std::hash<int>{}(int(std::lround(settings.contoning_flat_surface_surface_scatter * 1000000.f))));
|
||||
for (const float opacity : settings.contoning_flat_surface_layer_opacities)
|
||||
mix(std::hash<int>{}(int(std::lround(opacity * 1000000.f))));
|
||||
if (settings.contoning_flat_surface_td_effective_alpha_correction)
|
||||
for (const ColorSolverStackComponentRole role : settings.component_roles)
|
||||
mix(std::hash<int>{}(int(role)));
|
||||
}
|
||||
mix(std::hash<int>{}(int(std::lround(settings.contrast_pct * 100.f))));
|
||||
mix(std::hash<int>{}(int(std::lround(settings.tone_gamma * 1000.f))));
|
||||
@@ -2879,7 +2894,9 @@ TexturePreviewSimulationResult build_simulated_texture_preview_result(size_t sig
|
||||
k_contoning_flat_surface_preview_max_ordered_candidates,
|
||||
k_contoning_flat_surface_preview_max_ordered_stack_items,
|
||||
settings.contoning_flat_surface_surface_scatter,
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction) :
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction,
|
||||
settings.contoning_flat_surface_td_effective_alpha_correction,
|
||||
settings.component_roles) :
|
||||
ColorSolverOrderedStackCandidateSet{};
|
||||
const std::vector<TexturePreviewMixCandidate> contoning_flat_surface_candidates =
|
||||
use_contoning_flat_surface_quantization && contoning_flat_surface_ordered_candidates.empty() ?
|
||||
@@ -5694,6 +5711,7 @@ static size_t texture_preview_settings_signature_impl(size_t num_physical,
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_td_adjustment_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_surface_scatter_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_beer_lambert_rgb_correction_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_td_effective_alpha_correction_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.nonlinear_offset_adjustment ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.compact_offset_mode ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.use_legacy_fixed_color_mode ? 1 : 0));
|
||||
@@ -5849,6 +5867,7 @@ static void texture_preview_mix_zone_baked_model_settings(size_t &signature,
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_td_adjustment_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_surface_scatter_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_beer_lambert_rgb_correction_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.top_surface_contoning_td_effective_alpha_correction_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.nonlinear_offset_adjustment ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.compact_offset_mode ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.use_legacy_fixed_color_mode ? 1 : 0));
|
||||
|
||||
@@ -2108,6 +2108,7 @@ public:
|
||||
bool top_surface_contoning_td_adjustment_enabled,
|
||||
bool top_surface_contoning_surface_scatter_enabled,
|
||||
bool top_surface_contoning_beer_lambert_rgb_correction_enabled,
|
||||
bool top_surface_contoning_td_effective_alpha_correction_enabled,
|
||||
const TextureMappingZoneShellUsageSummary &top_surface_contoning_shell_usage,
|
||||
const TextureMappingManager &texture_mapping_zones,
|
||||
const TextureMappingGlobalSettings &global_settings,
|
||||
@@ -2806,6 +2807,15 @@ public:
|
||||
0,
|
||||
wxEXPAND | wxTOP | wxBOTTOM,
|
||||
gap / 2);
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox =
|
||||
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("TD Effective Alpha correction"));
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->SetValue(top_surface_contoning_td_effective_alpha_correction_enabled);
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->SetMinSize(
|
||||
wxSize(-1, std::max(m_top_surface_contoning_td_effective_alpha_correction_checkbox->GetBestSize().GetHeight(), FromDIP(24))));
|
||||
contoning_checkboxes_root->Add(m_top_surface_contoning_td_effective_alpha_correction_checkbox,
|
||||
0,
|
||||
wxEXPAND | wxTOP | wxBOTTOM,
|
||||
gap / 2);
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox =
|
||||
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("RGB Beer-Lambert correction"));
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox->SetValue(top_surface_contoning_beer_lambert_rgb_correction_enabled);
|
||||
@@ -3002,6 +3012,12 @@ public:
|
||||
queue_top_surface_contoning_message_update(true);
|
||||
});
|
||||
}
|
||||
if (m_top_surface_contoning_td_effective_alpha_correction_checkbox != nullptr) {
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &) {
|
||||
update_top_surface_image_options_visibility(false);
|
||||
queue_top_surface_contoning_message_update(true);
|
||||
});
|
||||
}
|
||||
if (m_top_surface_contoning_beer_lambert_rgb_correction_checkbox != nullptr) {
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &) {
|
||||
queue_top_surface_contoning_message_update(true);
|
||||
@@ -3508,10 +3524,18 @@ public:
|
||||
bool top_surface_contoning_beer_lambert_rgb_correction_enabled() const
|
||||
{
|
||||
return top_surface_contoning_td_adjustment_enabled() &&
|
||||
!top_surface_contoning_td_effective_alpha_correction_enabled() &&
|
||||
(m_top_surface_contoning_beer_lambert_rgb_correction_checkbox == nullptr ?
|
||||
TextureMappingZone::DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled :
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox->GetValue());
|
||||
}
|
||||
bool top_surface_contoning_td_effective_alpha_correction_enabled() const
|
||||
{
|
||||
return top_surface_contoning_td_adjustment_enabled() &&
|
||||
(m_top_surface_contoning_td_effective_alpha_correction_checkbox == nullptr ?
|
||||
TextureMappingZone::DefaultTopSurfaceContoningTdEffectiveAlphaCorrectionEnabled :
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->GetValue());
|
||||
}
|
||||
bool minimum_visibility_offset_enabled() const
|
||||
{
|
||||
return m_minimum_visibility_offset_checkbox && m_minimum_visibility_offset_checkbox->GetValue();
|
||||
@@ -3854,7 +3878,8 @@ private:
|
||||
if (safe_strength <= surface_scatter)
|
||||
return 1;
|
||||
const float remaining = std::clamp((1.f - safe_strength) / (1.f - surface_scatter), 1e-6f, 0.999999f);
|
||||
const float layers = (td_mm / (2.f * layer_height)) * (std::log(remaining) / std::log(0.05f));
|
||||
const float density_scale = top_surface_contoning_td_effective_alpha_correction_enabled() ? 0.6761904762f : 1.f;
|
||||
const float layers = (td_mm / (2.f * layer_height * density_scale)) * (std::log(remaining) / std::log(0.05f));
|
||||
return std::max(1, int(std::ceil(layers)));
|
||||
}
|
||||
|
||||
@@ -4314,8 +4339,20 @@ private:
|
||||
contoning &&
|
||||
m_top_surface_contoning_td_adjustment_checkbox != nullptr &&
|
||||
m_top_surface_contoning_td_adjustment_checkbox->GetValue();
|
||||
const bool td_effective_alpha =
|
||||
td_adjustment &&
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox != nullptr &&
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->GetValue();
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox->Show(contoning);
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox->Enable(td_adjustment);
|
||||
m_top_surface_contoning_beer_lambert_rgb_correction_checkbox->Enable(td_adjustment && !td_effective_alpha);
|
||||
}
|
||||
if (m_top_surface_contoning_td_effective_alpha_correction_checkbox != nullptr) {
|
||||
const bool td_adjustment =
|
||||
contoning &&
|
||||
m_top_surface_contoning_td_adjustment_checkbox != nullptr &&
|
||||
m_top_surface_contoning_td_adjustment_checkbox->GetValue();
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->Show(contoning);
|
||||
m_top_surface_contoning_td_effective_alpha_correction_checkbox->Enable(td_adjustment);
|
||||
}
|
||||
if (m_top_surface_contoning_only_one_perimeter_around_shell_infill_checkbox != nullptr) {
|
||||
m_top_surface_contoning_only_one_perimeter_around_shell_infill_checkbox->Show(contoning);
|
||||
@@ -4465,6 +4502,7 @@ private:
|
||||
wxCheckBox *m_top_surface_contoning_td_adjustment_checkbox {nullptr};
|
||||
wxCheckBox *m_top_surface_contoning_surface_scatter_checkbox {nullptr};
|
||||
wxCheckBox *m_top_surface_contoning_beer_lambert_rgb_correction_checkbox {nullptr};
|
||||
wxCheckBox *m_top_surface_contoning_td_effective_alpha_correction_checkbox {nullptr};
|
||||
wxCheckBox *m_use_legacy_fixed_color_mode_checkbox {nullptr};
|
||||
wxCheckBox *m_minimum_visibility_offset_checkbox {nullptr};
|
||||
wxSpinCtrl *m_minimum_visibility_offset_spin {nullptr};
|
||||
@@ -9497,6 +9535,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
updated.top_surface_contoning_td_adjustment_enabled,
|
||||
updated.top_surface_contoning_surface_scatter_enabled,
|
||||
updated.top_surface_contoning_beer_lambert_rgb_correction_enabled,
|
||||
updated.top_surface_contoning_td_effective_alpha_correction_enabled,
|
||||
shell_usage,
|
||||
bundle->texture_mapping_zones,
|
||||
bundle->texture_mapping_global_settings,
|
||||
@@ -9579,6 +9618,8 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
dlg.top_surface_contoning_surface_scatter_enabled();
|
||||
updated.top_surface_contoning_beer_lambert_rgb_correction_enabled =
|
||||
dlg.top_surface_contoning_beer_lambert_rgb_correction_enabled();
|
||||
updated.top_surface_contoning_td_effective_alpha_correction_enabled =
|
||||
dlg.top_surface_contoning_td_effective_alpha_correction_enabled();
|
||||
if (updated.top_surface_image_printing_enabled &&
|
||||
updated.top_surface_image_printing_method == int(TextureMappingZone::TopSurfaceImageContoning)) {
|
||||
updated.modulation_mode = int(TextureMappingZone::ModulationPerimeterPathV2);
|
||||
|
||||
Reference in New Issue
Block a user