Add filament TD calibration options
This commit is contained in:
@@ -5930,15 +5930,150 @@ static float overhang_filament_minimum_offset_factor_for_gcode(const TextureMapp
|
||||
return std::clamp(minimum_offset_pct / 100.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
struct TransmissionDistanceCalibrationContextForGCode {
|
||||
bool enabled { false };
|
||||
int mode { int(TextureMappingZone::TDCalibrationNone) };
|
||||
std::vector<float> own_width_factors;
|
||||
std::vector<float> neighbor_opacity_ratios;
|
||||
};
|
||||
|
||||
static bool texture_mapping_component_is_black_for_gcode(size_t component_idx,
|
||||
int filament_color_mode,
|
||||
const std::vector<std::array<float, 3>> &component_colors)
|
||||
{
|
||||
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW))) {
|
||||
case int(TextureMappingZone::FilamentColorCMYK):
|
||||
case int(TextureMappingZone::FilamentColorRGBK):
|
||||
if (component_idx == 3)
|
||||
return true;
|
||||
break;
|
||||
case int(TextureMappingZone::FilamentColorBW):
|
||||
if (component_idx == 0)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (component_idx >= component_colors.size())
|
||||
return false;
|
||||
|
||||
const std::array<float, 3> &c = component_colors[component_idx];
|
||||
const float max_channel = std::max({ c[0], c[1], c[2] });
|
||||
const float luminance = 0.2126f * c[0] + 0.7152f * c[1] + 0.0722f * c[2];
|
||||
return max_channel <= 0.18f && luminance <= 0.12f;
|
||||
}
|
||||
|
||||
static bool overhang_filament_explicit_transmission_distance_for_gcode(const TextureMappingZone &zone,
|
||||
unsigned int physical_filament_id,
|
||||
float &td_mm)
|
||||
{
|
||||
if (physical_filament_id == 0)
|
||||
return false;
|
||||
|
||||
const size_t idx = size_t(physical_filament_id - 1);
|
||||
if (idx >= zone.filament_transmission_distances_mm.size())
|
||||
return false;
|
||||
|
||||
const float value = zone.filament_transmission_distances_mm[idx];
|
||||
if (!std::isfinite(value) || value <= 0.f)
|
||||
return false;
|
||||
|
||||
td_mm = std::clamp(value, 0.01f, 50.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
static float transmission_distance_reference_for_gcode(bool is_black)
|
||||
{
|
||||
return is_black ? 0.1f : 3.f;
|
||||
}
|
||||
|
||||
static float transmission_distance_opacity_for_gcode(float td_mm, float path_extension_mm)
|
||||
{
|
||||
constexpr float surface_scatter = 0.50f;
|
||||
constexpr float surface_depth_mm = 0.32f;
|
||||
const float safe_td = std::clamp(td_mm, 0.01f, 50.f);
|
||||
const float path_mm = std::max(0.f, surface_depth_mm + std::max(0.f, path_extension_mm));
|
||||
const float opacity = surface_scatter + (1.f - surface_scatter) * (1.f - std::exp(-path_mm / safe_td));
|
||||
return std::clamp(opacity, 1e-4f, 1.f);
|
||||
}
|
||||
|
||||
static TransmissionDistanceCalibrationContextForGCode transmission_distance_calibration_context_for_gcode(
|
||||
const TextureMappingZone &zone,
|
||||
const std::vector<unsigned int> &component_ids,
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
int filament_color_mode)
|
||||
{
|
||||
TransmissionDistanceCalibrationContextForGCode context;
|
||||
context.mode = std::clamp(zone.transmission_distance_calibration_mode,
|
||||
int(TextureMappingZone::TDCalibrationNone),
|
||||
int(TextureMappingZone::TDCalibrationNeighbor));
|
||||
if (context.mode == int(TextureMappingZone::TDCalibrationNone) || component_ids.empty())
|
||||
return context;
|
||||
|
||||
std::vector<float> explicit_tds(component_ids.size(), 0.f);
|
||||
bool has_active_explicit_td = false;
|
||||
for (size_t idx = 0; idx < component_ids.size(); ++idx) {
|
||||
float td_mm = 0.f;
|
||||
if (overhang_filament_explicit_transmission_distance_for_gcode(zone, component_ids[idx], td_mm)) {
|
||||
explicit_tds[idx] = td_mm;
|
||||
has_active_explicit_td = true;
|
||||
}
|
||||
}
|
||||
if (!has_active_explicit_td)
|
||||
return context;
|
||||
|
||||
const bool neighbor_mode = context.mode == int(TextureMappingZone::TDCalibrationNeighbor);
|
||||
const float path_extension_mm = neighbor_mode ? 0.16f : 0.12f;
|
||||
const float own_power = neighbor_mode ? 0.25f : 0.35f;
|
||||
context.own_width_factors.assign(component_ids.size(), 1.f);
|
||||
context.neighbor_opacity_ratios.assign(component_ids.size(), 1.f);
|
||||
context.enabled = true;
|
||||
|
||||
for (size_t idx = 0; idx < component_ids.size(); ++idx) {
|
||||
const bool is_black = texture_mapping_component_is_black_for_gcode(idx, filament_color_mode, component_colors);
|
||||
const float reference_td_mm = transmission_distance_reference_for_gcode(is_black);
|
||||
const float actual_td_mm = explicit_tds[idx] > 0.f ? explicit_tds[idx] : reference_td_mm;
|
||||
const float actual_opacity = transmission_distance_opacity_for_gcode(actual_td_mm, path_extension_mm);
|
||||
const float reference_opacity = transmission_distance_opacity_for_gcode(reference_td_mm, path_extension_mm);
|
||||
context.own_width_factors[idx] =
|
||||
std::clamp(std::pow(reference_opacity / std::max(actual_opacity, 1e-4f), own_power), 0.25f, 2.f);
|
||||
context.neighbor_opacity_ratios[idx] =
|
||||
std::clamp(actual_opacity / std::max(reference_opacity, 1e-4f), 0.25f, 4.f);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static float transmission_distance_width_factor_for_gcode(const TransmissionDistanceCalibrationContextForGCode &context,
|
||||
size_t active_component_idx,
|
||||
size_t previous_component_idx)
|
||||
{
|
||||
if (!context.enabled || active_component_idx >= context.own_width_factors.size())
|
||||
return 1.f;
|
||||
|
||||
float factor = context.own_width_factors[active_component_idx];
|
||||
if (context.mode == int(TextureMappingZone::TDCalibrationNeighbor) &&
|
||||
previous_component_idx < context.neighbor_opacity_ratios.size())
|
||||
factor *= std::pow(context.neighbor_opacity_ratios[previous_component_idx], 0.20f);
|
||||
|
||||
return std::clamp(factor, 0.25f, 2.f);
|
||||
}
|
||||
|
||||
static float variable_width_delta_for_overhang_range_for_gcode(float inset_strength,
|
||||
float max_width_delta_limit_mm,
|
||||
float minimum_offset_factor,
|
||||
float strength_factor)
|
||||
float strength_factor,
|
||||
float transmission_distance_width_factor)
|
||||
{
|
||||
if (!std::isfinite(max_width_delta_limit_mm) || max_width_delta_limit_mm <= 0.f)
|
||||
return 0.f;
|
||||
|
||||
const float desired_width_factor = 1.f - std::clamp(inset_strength, 0.f, 1.f);
|
||||
const float desired_width_factor =
|
||||
std::clamp((1.f - std::clamp(inset_strength, 0.f, 1.f)) *
|
||||
std::clamp(transmission_distance_width_factor, 0.f, 2.f),
|
||||
0.f,
|
||||
1.f);
|
||||
const float min_width_factor = std::clamp(minimum_offset_factor, 0.f, 1.f);
|
||||
const float adjusted_width_factor =
|
||||
min_width_factor + desired_width_factor * std::clamp(strength_factor, 0.f, 1.f) * (1.f - min_width_factor);
|
||||
@@ -6014,6 +6149,7 @@ static float variable_width_delta_for_visibility_range_for_gcode(float inset_str
|
||||
float max_width_delta_limit_mm,
|
||||
float minimum_offset_factor,
|
||||
float strength_factor,
|
||||
float transmission_distance_width_factor,
|
||||
bool nonlinear_offset_adjustment,
|
||||
float layer_height_mm,
|
||||
float stair_step_mm,
|
||||
@@ -6022,7 +6158,11 @@ static float variable_width_delta_for_visibility_range_for_gcode(float inset_str
|
||||
if (!std::isfinite(max_width_delta_limit_mm) || max_width_delta_limit_mm <= 0.f)
|
||||
return 0.f;
|
||||
|
||||
float desired_width_factor = 1.f - std::clamp(inset_strength, 0.f, 1.f);
|
||||
float desired_width_factor =
|
||||
std::clamp((1.f - std::clamp(inset_strength, 0.f, 1.f)) *
|
||||
std::clamp(transmission_distance_width_factor, 0.f, 2.f),
|
||||
0.f,
|
||||
1.f);
|
||||
if (nonlinear_offset_adjustment)
|
||||
desired_width_factor = nonlinear_visibility_width_factor_for_gcode(desired_width_factor,
|
||||
layer_height_mm,
|
||||
@@ -8110,6 +8250,12 @@ std::optional<Point> GCode::texture_mapping_seam_hiding_point(const ExtrusionLoo
|
||||
if (missing_component_color || component_colors.size() != component_ids.size() || component_colors.empty())
|
||||
return std::nullopt;
|
||||
|
||||
const TransmissionDistanceCalibrationContextForGCode td_calibration_context =
|
||||
transmission_distance_calibration_context_for_gcode(*zone,
|
||||
component_ids,
|
||||
component_colors,
|
||||
texture_filament_color_mode);
|
||||
|
||||
std::ostringstream component_key_stream;
|
||||
for (size_t idx = 0; idx < component_ids.size(); ++idx) {
|
||||
if (idx > 0)
|
||||
@@ -8136,6 +8282,7 @@ std::optional<Point> GCode::texture_mapping_seam_hiding_point(const ExtrusionLoo
|
||||
const VertexColorOverhangWeightField *weight_field { nullptr };
|
||||
float active_component_strength_factor { 1.f };
|
||||
float active_component_minimum_offset_factor { 0.f };
|
||||
float active_component_td_width_factor { 1.f };
|
||||
float signed_fade_factor { 1.f };
|
||||
float fade_factor { 1.f };
|
||||
};
|
||||
@@ -8156,6 +8303,15 @@ std::optional<Point> GCode::texture_mapping_seam_hiding_point(const ExtrusionLoo
|
||||
const auto active_component_it = std::find(component_ids.begin(), component_ids.end(), active_component_id);
|
||||
if (active_component_it == component_ids.end())
|
||||
return std::nullopt;
|
||||
const size_t active_component_idx = size_t(active_component_it - component_ids.begin());
|
||||
size_t previous_component_idx = size_t(-1);
|
||||
if (layer_index > 0) {
|
||||
const unsigned int previous_component_id =
|
||||
texture_mgr.resolve_zone_component(texture_zone_id, num_physical, layer_index - 1);
|
||||
const auto previous_component_it = std::find(component_ids.begin(), component_ids.end(), previous_component_id);
|
||||
if (previous_component_it != component_ids.end())
|
||||
previous_component_idx = size_t(previous_component_it - component_ids.begin());
|
||||
}
|
||||
|
||||
std::ostringstream layer_key_stream;
|
||||
layer_key_stream << component_key_prefix << "|seamL" << layer->id();
|
||||
@@ -8199,10 +8355,11 @@ std::optional<Point> GCode::texture_mapping_seam_hiding_point(const ExtrusionLoo
|
||||
layer,
|
||||
layer_height_mm,
|
||||
active_component_id,
|
||||
size_t(active_component_it - component_ids.begin()),
|
||||
active_component_idx,
|
||||
&weight_field,
|
||||
overhang_filament_strength_factor_for_gcode(*zone, active_component_id),
|
||||
overhang_filament_minimum_offset_factor_for_gcode(*zone, active_component_id),
|
||||
transmission_distance_width_factor_for_gcode(td_calibration_context, active_component_idx, previous_component_idx),
|
||||
signed_fade_factor,
|
||||
fade_factor
|
||||
};
|
||||
@@ -8300,7 +8457,8 @@ std::optional<Point> GCode::texture_mapping_seam_hiding_point(const ExtrusionLoo
|
||||
variable_width_delta_for_overhang_range_for_gcode(inset_strength,
|
||||
max_width_delta_limit_mm,
|
||||
state.active_component_minimum_offset_factor,
|
||||
state.active_component_strength_factor);
|
||||
state.active_component_strength_factor,
|
||||
state.active_component_td_width_factor);
|
||||
const float width_delta_mm = std::clamp(variable_width_delta_mm, 0.f, max_width_delta_limit_mm);
|
||||
if (!std::isfinite(width_delta_mm))
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
@@ -9027,6 +9185,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
float max_width_delta_mm { 0.f };
|
||||
float active_component_strength_factor { 1.f };
|
||||
float active_component_minimum_offset_factor { 0.f };
|
||||
float active_component_td_width_factor { 1.f };
|
||||
float base_outer_width_mm { 0.4f };
|
||||
float flow_reference_width_mm { 0.4f };
|
||||
float base_centerline_shift_mm { 0.f };
|
||||
@@ -9220,32 +9379,51 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
const float texture_sagging_ratio =
|
||||
std::isfinite(zone->sagging_ratio) ? std::clamp(zone->sagging_ratio, 0.f, 6.f) : 0.f;
|
||||
|
||||
const bool raw_texture_mapping_mode =
|
||||
zone->texture_mapping_mode == int(TextureMappingZone::TextureMappingRawValues);
|
||||
std::vector<std::array<float, 3>> component_colors;
|
||||
component_colors.reserve(component_ids.size());
|
||||
bool missing_component_color = false;
|
||||
for (const unsigned int id : component_ids) {
|
||||
if (id < 1 || id > m_config.filament_colour.values.size()) {
|
||||
if (raw_texture_mapping_mode)
|
||||
component_colors.push_back({ 0.f, 0.f, 0.f });
|
||||
else
|
||||
missing_component_color = true;
|
||||
continue;
|
||||
}
|
||||
ColorRGB decoded;
|
||||
if (!decode_color(m_config.filament_colour.get_at(size_t(id - 1)), decoded)) {
|
||||
if (raw_texture_mapping_mode)
|
||||
component_colors.push_back({ 0.f, 0.f, 0.f });
|
||||
else
|
||||
missing_component_color = true;
|
||||
continue;
|
||||
}
|
||||
component_colors.push_back({ decoded.r(), decoded.g(), decoded.b() });
|
||||
}
|
||||
const TransmissionDistanceCalibrationContextForGCode td_calibration_context =
|
||||
transmission_distance_calibration_context_for_gcode(*zone,
|
||||
component_ids,
|
||||
component_colors,
|
||||
texture_filament_color_mode);
|
||||
size_t previous_component_idx = size_t(-1);
|
||||
if (current_layer_index > 0) {
|
||||
const unsigned int previous_component_id =
|
||||
texture_mgr.resolve_zone_component(texture_zone_id, num_physical, current_layer_index - 1);
|
||||
const auto previous_component_it =
|
||||
std::find(component_ids.begin(), component_ids.end(), previous_component_id);
|
||||
if (previous_component_it != component_ids.end())
|
||||
previous_component_idx = size_t(previous_component_it - component_ids.begin());
|
||||
}
|
||||
const float active_component_td_width_factor =
|
||||
transmission_distance_width_factor_for_gcode(td_calibration_context,
|
||||
active_component_idx,
|
||||
previous_component_idx);
|
||||
|
||||
const VertexColorOverhangWeightField *vertex_color_weight_field = nullptr;
|
||||
auto *generic_mix_candidate_cache = &m_generic_solver_mix_candidate_cache;
|
||||
if (vertex_color_match_mode && layer_object != nullptr) {
|
||||
const bool raw_texture_mapping_mode =
|
||||
zone->texture_mapping_mode == int(TextureMappingZone::TextureMappingRawValues);
|
||||
std::vector<std::array<float, 3>> component_colors;
|
||||
component_colors.reserve(component_ids.size());
|
||||
bool missing_component_color = false;
|
||||
for (const unsigned int id : component_ids) {
|
||||
if (id < 1 || id > m_config.filament_colour.values.size()) {
|
||||
if (raw_texture_mapping_mode)
|
||||
component_colors.push_back({ 0.f, 0.f, 0.f });
|
||||
else
|
||||
missing_component_color = true;
|
||||
continue;
|
||||
}
|
||||
ColorRGB decoded;
|
||||
if (!decode_color(m_config.filament_colour.get_at(size_t(id - 1)), decoded)) {
|
||||
if (raw_texture_mapping_mode)
|
||||
component_colors.push_back({ 0.f, 0.f, 0.f });
|
||||
else
|
||||
missing_component_color = true;
|
||||
continue;
|
||||
}
|
||||
component_colors.push_back({ decoded.r(), decoded.g(), decoded.b() });
|
||||
}
|
||||
if (!missing_component_color && component_colors.size() == component_ids.size() && !component_colors.empty()) {
|
||||
std::ostringstream component_key_stream;
|
||||
for (size_t idx = 0; idx < component_ids.size(); ++idx) {
|
||||
@@ -9321,6 +9499,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
outer_wall_gradient_dynamic_ctx.max_width_delta_mm = effective_max_width_delta_mm;
|
||||
outer_wall_gradient_dynamic_ctx.active_component_strength_factor = active_component_strength_factor;
|
||||
outer_wall_gradient_dynamic_ctx.active_component_minimum_offset_factor = active_component_minimum_offset_factor;
|
||||
outer_wall_gradient_dynamic_ctx.active_component_td_width_factor = active_component_td_width_factor;
|
||||
outer_wall_gradient_dynamic_ctx.base_outer_width_mm = base_outer_width_mm;
|
||||
outer_wall_gradient_dynamic_ctx.flow_reference_width_mm = flow_reference_width_mm;
|
||||
outer_wall_gradient_dynamic_ctx.base_centerline_shift_mm = base_centerline_shift_mm;
|
||||
@@ -9435,6 +9614,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
max_width_delta_limit_mm,
|
||||
active_component_minimum_offset_factor,
|
||||
active_component_strength_factor,
|
||||
active_component_td_width_factor,
|
||||
nonlinear_offset_adjustment,
|
||||
layer_height_mm,
|
||||
stair_step_mm,
|
||||
@@ -10151,6 +10331,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
max_width_delta_limit_mm,
|
||||
outer_wall_gradient_dynamic_ctx.active_component_minimum_offset_factor,
|
||||
outer_wall_gradient_dynamic_ctx.active_component_strength_factor,
|
||||
outer_wall_gradient_dynamic_ctx.active_component_td_width_factor,
|
||||
outer_wall_gradient_dynamic_ctx.nonlinear_offset_adjustment,
|
||||
outer_wall_gradient_dynamic_ctx.layer_height_mm,
|
||||
stair_step_mm,
|
||||
|
||||
@@ -352,14 +352,27 @@ static std::vector<float> normalize_minimum_offsets(const std::vector<float> &va
|
||||
return out;
|
||||
}
|
||||
|
||||
static std::vector<float> normalize_transmission_distances(const std::vector<float> &values)
|
||||
{
|
||||
std::vector<float> out;
|
||||
out.reserve(std::min<size_t>(values.size(), 9));
|
||||
for (size_t i = 0; i < std::min<size_t>(values.size(), 9); ++i) {
|
||||
const float value = finite_or(values[i], 0.f);
|
||||
out.emplace_back(value > 0.f ? std::clamp(value, 0.01f, 50.f) : 0.f);
|
||||
}
|
||||
while (!out.empty() && std::abs(out.back()) <= 1e-6f)
|
||||
out.pop_back();
|
||||
return out;
|
||||
}
|
||||
|
||||
static float normalize_tone_gamma(float value)
|
||||
{
|
||||
return (!std::isfinite(value) || value <= 0.f) ? 1.f : std::clamp(value, 0.5f, 3.f);
|
||||
}
|
||||
|
||||
static float normalize_sagging_ratio(float value)
|
||||
static float normalize_sagging_ratio(float)
|
||||
{
|
||||
return std::isfinite(value) ? std::clamp(value, 0.f, 6.f) : 0.f;
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
static RGB filament_color(unsigned int id, const std::vector<std::string> &filament_colours)
|
||||
@@ -553,6 +566,52 @@ static int generic_solver_mix_model_from_name(std::string)
|
||||
return TextureMappingZone::DefaultGenericSolverMixModel;
|
||||
}
|
||||
|
||||
static std::string transmission_distance_calibration_mode_name(int mode)
|
||||
{
|
||||
switch (clamp_int(mode,
|
||||
int(TextureMappingZone::TDCalibrationNone),
|
||||
int(TextureMappingZone::TDCalibrationNeighbor))) {
|
||||
case int(TextureMappingZone::TDCalibrationNone): return "none";
|
||||
case int(TextureMappingZone::TDCalibrationNeighbor): return "neighbor";
|
||||
default: return "absolute";
|
||||
}
|
||||
}
|
||||
|
||||
static int transmission_distance_calibration_mode_from_name(std::string name)
|
||||
{
|
||||
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) { return char(std::tolower(c)); });
|
||||
if (name == "none" || name == "off" || name == "disabled")
|
||||
return int(TextureMappingZone::TDCalibrationNone);
|
||||
if (name == "neighbor" || name == "neighbour")
|
||||
return int(TextureMappingZone::TDCalibrationNeighbor);
|
||||
return int(TextureMappingZone::TDCalibrationAbsolute);
|
||||
}
|
||||
|
||||
static int transmission_distance_calibration_mode_from_json(const nlohmann::json &texture)
|
||||
{
|
||||
const auto mode_it = texture.find("transmission_distance_calibration");
|
||||
if (mode_it != texture.end()) {
|
||||
if (mode_it->is_string())
|
||||
return transmission_distance_calibration_mode_from_name(mode_it->get<std::string>());
|
||||
if (mode_it->is_number_integer() || mode_it->is_number_unsigned())
|
||||
return clamp_int(mode_it->get<int>(),
|
||||
int(TextureMappingZone::TDCalibrationNone),
|
||||
int(TextureMappingZone::TDCalibrationNeighbor));
|
||||
if (mode_it->is_boolean())
|
||||
return mode_it->get<bool>() ?
|
||||
int(TextureMappingZone::TDCalibrationAbsolute) :
|
||||
int(TextureMappingZone::TDCalibrationNone);
|
||||
}
|
||||
|
||||
const auto legacy_it = texture.find("transmission_distance_calibration_enabled");
|
||||
if (legacy_it != texture.end() && legacy_it->is_boolean())
|
||||
return legacy_it->get<bool>() ?
|
||||
int(TextureMappingZone::TDCalibrationAbsolute) :
|
||||
int(TextureMappingZone::TDCalibrationNone);
|
||||
|
||||
return TextureMappingZone::DefaultTransmissionDistanceCalibrationMode;
|
||||
}
|
||||
|
||||
static std::string normalized_prime_tower_color_mode_name(std::string name)
|
||||
{
|
||||
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) { return char(std::tolower(c)); });
|
||||
@@ -708,12 +767,14 @@ bool TextureMappingZone::operator==(const TextureMappingZone &rhs) const
|
||||
high_resolution_sampling == rhs.high_resolution_sampling &&
|
||||
std::abs(tone_gamma - rhs.tone_gamma) <= eps &&
|
||||
std::abs(sagging_ratio - rhs.sagging_ratio) <= eps &&
|
||||
transmission_distance_calibration_mode == rhs.transmission_distance_calibration_mode &&
|
||||
std::abs(preview_opacity_pct - rhs.preview_opacity_pct) <= eps &&
|
||||
preview_simulate_colors == rhs.preview_simulate_colors &&
|
||||
preview_limit_resolution == rhs.preview_limit_resolution &&
|
||||
auto_adjust_filament_selection == rhs.auto_adjust_filament_selection &&
|
||||
floats_equal(filament_strengths_pct, rhs.filament_strengths_pct) &&
|
||||
floats_equal(filament_minimum_offsets_pct, rhs.filament_minimum_offsets_pct);
|
||||
floats_equal(filament_minimum_offsets_pct, rhs.filament_minimum_offsets_pct) &&
|
||||
floats_equal(filament_transmission_distances_mm, rhs.filament_transmission_distances_mm);
|
||||
}
|
||||
|
||||
uint64_t TextureMappingManager::allocate_stable_id()
|
||||
@@ -796,6 +857,7 @@ void TextureMappingManager::remove_physical_filament(unsigned int deleted_filame
|
||||
};
|
||||
remove_index(zone.filament_strengths_pct);
|
||||
remove_index(zone.filament_minimum_offsets_pct);
|
||||
remove_index(zone.filament_transmission_distances_mm);
|
||||
}
|
||||
normalize_zone_ids(new_physical_count);
|
||||
}
|
||||
@@ -920,6 +982,8 @@ std::string TextureMappingManager::serialize_entries()
|
||||
const std::string normalized_angles = normalize_offset_angles(zone.offset_angles, component_ids.size());
|
||||
const std::vector<float> normalized_strengths = normalize_strengths(zone.filament_strengths_pct);
|
||||
const std::vector<float> normalized_min_offsets = normalize_minimum_offsets(zone.filament_minimum_offsets_pct);
|
||||
const std::vector<float> normalized_transmission_distances =
|
||||
normalize_transmission_distances(zone.filament_transmission_distances_mm);
|
||||
|
||||
nlohmann::json entry;
|
||||
entry["schema"] = 2;
|
||||
@@ -950,12 +1014,16 @@ std::string TextureMappingManager::serialize_entries()
|
||||
texture["high_resolution_sampling"] = zone.high_resolution_sampling;
|
||||
texture["tone_gamma"] = normalize_tone_gamma(zone.tone_gamma);
|
||||
texture["sagging_ratio"] = normalize_sagging_ratio(zone.sagging_ratio);
|
||||
texture["preview_opacity_pct"] = std::clamp(finite_or(zone.preview_opacity_pct, TextureMappingZone::DefaultPreviewOpacityPct), 0.f, 100.f);
|
||||
texture["transmission_distance_calibration"] =
|
||||
transmission_distance_calibration_mode_name(zone.transmission_distance_calibration_mode);
|
||||
texture["preview_opacity_pct"] =
|
||||
std::clamp(finite_or(zone.preview_opacity_pct, TextureMappingZone::DefaultPreviewOpacityPct), 0.f, 100.f);
|
||||
texture["simulate_preview_colors"] = zone.preview_simulate_colors;
|
||||
texture["limit_preview_resolution"] = zone.preview_limit_resolution;
|
||||
texture["auto_adjust_filaments"] = zone.auto_adjust_filament_selection;
|
||||
texture["strength_pct"] = floats_to_json(normalized_strengths);
|
||||
texture["minimum_offset_pct"] = floats_to_json(normalized_min_offsets);
|
||||
texture["transmission_distance_mm"] = floats_to_json(normalized_transmission_distances);
|
||||
entry["texture_options"] = std::move(texture);
|
||||
|
||||
nlohmann::json offset;
|
||||
@@ -1083,12 +1151,17 @@ void TextureMappingManager::load_entries(const std::string &serialized,
|
||||
zone.high_resolution_sampling = texture.value("high_resolution_sampling", true);
|
||||
zone.tone_gamma = normalize_tone_gamma(texture.value("tone_gamma", 1.f));
|
||||
zone.sagging_ratio = normalize_sagging_ratio(texture.value("sagging_ratio", 0.f));
|
||||
zone.preview_opacity_pct = std::clamp(texture.value("preview_opacity_pct", TextureMappingZone::DefaultPreviewOpacityPct), 0.f, 100.f);
|
||||
zone.transmission_distance_calibration_mode = transmission_distance_calibration_mode_from_json(texture);
|
||||
zone.preview_opacity_pct =
|
||||
std::clamp(texture.value("preview_opacity_pct", TextureMappingZone::DefaultPreviewOpacityPct), 0.f, 100.f);
|
||||
zone.preview_simulate_colors = texture.value("simulate_preview_colors", false);
|
||||
zone.preview_limit_resolution = texture.value("limit_preview_resolution", true);
|
||||
zone.auto_adjust_filament_selection = texture.value("auto_adjust_filaments", true);
|
||||
zone.filament_strengths_pct = normalize_strengths(floats_from_json(texture.value("strength_pct", nlohmann::json::array())));
|
||||
zone.filament_minimum_offsets_pct = normalize_minimum_offsets(floats_from_json(texture.value("minimum_offset_pct", nlohmann::json::array())));
|
||||
zone.filament_minimum_offsets_pct =
|
||||
normalize_minimum_offsets(floats_from_json(texture.value("minimum_offset_pct", nlohmann::json::array())));
|
||||
zone.filament_transmission_distances_mm =
|
||||
normalize_transmission_distances(floats_from_json(texture.value("transmission_distance_mm", nlohmann::json::array())));
|
||||
|
||||
const nlohmann::json offset = entry.value("surface_offset", nlohmann::json::object());
|
||||
zone.offset_distances =
|
||||
|
||||
@@ -69,6 +69,12 @@ struct TextureMappingZone
|
||||
GenericSolverPigmentPainter = 0
|
||||
};
|
||||
|
||||
enum TransmissionDistanceCalibrationMode : uint8_t {
|
||||
TDCalibrationNone = 0,
|
||||
TDCalibrationAbsolute = 1,
|
||||
TDCalibrationNeighbor = 2
|
||||
};
|
||||
|
||||
static constexpr int DefaultSurfacePattern = int(ImageTexture);
|
||||
static constexpr int DefaultOffsetMode = int(OffsetBasic);
|
||||
static constexpr bool DefaultOffsetRotationEnabled = true;
|
||||
@@ -93,6 +99,7 @@ struct TextureMappingZone
|
||||
static constexpr bool DefaultHighResolutionSampling = true;
|
||||
static constexpr float DefaultToneGamma = 1.f;
|
||||
static constexpr float DefaultSaggingRatio = 0.f;
|
||||
static constexpr int DefaultTransmissionDistanceCalibrationMode = int(TDCalibrationAbsolute);
|
||||
static constexpr bool DefaultPreviewSimulateColors = false;
|
||||
static constexpr bool DefaultPreviewLimitResolution = true;
|
||||
static constexpr bool DefaultAutoAdjustFilamentSelection = true;
|
||||
@@ -134,12 +141,14 @@ struct TextureMappingZone
|
||||
bool high_resolution_sampling = DefaultHighResolutionSampling;
|
||||
float tone_gamma = DefaultToneGamma;
|
||||
float sagging_ratio = DefaultSaggingRatio;
|
||||
int transmission_distance_calibration_mode = DefaultTransmissionDistanceCalibrationMode;
|
||||
float preview_opacity_pct = DefaultPreviewOpacityPct;
|
||||
bool preview_simulate_colors = DefaultPreviewSimulateColors;
|
||||
bool preview_limit_resolution = DefaultPreviewLimitResolution;
|
||||
bool auto_adjust_filament_selection = DefaultAutoAdjustFilamentSelection;
|
||||
std::vector<float> filament_strengths_pct;
|
||||
std::vector<float> filament_minimum_offsets_pct;
|
||||
std::vector<float> filament_transmission_distances_mm;
|
||||
|
||||
bool is_image_texture() const { return surface_pattern == int(ImageTexture); }
|
||||
bool is_2d_gradient() const { return surface_pattern == int(Gradient2D); }
|
||||
@@ -175,12 +184,14 @@ struct TextureMappingZone
|
||||
high_resolution_sampling = DefaultHighResolutionSampling;
|
||||
tone_gamma = DefaultToneGamma;
|
||||
sagging_ratio = DefaultSaggingRatio;
|
||||
transmission_distance_calibration_mode = DefaultTransmissionDistanceCalibrationMode;
|
||||
preview_opacity_pct = DefaultPreviewOpacityPct;
|
||||
preview_simulate_colors = DefaultPreviewSimulateColors;
|
||||
preview_limit_resolution = DefaultPreviewLimitResolution;
|
||||
auto_adjust_filament_selection = DefaultAutoAdjustFilamentSelection;
|
||||
filament_strengths_pct.clear();
|
||||
filament_minimum_offsets_pct.clear();
|
||||
filament_transmission_distances_mm.clear();
|
||||
}
|
||||
|
||||
bool has_custom_offset_settings() const
|
||||
|
||||
@@ -1023,8 +1023,9 @@ public:
|
||||
const std::vector<unsigned int> &component_ids,
|
||||
const std::vector<float> &component_strengths_pct,
|
||||
const std::vector<float> &component_minimum_offsets_pct,
|
||||
const std::vector<float> &component_transmission_distances_mm,
|
||||
int transmission_distance_calibration_mode,
|
||||
float tone_gamma,
|
||||
float sagging_ratio,
|
||||
float preview_opacity_pct,
|
||||
bool force_sequential_filaments,
|
||||
bool auto_adjust_filament_selection,
|
||||
@@ -1099,19 +1100,6 @@ public:
|
||||
tone_gamma_row->Add(new wxStaticText(image_page, wxID_ANY, _L("x")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
image_root->Add(tone_gamma_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
|
||||
auto *sagging_row = new wxBoxSizer(wxHORIZONTAL);
|
||||
sagging_row->Add(new wxStaticText(filament_page, wxID_ANY, _L("Sagging ratio limit")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
|
||||
m_sagging_ratio_spin = new wxSpinCtrlDouble(filament_page, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(84), -1),
|
||||
wxSP_ARROW_KEYS | wxALIGN_RIGHT, 0.0, 6.0, std::clamp(double(sagging_ratio), 0.0, 6.0), 0.1);
|
||||
m_sagging_ratio_spin->SetDigits(2);
|
||||
sagging_row->Add(m_sagging_ratio_spin, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap / 2);
|
||||
sagging_row->Add(new wxStaticText(filament_page, wxID_ANY, _L("x h")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
filament_root->Add(sagging_row, 0, wxEXPAND | wxALL, gap);
|
||||
|
||||
m_force_sequential_filaments_checkbox = new wxCheckBox(filament_page, wxID_ANY, _L("Force sequential order for filaments"));
|
||||
m_force_sequential_filaments_checkbox->SetValue(force_sequential_filaments);
|
||||
filament_root->Add(m_force_sequential_filaments_checkbox, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
|
||||
auto *minimum_offsets_box = new wxStaticBoxSizer(wxVERTICAL, filament_page, _L("Per-filament minimum offset"));
|
||||
auto *strengths_box = new wxStaticBoxSizer(wxVERTICAL, filament_page, _L("Per-filament strength"));
|
||||
const std::vector<wxString> channel_labels = texture_mapping_channel_labels(filament_color_mode);
|
||||
@@ -1147,11 +1135,15 @@ public:
|
||||
box->Add(row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap);
|
||||
};
|
||||
for (size_t i = 0; i < component_ids.size(); ++i) {
|
||||
const int offset_value = i < component_minimum_offsets_pct.size() ? std::clamp(int(std::lround(component_minimum_offsets_pct[i])), 0, 100) : 0;
|
||||
const int offset_value = i < component_minimum_offsets_pct.size() ?
|
||||
std::clamp(int(std::lround(component_minimum_offsets_pct[i])), 0, 100) :
|
||||
0;
|
||||
add_percent_row(minimum_offsets_box, i, offset_value, m_minimum_offset_sliders, m_minimum_offset_spins);
|
||||
}
|
||||
for (size_t i = 0; i < component_ids.size(); ++i) {
|
||||
const int strength_value = i < component_strengths_pct.size() ? std::clamp(int(std::lround(component_strengths_pct[i])), 0, 100) : 100;
|
||||
const int strength_value = i < component_strengths_pct.size() ?
|
||||
std::clamp(int(std::lround(component_strengths_pct[i])), 0, 100) :
|
||||
100;
|
||||
add_percent_row(strengths_box, i, strength_value, m_strength_sliders, m_strength_spins);
|
||||
}
|
||||
filament_root->Add(minimum_offsets_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
@@ -1160,9 +1152,59 @@ public:
|
||||
reset_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { reset_strengths_and_offsets(); });
|
||||
filament_root->Add(reset_btn, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
|
||||
auto *td_box = new wxStaticBoxSizer(wxVERTICAL, filament_page, _L("Transmission distance"));
|
||||
auto *td_mode_row = new wxBoxSizer(wxHORIZONTAL);
|
||||
td_mode_row->Add(new wxStaticText(filament_page, wxID_ANY, _L("TD calibration mode")),
|
||||
0,
|
||||
wxALIGN_CENTER_VERTICAL | wxRIGHT,
|
||||
gap);
|
||||
wxArrayString td_mode_choices;
|
||||
td_mode_choices.Add(_L("None"));
|
||||
td_mode_choices.Add(_L("Absolute"));
|
||||
td_mode_choices.Add(_L("Neighbor"));
|
||||
m_transmission_distance_calibration_mode_choice =
|
||||
new wxChoice(filament_page, wxID_ANY, wxDefaultPosition, wxDefaultSize, td_mode_choices);
|
||||
m_transmission_distance_calibration_mode_choice->SetSelection(
|
||||
std::clamp(transmission_distance_calibration_mode,
|
||||
int(TextureMappingZone::TDCalibrationNone),
|
||||
int(TextureMappingZone::TDCalibrationNeighbor)));
|
||||
td_mode_row->Add(m_transmission_distance_calibration_mode_choice, 1, wxALIGN_CENTER_VERTICAL);
|
||||
td_box->Add(td_mode_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap);
|
||||
for (size_t i = 0; i < component_ids.size(); ++i) {
|
||||
auto *row = new wxBoxSizer(wxHORIZONTAL);
|
||||
row->Add(new wxStaticText(filament_page, wxID_ANY, component_label(i)), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
|
||||
const double value = i < component_transmission_distances_mm.size() ?
|
||||
std::clamp(double(component_transmission_distances_mm[i]), 0.0, 50.0) :
|
||||
0.0;
|
||||
auto *spin = new wxSpinCtrlDouble(filament_page,
|
||||
wxID_ANY,
|
||||
wxEmptyString,
|
||||
wxDefaultPosition,
|
||||
wxSize(FromDIP(84), -1),
|
||||
wxSP_ARROW_KEYS | wxALIGN_RIGHT,
|
||||
0.0,
|
||||
50.0,
|
||||
value,
|
||||
0.1);
|
||||
spin->SetDigits(2);
|
||||
row->Add(spin, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap / 2);
|
||||
row->Add(new wxStaticText(filament_page, wxID_ANY, _L("mm")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
m_transmission_distance_spins.emplace_back(spin);
|
||||
td_box->Add(row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap);
|
||||
}
|
||||
filament_root->Add(td_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
|
||||
m_force_sequential_filaments_checkbox =
|
||||
new wxCheckBox(filament_page, wxID_ANY, _L("Force sequential order for filaments"));
|
||||
m_force_sequential_filaments_checkbox->SetValue(force_sequential_filaments);
|
||||
filament_root->Add(m_force_sequential_filaments_checkbox, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
|
||||
auto *preview_box = new wxStaticBoxSizer(wxVERTICAL, preview_page, _L("3D Preview"));
|
||||
auto *preview_opacity_row = new wxBoxSizer(wxHORIZONTAL);
|
||||
preview_opacity_row->Add(new wxStaticText(preview_page, wxID_ANY, _L("Texture opacity")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
|
||||
preview_opacity_row->Add(new wxStaticText(preview_page, wxID_ANY, _L("Texture opacity")),
|
||||
0,
|
||||
wxALIGN_CENTER_VERTICAL | wxRIGHT,
|
||||
gap);
|
||||
const int opacity = std::clamp(int(std::lround(preview_opacity_pct)), 0, 100);
|
||||
m_preview_opacity_slider = new wxSlider(preview_page, wxID_ANY, opacity, 0, 100, wxDefaultPosition, wxSize(FromDIP(180), -1), wxSL_HORIZONTAL | wxSL_AUTOTICKS);
|
||||
m_preview_opacity_spin = new wxSpinCtrl(preview_page, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(70), -1),
|
||||
@@ -1391,7 +1433,15 @@ 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 sagging_ratio() const { return float(std::clamp(m_sagging_ratio_spin ? m_sagging_ratio_spin->GetValue() : 0.0, 0.0, 6.0)); }
|
||||
int transmission_distance_calibration_mode() const
|
||||
{
|
||||
return m_transmission_distance_calibration_mode_choice ?
|
||||
std::clamp(m_transmission_distance_calibration_mode_choice->GetSelection(),
|
||||
int(TextureMappingZone::TDCalibrationNone),
|
||||
int(TextureMappingZone::TDCalibrationNeighbor)) :
|
||||
TextureMappingZone::DefaultTransmissionDistanceCalibrationMode;
|
||||
}
|
||||
|
||||
float preview_opacity_pct() const { return float(std::clamp(m_preview_opacity_spin ? m_preview_opacity_spin->GetValue() : 100, 0, 100)); }
|
||||
bool force_sequential_filaments() const { return m_force_sequential_filaments_checkbox && m_force_sequential_filaments_checkbox->GetValue(); }
|
||||
bool auto_adjust_filament_selection() const { return m_auto_adjust_filament_selection_checkbox == nullptr || m_auto_adjust_filament_selection_checkbox->GetValue(); }
|
||||
@@ -1482,6 +1532,17 @@ public:
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<float> component_transmission_distances_mm() const
|
||||
{
|
||||
std::vector<float> out;
|
||||
out.reserve(m_transmission_distance_spins.size());
|
||||
for (wxSpinCtrlDouble *spin : m_transmission_distance_spins) {
|
||||
const double value = spin ? spin->GetValue() : 0.0;
|
||||
out.emplace_back(value > 0.0 ? float(std::clamp(value, 0.01, 50.0)) : 0.f);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string prime_tower_color_mode_name(int selection)
|
||||
{
|
||||
@@ -1612,7 +1673,7 @@ private:
|
||||
wxSimplebook *m_options_book {nullptr};
|
||||
wxChoice *m_texture_mapping_mode_choice {nullptr};
|
||||
wxSpinCtrlDouble *m_tone_gamma_spin {nullptr};
|
||||
wxSpinCtrlDouble *m_sagging_ratio_spin {nullptr};
|
||||
wxChoice *m_transmission_distance_calibration_mode_choice {nullptr};
|
||||
wxSlider *m_preview_opacity_slider {nullptr};
|
||||
wxSpinCtrl *m_preview_opacity_spin {nullptr};
|
||||
wxCheckBox *m_force_sequential_filaments_checkbox {nullptr};
|
||||
@@ -1640,6 +1701,7 @@ private:
|
||||
std::vector<wxSpinCtrl*> m_minimum_offset_spins;
|
||||
std::vector<wxSlider*> m_strength_sliders;
|
||||
std::vector<wxSpinCtrl*> m_strength_spins;
|
||||
std::vector<wxSpinCtrlDouble*> m_transmission_distance_spins;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -5551,19 +5613,35 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
apply_zone(std::move(updated));
|
||||
update_texture_mapping_panel(false);
|
||||
});
|
||||
advanced_btn->Bind(wxEVT_BUTTON, [this, zone_index, mgr_ptr, palette, apply_zone, bundle, set_config_string](wxCommandEvent &) {
|
||||
advanced_btn->Bind(wxEVT_BUTTON, [this,
|
||||
zone_index,
|
||||
mgr_ptr,
|
||||
palette,
|
||||
physical_colors,
|
||||
apply_zone,
|
||||
bundle,
|
||||
set_config_string](wxCommandEvent &) {
|
||||
if (zone_index >= mgr_ptr->zones().size())
|
||||
return;
|
||||
TextureMappingZone updated = mgr_ptr->zones()[zone_index];
|
||||
const std::vector<unsigned int> ids = texture_mapping_selected_ids(updated, palette.size());
|
||||
std::vector<unsigned int> ids = updated.is_image_texture() ?
|
||||
TextureMappingManager::effective_texture_component_ids(updated, palette.size(), physical_colors) :
|
||||
texture_mapping_selected_ids(updated, palette.size());
|
||||
if (ids.empty())
|
||||
ids = texture_mapping_selected_ids(updated, palette.size());
|
||||
std::vector<float> strengths;
|
||||
std::vector<float> offsets;
|
||||
std::vector<float> transmission_distances;
|
||||
strengths.reserve(ids.size());
|
||||
offsets.reserve(ids.size());
|
||||
transmission_distances.reserve(ids.size());
|
||||
for (const unsigned int id : ids) {
|
||||
const size_t idx = id > 0 ? size_t(id - 1) : size_t(0);
|
||||
strengths.emplace_back(idx < updated.filament_strengths_pct.size() ? updated.filament_strengths_pct[idx] : 100.f);
|
||||
offsets.emplace_back(idx < updated.filament_minimum_offsets_pct.size() ? updated.filament_minimum_offsets_pct[idx] : 0.f);
|
||||
transmission_distances.emplace_back(idx < updated.filament_transmission_distances_mm.size() ?
|
||||
updated.filament_transmission_distances_mm[idx] :
|
||||
0.f);
|
||||
}
|
||||
TextureMappingAdvancedOptionsDialog dlg(this,
|
||||
updated.texture_mapping_mode,
|
||||
@@ -5571,8 +5649,9 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
ids,
|
||||
strengths,
|
||||
offsets,
|
||||
transmission_distances,
|
||||
updated.transmission_distance_calibration_mode,
|
||||
updated.tone_gamma,
|
||||
updated.sagging_ratio,
|
||||
updated.preview_opacity_pct,
|
||||
updated.force_sequential_filaments,
|
||||
updated.auto_adjust_filament_selection,
|
||||
@@ -5596,7 +5675,8 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
return;
|
||||
updated.texture_mapping_mode = dlg.texture_mapping_mode();
|
||||
updated.tone_gamma = dlg.tone_gamma();
|
||||
updated.sagging_ratio = dlg.sagging_ratio();
|
||||
updated.sagging_ratio = TextureMappingZone::DefaultSaggingRatio;
|
||||
updated.transmission_distance_calibration_mode = dlg.transmission_distance_calibration_mode();
|
||||
updated.preview_opacity_pct = dlg.preview_opacity_pct();
|
||||
updated.force_sequential_filaments = dlg.force_sequential_filaments();
|
||||
updated.auto_adjust_filament_selection = dlg.auto_adjust_filament_selection();
|
||||
@@ -5634,6 +5714,15 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
updated.filament_minimum_offsets_pct[size_t(ids[i] - 1)] = dlg_offsets[i];
|
||||
while (!updated.filament_minimum_offsets_pct.empty() && std::abs(updated.filament_minimum_offsets_pct.back()) <= 1e-6f)
|
||||
updated.filament_minimum_offsets_pct.pop_back();
|
||||
if (updated.filament_transmission_distances_mm.size() < palette.size())
|
||||
updated.filament_transmission_distances_mm.resize(palette.size(), 0.f);
|
||||
const std::vector<float> dlg_transmission_distances = dlg.component_transmission_distances_mm();
|
||||
for (size_t i = 0; i < ids.size() && i < dlg_transmission_distances.size(); ++i)
|
||||
if (ids[i] > 0 && size_t(ids[i] - 1) < updated.filament_transmission_distances_mm.size())
|
||||
updated.filament_transmission_distances_mm[size_t(ids[i] - 1)] = dlg_transmission_distances[i];
|
||||
while (!updated.filament_transmission_distances_mm.empty() &&
|
||||
std::abs(updated.filament_transmission_distances_mm.back()) <= 1e-6f)
|
||||
updated.filament_transmission_distances_mm.pop_back();
|
||||
apply_zone(std::move(updated));
|
||||
if (p->plater != nullptr && !p->plater->is_preview_shown()) {
|
||||
if (GLCanvas3D *canvas = p->plater->get_view3D_canvas3D())
|
||||
|
||||
Reference in New Issue
Block a user