Move overhang amount contrast to experimental settings

This commit is contained in:
sentientstardust
2026-06-10 01:40:11 +01:00
parent 0493de8084
commit 4084c0a8d8
11 changed files with 150 additions and 84 deletions

View File

@@ -5765,7 +5765,8 @@ static std::optional<TopSurfaceImageContoningSourceContext> top_surface_image_co
zone.generic_solver_mix_model),
sample_z_mm,
top_surface_image_contoning_texture_sample_pitch_mm(plan),
raw_top_surface_depth_override);
raw_top_surface_depth_override,
TextureMappingZone::DefaultFilamentOverhangContrastPct);
if (!offset_context)
return std::nullopt;
@@ -12305,7 +12306,11 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree,
float(this->height),
std::nullopt,
surface_fill.params.texture_mapping_top_surface_min_width_mm,
background);
background,
std::nullopt,
std::nullopt,
std::nullopt,
TextureMappingZone::DefaultFilamentOverhangContrastPct);
}
}

View File

@@ -6887,7 +6887,7 @@ static float apply_texture_tone_gamma_for_gcode(float channel, float tone_gamma)
return clamp01f_for_gcode(std::pow(safe_channel, 1.f / safe_gamma));
}
static void apply_texture_contrast_to_mapped_components_for_gcode(std::vector<float> &component_weights,
static void apply_filament_overhang_contrast_to_mapped_components_for_gcode(std::vector<float> &component_weights,
float contrast_factor,
size_t mapped_component_count)
{
@@ -6906,7 +6906,7 @@ static void apply_texture_contrast_to_mapped_components_for_gcode(std::vector<fl
}
}
static std::array<float, 3> apply_texture_contrast_to_rgb_for_gcode(const std::array<float, 3> &rgb, float contrast_factor)
static std::array<float, 3> apply_filament_overhang_contrast_to_rgb_for_gcode(const std::array<float, 3> &rgb, float contrast_factor)
{
const float clamped_contrast = std::clamp(contrast_factor, 0.25f, 3.f);
if (std::abs(clamped_contrast - 1.f) <= 1e-5f)
@@ -8277,7 +8277,7 @@ static VertexColorOverhangWeightField build_vertex_color_weight_field_for_gcode(
const GCodeGenericMixCandidateSet *calibrated_side_candidates,
std::map<std::string, GCodeGenericMixCandidateSet> *generic_mix_candidate_cache,
std::map<const PrintObject*, GCodeUVTextureTriangleCache> *uv_texture_triangle_cache,
float texture_contrast_pct,
float texture_filament_overhang_contrast_pct,
float texture_tone_gamma,
bool layer_aware_weighting,
float layer_z_mm,
@@ -8310,7 +8310,7 @@ static VertexColorOverhangWeightField build_vertex_color_weight_field_for_gcode(
const bool use_layer_weighting = layer_aware_weighting && std::isfinite(layer_z_mm);
const float safe_layer_z_falloff_mm = std::max(layer_z_falloff_mm, 1e-3f);
const float contrast_factor = std::clamp(texture_contrast_pct, 25.f, 300.f) / 100.f;
const float contrast_factor = std::clamp(texture_filament_overhang_contrast_pct, 25.f, 300.f) / 100.f;
const float tone_gamma =
(!std::isfinite(texture_tone_gamma) || texture_tone_gamma <= 0.f) ? 1.f : std::clamp(texture_tone_gamma, 0.5f, 3.f);
const float physical_sample_pitch_mm =
@@ -8849,7 +8849,7 @@ static VertexColorOverhangWeightField build_vertex_color_weight_field_for_gcode(
target[1] = apply_texture_tone_gamma_for_gcode(target[1], tone_gamma);
target[2] = apply_texture_tone_gamma_for_gcode(target[2], tone_gamma);
}
target = apply_texture_contrast_to_rgb_for_gcode(target, contrast_factor);
target = apply_filament_overhang_contrast_to_rgb_for_gcode(target, contrast_factor);
return effective_solver_mode == int(TextureMappingZone::GenericSolverRGB) ?
target :
oklab_from_srgb_for_gcode(target);
@@ -9076,7 +9076,7 @@ static VertexColorOverhangWeightField build_vertex_color_weight_field_for_gcode(
}
if (!has_binary_dither && !has_raw_component_weights && !has_calibrated_side_candidates && std::abs(contrast_factor - 1.f) > 1e-5f)
apply_texture_contrast_to_mapped_components_for_gcode(desired, contrast_factor, mapped_component_count);
apply_filament_overhang_contrast_to_mapped_components_for_gcode(desired, contrast_factor, mapped_component_count);
for (size_t component_idx = 0; component_idx < component_count; ++component_idx) {
const float v = clamp01f_for_gcode(desired[component_idx]);
@@ -9557,7 +9557,6 @@ std::optional<PreferredSeamPoint> GCode::texture_mapping_seam_hiding_hint(const
const bool compact_offset_mode = halftone_dithering_enabled ? false : zone->compact_offset_mode || dithering_enabled;
const bool nonlinear_offset_adjustment = zone->nonlinear_offset_adjustment;
const bool use_legacy_fixed_color_mode = zone->use_legacy_fixed_color_mode;
const float texture_contrast_pct = std::clamp(zone->contrast_pct, 25.f, 300.f);
const float texture_tone_gamma =
(!std::isfinite(zone->tone_gamma) || zone->tone_gamma <= 0.f) ?
1.f :
@@ -9568,6 +9567,10 @@ std::optional<PreferredSeamPoint> GCode::texture_mapping_seam_hiding_hint(const
vertex_color_match_mode &&
!raw_texture_mapping_mode &&
zone->transmission_distance_calibration_mode == int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample);
const float texture_filament_overhang_contrast_pct =
calibrated_side_mode ?
TextureMappingZone::DefaultFilamentOverhangContrastPct :
std::clamp(zone->filament_overhang_contrast_pct, 25.f, 300.f);
std::vector<float> component_strength_factors;
component_strength_factors.reserve(component_ids.size());
std::vector<float> component_minimum_offset_factors;
@@ -9652,7 +9655,7 @@ std::optional<PreferredSeamPoint> GCode::texture_mapping_seam_hiding_hint(const
for (const float minimum_offset_factor : component_minimum_offset_factors)
component_key_stream << "|mo" << int(std::lround(std::clamp(minimum_offset_factor, 0.f, 1.f) * 1000.f));
component_key_stream << "|lf" << (use_legacy_fixed_color_mode ? 1 : 0);
component_key_stream << "|ct" << int(std::lround(texture_contrast_pct));
component_key_stream << "|ct" << int(std::lround(texture_filament_overhang_contrast_pct));
component_key_stream << "|tg" << int(std::lround(texture_tone_gamma * 100.f));
component_key_stream << "|hr" << (high_resolution_texture_sampling ? 1 : 0);
component_key_stream << "|hs" << (high_speed_image_texture_sampling ? 1 : 0);
@@ -9731,7 +9734,7 @@ std::optional<PreferredSeamPoint> GCode::texture_mapping_seam_hiding_hint(const
calibrated_side_candidates_ptr,
&m_generic_solver_mix_candidate_cache,
&m_uv_texture_triangle_cache,
texture_contrast_pct,
texture_filament_overhang_contrast_pct,
texture_tone_gamma,
true,
float(layer->print_z),

View File

@@ -56,7 +56,7 @@ struct PrimeTowerTextureRenderSettings
int generic_solver_lookup_mode = TextureMappingZone::DefaultGenericSolverLookupMode;
int generic_solver_mode = TextureMappingZone::DefaultGenericSolverMode;
int generic_solver_mix_model = TextureMappingZone::DefaultGenericSolverMixModel;
float contrast_pct = 100.f;
float filament_overhang_contrast_pct = TextureMappingZone::DefaultFilamentOverhangContrastPct;
float tone_gamma = 1.f;
float global_strength = 1.f;
float max_line_width = 0.95f;
@@ -573,7 +573,7 @@ private:
return {};
}
static void apply_contrast(std::vector<float> &weights, float contrast_factor, size_t mapped_count)
static void apply_filament_overhang_contrast(std::vector<float> &weights, float contrast_factor, size_t mapped_count)
{
const size_t count = std::min(mapped_count, weights.size());
if (count == 0)
@@ -638,7 +638,7 @@ private:
if (weights.size() != component_ids.size() || component_idx >= weights.size())
return sample_image_tool_visibility(tool, u, v, back, solver_tools);
apply_contrast(weights, std::clamp(contrast_pct, 25.f, 300.f) / 100.f, mapped_count);
apply_filament_overhang_contrast(weights, std::clamp(filament_overhang_contrast_pct, 25.f, 300.f) / 100.f, mapped_count);
return std::clamp(weights[component_idx], 0.f, 1.f);
}

View File

@@ -505,8 +505,25 @@ static std::optional<PerimeterTextureRecolorSampler> perimeter_texture_make_reco
if (num_physical == 0)
return std::nullopt;
const std::optional<float> filament_overhang_contrast_override =
zone.top_surface_contoning_perimeters_active() ?
std::optional<float>(TextureMappingZone::DefaultFilamentOverhangContrastPct) :
std::nullopt;
std::optional<TextureMappingOffsetContext> context =
build_texture_mapping_offset_context_for_layer(*print_object, *layer, zone, texture_zone_id, 0, base_outer_width_mm);
build_texture_mapping_offset_context_for_layer(*print_object,
*layer,
zone,
texture_zone_id,
0,
base_outer_width_mm,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
filament_overhang_contrast_override);
if (!context || print->canceled() || context->component_ids.empty())
return std::nullopt;
@@ -2598,7 +2615,17 @@ static SurfaceCollection perimeter_path_modulated_surfaces(const LayerRegion
zone,
texture_zone_id,
0,
base_outer_width_mm);
base_outer_width_mm,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
std::nullopt,
zone.top_surface_contoning_perimeters_active() ?
std::optional<float>(TextureMappingZone::DefaultFilamentOverhangContrastPct) :
std::nullopt);
if (!built_context)
return slices;
context = &*built_context;

View File

@@ -3510,7 +3510,10 @@ void Print::_make_wipe_tower()
texture.generic_solver_lookup_mode = settings_zone->generic_solver_lookup_mode;
texture.generic_solver_mode = settings_zone->generic_solver_mode;
texture.generic_solver_mix_model = settings_zone->generic_solver_mix_model;
texture.contrast_pct = settings_zone->contrast_pct;
texture.filament_overhang_contrast_pct =
settings_zone->transmission_distance_calibration_mode == int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample) ?
TextureMappingZone::DefaultFilamentOverhangContrastPct :
settings_zone->filament_overhang_contrast_pct;
texture.tone_gamma = settings_zone->tone_gamma;
texture.filament_strengths_pct = settings_zone->filament_strengths_pct;
texture.filament_minimum_offsets_pct = settings_zone->filament_minimum_offsets_pct;

View File

@@ -2451,7 +2451,7 @@ bool TextureMappingZone::operator==(const TextureMappingZone &rhs) const
dithering_method == rhs.dithering_method &&
std::abs(dithering_resolution_mm - rhs.dithering_resolution_mm) <= eps &&
std::abs(halftone_dot_size_mm - rhs.halftone_dot_size_mm) <= eps &&
std::abs(contrast_pct - rhs.contrast_pct) <= eps &&
std::abs(filament_overhang_contrast_pct - rhs.filament_overhang_contrast_pct) <= eps &&
high_resolution_sampling == rhs.high_resolution_sampling &&
std::abs(tone_gamma - rhs.tone_gamma) <= eps &&
transmission_distance_calibration_mode == rhs.transmission_distance_calibration_mode &&
@@ -2894,7 +2894,11 @@ std::string TextureMappingManager::serialize_entries()
std::clamp(finite_or(zone.halftone_dot_size_mm, TextureMappingZone::DefaultHalftoneDotSizeMm),
TextureMappingZone::MinHalftoneDotSizeMm,
TextureMappingZone::MaxHalftoneDotSizeMm);
texture["contrast_pct"] = std::clamp(finite_or(zone.contrast_pct, 100.f), 25.f, 300.f);
texture["filament_overhang_contrast_pct"] =
std::clamp(finite_or(zone.filament_overhang_contrast_pct,
TextureMappingZone::DefaultFilamentOverhangContrastPct),
25.f,
300.f);
texture["high_resolution_sampling"] = true;
texture["tone_gamma"] = normalize_tone_gamma(zone.tone_gamma);
texture["transmission_distance_calibration"] =
@@ -3284,7 +3288,12 @@ void TextureMappingManager::load_entries(const std::string &serialized,
TextureMappingZone::MaxHalftoneDotSizeMm);
if (zone.dithering_enabled)
zone.compact_offset_mode = true;
zone.contrast_pct = std::clamp(texture.value("contrast_pct", 100.f), 25.f, 300.f);
zone.filament_overhang_contrast_pct =
std::clamp(texture.value("filament_overhang_contrast_pct",
texture.value("contrast_pct",
TextureMappingZone::DefaultFilamentOverhangContrastPct)),
25.f,
300.f);
zone.high_resolution_sampling = true;
zone.tone_gamma = normalize_tone_gamma(texture.value("tone_gamma", 1.f));
zone.transmission_distance_calibration_mode = transmission_distance_calibration_mode_from_json(texture);

View File

@@ -259,7 +259,7 @@ struct TextureMappingZone
static constexpr float MinHalftoneDotSizeMm = 0.08f;
static constexpr float MaxHalftoneDotSizeMm = 50.f;
static constexpr float DefaultHalftoneDotSizeMm = 2.f;
static constexpr float DefaultContrastPct = 100.f;
static constexpr float DefaultFilamentOverhangContrastPct = 100.f;
static constexpr bool DefaultHighResolutionSampling = true;
static constexpr float DefaultToneGamma = 1.f;
static constexpr int DefaultTransmissionDistanceCalibrationMode = int(TDCalibrationAbsolute);
@@ -533,7 +533,7 @@ struct TextureMappingZone
int dithering_method = DefaultDitheringMethod;
float dithering_resolution_mm = DefaultDitheringResolutionMm;
float halftone_dot_size_mm = DefaultHalftoneDotSizeMm;
float contrast_pct = DefaultContrastPct;
float filament_overhang_contrast_pct = DefaultFilamentOverhangContrastPct;
bool high_resolution_sampling = DefaultHighResolutionSampling;
float tone_gamma = DefaultToneGamma;
int transmission_distance_calibration_mode = DefaultTransmissionDistanceCalibrationMode;
@@ -840,7 +840,7 @@ struct TextureMappingZone
dithering_method = DefaultDitheringMethod;
dithering_resolution_mm = DefaultDitheringResolutionMm;
halftone_dot_size_mm = DefaultHalftoneDotSizeMm;
contrast_pct = DefaultContrastPct;
filament_overhang_contrast_pct = DefaultFilamentOverhangContrastPct;
high_resolution_sampling = DefaultHighResolutionSampling;
tone_gamma = DefaultToneGamma;
transmission_distance_calibration_mode = DefaultTransmissionDistanceCalibrationMode;

View File

@@ -1013,7 +1013,7 @@ float apply_texture_tone_gamma(float channel, float tone_gamma)
return clamp01f(std::pow(safe_channel, 1.f / safe_gamma));
}
void apply_texture_contrast_to_components(std::vector<float> &component_weights,
void apply_filament_overhang_contrast_to_components(std::vector<float> &component_weights,
float contrast_factor,
size_t mapped_component_count)
{
@@ -1032,7 +1032,7 @@ void apply_texture_contrast_to_components(std::vector<float> &component_weights,
}
}
std::array<float, 3> apply_texture_contrast_to_rgb(const std::array<float, 3> &rgb, float contrast_factor)
std::array<float, 3> apply_filament_overhang_contrast_to_rgb(const std::array<float, 3> &rgb, float contrast_factor)
{
const float clamped_contrast = std::clamp(contrast_factor, 0.25f, 3.f);
if (std::abs(clamped_contrast - 1.f) <= 1e-5f)
@@ -1058,7 +1058,7 @@ std::array<float, 3> texture_sample_target_rgb(const WeightedTextureSample &samp
target[1] = apply_texture_tone_gamma(target[1], tone_gamma);
target[2] = apply_texture_tone_gamma(target[2], tone_gamma);
}
return apply_texture_contrast_to_rgb(target, contrast_factor);
return apply_filament_overhang_contrast_to_rgb(target, contrast_factor);
}
std::array<float, 3> generic_solver_oklab_axis_weights(const std::array<float, 3> &target_oklab)
@@ -1696,7 +1696,7 @@ std::vector<float> component_weights_for_sample(const WeightedTextureSample &sam
}
if (!has_raw_component_weights && !has_calibrated_side_candidates && std::abs(contrast_factor - 1.f) > 1e-5f)
apply_texture_contrast_to_components(desired, contrast_factor, mapped_component_count);
apply_filament_overhang_contrast_to_components(desired, contrast_factor, mapped_component_count);
for (float &v : desired)
v = clamp01f(v);
return desired;
@@ -1720,7 +1720,7 @@ TextureMappingOffsetWeightField build_texture_mapping_offset_weight_field(const
float dither_cell_size_mm,
const std::vector<float>& component_strength_factors,
const std::vector<float>& component_minimum_offset_factors,
float texture_contrast_pct,
float texture_filament_overhang_contrast_pct,
float texture_tone_gamma,
float layer_z_mm,
float layer_z_falloff_mm,
@@ -1754,7 +1754,7 @@ TextureMappingOffsetWeightField build_texture_mapping_offset_weight_field(const
return {};
const float safe_layer_z_falloff_mm = std::max(layer_z_falloff_mm, 1e-3f);
const float contrast_factor = std::clamp(texture_contrast_pct, 25.f, 300.f) / 100.f;
const float contrast_factor = std::clamp(texture_filament_overhang_contrast_pct, 25.f, 300.f) / 100.f;
const float tone_gamma =
(!std::isfinite(texture_tone_gamma) || texture_tone_gamma <= 0.f) ? 1.f : std::clamp(texture_tone_gamma, 0.5f, 3.f);
const float default_physical_sample_pitch_mm =
@@ -3446,7 +3446,8 @@ std::optional<TextureMappingOffsetContext> build_texture_mapping_offset_context_
std::optional<std::array<float, 4>> image_background_rgba_override,
std::optional<float> sample_z_mm_override,
std::optional<float> texture_sample_pitch_mm_override,
std::optional<int> raw_top_surface_depth_override)
std::optional<int> raw_top_surface_depth_override,
std::optional<float> filament_overhang_contrast_pct_override)
{
const Print *print = print_object.print();
if (print == nullptr)
@@ -3502,7 +3503,10 @@ std::optional<TextureMappingOffsetContext> build_texture_mapping_offset_context_
const int generic_solver_mix_model = std::clamp(zone.generic_solver_mix_model,
int(TextureMappingZone::GenericSolverPigmentPainter),
int(TextureMappingZone::GenericSolverPrusaFdmMixer));
const float texture_contrast_pct = std::clamp(zone.contrast_pct, 25.f, 300.f);
const float requested_filament_overhang_contrast_pct =
filament_overhang_contrast_pct_override ?
*filament_overhang_contrast_pct_override :
zone.filament_overhang_contrast_pct;
const float texture_tone_gamma =
(!std::isfinite(zone.tone_gamma) || zone.tone_gamma <= 0.f) ?
1.f :
@@ -3631,6 +3635,10 @@ std::optional<TextureMappingOffsetContext> build_texture_mapping_offset_context_
vertex_color_match_mode &&
!raw_texture_mapping_mode &&
zone.transmission_distance_calibration_mode == int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample);
const float texture_filament_overhang_contrast_pct =
calibrated_side_mode ?
TextureMappingZone::DefaultFilamentOverhangContrastPct :
std::clamp(requested_filament_overhang_contrast_pct, 25.f, 300.f);
std::vector<float> component_strength_factors;
component_strength_factors.reserve(component_ids.size());
std::vector<float> component_minimum_offset_factors;
@@ -3670,7 +3678,7 @@ std::optional<TextureMappingOffsetContext> build_texture_mapping_offset_context_
generic_solver_lookup_mode, generic_solver_mode, generic_solver_mix_model,
zone.use_legacy_fixed_color_mode, dithering_enabled, dithering_method,
dither_pitch_mm, dither_cell_size_mm, component_strength_factors,
component_minimum_offset_factors, texture_contrast_pct, texture_tone_gamma,
component_minimum_offset_factors, texture_filament_overhang_contrast_pct, texture_tone_gamma,
sample_z_mm, layer_sample_falloff_mm, high_resolution_texture_sampling,
zone.high_speed_image_texture_sampling, texture_sample_pitch_mm_override,
image_background_rgba_override, calibrated_side_candidates_ptr,

View File

@@ -121,7 +121,8 @@ std::optional<TextureMappingOffsetContext> build_texture_mapping_offset_context_
std::optional<std::array<float, 4>> image_background_rgba_override = std::nullopt,
std::optional<float> sample_z_mm_override = std::nullopt,
std::optional<float> texture_sample_pitch_mm_override = std::nullopt,
std::optional<int> raw_top_surface_depth_override = std::nullopt);
std::optional<int> raw_top_surface_depth_override = std::nullopt,
std::optional<float> filament_overhang_contrast_pct_override = std::nullopt);
std::vector<float> sample_weight_field_components(const TextureMappingOffsetWeightField &weight_field,
float x_mm,

View File

@@ -90,7 +90,7 @@ struct TexturePreviewSimulationSettings
float dithering_resolution_mm = TextureMappingZone::DefaultDitheringResolutionMm;
float halftone_dot_size_mm = TextureMappingZone::DefaultHalftoneDotSizeMm;
float texture_preview_mm_per_pixel = TextureMappingZone::DefaultDitheringResolutionMm;
float contrast_pct = 100.f;
float filament_overhang_contrast_pct = TextureMappingZone::DefaultFilamentOverhangContrastPct;
float tone_gamma = 1.f;
int generic_solver_lookup_mode = int(TextureMappingZone::GenericSolverClosestMix);
int generic_solver_mode = TextureMappingZone::DefaultGenericSolverMode;
@@ -2311,7 +2311,7 @@ float apply_texture_tone_gamma(float channel, float tone_gamma)
return clamp01(std::pow(safe_channel, 1.f / safe_gamma));
}
void apply_texture_contrast_to_mapped_components(std::vector<float> &component_weights,
void apply_filament_overhang_contrast_to_mapped_components(std::vector<float> &component_weights,
float contrast_factor,
size_t mapped_component_count)
{
@@ -2330,7 +2330,7 @@ void apply_texture_contrast_to_mapped_components(std::vector<float> &component_w
}
}
std::array<float, 3> apply_texture_contrast_to_rgb(const std::array<float, 3> &rgb, float contrast_factor)
std::array<float, 3> apply_filament_overhang_contrast_to_rgb(const std::array<float, 3> &rgb, float contrast_factor)
{
const float clamped_contrast = std::clamp(contrast_factor, 0.25f, 3.f);
if (std::abs(clamped_contrast - 1.f) <= 1e-5f)
@@ -2482,7 +2482,7 @@ std::array<float, 3> texture_preview_target_rgb(const TexturePreviewSimulationSe
target[1] = apply_texture_tone_gamma(target[1], settings.tone_gamma);
target[2] = apply_texture_tone_gamma(target[2], settings.tone_gamma);
}
return apply_texture_contrast_to_rgb(target, std::clamp(settings.contrast_pct, 25.f, 300.f) / 100.f);
return apply_filament_overhang_contrast_to_rgb(target, std::clamp(settings.filament_overhang_contrast_pct, 25.f, 300.f) / 100.f);
}
std::array<float, 3> texture_preview_target_color(const TexturePreviewSimulationSettings &settings,
@@ -2936,10 +2936,10 @@ std::vector<float> component_weights_for_texture_preview(const TexturePreviewSim
}
}
const float contrast_factor = std::clamp(settings.contrast_pct, 25.f, 300.f) / 100.f;
const float contrast_factor = std::clamp(settings.filament_overhang_contrast_pct, 25.f, 300.f) / 100.f;
if (!texture_preview_has_side_surface_calibrated_candidates(settings) &&
std::abs(contrast_factor - 1.f) > 1e-5f)
apply_texture_contrast_to_mapped_components(desired, contrast_factor, mapped_component_count);
apply_filament_overhang_contrast_to_mapped_components(desired, contrast_factor, mapped_component_count);
if (!texture_preview_has_side_surface_calibrated_candidates(settings) &&
settings.compact_offset_mode) {
@@ -2972,6 +2972,7 @@ std::array<float, 3> fallback_contoning_flat_surface_rgb_for_texture_preview(
local_settings.dithering_enabled = false;
local_settings.compact_offset_mode = false;
local_settings.contoning_flat_surface_quantization = false;
local_settings.filament_overhang_contrast_pct = TextureMappingZone::DefaultFilamentOverhangContrastPct;
std::vector<float> continuous_weights = component_weights_for_texture_preview(local_settings, sample_rgba, false);
continuous_weights.resize(component_count, 0.f);
@@ -2982,7 +2983,7 @@ std::array<float, 3> fallback_contoning_flat_surface_rgb_for_texture_preview(
}
if (total_weight <= k_epsilon) {
const std::array<float, 3> target_rgb = texture_preview_target_rgb(settings, sample_rgba);
const std::array<float, 3> target_rgb = texture_preview_target_rgb(local_settings, sample_rgba);
const std::array<float, 3> target_oklab = oklab_from_srgb(target_rgb);
const std::array<float, 3> axis_weights = { 1.f, 4.f, 4.f };
size_t best_idx = 0;
@@ -3044,7 +3045,9 @@ std::array<float, 3> contoning_flat_surface_rgb_for_texture_preview(
int root,
int total_units)
{
const std::array<float, 3> target_rgb = texture_preview_target_rgb(settings, sample_rgba);
TexturePreviewSimulationSettings local_settings = settings;
local_settings.filament_overhang_contrast_pct = TextureMappingZone::DefaultFilamentOverhangContrastPct;
const std::array<float, 3> target_rgb = texture_preview_target_rgb(local_settings, sample_rgba);
if (settings.contoning_flat_surface_td_adjustment && !ordered_candidates.empty()) {
const std::vector<uint16_t> surface_to_deep =
solve_color_solver_ordered_stack_for_target(ordered_candidates, target_rgb, ColorSolverMode::OklabSoftCap4Dark4);
@@ -3079,7 +3082,7 @@ std::array<float, 3> contoning_flat_surface_rgb_for_texture_preview(
if (nearest.best_idx < candidates.size())
return candidates[nearest.best_idx].rgb;
}
return fallback_contoning_flat_surface_rgb_for_texture_preview(settings, sample_rgba, total_units);
return fallback_contoning_flat_surface_rgb_for_texture_preview(local_settings, sample_rgba, total_units);
}
std::vector<float> raw_offset_print_width_weights_for_texture_preview(const TexturePreviewSimulationSettings &settings,
@@ -3203,7 +3206,10 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
settings.compact_offset_mode =
halftone_dithering_enabled ? false : zone->compact_offset_mode || settings.dithering_enabled;
settings.use_legacy_fixed_color_mode = zone->use_legacy_fixed_color_mode;
settings.contrast_pct = std::clamp(zone->contrast_pct, 25.f, 300.f);
settings.filament_overhang_contrast_pct =
zone->transmission_distance_calibration_mode == int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample) ?
TextureMappingZone::DefaultFilamentOverhangContrastPct :
std::clamp(zone->filament_overhang_contrast_pct, 25.f, 300.f);
settings.tone_gamma = (!std::isfinite(zone->tone_gamma) || zone->tone_gamma <= 0.f) ?
1.f :
std::clamp(zone->tone_gamma, 0.5f, 3.f);
@@ -3408,7 +3414,7 @@ size_t texture_preview_simulation_signature(const ModelVolume &model_volume,
if (settings.contoning_flat_surface_calibrated_stack_model.valid())
mix(std::hash<std::string>{}(settings.contoning_flat_surface_calibrated_stack_model.cache_key()));
}
mix(std::hash<int>{}(int(std::lround(settings.contrast_pct * 100.f))));
mix(std::hash<int>{}(int(std::lround(settings.filament_overhang_contrast_pct * 100.f))));
mix(std::hash<int>{}(int(std::lround(settings.tone_gamma * 1000.f))));
mix(std::hash<int>{}(int(std::lround(settings.minimum_visibility_offset_factor * 100000.f))));
for (const unsigned int id : settings.component_ids)
@@ -4279,6 +4285,8 @@ const GUI::GLTexture *simulated_texture_preview_texture_for_filament(const Model
contoning_flat_surface_raw_top_stack_preview &&
contoning_flat_surface_quantization &&
model_volume_has_raw_top_surface_stack_preview_data_for_zone_impl(model_volume, *zone);
if (settings->contoning_flat_surface_quantization || settings->contoning_flat_surface_pattern_blend)
settings->filament_overhang_contrast_pct = TextureMappingZone::DefaultFilamentOverhangContrastPct;
if ((contoning_flat_surface_quantization || contoning_flat_surface_pattern_blend) &&
zone->texture_mapping_mode == int(TextureMappingZone::TextureMappingRawValues) &&
!settings->contoning_flat_surface_raw_top_stack_preview)
@@ -6456,7 +6464,10 @@ static size_t texture_preview_settings_signature_impl(size_t num_physical,
signature_mix(std::hash<int>{}(zone.generic_solver_lookup_mode));
signature_mix(std::hash<int>{}(zone.generic_solver_mode));
signature_mix(std::hash<int>{}(TextureMappingZone::DefaultGenericSolverMixModel));
signature_mix_float(zone.contrast_pct, 100.f);
signature_mix_float(zone.transmission_distance_calibration_mode == int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample) ?
TextureMappingZone::DefaultFilamentOverhangContrastPct :
zone.filament_overhang_contrast_pct,
100.f);
signature_mix_float(zone.tone_gamma);
for (const float strength_pct : zone.filament_strengths_pct)
signature_mix_float(strength_pct, 100.f);
@@ -6618,7 +6629,10 @@ static void texture_preview_mix_zone_baked_model_settings(size_t &signature,
signature_mix(std::hash<int>{}(zone.generic_solver_lookup_mode));
signature_mix(std::hash<int>{}(zone.generic_solver_mode));
signature_mix(std::hash<int>{}(TextureMappingZone::DefaultGenericSolverMixModel));
signature_mix_float(zone.contrast_pct, 100.f);
signature_mix_float(zone.transmission_distance_calibration_mode == int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample) ?
TextureMappingZone::DefaultFilamentOverhangContrastPct :
zone.filament_overhang_contrast_pct,
100.f);
signature_mix_float(zone.tone_gamma);
signature_mix(std::hash<int>{}(zone.linear_gradient_mode));
signature_mix_float(zone.linear_gradient_radius_mm, 1000.f);

View File

@@ -2495,6 +2495,7 @@ public:
const std::vector<float> &component_transmission_distances_mm,
int transmission_distance_calibration_mode,
float tone_gamma,
float filament_overhang_contrast_pct,
bool force_sequential_filaments,
bool auto_adjust_filament_selection,
bool reduce_outer_surface_texture,
@@ -2955,6 +2956,25 @@ public:
m_nonlinear_offset_adjustment_checkbox->SetToolTip(
_L("Adjusts line-width offsets using a surface-visibility model derived from Kuipers et al. 2018."));
experimental_box->Add(m_nonlinear_offset_adjustment_checkbox, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
auto *filament_overhang_contrast_row = new wxBoxSizer(wxHORIZONTAL);
filament_overhang_contrast_row->Add(new wxStaticText(experimental_page, wxID_ANY, _L("Filament overhang contrast")),
0,
wxALIGN_CENTER_VERTICAL | wxRIGHT,
gap);
m_filament_overhang_contrast_spin = new wxSpinCtrl(experimental_page,
wxID_ANY,
wxEmptyString,
wxDefaultPosition,
wxSize(FromDIP(70), -1),
wxSP_ARROW_KEYS | wxALIGN_RIGHT,
25,
300,
std::clamp(int(std::lround(filament_overhang_contrast_pct)), 25, 300));
m_filament_overhang_contrast_spin->Enable(
transmission_distance_calibration_mode != int(TextureMappingZone::TDCalibrationCalibratedNearestMeasuredSample));
filament_overhang_contrast_row->Add(m_filament_overhang_contrast_spin, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap / 2);
filament_overhang_contrast_row->Add(new wxStaticText(experimental_page, wxID_ANY, _L("%")), 0, wxALIGN_CENTER_VERTICAL);
experimental_box->Add(filament_overhang_contrast_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
m_compact_offset_mode_checkbox = new wxCheckBox(experimental_page, wxID_ANY, _L("Compact Offset Mode"));
m_compact_offset_mode_checkbox->SetValue(compact_offset_mode);
m_compact_offset_mode_checkbox->SetToolTip(
@@ -3841,6 +3861,13 @@ public:
}
float tone_gamma() const { return float(std::clamp(m_tone_gamma_spin ? m_tone_gamma_spin->GetValue() : 1.0, 0.5, 3.0)); }
float filament_overhang_contrast_pct() const
{
const int value = m_filament_overhang_contrast_spin != nullptr ?
m_filament_overhang_contrast_spin->GetValue() :
int(TextureMappingZone::DefaultFilamentOverhangContrastPct);
return float(std::clamp(value, 25, 300));
}
int transmission_distance_calibration_mode() const
{
if (m_transmission_distance_calibration_mode_choice == nullptr)
@@ -5016,6 +5043,8 @@ private:
for (wxSpinCtrl *spin : m_strength_spins)
if (spin)
spin->Enable(manual_controls_enabled);
if (m_filament_overhang_contrast_spin != nullptr)
m_filament_overhang_contrast_spin->Enable(manual_controls_enabled);
if (m_strength_offsets_reset_button != nullptr)
m_strength_offsets_reset_button->Enable(manual_controls_enabled);
if (m_strength_offsets_panel != nullptr)
@@ -5708,6 +5737,7 @@ private:
wxCheckBox *m_reduce_outer_surface_texture_checkbox {nullptr};
wxCheckBox *m_seam_hiding_checkbox {nullptr};
wxCheckBox *m_nonlinear_offset_adjustment_checkbox {nullptr};
wxSpinCtrl *m_filament_overhang_contrast_spin {nullptr};
wxCheckBox *m_use_modulated_overhang_geometry_for_support_checkbox {nullptr};
wxChoice *m_modulation_mode_choice {nullptr};
std::vector<int> m_modulation_mode_choice_values;
@@ -10128,22 +10158,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
mode_row->Add(mode_choice, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
editor_sizer->Add(mode_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap);
auto *contrast_row = new wxWrapSizer(wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS);
contrast_row->Add(new wxStaticText(editor, wxID_ANY, _L("Texture contrast")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
auto *contrast_spin = new ::SpinInput(editor,
wxEmptyString,
wxEmptyString,
wxDefaultPosition,
wxSize(FromDIP(86), -1),
wxSP_ARROW_KEYS,
25,
300,
std::clamp(int(std::lround(entry.contrast_pct)), 25, 300),
5);
contrast_row->Add(contrast_spin, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap / 2);
contrast_row->Add(new wxStaticText(editor, wxID_ANY, _L("%")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
editor_sizer->Add(contrast_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap);
::CheckBox *preview_colors_chk = nullptr;
auto *preview_colors_row = make_sidebar_checkbox_row(editor,
preview_colors_chk,
@@ -10178,7 +10192,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
linear_gradient_stops_bar, linear_gradient_mode_choice, linear_gradient_radius_spin,
linear_gradient_radius_percent_chk,
surface_pattern_from_selection, linear_gradient_mode_from_selection, mode_choice,
show_direction_arrow_chk, contrast_spin, apply_zone, update_color_calibration_warning_text]() {
show_direction_arrow_chk, apply_zone, update_color_calibration_warning_text]() {
if (mgr_ptr == nullptr)
return;
auto &rows = mgr_ptr->zones();
@@ -10228,7 +10242,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
texture_mapping_color_mode_from_selection(mode_choice->GetSelection(), updated.filament_color_mode) :
updated.filament_color_mode;
updated.show_linear_gradient_direction_arrow = show_direction_arrow_chk != nullptr && show_direction_arrow_chk->GetValue();
updated.contrast_pct = contrast_spin != nullptr ? std::clamp(float(contrast_spin->GetValue()), 25.f, 300.f) : updated.contrast_pct;
updated.high_resolution_sampling = true;
update_color_calibration_warning_text(updated);
apply_zone(std::move(updated));
@@ -10244,17 +10257,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
});
}
contrast_spin->Bind(wxEVT_CHAR_HOOK, [contrast_spin, apply_controls](wxKeyEvent &evt) {
const int key = evt.GetKeyCode();
if (key == WXK_UP || key == WXK_NUMPAD_UP || key == WXK_DOWN || key == WXK_NUMPAD_DOWN) {
const int direction = (key == WXK_UP || key == WXK_NUMPAD_UP) ? 1 : -1;
contrast_spin->SetValue(std::clamp(contrast_spin->GetValue() + direction * 5, 25, 300));
apply_controls();
return;
}
evt.Skip();
});
auto update_pattern_visibility = [this, editor_sizer, filaments_row, linear_gradient_mode_row, linear_gradient_mode_choice, linear_gradient_stops_bar, linear_gradient_row, linear_gradient_point_row, linear_gradient_buttons_row, linear_gradient_radius_row, show_direction_arrow_row, mode_row, contrast_row, preview_colors_row, color_calibration_warning_text, offset_btn, advanced_btn, surface_choice, row, editor, update_texture_mapping_area_height, set_linear_gradient_picker_button_labels, sync_linear_gradient_stop_controls]() {
auto update_pattern_visibility = [this, editor_sizer, filaments_row, linear_gradient_mode_row, linear_gradient_mode_choice, linear_gradient_stops_bar, linear_gradient_row, linear_gradient_point_row, linear_gradient_buttons_row, linear_gradient_radius_row, show_direction_arrow_row, mode_row, preview_colors_row, color_calibration_warning_text, offset_btn, advanced_btn, surface_choice, row, editor, update_texture_mapping_area_height, set_linear_gradient_picker_button_labels, sync_linear_gradient_stop_controls]() {
const int selection = surface_choice == nullptr ? 0 : surface_choice->GetSelection();
const bool image_texture = selection == 0;
const bool linear_gradient = selection == 1;
@@ -10269,7 +10272,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
editor_sizer->Show(linear_gradient_radius_row, radial_gradient, true);
editor_sizer->Show(show_direction_arrow_row, linear_gradient, true);
editor_sizer->Show(mode_row, image_texture, true);
editor_sizer->Show(contrast_row, image_texture, true);
editor_sizer->Show(preview_colors_row, image_texture, true);
if (color_calibration_warning_text != nullptr)
editor_sizer->Show(color_calibration_warning_text, !color_calibration_warning_text->GetLabel().empty(), true);
@@ -10344,7 +10346,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
linear_gradient_mode_from_selection,
mode_choice,
surface_choice,
contrast_spin,
set_sidebar_checkbox_value,
update_color_calibration_warning_text,
surface_pattern_from_selection,
@@ -10405,7 +10406,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
updated.filament_color_mode = mode_choice != nullptr ?
texture_mapping_color_mode_from_selection(mode_choice->GetSelection(), updated.filament_color_mode) :
updated.filament_color_mode;
updated.contrast_pct = contrast_spin != nullptr ? std::clamp(float(contrast_spin->GetValue()), 25.f, 300.f) : updated.contrast_pct;
updated.high_resolution_sampling = true;
if (updated.is_image_texture() && updated.auto_adjust_filament_selection) {
@@ -10484,12 +10484,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
evt.Skip();
});
}
contrast_spin->Bind(wxEVT_SPINCTRL, [apply_controls](wxCommandEvent &) { apply_controls(); });
contrast_spin->Bind(wxEVT_TEXT_ENTER, [apply_controls](wxCommandEvent &) { apply_controls(); });
contrast_spin->Bind(wxEVT_KILL_FOCUS, [apply_controls](wxFocusEvent &evt) {
apply_controls();
evt.Skip();
});
auto make_linear_gradient_anchor = [this](const GLGizmoTextureGradientPointPicker::Pick &pick) {
TextureMappingZone::LinearGradientAnchor anchor;
anchor.valid = true;
@@ -10840,6 +10834,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
transmission_distances,
updated.transmission_distance_calibration_mode,
updated.tone_gamma,
updated.filament_overhang_contrast_pct,
updated.force_sequential_filaments,
updated.auto_adjust_filament_selection,
updated.reduce_outer_surface_texture,
@@ -10927,6 +10922,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
}
updated.texture_mapping_mode = dlg.texture_mapping_mode();
updated.tone_gamma = dlg.tone_gamma();
updated.filament_overhang_contrast_pct = dlg.filament_overhang_contrast_pct();
updated.transmission_distance_calibration_mode = dlg.transmission_distance_calibration_mode();
updated.force_sequential_filaments = dlg.force_sequential_filaments();
if (updated.force_sequential_filaments && ids.size() >= 2) {