Allow using top-surface coloring with side-surface variable line width modulation mode. Add boundary skin mode with more overlap
- Improve warnings for nearest measured sample mode fallback
This commit is contained in:
@@ -2098,6 +2098,87 @@ static int top_surface_image_contoning_label_valid_depth(const TopSurfaceImageCo
|
||||
return label.valid_depth > 0 ? label.valid_depth : int(label.bottom_to_top.size());
|
||||
}
|
||||
|
||||
static double top_surface_image_contoning_grid_cell_area_mm2(
|
||||
int row,
|
||||
int col,
|
||||
coord_t min_x,
|
||||
coord_t min_y,
|
||||
coord_t step,
|
||||
const BoundingBox &bbox)
|
||||
{
|
||||
const coord_t x0 = min_x + coord_t(col) * step;
|
||||
const coord_t y0 = min_y + coord_t(row) * step;
|
||||
const coord_t x1 = std::min<coord_t>(x0 + step, bbox.max.x());
|
||||
const coord_t y1 = std::min<coord_t>(y0 + step, bbox.max.y());
|
||||
if (x1 <= x0 || y1 <= y0)
|
||||
return 0.;
|
||||
return unscale<double>(x1 - x0) * unscale<double>(y1 - y0);
|
||||
}
|
||||
|
||||
static void top_surface_image_contoning_record_nearest_measured_sample_fallback_area(
|
||||
const std::vector<int> &label_grid,
|
||||
int cols,
|
||||
int rows,
|
||||
const std::vector<TopSurfaceImageContoningVectorLabel> &labels,
|
||||
const std::vector<std::optional<TopSurfaceImageContoningCellSample>> &cell_samples,
|
||||
const TextureMappingContoningSolver &solver,
|
||||
bool lower_surface,
|
||||
const std::vector<float> &surface_to_deep_layer_heights_mm,
|
||||
const std::vector<int> &surface_to_deep_layer_ids,
|
||||
coord_t min_x,
|
||||
coord_t min_y,
|
||||
coord_t step,
|
||||
const BoundingBox &bbox,
|
||||
const ThrowIfCanceled *throw_if_canceled)
|
||||
{
|
||||
if (!solver.nearest_measured_sample_mode() ||
|
||||
label_grid.empty() ||
|
||||
labels.empty() ||
|
||||
cols <= 0 ||
|
||||
rows <= 0 ||
|
||||
label_grid.size() != size_t(cols) * size_t(rows) ||
|
||||
cell_samples.size() != label_grid.size())
|
||||
return;
|
||||
|
||||
std::vector<unsigned char> fallback_labels(labels.size(), 0);
|
||||
for (size_t label_idx = 0; label_idx < labels.size(); ++label_idx) {
|
||||
const TopSurfaceImageContoningVectorLabel &label = labels[label_idx];
|
||||
if (label.bottom_to_top.empty())
|
||||
continue;
|
||||
const int visible_depth = top_surface_image_contoning_label_valid_depth(label);
|
||||
fallback_labels[label_idx] =
|
||||
!solver.nearest_measured_sample_stack_compatible(int(label.bottom_to_top.size()),
|
||||
visible_depth,
|
||||
surface_to_deep_layer_heights_mm,
|
||||
surface_to_deep_layer_ids,
|
||||
lower_surface);
|
||||
}
|
||||
|
||||
double fallback_area_mm2 = 0.;
|
||||
double total_area_mm2 = 0.;
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
if ((row & 15) == 0)
|
||||
check_canceled(throw_if_canceled);
|
||||
for (int col = 0; col < cols; ++col) {
|
||||
const size_t grid_idx = size_t(row * cols + col);
|
||||
if (!cell_samples[grid_idx])
|
||||
continue;
|
||||
const int label = label_grid[grid_idx];
|
||||
if (label < 0 || label >= int(labels.size()))
|
||||
continue;
|
||||
const double area_mm2 =
|
||||
top_surface_image_contoning_grid_cell_area_mm2(row, col, min_x, min_y, step, bbox);
|
||||
if (area_mm2 <= 0.)
|
||||
continue;
|
||||
total_area_mm2 += area_mm2;
|
||||
if (fallback_labels[size_t(label)])
|
||||
fallback_area_mm2 += area_mm2;
|
||||
}
|
||||
}
|
||||
|
||||
solver.record_nearest_measured_sample_fallback_area(lower_surface, fallback_area_mm2, total_area_mm2);
|
||||
}
|
||||
|
||||
struct TopSurfaceImageContoningDepthRegionPlan {
|
||||
std::vector<std::vector<TopSurfaceImageContoningVectorRegion>> fill_regions_by_depth;
|
||||
std::vector<std::vector<TopSurfaceImageContoningVectorRegion>> perimeter_regions_by_depth;
|
||||
@@ -6363,6 +6444,20 @@ static void top_surface_image_contoning_solve_anchored_region(
|
||||
top_surface_image_debug_elapsed_ms(debug_step_start),
|
||||
grid_cells,
|
||||
true);
|
||||
top_surface_image_contoning_record_nearest_measured_sample_fallback_area(grid,
|
||||
cols,
|
||||
rows,
|
||||
labels,
|
||||
cell_samples,
|
||||
solver,
|
||||
lower_surface,
|
||||
source_context.surface_to_deep_layer_heights_mm,
|
||||
source_context.surface_to_deep_layer_ids,
|
||||
min_x,
|
||||
min_y,
|
||||
step,
|
||||
bbox,
|
||||
throw_if_canceled);
|
||||
}
|
||||
check_canceled(throw_if_canceled);
|
||||
if (debug_enabled)
|
||||
@@ -8016,6 +8111,20 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
|
||||
source->surface_to_deep_layer_heights_mm,
|
||||
source->surface_to_deep_layer_ids,
|
||||
throw_if_canceled);
|
||||
top_surface_image_contoning_record_nearest_measured_sample_fallback_area(grid,
|
||||
cols,
|
||||
rows,
|
||||
labels,
|
||||
cell_samples,
|
||||
solver,
|
||||
source_surface == TopSurfaceImageSourceSurface::Bottom,
|
||||
source->surface_to_deep_layer_heights_mm,
|
||||
source->surface_to_deep_layer_ids,
|
||||
min_x,
|
||||
min_y,
|
||||
step,
|
||||
bbox,
|
||||
throw_if_canceled);
|
||||
}
|
||||
check_canceled(throw_if_canceled);
|
||||
|
||||
@@ -8247,6 +8356,20 @@ static std::shared_ptr<const TopSurfaceImageContoningStackPlan> top_surface_imag
|
||||
source_context->surface_to_deep_layer_heights_mm,
|
||||
source_context->surface_to_deep_layer_ids,
|
||||
throw_if_canceled);
|
||||
top_surface_image_contoning_record_nearest_measured_sample_fallback_area(grid,
|
||||
cols,
|
||||
rows,
|
||||
out->labels,
|
||||
cell_samples,
|
||||
solver,
|
||||
source_surface == TopSurfaceImageSourceSurface::Bottom,
|
||||
source_context->surface_to_deep_layer_heights_mm,
|
||||
source_context->surface_to_deep_layer_ids,
|
||||
min_x,
|
||||
min_y,
|
||||
step,
|
||||
bbox,
|
||||
throw_if_canceled);
|
||||
}
|
||||
for (size_t idx = 0; idx < out->cells.size(); ++idx)
|
||||
out->cells[idx].label = grid[idx];
|
||||
@@ -8663,6 +8786,95 @@ static std::string top_surface_image_contoning_nearest_measured_sample_fallback_
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static std::string top_surface_image_contoning_format_area_value(double value, int large_precision, int medium_precision, int small_precision)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
const double abs_value = std::abs(value);
|
||||
int precision = small_precision;
|
||||
if (abs_value >= 100.)
|
||||
precision = large_precision;
|
||||
else if (abs_value >= 1.)
|
||||
precision = medium_precision;
|
||||
ss << std::fixed << std::setprecision(precision) << value;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static std::string top_surface_image_contoning_format_fallback_percentage(double fallback_area_mm2, double total_area_mm2)
|
||||
{
|
||||
if (!std::isfinite(fallback_area_mm2) ||
|
||||
!std::isfinite(total_area_mm2) ||
|
||||
total_area_mm2 <= 0.)
|
||||
return {};
|
||||
const double pct = std::clamp(100. * fallback_area_mm2 / total_area_mm2, 0., 100.);
|
||||
std::ostringstream ss;
|
||||
int precision = 5;
|
||||
if (pct >= 10.)
|
||||
precision = 1;
|
||||
else if (pct >= 1.)
|
||||
precision = 2;
|
||||
else if (pct >= 0.01)
|
||||
precision = 3;
|
||||
ss << std::fixed << std::setprecision(precision) << pct;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static double top_surface_image_contoning_fallback_percentage_value(
|
||||
const TextureMappingContoningNearestMeasuredSampleFallbackArea &area)
|
||||
{
|
||||
if (!std::isfinite(area.fallback_area_mm2) ||
|
||||
!std::isfinite(area.total_area_mm2) ||
|
||||
area.total_area_mm2 <= 0.)
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
return std::clamp(100. * area.fallback_area_mm2 / area.total_area_mm2, 0., 100.);
|
||||
}
|
||||
|
||||
static std::optional<TextureMappingContoningNearestMeasuredSampleFallbackArea>
|
||||
top_surface_image_contoning_nearest_measured_sample_total_fallback_area(
|
||||
const TextureMappingContoningSolver &solver,
|
||||
bool upper_nearest_sample_fallback,
|
||||
bool lower_nearest_sample_fallback)
|
||||
{
|
||||
TextureMappingContoningNearestMeasuredSampleFallbackArea total_area;
|
||||
bool has_area = false;
|
||||
auto add_area = [&](bool lower_surface) {
|
||||
const TextureMappingContoningNearestMeasuredSampleFallbackArea area =
|
||||
solver.nearest_measured_sample_fallback_area(lower_surface);
|
||||
if (!std::isfinite(area.total_area_mm2) || area.total_area_mm2 <= 0.)
|
||||
return;
|
||||
total_area.fallback_area_mm2 += std::max(0., area.fallback_area_mm2);
|
||||
total_area.total_area_mm2 += area.total_area_mm2;
|
||||
has_area = true;
|
||||
};
|
||||
|
||||
if (upper_nearest_sample_fallback)
|
||||
add_area(false);
|
||||
if (lower_nearest_sample_fallback)
|
||||
add_area(true);
|
||||
if (!has_area || total_area.total_area_mm2 <= 0.)
|
||||
return std::nullopt;
|
||||
return total_area;
|
||||
}
|
||||
|
||||
static std::string top_surface_image_contoning_nearest_measured_sample_fallback_area_details(
|
||||
const TextureMappingContoningNearestMeasuredSampleFallbackArea &total_area)
|
||||
{
|
||||
if (total_area.total_area_mm2 <= 0.)
|
||||
return {};
|
||||
|
||||
const std::string pct =
|
||||
top_surface_image_contoning_format_fallback_percentage(total_area.fallback_area_mm2, total_area.total_area_mm2);
|
||||
if (pct.empty())
|
||||
return {};
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "Fallback affected " << pct << "% of sampled surface area ("
|
||||
<< top_surface_image_contoning_format_area_value(total_area.fallback_area_mm2, 1, 2, 3)
|
||||
<< " mm2 of "
|
||||
<< top_surface_image_contoning_format_area_value(total_area.total_area_mm2, 1, 2, 3)
|
||||
<< " mm2).";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
struct TopSurfaceImageContoningComponentArea {
|
||||
unsigned int component_id = 0;
|
||||
ExPolygons area;
|
||||
@@ -9135,7 +9347,7 @@ static std::vector<TopSurfaceImageRegionPlan> top_surface_image_region_plans(
|
||||
plan.contoning_flat_surface_infill_mode =
|
||||
std::clamp(zone->effective_top_surface_contoning_flat_surface_infill_mode(),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinear),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillAdaptiveLines));
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap));
|
||||
plan.contoning_layer_phase_enabled = zone->effective_top_surface_contoning_layer_phase_enabled();
|
||||
plan.contoning_varied_infill_angles_enabled = zone->top_surface_contoning_varied_infill_angles_enabled;
|
||||
plan.contoning_blue_noise_error_diffusion_enabled =
|
||||
@@ -9279,32 +9491,47 @@ static std::vector<TopSurfaceImageRegionPlan> top_surface_image_region_plans(
|
||||
const bool upper_nearest_sample_fallback = contoning_solver.nearest_measured_sample_fallback_used(false);
|
||||
const bool lower_nearest_sample_fallback = contoning_solver.nearest_measured_sample_fallback_used(true);
|
||||
if ((upper_nearest_sample_fallback || lower_nearest_sample_fallback) && object != nullptr) {
|
||||
const char *surface_name =
|
||||
upper_nearest_sample_fallback && lower_nearest_sample_fallback ?
|
||||
"upper and lower surfaces" :
|
||||
(upper_nearest_sample_fallback ? "upper surfaces" : "lower surfaces");
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> fallback_issues;
|
||||
if (upper_nearest_sample_fallback) {
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> upper_issues =
|
||||
contoning_solver.nearest_measured_sample_fallback_issues(false);
|
||||
fallback_issues.insert(fallback_issues.end(), upper_issues.begin(), upper_issues.end());
|
||||
const std::optional<TextureMappingContoningNearestMeasuredSampleFallbackArea> fallback_area =
|
||||
top_surface_image_contoning_nearest_measured_sample_total_fallback_area(contoning_solver,
|
||||
upper_nearest_sample_fallback,
|
||||
lower_nearest_sample_fallback);
|
||||
const double fallback_pct =
|
||||
fallback_area ? top_surface_image_contoning_fallback_percentage_value(*fallback_area) :
|
||||
std::numeric_limits<double>::quiet_NaN();
|
||||
if (!std::isfinite(fallback_pct) || fallback_pct >= 0.01) {
|
||||
const char *surface_name =
|
||||
upper_nearest_sample_fallback && lower_nearest_sample_fallback ?
|
||||
"upper and lower surfaces" :
|
||||
(upper_nearest_sample_fallback ? "upper surfaces" : "lower surfaces");
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> fallback_issues;
|
||||
if (upper_nearest_sample_fallback) {
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> upper_issues =
|
||||
contoning_solver.nearest_measured_sample_fallback_issues(false);
|
||||
fallback_issues.insert(fallback_issues.end(), upper_issues.begin(), upper_issues.end());
|
||||
}
|
||||
if (lower_nearest_sample_fallback) {
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> lower_issues =
|
||||
contoning_solver.nearest_measured_sample_fallback_issues(true);
|
||||
fallback_issues.insert(fallback_issues.end(), lower_issues.begin(), lower_issues.end());
|
||||
}
|
||||
std::string warning = Slic3r::format(
|
||||
L("Top-surface color prediction fell back from calibrated nearest measured sample to %1% for %2% because the current layer heights or stack depth do not match the calibration sheet."),
|
||||
contoning_solver.nearest_measured_sample_fallback_name(),
|
||||
surface_name);
|
||||
const std::string details =
|
||||
top_surface_image_contoning_nearest_measured_sample_fallback_details(fallback_issues);
|
||||
if (!details.empty())
|
||||
warning += " " + details;
|
||||
if (fallback_area) {
|
||||
const std::string area_details =
|
||||
top_surface_image_contoning_nearest_measured_sample_fallback_area_details(*fallback_area);
|
||||
if (!area_details.empty())
|
||||
warning += " " + area_details;
|
||||
}
|
||||
object->add_slicing_warning(
|
||||
PrintStateBase::WarningLevel::NON_CRITICAL,
|
||||
warning);
|
||||
}
|
||||
if (lower_nearest_sample_fallback) {
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> lower_issues =
|
||||
contoning_solver.nearest_measured_sample_fallback_issues(true);
|
||||
fallback_issues.insert(fallback_issues.end(), lower_issues.begin(), lower_issues.end());
|
||||
}
|
||||
std::string warning = Slic3r::format(
|
||||
L("Top-surface color prediction fell back from calibrated nearest measured sample to %1% for %2% because the current layer heights or stack depth do not match the calibration sheet."),
|
||||
contoning_solver.nearest_measured_sample_fallback_name(),
|
||||
surface_name);
|
||||
const std::string details =
|
||||
top_surface_image_contoning_nearest_measured_sample_fallback_details(fallback_issues);
|
||||
if (!details.empty())
|
||||
warning += " " + details;
|
||||
object->add_slicing_warning(
|
||||
PrintStateBase::WarningLevel::NON_CRITICAL,
|
||||
warning);
|
||||
}
|
||||
} else {
|
||||
for (int depth = 0; depth < stack_depth; ++depth) {
|
||||
@@ -10867,6 +11094,7 @@ static bool top_surface_image_contoning_boundary_skin_mode(int mode)
|
||||
{
|
||||
return mode == int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinFixed) ||
|
||||
mode == int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable) ||
|
||||
mode == int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap) ||
|
||||
mode == int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinHybrid);
|
||||
}
|
||||
|
||||
@@ -14599,7 +14827,12 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree,
|
||||
surface_fill.params.texture_mapping_top_surface_contoning_flat_surface_infill_mode)) {
|
||||
const bool variable_width_boundary_skin =
|
||||
surface_fill.params.texture_mapping_top_surface_contoning_flat_surface_infill_mode ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable);
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable) ||
|
||||
surface_fill.params.texture_mapping_top_surface_contoning_flat_surface_infill_mode ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap);
|
||||
const bool overlap_boundary_skin =
|
||||
surface_fill.params.texture_mapping_top_surface_contoning_flat_surface_infill_mode ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap);
|
||||
const bool hybrid_boundary_skin =
|
||||
surface_fill.params.texture_mapping_top_surface_contoning_flat_surface_infill_mode ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinHybrid);
|
||||
@@ -14626,7 +14859,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree,
|
||||
fallback_params.flow = fallback_flow;
|
||||
fallback_params.pattern = ipRectilinear;
|
||||
fallback_params.no_edge_overlap = true;
|
||||
fallback_params.edge_overlap_width_factor = 0.0f;
|
||||
fallback_params.edge_overlap_width_factor =
|
||||
overlap_boundary_skin ? 1.0f : (variable_width_boundary_skin ? 0.5f : 0.0f);
|
||||
ExtrusionEntitiesPtr hybrid_interior_entities;
|
||||
if (!hybrid_boundary_skin && collection && !collection->empty()) {
|
||||
apply_top_surface_image_collection_metadata(*collection, surface_fill.params, std::nullopt, throw_if_canceled_ptr);
|
||||
|
||||
@@ -2358,6 +2358,7 @@ static std::vector<PerimeterPathBoundarySample> perimeter_texture_sample_polygon
|
||||
const ExPolygon &source,
|
||||
const std::vector<ExPolygons> &erode_ladder,
|
||||
float erode_step_mm,
|
||||
bool disable_smoothing,
|
||||
const PerimeterTextureMaskIndex *top_visible_recolor_mask = nullptr,
|
||||
const PerimeterTextureTopVisibleRecolorThresholds *top_visible_recolor_thresholds = nullptr)
|
||||
{
|
||||
@@ -2450,7 +2451,8 @@ static std::vector<PerimeterPathBoundarySample> perimeter_texture_sample_polygon
|
||||
samples[idx].inset_mm = smoothed[idx];
|
||||
};
|
||||
|
||||
smooth_insets(std::max(0.30f, 1.15f * context.base_outer_width_mm));
|
||||
if (!disable_smoothing)
|
||||
smooth_insets(std::max(0.30f, 1.15f * context.base_outer_width_mm));
|
||||
|
||||
for (int pass = 0; pass < 4; ++pass) {
|
||||
for (size_t idx = 0; idx < samples.size(); ++idx) {
|
||||
@@ -2467,7 +2469,8 @@ static std::vector<PerimeterPathBoundarySample> perimeter_texture_sample_polygon
|
||||
}
|
||||
}
|
||||
|
||||
smooth_insets(std::max(0.20f, 0.45f * context.base_outer_width_mm));
|
||||
if (!disable_smoothing)
|
||||
smooth_insets(std::max(0.20f, 0.45f * context.base_outer_width_mm));
|
||||
|
||||
return samples;
|
||||
}
|
||||
@@ -2496,6 +2499,7 @@ static Polygon perimeter_texture_moved_polygon_from_samples(const std::vector<Pe
|
||||
|
||||
static ExPolygons perimeter_texture_modulated_expolygon(const ExPolygon &source,
|
||||
const TextureMappingOffsetContext &context,
|
||||
bool disable_smoothing,
|
||||
const ExPolygons *top_visible_recolor_mask,
|
||||
const PerimeterTextureTopVisibleRecolorThresholds *top_visible_recolor_thresholds,
|
||||
bool &ok)
|
||||
@@ -2522,6 +2526,7 @@ static ExPolygons perimeter_texture_modulated_expolygon(const ExPolygon &source,
|
||||
source,
|
||||
erode_ladder,
|
||||
erode_step_mm,
|
||||
disable_smoothing,
|
||||
protection_mask_ptr,
|
||||
top_visible_recolor_thresholds);
|
||||
if (contour_samples.size() < 3)
|
||||
@@ -2542,6 +2547,7 @@ static ExPolygons perimeter_texture_modulated_expolygon(const ExPolygon &source,
|
||||
source,
|
||||
erode_ladder,
|
||||
erode_step_mm,
|
||||
disable_smoothing,
|
||||
protection_mask_ptr,
|
||||
top_visible_recolor_thresholds));
|
||||
if (hole_samples.back().size() < 3)
|
||||
@@ -2633,10 +2639,18 @@ static SurfaceCollection perimeter_path_modulated_surfaces(const LayerRegion
|
||||
|
||||
SurfaceCollection out;
|
||||
out.surfaces.reserve(slices.surfaces.size());
|
||||
const bool disable_smoothing =
|
||||
zone.uses_perimeter_path_modulation_v2() &&
|
||||
zone.disable_v2_perimeter_path_modulation_smoothing;
|
||||
for (const Surface &surface : slices.surfaces) {
|
||||
bool ok = false;
|
||||
ExPolygons modulated =
|
||||
perimeter_texture_modulated_expolygon(surface.expolygon, *context, top_visible_recolor_mask, top_visible_recolor_thresholds, ok);
|
||||
perimeter_texture_modulated_expolygon(surface.expolygon,
|
||||
*context,
|
||||
disable_smoothing,
|
||||
top_visible_recolor_mask,
|
||||
top_visible_recolor_thresholds,
|
||||
ok);
|
||||
if (ok && !modulated.empty())
|
||||
out.append(std::move(modulated), surface);
|
||||
else
|
||||
|
||||
@@ -853,7 +853,7 @@ static std::string top_surface_contoning_flat_surface_infill_mode_name(int mode)
|
||||
{
|
||||
switch (clamp_int(mode,
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillDefault),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillAdaptiveLines))) {
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap))) {
|
||||
case int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinear):
|
||||
return "rectilinear";
|
||||
case int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinearWithBoundary):
|
||||
@@ -866,6 +866,8 @@ static std::string top_surface_contoning_flat_surface_infill_mode_name(int mode)
|
||||
return "boundary_skin_fixed";
|
||||
case int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable):
|
||||
return "boundary_skin_variable";
|
||||
case int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap):
|
||||
return "boundary_skin_variable_overlap";
|
||||
case int(TextureMappingZone::ContoningFlatSurfaceInfillSpiral):
|
||||
return "spiral";
|
||||
case int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinHybrid):
|
||||
@@ -889,6 +891,8 @@ static int top_surface_contoning_flat_surface_infill_mode_from_name(const std::s
|
||||
return int(TextureMappingZone::ContoningFlatSurfaceInfillConcentric);
|
||||
if (name == "boundary_skin" || name == "boundary_skin_variable")
|
||||
return int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable);
|
||||
if (name == "boundary_skin_variable_overlap" || name == "boundary_skin_overlap")
|
||||
return int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap);
|
||||
if (name == "boundary_skin_fixed")
|
||||
return int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinFixed);
|
||||
if (name == "spiral")
|
||||
@@ -2435,6 +2439,8 @@ bool TextureMappingZone::operator==(const TextureMappingZone &rhs) const
|
||||
nonlinear_offset_adjustment == rhs.nonlinear_offset_adjustment &&
|
||||
modulation_mode == rhs.modulation_mode &&
|
||||
use_modulated_overhang_geometry_for_support == rhs.use_modulated_overhang_geometry_for_support &&
|
||||
(!uses_perimeter_path_modulation_v2() ||
|
||||
disable_v2_perimeter_path_modulation_smoothing == rhs.disable_v2_perimeter_path_modulation_smoothing) &&
|
||||
modulation_mode_manually_changed == rhs.modulation_mode_manually_changed &&
|
||||
recolor_small_perimeter_loops == rhs.recolor_small_perimeter_loops &&
|
||||
recolor_top_visible_perimeter_sections == rhs.recolor_top_visible_perimeter_sections &&
|
||||
@@ -2812,6 +2818,7 @@ std::string TextureMappingManager::serialize_entries()
|
||||
texture["nonlinear_offset_adjustment"] = zone.nonlinear_offset_adjustment;
|
||||
texture["modulation_mode"] = modulation_mode_name(zone.modulation_mode);
|
||||
texture["use_modulated_overhang_geometry_for_support"] = zone.use_modulated_overhang_geometry_for_support;
|
||||
texture["disable_v2_perimeter_path_modulation_smoothing"] = zone.disable_v2_perimeter_path_modulation_smoothing;
|
||||
texture["modulation_mode_manually_changed"] = zone.modulation_mode_manually_changed;
|
||||
texture["recolor_small_perimeter_loops"] = zone.recolor_small_perimeter_loops || zone.recolor_top_visible_perimeter_sections;
|
||||
texture["recolor_top_visible_perimeter_sections"] = zone.recolor_top_visible_perimeter_sections;
|
||||
@@ -3099,6 +3106,9 @@ void TextureMappingManager::load_entries(const std::string &serialized,
|
||||
zone.use_modulated_overhang_geometry_for_support =
|
||||
texture.value("use_modulated_overhang_geometry_for_support",
|
||||
TextureMappingZone::DefaultUseModulatedOverhangGeometryForSupport);
|
||||
zone.disable_v2_perimeter_path_modulation_smoothing =
|
||||
texture.value("disable_v2_perimeter_path_modulation_smoothing",
|
||||
TextureMappingZone::DefaultDisableV2PerimeterPathModulationSmoothing);
|
||||
const auto modulation_mode_it = texture.find("modulation_mode");
|
||||
const bool has_modulation_mode =
|
||||
modulation_mode_it != texture.end() && modulation_mode_it->is_string();
|
||||
@@ -3220,7 +3230,7 @@ void TextureMappingManager::load_entries(const std::string &serialized,
|
||||
flat_surface_infill_mode_it->get<int>() :
|
||||
TextureMappingZone::DefaultTopSurfaceContoningFlatSurfaceInfillMode,
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillDefault),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillAdaptiveLines));
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap));
|
||||
zone.top_surface_contoning_layer_phase_enabled =
|
||||
texture.value("top_surface_contoning_layer_phase_enabled",
|
||||
TextureMappingZone::DefaultTopSurfaceContoningLayerPhaseEnabled);
|
||||
|
||||
@@ -97,7 +97,8 @@ struct TextureMappingZone
|
||||
ContoningFlatSurfaceInfillBoundarySkinHybrid = 6,
|
||||
ContoningFlatSurfaceInfillRectilinearWithBoundary = 7,
|
||||
ContoningFlatSurfaceInfillRectilinearWithRepair = 8,
|
||||
ContoningFlatSurfaceInfillAdaptiveLines = 9
|
||||
ContoningFlatSurfaceInfillAdaptiveLines = 9,
|
||||
ContoningFlatSurfaceInfillBoundarySkinVariableOverlap = 10
|
||||
};
|
||||
|
||||
enum TopSurfaceContoningColorPredictionMode : uint8_t {
|
||||
@@ -190,6 +191,7 @@ struct TextureMappingZone
|
||||
static constexpr int DefaultModulationMode = DefaultImageTextureModulationMode;
|
||||
static constexpr bool DefaultModulationModeManuallyChanged = false;
|
||||
static constexpr bool DefaultUseModulatedOverhangGeometryForSupport = false;
|
||||
static constexpr bool DefaultDisableV2PerimeterPathModulationSmoothing = false;
|
||||
static constexpr bool DefaultRecolorSmallPerimeterLoops = false;
|
||||
static constexpr bool DefaultRecolorTopVisiblePerimeterSections = false;
|
||||
static constexpr int DefaultTopVisiblePerimeterRecolorAggressiveness = int(TopVisibleRecolorAggressive);
|
||||
@@ -305,11 +307,12 @@ struct TextureMappingZone
|
||||
{
|
||||
const int clamped_mode = std::clamp(mode,
|
||||
int(ContoningFlatSurfaceInfillDefault),
|
||||
int(ContoningFlatSurfaceInfillAdaptiveLines));
|
||||
int(ContoningFlatSurfaceInfillBoundarySkinVariableOverlap));
|
||||
if (ShowExperimentalTopSurfaceContoningOptions)
|
||||
return clamped_mode;
|
||||
return clamped_mode == int(ContoningFlatSurfaceInfillRectilinear) ||
|
||||
clamped_mode == int(ContoningFlatSurfaceInfillBoundarySkinVariable) ||
|
||||
clamped_mode == int(ContoningFlatSurfaceInfillBoundarySkinVariableOverlap) ||
|
||||
clamped_mode == int(ContoningFlatSurfaceInfillAdaptiveLines) ?
|
||||
clamped_mode :
|
||||
DefaultTopSurfaceContoningFlatSurfaceInfillMode;
|
||||
@@ -485,6 +488,7 @@ struct TextureMappingZone
|
||||
bool nonlinear_offset_adjustment = DefaultNonlinearOffsetAdjustment;
|
||||
int modulation_mode = DefaultModulationMode;
|
||||
bool use_modulated_overhang_geometry_for_support = DefaultUseModulatedOverhangGeometryForSupport;
|
||||
bool disable_v2_perimeter_path_modulation_smoothing = DefaultDisableV2PerimeterPathModulationSmoothing;
|
||||
bool modulation_mode_manually_changed = DefaultModulationModeManuallyChanged;
|
||||
bool recolor_small_perimeter_loops = DefaultRecolorSmallPerimeterLoops;
|
||||
bool recolor_top_visible_perimeter_sections = DefaultRecolorTopVisiblePerimeterSections;
|
||||
@@ -578,15 +582,13 @@ struct TextureMappingZone
|
||||
(is_image_texture() || is_surface_gradient()) &&
|
||||
(top_surface_image_printing_method == int(TopSurfaceImageSameAngle45Width) ||
|
||||
top_surface_image_printing_method == int(TopSurfaceImageSameLayer45Partition) ||
|
||||
(top_surface_image_printing_method == int(TopSurfaceImageContoning) &&
|
||||
uses_perimeter_path_modulation_v2()));
|
||||
top_surface_image_printing_method == int(TopSurfaceImageContoning));
|
||||
}
|
||||
bool top_surface_contoning_active() const
|
||||
{
|
||||
return top_surface_image_printing_enabled &&
|
||||
(is_image_texture() || is_surface_gradient()) &&
|
||||
top_surface_image_printing_method == int(TopSurfaceImageContoning) &&
|
||||
uses_perimeter_path_modulation_v2();
|
||||
top_surface_image_printing_method == int(TopSurfaceImageContoning);
|
||||
}
|
||||
|
||||
bool top_surface_image_fixed_coloring_filaments_active() const
|
||||
@@ -598,6 +600,7 @@ struct TextureMappingZone
|
||||
{
|
||||
return is_image_texture() &&
|
||||
top_surface_contoning_active() &&
|
||||
uses_perimeter_path_modulation_v2() &&
|
||||
top_surface_contoning_colors_upper_surfaces() &&
|
||||
!effective_top_surface_contoning_only_color_surface_infill() &&
|
||||
!effective_top_surface_contoning_replace_top_perimeters_with_infill() &&
|
||||
@@ -751,8 +754,6 @@ struct TextureMappingZone
|
||||
{
|
||||
if (top_surface_image_printing_enabled &&
|
||||
top_surface_image_printing_method == int(TopSurfaceImageContoning)) {
|
||||
modulation_mode = int(ModulationPerimeterPathV2);
|
||||
modulation_mode_manually_changed = true;
|
||||
top_surface_image_fixed_coloring_filaments = true;
|
||||
}
|
||||
if (!ShowExperimentalTopSurfaceContoningOptions) {
|
||||
@@ -814,6 +815,7 @@ struct TextureMappingZone
|
||||
seam_hiding = DefaultSeamHiding;
|
||||
nonlinear_offset_adjustment = DefaultNonlinearOffsetAdjustment;
|
||||
use_modulated_overhang_geometry_for_support = DefaultUseModulatedOverhangGeometryForSupport;
|
||||
disable_v2_perimeter_path_modulation_smoothing = DefaultDisableV2PerimeterPathModulationSmoothing;
|
||||
modulation_mode = default_modulation_mode_for_surface_pattern(surface_pattern);
|
||||
modulation_mode_manually_changed = DefaultModulationModeManuallyChanged;
|
||||
recolor_small_perimeter_loops = DefaultRecolorSmallPerimeterLoops;
|
||||
|
||||
@@ -548,6 +548,15 @@ TextureMappingContoningSolver::nearest_measured_sample_fallback_issues(bool lowe
|
||||
return out;
|
||||
}
|
||||
|
||||
TextureMappingContoningNearestMeasuredSampleFallbackArea
|
||||
TextureMappingContoningSolver::nearest_measured_sample_fallback_area(bool lower_surface) const
|
||||
{
|
||||
if (!m_nearest_measured_sample_fallback_area_mutex || !m_nearest_measured_sample_fallback_areas)
|
||||
return {};
|
||||
std::lock_guard<std::mutex> lock(*m_nearest_measured_sample_fallback_area_mutex);
|
||||
return (*m_nearest_measured_sample_fallback_areas)[lower_surface ? 1 : 0];
|
||||
}
|
||||
|
||||
std::string TextureMappingContoningSolver::nearest_measured_sample_fallback_name() const
|
||||
{
|
||||
if (m_nearest_measured_sample_fallback_model.valid()) {
|
||||
@@ -559,6 +568,39 @@ std::string TextureMappingContoningSolver::nearest_measured_sample_fallback_name
|
||||
return "default uncalibrated";
|
||||
}
|
||||
|
||||
bool TextureMappingContoningSolver::nearest_measured_sample_stack_compatible(
|
||||
int stack_layers,
|
||||
int visible_depth,
|
||||
const std::vector<float> &surface_to_deep_layer_heights_mm,
|
||||
const std::vector<int> &surface_to_deep_layer_ids,
|
||||
bool lower_surface) const
|
||||
{
|
||||
return nearest_measured_sample_compatible(stack_layers,
|
||||
visible_depth,
|
||||
surface_to_deep_layer_heights_mm,
|
||||
surface_to_deep_layer_ids,
|
||||
lower_surface,
|
||||
false);
|
||||
}
|
||||
|
||||
void TextureMappingContoningSolver::record_nearest_measured_sample_fallback_area(
|
||||
bool lower_surface,
|
||||
double fallback_area_mm2,
|
||||
double total_area_mm2) const
|
||||
{
|
||||
if (!m_nearest_measured_sample_fallback_area_mutex || !m_nearest_measured_sample_fallback_areas)
|
||||
return;
|
||||
if (!std::isfinite(total_area_mm2) || total_area_mm2 <= 0.)
|
||||
return;
|
||||
if (!std::isfinite(fallback_area_mm2))
|
||||
fallback_area_mm2 = 0.;
|
||||
std::lock_guard<std::mutex> lock(*m_nearest_measured_sample_fallback_area_mutex);
|
||||
TextureMappingContoningNearestMeasuredSampleFallbackArea &area =
|
||||
(*m_nearest_measured_sample_fallback_areas)[lower_surface ? 1 : 0];
|
||||
area.fallback_area_mm2 += std::clamp(fallback_area_mm2, 0., total_area_mm2);
|
||||
area.total_area_mm2 += total_area_mm2;
|
||||
}
|
||||
|
||||
const std::vector<TextureMappingContoningSolver::Candidate>&
|
||||
TextureMappingContoningSolver::candidates_for_depth(int stack_layers) const
|
||||
{
|
||||
|
||||
@@ -38,6 +38,11 @@ struct TextureMappingContoningNearestMeasuredSampleFallbackIssue {
|
||||
float expected_layer_height_mm { 0.f };
|
||||
};
|
||||
|
||||
struct TextureMappingContoningNearestMeasuredSampleFallbackArea {
|
||||
double fallback_area_mm2 { 0. };
|
||||
double total_area_mm2 { 0. };
|
||||
};
|
||||
|
||||
class TextureMappingContoningSolver
|
||||
{
|
||||
public:
|
||||
@@ -56,7 +61,16 @@ public:
|
||||
bool nearest_measured_sample_fallback_used() const;
|
||||
bool nearest_measured_sample_fallback_used(bool lower_surface) const;
|
||||
std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue> nearest_measured_sample_fallback_issues(bool lower_surface) const;
|
||||
TextureMappingContoningNearestMeasuredSampleFallbackArea nearest_measured_sample_fallback_area(bool lower_surface) const;
|
||||
std::string nearest_measured_sample_fallback_name() const;
|
||||
bool nearest_measured_sample_stack_compatible(int stack_layers,
|
||||
int visible_depth,
|
||||
const std::vector<float> &surface_to_deep_layer_heights_mm,
|
||||
const std::vector<int> &surface_to_deep_layer_ids,
|
||||
bool lower_surface) const;
|
||||
void record_nearest_measured_sample_fallback_area(bool lower_surface,
|
||||
double fallback_area_mm2,
|
||||
double total_area_mm2) const;
|
||||
|
||||
TextureMappingContoningStack solve(const std::array<float, 3> &target_rgb,
|
||||
int stack_layers,
|
||||
@@ -153,6 +167,8 @@ private:
|
||||
mutable std::shared_ptr<std::atomic<bool>> m_nearest_measured_sample_lower_fallback_used { std::make_shared<std::atomic<bool>>(false) };
|
||||
mutable std::shared_ptr<std::mutex> m_nearest_measured_sample_fallback_issue_mutex { std::make_shared<std::mutex>() };
|
||||
mutable std::shared_ptr<std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue>> m_nearest_measured_sample_fallback_issues { std::make_shared<std::vector<TextureMappingContoningNearestMeasuredSampleFallbackIssue>>() };
|
||||
mutable std::shared_ptr<std::mutex> m_nearest_measured_sample_fallback_area_mutex { std::make_shared<std::mutex>() };
|
||||
mutable std::shared_ptr<std::array<TextureMappingContoningNearestMeasuredSampleFallbackArea, 2>> m_nearest_measured_sample_fallback_areas { std::make_shared<std::array<TextureMappingContoningNearestMeasuredSampleFallbackArea, 2>>() };
|
||||
};
|
||||
|
||||
std::vector<unsigned int> texture_mapping_contoning_components_bottom_to_top(const TextureMappingZone &zone,
|
||||
|
||||
@@ -8462,14 +8462,6 @@ static std::vector<unsigned int> auto_enable_raw_top_surface_projection_zones(co
|
||||
zone->top_surface_contoning_color_lower_surfaces = true;
|
||||
changed = true;
|
||||
}
|
||||
if (zone->modulation_mode != int(TextureMappingZone::ModulationPerimeterPathV2)) {
|
||||
zone->modulation_mode = int(TextureMappingZone::ModulationPerimeterPathV2);
|
||||
changed = true;
|
||||
}
|
||||
if (!zone->modulation_mode_manually_changed) {
|
||||
zone->modulation_mode_manually_changed = true;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
|
||||
@@ -2503,6 +2503,7 @@ public:
|
||||
bool nonlinear_offset_adjustment,
|
||||
int modulation_mode,
|
||||
bool use_modulated_overhang_geometry_for_support,
|
||||
bool disable_v2_perimeter_path_modulation_smoothing,
|
||||
bool modulation_mode_manually_changed,
|
||||
bool recolor_small_perimeter_loops,
|
||||
bool recolor_top_visible_perimeter_sections,
|
||||
@@ -2882,7 +2883,7 @@ public:
|
||||
auto *modulation_mode_row = new wxBoxSizer(wxHORIZONTAL);
|
||||
modulation_mode_row->Add(new wxStaticText(print_settings_page, wxID_ANY, _L("Modulation mode:")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
|
||||
m_modulation_mode_choice = new wxChoice(print_settings_page, wxID_ANY);
|
||||
update_modulation_mode_choices(false, modulation_mode);
|
||||
update_modulation_mode_choices(modulation_mode);
|
||||
modulation_mode_row->Add(m_modulation_mode_choice, 1, wxALIGN_CENTER_VERTICAL);
|
||||
print_settings_root->Add(modulation_mode_row, 0, wxEXPAND | wxALL, gap);
|
||||
m_modulation_mode_choice->Bind(wxEVT_CHOICE, [this](wxCommandEvent &) {
|
||||
@@ -2984,6 +2985,14 @@ public:
|
||||
new wxCheckBox(experimental_page, wxID_ANY, _L("Use modulated overhang geometry in support generation"));
|
||||
m_use_modulated_overhang_geometry_for_support_checkbox->SetValue(use_modulated_overhang_geometry_for_support);
|
||||
experimental_box->Add(m_use_modulated_overhang_geometry_for_support_checkbox, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
m_disable_v2_perimeter_path_modulation_smoothing_checkbox =
|
||||
new wxCheckBox(experimental_page, wxID_ANY, _L("Disable v2 perimeter path modulation smoothing"));
|
||||
m_disable_v2_perimeter_path_modulation_smoothing_checkbox->SetValue(
|
||||
modulation_mode == int(TextureMappingZone::ModulationPerimeterPathV2) &&
|
||||
disable_v2_perimeter_path_modulation_smoothing);
|
||||
m_disable_v2_perimeter_path_modulation_smoothing_checkbox->SetToolTip(
|
||||
_L("Leaves v2 perimeter path modulation insets unsmoothed so fine texture changes can produce bumpier path geometry."));
|
||||
experimental_box->Add(m_disable_v2_perimeter_path_modulation_smoothing_checkbox, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
|
||||
m_top_visible_perimeter_recolor_point_sampling_checkbox =
|
||||
new wxCheckBox(experimental_page, wxID_ANY, _L("Point-sample visible layer-line recolor"));
|
||||
m_top_visible_perimeter_recolor_point_sampling_checkbox->SetValue(top_visible_perimeter_recolor_point_sampling);
|
||||
@@ -3295,6 +3304,9 @@ public:
|
||||
if (!TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions)
|
||||
add_contoning_flat_infill_choice(_L("Boundary Skin (variable width)"),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable));
|
||||
if (!TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions)
|
||||
add_contoning_flat_infill_choice(_L("Boundary Skin (variable width, more overlap)"),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap));
|
||||
if (TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions) {
|
||||
add_contoning_flat_infill_choice(_L("Concentric"),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillConcentric));
|
||||
@@ -3302,6 +3314,8 @@ public:
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinFixed));
|
||||
add_contoning_flat_infill_choice(_L("Boundary Skin (variable width)"),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable));
|
||||
add_contoning_flat_infill_choice(_L("Boundary Skin (variable width, more overlap)"),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap));
|
||||
add_contoning_flat_infill_choice(_L("Spiral"),
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillSpiral));
|
||||
add_contoning_flat_infill_choice(_L("Boundary Skin Hybrid"),
|
||||
@@ -3901,6 +3915,12 @@ public:
|
||||
return m_use_modulated_overhang_geometry_for_support_checkbox != nullptr &&
|
||||
m_use_modulated_overhang_geometry_for_support_checkbox->GetValue();
|
||||
}
|
||||
bool disable_v2_perimeter_path_modulation_smoothing() const
|
||||
{
|
||||
return modulation_mode() == int(TextureMappingZone::ModulationPerimeterPathV2) &&
|
||||
m_disable_v2_perimeter_path_modulation_smoothing_checkbox != nullptr &&
|
||||
m_disable_v2_perimeter_path_modulation_smoothing_checkbox->GetValue();
|
||||
}
|
||||
int modulation_mode() const
|
||||
{
|
||||
if (m_modulation_mode_choice == nullptr)
|
||||
@@ -5435,6 +5455,8 @@ private:
|
||||
m_recolor_top_visible_perimeter_sections_checkbox->Enable(perimeter_path_mode);
|
||||
if (m_use_modulated_overhang_geometry_for_support_checkbox != nullptr)
|
||||
m_use_modulated_overhang_geometry_for_support_checkbox->Enable(perimeter_path_v2_mode);
|
||||
if (m_disable_v2_perimeter_path_modulation_smoothing_checkbox != nullptr)
|
||||
m_disable_v2_perimeter_path_modulation_smoothing_checkbox->Enable(perimeter_path_v2_mode);
|
||||
if (m_top_visible_perimeter_recolor_point_sampling_checkbox != nullptr)
|
||||
m_top_visible_perimeter_recolor_point_sampling_checkbox->Enable(perimeter_path_v2_mode);
|
||||
const bool top_visible_enabled =
|
||||
@@ -5458,20 +5480,16 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void update_modulation_mode_choices(bool force_perimeter_path_v2, int preferred_mode)
|
||||
void update_modulation_mode_choices(int preferred_mode)
|
||||
{
|
||||
if (m_modulation_mode_choice == nullptr)
|
||||
return;
|
||||
const int mode = force_perimeter_path_v2 ?
|
||||
int(TextureMappingZone::ModulationPerimeterPathV2) :
|
||||
std::clamp(preferred_mode,
|
||||
int(TextureMappingZone::ModulationLineWidth),
|
||||
int(TextureMappingZone::ModulationPerimeterPathV2));
|
||||
const int mode = std::clamp(preferred_mode,
|
||||
int(TextureMappingZone::ModulationLineWidth),
|
||||
int(TextureMappingZone::ModulationPerimeterPathV2));
|
||||
m_modulation_mode_choice->Clear();
|
||||
m_modulation_mode_choice_values.clear();
|
||||
auto append_mode = [this, force_perimeter_path_v2](int value, const wxString &label) {
|
||||
if (force_perimeter_path_v2 && value != int(TextureMappingZone::ModulationPerimeterPathV2))
|
||||
return;
|
||||
auto append_mode = [this](int value, const wxString &label) {
|
||||
m_modulation_mode_choice->Append(label);
|
||||
m_modulation_mode_choice_values.emplace_back(value);
|
||||
};
|
||||
@@ -5530,6 +5548,9 @@ private:
|
||||
TextureMappingZone::effective_top_surface_contoning_flat_surface_infill_mode(
|
||||
top_surface_contoning_flat_surface_infill_mode()) ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable) ||
|
||||
TextureMappingZone::effective_top_surface_contoning_flat_surface_infill_mode(
|
||||
top_surface_contoning_flat_surface_infill_mode()) ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariableOverlap) ||
|
||||
TextureMappingZone::effective_top_surface_contoning_flat_surface_infill_mode(
|
||||
top_surface_contoning_flat_surface_infill_mode()) ==
|
||||
int(TextureMappingZone::ContoningFlatSurfaceInfillAdaptiveLines);
|
||||
@@ -5579,10 +5600,7 @@ private:
|
||||
const bool contoning = enabled && contoning_selected;
|
||||
if (m_modulation_mode_choice != nullptr) {
|
||||
const int preferred_mode = modulation_mode();
|
||||
update_modulation_mode_choices(contoning, preferred_mode);
|
||||
}
|
||||
if (contoning) {
|
||||
m_modulation_mode_manually_changed = true;
|
||||
update_modulation_mode_choices(preferred_mode);
|
||||
update_modulation_mode_options_visibility(false);
|
||||
}
|
||||
const bool same_layer =
|
||||
@@ -5758,6 +5776,7 @@ private:
|
||||
wxCheckBox *m_nonlinear_offset_adjustment_checkbox {nullptr};
|
||||
wxSpinCtrl *m_filament_overhang_contrast_spin {nullptr};
|
||||
wxCheckBox *m_use_modulated_overhang_geometry_for_support_checkbox {nullptr};
|
||||
wxCheckBox *m_disable_v2_perimeter_path_modulation_smoothing_checkbox {nullptr};
|
||||
wxChoice *m_modulation_mode_choice {nullptr};
|
||||
std::vector<int> m_modulation_mode_choice_values;
|
||||
bool m_modulation_mode_manually_changed {false};
|
||||
@@ -10862,6 +10881,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
updated.nonlinear_offset_adjustment,
|
||||
updated.modulation_mode,
|
||||
updated.use_modulated_overhang_geometry_for_support,
|
||||
updated.disable_v2_perimeter_path_modulation_smoothing,
|
||||
updated.modulation_mode_manually_changed,
|
||||
updated.recolor_small_perimeter_loops,
|
||||
updated.recolor_top_visible_perimeter_sections,
|
||||
@@ -10958,6 +10978,9 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
updated.use_modulated_overhang_geometry_for_support = dlg.use_modulated_overhang_geometry_for_support();
|
||||
updated.modulation_mode_manually_changed = dlg.modulation_mode_manually_changed();
|
||||
updated.apply_default_modulation_mode();
|
||||
updated.disable_v2_perimeter_path_modulation_smoothing =
|
||||
updated.uses_perimeter_path_modulation_v2() &&
|
||||
dlg.disable_v2_perimeter_path_modulation_smoothing();
|
||||
updated.recolor_small_perimeter_loops = dlg.recolor_small_perimeter_loops();
|
||||
updated.recolor_top_visible_perimeter_sections = dlg.recolor_top_visible_perimeter_sections();
|
||||
updated.top_visible_perimeter_recolor_aggressiveness = dlg.top_visible_perimeter_recolor_aggressiveness();
|
||||
@@ -11037,11 +11060,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
dlg.side_surface_color_calibration_name();
|
||||
updated.side_surface_color_calibration_json =
|
||||
dlg.side_surface_color_calibration_json();
|
||||
if (updated.top_surface_image_printing_enabled &&
|
||||
updated.top_surface_image_printing_method == int(TextureMappingZone::TopSurfaceImageContoning)) {
|
||||
updated.modulation_mode = int(TextureMappingZone::ModulationPerimeterPathV2);
|
||||
updated.modulation_mode_manually_changed = true;
|
||||
}
|
||||
if (updated.dithering_enabled)
|
||||
updated.compact_offset_mode = true;
|
||||
updated.minimum_visibility_offset_enabled = dlg.minimum_visibility_offset_enabled();
|
||||
@@ -17392,16 +17410,21 @@ void Plater::priv::clear_warnings()
|
||||
}
|
||||
bool Plater::priv::warnings_dialog()
|
||||
{
|
||||
if (current_warnings.empty())
|
||||
std::vector<const std::pair<Slic3r::PrintStateBase::Warning, size_t>*> critical_warnings;
|
||||
for (auto const& it : current_warnings)
|
||||
if (it.first.level == PrintStateBase::WarningLevel::CRITICAL)
|
||||
critical_warnings.emplace_back(&it);
|
||||
|
||||
if (critical_warnings.empty())
|
||||
return true;
|
||||
std::string text = _u8L("There are warnings after slicing models:") + "\n";
|
||||
for (auto const& it : current_warnings) {
|
||||
size_t next_n = it.first.message.find_first_of('\n', 0);
|
||||
for (auto const* it : critical_warnings) {
|
||||
size_t next_n = it->first.message.find_first_of('\n', 0);
|
||||
text += "\n";
|
||||
if (next_n != std::string::npos)
|
||||
text += it.first.message.substr(0, next_n);
|
||||
text += it->first.message.substr(0, next_n);
|
||||
else
|
||||
text += it.first.message;
|
||||
text += it->first.message;
|
||||
}
|
||||
//text += "\n\nDo you still wish to export?";
|
||||
MessageDialog msg_window(this->q, from_u8(text), _L("warnings"), wxOK);
|
||||
|
||||
Reference in New Issue
Block a user