Add Vector-border shared Gaussian partition polygonization mode for top-surface coloring

- Allow changing surface infill type
This commit is contained in:
sentientstardust
2026-05-31 21:51:25 +01:00
parent 25aeaec0e5
commit 1a6bb9d652
4 changed files with 493 additions and 46 deletions

View File

@@ -511,6 +511,7 @@ struct TopSurfaceImageRegionPlan {
bool contoning_supersampled_cells_enabled = false;
bool contoning_polygonize_color_regions_enabled = false;
bool contoning_fast_mode_enabled = TextureMappingZone::DefaultTopSurfaceContoningFastModeEnabled;
int contoning_polygonization_mode = TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode;
int contoning_polygonize_resolution = TextureMappingZone::DefaultTopSurfaceContoningPolygonizeResolution;
bool contoning_surface_anchored_stacks_enabled = false;
bool contoning_surface_anchored_stack_optimizations_enabled = TextureMappingZone::DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled;
@@ -2277,6 +2278,7 @@ struct TopSurfaceImageContoningStackPlanKey {
bool blue_noise { false };
bool polygonize { false };
bool fast_mode { false };
int polygonization_mode { TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode };
int polygonize_resolution { 1 };
bool surface_anchored_stack_optimizations { false };
bool td_adjustment { false };
@@ -2313,6 +2315,7 @@ struct TopSurfaceImageContoningStackPlanKey {
blue_noise,
polygonize,
fast_mode,
polygonization_mode,
polygonize_resolution,
surface_anchored_stack_optimizations,
td_adjustment,
@@ -2346,6 +2349,7 @@ struct TopSurfaceImageContoningStackPlanKey {
rhs.blue_noise,
rhs.polygonize,
rhs.fast_mode,
rhs.polygonization_mode,
rhs.polygonize_resolution,
rhs.surface_anchored_stack_optimizations,
rhs.td_adjustment,
@@ -3058,6 +3062,217 @@ static ExPolygons top_surface_image_contoning_polygonized_area_from_grid_label(c
throw_if_canceled);
}
static std::vector<int> top_surface_image_contoning_shared_gaussian_partition_grid(const std::vector<int> &grid,
int cols,
int rows,
const std::vector<int> &ids,
const ThrowIfCanceled *throw_if_canceled)
{
if (grid.empty() || ids.empty() || cols <= 0 || rows <= 0 || grid.size() != size_t(cols) * size_t(rows))
return grid;
int max_id = -1;
for (int id : ids)
if (id >= 0)
max_id = std::max(max_id, id);
if (max_id < 0)
return grid;
std::vector<int> id_to_slot(size_t(max_id) + 1, -1);
std::vector<int> active_ids;
active_ids.reserve(ids.size());
for (int id : ids) {
if (id < 0 || id > max_id || id_to_slot[size_t(id)] >= 0)
continue;
id_to_slot[size_t(id)] = int(active_ids.size());
active_ids.emplace_back(id);
}
if (active_ids.empty())
return grid;
static constexpr std::array<int, 5> kernel = { 1, 4, 6, 4, 1 };
std::vector<int> out(grid.size(), -1);
std::vector<int> scores(active_ids.size(), 0);
for (int row = 0; row < rows; ++row) {
check_canceled(throw_if_canceled);
for (int col = 0; col < cols; ++col) {
const size_t idx = size_t(row) * size_t(cols) + size_t(col);
const int center_id = grid[idx];
if (center_id < 0 || center_id > max_id || id_to_slot[size_t(center_id)] < 0)
continue;
std::fill(scores.begin(), scores.end(), 0);
for (int dy = -2; dy <= 2; ++dy) {
const int yy = row + dy;
if (yy < 0 || yy >= rows)
continue;
for (int dx = -2; dx <= 2; ++dx) {
const int xx = col + dx;
if (xx < 0 || xx >= cols)
continue;
const int neighbor_id = grid[size_t(yy) * size_t(cols) + size_t(xx)];
if (neighbor_id < 0 || neighbor_id > max_id)
continue;
const int slot = id_to_slot[size_t(neighbor_id)];
if (slot < 0)
continue;
scores[size_t(slot)] += kernel[size_t(dy + 2)] * kernel[size_t(dx + 2)];
}
}
int best_slot = id_to_slot[size_t(center_id)];
int best_score = scores[size_t(best_slot)];
for (size_t slot = 0; slot < scores.size(); ++slot) {
if (scores[slot] > best_score) {
best_slot = int(slot);
best_score = scores[slot];
}
}
out[idx] = active_ids[size_t(best_slot)];
}
}
return out;
}
static int top_surface_image_contoning_best_completion_index(const std::vector<ExPolygons> &areas,
const ExPolygons &leftover,
const std::vector<int> &fallback_indices,
coord_t touch_radius)
{
int best_index = -1;
double best_contact = 0.;
double best_area = 0.;
ExPolygons expanded_leftover = top_surface_clip_offset_ex(leftover, float(touch_radius));
for (int index : fallback_indices) {
if (index < 0 || size_t(index) >= areas.size() || areas[size_t(index)].empty())
continue;
const ExPolygons contact =
top_surface_clip_intersection_ex(expanded_leftover, areas[size_t(index)], ApplySafetyOffset::Yes);
const double contact_area = top_surface_image_abs_area(contact);
const double area = top_surface_image_abs_area(areas[size_t(index)]);
if (contact_area > best_contact + EPSILON ||
(std::abs(contact_area - best_contact) <= EPSILON && area > best_area)) {
best_index = index;
best_contact = contact_area;
best_area = area;
}
}
if (best_index >= 0)
return best_index;
for (int index : fallback_indices) {
if (index < 0 || size_t(index) >= areas.size() || areas[size_t(index)].empty())
continue;
const double area = top_surface_image_abs_area(areas[size_t(index)]);
if (area > best_area) {
best_index = index;
best_area = area;
}
}
if (best_index >= 0)
return best_index;
for (int index : fallback_indices)
if (index >= 0 && size_t(index) < areas.size())
return index;
return -1;
}
static void top_surface_image_contoning_complete_indexed_area(std::vector<ExPolygons> &areas,
const ExPolygons &target_area,
const std::vector<int> &fallback_indices,
float line_width_mm,
const ThrowIfCanceled *throw_if_canceled)
{
if (areas.empty() || target_area.empty() || fallback_indices.empty())
return;
ExPolygons covered;
for (const ExPolygons &area : areas) {
check_canceled(throw_if_canceled);
if (!area.empty())
append(covered, area);
}
ExPolygons leftover = covered.empty() ?
top_surface_clip_union_ex(target_area) :
top_surface_clip_diff_ex(target_area, top_surface_clip_union_ex(covered), ApplySafetyOffset::Yes);
if (leftover.empty())
return;
const coord_t touch_radius =
std::max<coord_t>(1, scale_(std::clamp(double(line_width_mm) * 0.25, 0.02, 0.20)));
for (ExPolygon &leftover_part : leftover) {
check_canceled(throw_if_canceled);
ExPolygons piece;
piece.emplace_back(std::move(leftover_part));
const int index = top_surface_image_contoning_best_completion_index(areas, piece, fallback_indices, touch_radius);
if (index < 0)
continue;
append(areas[size_t(index)], std::move(piece));
areas[size_t(index)] = top_surface_clip_union_ex(areas[size_t(index)]);
}
}
static std::vector<ExPolygons> top_surface_image_contoning_vector_border_shared_gaussian_partition_areas(
const std::vector<int> &grid,
int cols,
int rows,
const std::vector<int> &ids,
size_t area_count,
coord_t min_x,
coord_t min_y,
coord_t step,
const BoundingBox &bbox,
const ExPolygons &target_area,
float min_feature_mm,
bool cleanup_optimizations_enabled,
const ThrowIfCanceled *throw_if_canceled)
{
std::vector<ExPolygons> areas(area_count);
if (grid.empty() || ids.empty() || area_count == 0 || target_area.empty() ||
cols <= 0 || rows <= 0 || grid.size() != size_t(cols) * size_t(rows))
return areas;
const std::vector<int> partition_grid =
top_surface_image_contoning_shared_gaussian_partition_grid(grid, cols, rows, ids, throw_if_canceled);
ExPolygons taken;
for (int id : ids) {
check_canceled(throw_if_canceled);
if (id < 0 || size_t(id) >= areas.size())
continue;
ExPolygons raw_area =
top_surface_image_contoning_raw_partition_hierarchy_area_from_grid_label(partition_grid,
cols,
rows,
id,
min_x,
min_y,
step,
bbox,
throw_if_canceled);
if (raw_area.empty())
continue;
ExPolygons clean_area = top_surface_image_contoning_clean_area(std::move(raw_area),
target_area,
taken,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
if (clean_area.empty())
continue;
areas[size_t(id)] = std::move(clean_area);
append(taken, areas[size_t(id)]);
}
top_surface_image_contoning_complete_indexed_area(areas,
target_area,
ids,
min_feature_mm > 0.f ? min_feature_mm : 0.4f,
throw_if_canceled);
return areas;
}
static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_contoning_component_regions_from_grid(
const std::vector<int> &label_grid,
int cols,
@@ -3073,6 +3288,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
float min_feature_mm,
bool polygonize_color_regions,
bool fast_mode_enabled,
int polygonization_mode,
bool cleanup_optimizations_enabled,
bool lower_surface,
const ThrowIfCanceled *throw_if_canceled)
@@ -3132,7 +3348,16 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
return lhs < rhs;
});
const bool raw_partition_hierarchy_convert = fast_mode_enabled && polygonize_color_regions;
const int effective_polygonization_mode =
TextureMappingZone::effective_top_surface_contoning_polygonization_mode(polygonization_mode);
const bool vector_border_shared_gaussian_partition =
fast_mode_enabled &&
polygonize_color_regions &&
effective_polygonization_mode == int(TextureMappingZone::ContoningPolygonizationVectorBorderSharedGaussianPartition);
const bool raw_partition_hierarchy_convert =
fast_mode_enabled &&
polygonize_color_regions &&
effective_polygonization_mode == int(TextureMappingZone::ContoningPolygonizationMarchingSquares);
const ExPolygons empty_blocked_area;
ExPolygons valid_area;
if (!raw_partition_hierarchy_convert) {
@@ -3153,6 +3378,35 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
return regions;
}
if (vector_border_shared_gaussian_partition) {
std::vector<ExPolygons> component_areas =
top_surface_image_contoning_vector_border_shared_gaussian_partition_areas(component_grid,
cols,
rows,
component_order,
size_t(max_component_id) + 1,
min_x,
min_y,
step,
bbox,
valid_area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
for (int component_id : component_order) {
check_canceled(throw_if_canceled);
if (component_id <= 0 || size_t(component_id) >= component_areas.size() ||
component_areas[size_t(component_id)].empty())
continue;
TopSurfaceImageContoningVectorRegion region;
region.bottom_to_top.emplace_back(static_cast<unsigned int>(component_id));
region.cell_count = cell_counts[size_t(component_id)];
region.area = std::move(component_areas[size_t(component_id)]);
regions.emplace_back(std::move(region));
}
return regions;
}
ExPolygons taken;
for (int component_id : component_order) {
check_canceled(throw_if_canceled);
@@ -3231,6 +3485,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
float min_feature_mm,
bool polygonize_color_regions,
bool fast_mode_enabled,
int polygonization_mode,
bool cleanup_optimizations_enabled,
const ThrowIfCanceled *throw_if_canceled)
{
@@ -3256,7 +3511,44 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
return lhs < rhs;
});
const bool raw_partition_hierarchy_convert = fast_mode_enabled && polygonize_color_regions;
const int effective_polygonization_mode =
TextureMappingZone::effective_top_surface_contoning_polygonization_mode(polygonization_mode);
const bool vector_border_shared_gaussian_partition =
fast_mode_enabled &&
polygonize_color_regions &&
effective_polygonization_mode == int(TextureMappingZone::ContoningPolygonizationVectorBorderSharedGaussianPartition);
const bool raw_partition_hierarchy_convert =
fast_mode_enabled &&
polygonize_color_regions &&
effective_polygonization_mode == int(TextureMappingZone::ContoningPolygonizationMarchingSquares);
if (vector_border_shared_gaussian_partition) {
std::vector<ExPolygons> label_areas =
top_surface_image_contoning_vector_border_shared_gaussian_partition_areas(label_grid,
cols,
rows,
label_order,
labels.size(),
min_x,
min_y,
step,
bbox,
area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
for (int label : label_order) {
check_canceled(throw_if_canceled);
if (label < 0 || size_t(label) >= label_areas.size() || label_areas[size_t(label)].empty())
continue;
TopSurfaceImageContoningVectorRegion region;
region.bottom_to_top = labels[size_t(label)].bottom_to_top;
region.cell_count = cell_counts[size_t(label)];
region.area = std::move(label_areas[size_t(label)]);
regions.emplace_back(std::move(region));
}
return regions;
}
ExPolygons covered_parts;
const ExPolygons empty_blocked_area;
for (int label : label_order) {
@@ -4643,6 +4935,7 @@ static void top_surface_image_contoning_solve_anchored_region(
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_fast_mode_enabled,
plan.contoning_polygonization_mode,
plan.contoning_surface_anchored_stack_optimizations_enabled,
throw_if_canceled);
top_surface_image_debug_accumulate_timing_step(debug_timing.steps,
@@ -4690,6 +4983,7 @@ static void top_surface_image_contoning_solve_anchored_region(
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_fast_mode_enabled,
plan.contoning_polygonization_mode,
plan.contoning_surface_anchored_stack_optimizations_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
@@ -5090,6 +5384,9 @@ static TopSurfaceImageContoningStackPlanKey top_surface_image_contoning_anchored
key.blue_noise = false;
key.polygonize = plan.contoning_polygonize_color_regions_enabled;
key.fast_mode = plan.contoning_fast_mode_enabled;
key.polygonization_mode = plan.contoning_polygonize_color_regions_enabled && plan.contoning_fast_mode_enabled ?
TextureMappingZone::effective_top_surface_contoning_polygonization_mode(plan.contoning_polygonization_mode) :
TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode;
key.polygonize_resolution = plan.contoning_polygonize_color_regions_enabled ?
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(plan.contoning_polygonize_resolution) :
1;
@@ -5380,6 +5677,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_fast_mode_enabled,
plan.contoning_polygonization_mode,
plan.contoning_surface_anchored_stack_optimizations_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
@@ -5632,6 +5930,9 @@ static TopSurfaceImageContoningStackPlanKey top_surface_image_contoning_stack_pl
key.blue_noise = use_blue_noise_error_diffusion;
key.polygonize = plan.contoning_polygonize_color_regions_enabled;
key.fast_mode = plan.contoning_fast_mode_enabled;
key.polygonization_mode = plan.contoning_polygonize_color_regions_enabled && plan.contoning_fast_mode_enabled ?
TextureMappingZone::effective_top_surface_contoning_polygonization_mode(plan.contoning_polygonization_mode) :
TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode;
key.polygonize_resolution = plan.contoning_polygonize_color_regions_enabled ?
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(plan.contoning_polygonize_resolution) :
1;
@@ -5728,6 +6029,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_fast_mode_enabled,
plan.contoning_polygonization_mode,
plan.contoning_surface_anchored_stack_optimizations_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
@@ -6320,7 +6622,8 @@ static std::vector<TopSurfaceImageRegionPlan> top_surface_image_region_plans(
plan.contoning_supersampled_cells_enabled =
zone->effective_top_surface_contoning_supersampled_cells_enabled();
plan.contoning_polygonize_color_regions_enabled = zone->top_surface_contoning_polygonize_color_regions_enabled;
plan.contoning_fast_mode_enabled = zone->top_surface_contoning_fast_mode_enabled;
plan.contoning_fast_mode_enabled = zone->effective_top_surface_contoning_fast_mode_enabled();
plan.contoning_polygonization_mode = zone->effective_top_surface_contoning_polygonization_mode();
plan.contoning_polygonize_resolution =
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(zone->top_surface_contoning_polygonize_resolution);
plan.contoning_surface_anchored_stacks_enabled =

View File

@@ -751,6 +751,25 @@ static int top_surface_contoning_color_prediction_mode_from_name(std::string nam
return TextureMappingZone::DefaultTopSurfaceContoningColorPredictionMode;
}
static std::string top_surface_contoning_polygonization_mode_name(int mode)
{
if (TextureMappingZone::effective_top_surface_contoning_polygonization_mode(mode) ==
int(TextureMappingZone::ContoningPolygonizationMarchingSquares))
return "marching_squares";
return "vector_border_shared_gaussian_partition";
}
static int top_surface_contoning_polygonization_mode_from_name(std::string name)
{
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) {
const char lowered = char(std::tolower(c));
return lowered == '-' || lowered == ' ' ? '_' : lowered;
});
if (name == "marching_squares" || name == "marching_square")
return int(TextureMappingZone::ContoningPolygonizationMarchingSquares);
return TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode;
}
static std::string top_visible_recolor_aggressiveness_name(int mode)
{
switch (clamp_int(mode,
@@ -1197,7 +1216,8 @@ bool TextureMappingZone::operator==(const TextureMappingZone &rhs) const
effective_top_surface_contoning_supersampled_cells_enabled() ==
rhs.effective_top_surface_contoning_supersampled_cells_enabled() &&
top_surface_contoning_polygonize_color_regions_enabled == rhs.top_surface_contoning_polygonize_color_regions_enabled &&
top_surface_contoning_fast_mode_enabled == rhs.top_surface_contoning_fast_mode_enabled &&
effective_top_surface_contoning_fast_mode_enabled() == rhs.effective_top_surface_contoning_fast_mode_enabled() &&
effective_top_surface_contoning_polygonization_mode() == rhs.effective_top_surface_contoning_polygonization_mode() &&
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(top_surface_contoning_polygonize_resolution) ==
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(rhs.top_surface_contoning_polygonize_resolution) &&
effective_top_surface_contoning_surface_anchored_stacks_enabled() == rhs.effective_top_surface_contoning_surface_anchored_stacks_enabled() &&
@@ -1609,7 +1629,9 @@ std::string TextureMappingManager::serialize_entries()
texture["top_surface_contoning_polygonize_color_regions_enabled"] =
zone.top_surface_contoning_polygonize_color_regions_enabled;
texture["top_surface_contoning_fast_mode_enabled"] =
zone.top_surface_contoning_fast_mode_enabled;
zone.effective_top_surface_contoning_fast_mode_enabled();
texture["top_surface_contoning_polygonization_mode"] =
top_surface_contoning_polygonization_mode_name(zone.top_surface_contoning_polygonization_mode);
texture["top_surface_contoning_polygonize_resolution"] =
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(zone.top_surface_contoning_polygonize_resolution);
texture["top_surface_contoning_surface_anchored_stacks_enabled"] =
@@ -1923,6 +1945,14 @@ void TextureMappingManager::load_entries(const std::string &serialized,
zone.top_surface_contoning_fast_mode_enabled =
texture.value("top_surface_contoning_fast_mode_enabled",
TextureMappingZone::DefaultTopSurfaceContoningFastModeEnabled);
auto polygonization_mode_it = texture.find("top_surface_contoning_polygonization_mode");
zone.top_surface_contoning_polygonization_mode =
polygonization_mode_it != texture.end() && polygonization_mode_it->is_string() ?
top_surface_contoning_polygonization_mode_from_name(polygonization_mode_it->get<std::string>()) :
TextureMappingZone::normalize_top_surface_contoning_polygonization_mode(
polygonization_mode_it != texture.end() && polygonization_mode_it->is_number_integer() ?
polygonization_mode_it->get<int>() :
TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode);
auto polygonize_resolution_it = texture.find("top_surface_contoning_polygonize_resolution");
zone.top_surface_contoning_polygonize_resolution =
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(

View File

@@ -95,6 +95,11 @@ struct TextureMappingZone
ContoningColorPredictionBeerLambertRgb = 2
};
enum TopSurfaceContoningPolygonizationMode : uint8_t {
ContoningPolygonizationVectorBorderSharedGaussianPartition = 0,
ContoningPolygonizationMarchingSquares = 1
};
enum FilamentColorMode : uint8_t {
FilamentColorAny = 0,
FilamentColorRGB = 1,
@@ -208,6 +213,8 @@ struct TextureMappingZone
static constexpr bool DefaultTopSurfaceContoningSupersampledCellsEnabled = false;
static constexpr bool DefaultTopSurfaceContoningPolygonizeColorRegionsEnabled = true;
static constexpr bool DefaultTopSurfaceContoningFastModeEnabled = true;
static constexpr int DefaultTopSurfaceContoningPolygonizationMode =
int(ContoningPolygonizationVectorBorderSharedGaussianPartition);
static constexpr int DefaultTopSurfaceContoningPolygonizeResolution = 4;
static constexpr bool DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled = true;
static constexpr bool DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled = true;
@@ -266,16 +273,22 @@ struct TextureMappingZone
static int effective_top_surface_contoning_flat_surface_infill_mode(int mode)
{
if (!ShowExperimentalTopSurfaceContoningOptions)
return SlicerDefaultTopSurfaceContoningFlatSurfaceInfillMode;
return mode == int(ContoningFlatSurfaceInfillDefault) ?
const int stored_mode = stored_top_surface_contoning_flat_surface_infill_mode(mode);
return stored_mode == int(ContoningFlatSurfaceInfillDefault) ?
SlicerDefaultTopSurfaceContoningFlatSurfaceInfillMode :
mode;
stored_mode;
}
static int stored_top_surface_contoning_flat_surface_infill_mode(int mode)
{
return ShowExperimentalTopSurfaceContoningOptions ? mode : DefaultTopSurfaceContoningFlatSurfaceInfillMode;
const int clamped_mode = std::clamp(mode,
int(ContoningFlatSurfaceInfillDefault),
int(ContoningFlatSurfaceInfillRectilinearWithBoundary));
if (ShowExperimentalTopSurfaceContoningOptions)
return clamped_mode;
return clamped_mode == int(ContoningFlatSurfaceInfillRectilinear) ?
clamped_mode :
DefaultTopSurfaceContoningFlatSurfaceInfillMode;
}
static int stored_top_surface_contoning_perimeter_mode(int mode)
@@ -333,6 +346,23 @@ struct TextureMappingZone
return ShowExperimentalTopSurfaceContoningOptions && value;
}
static bool effective_top_surface_contoning_fast_mode_enabled(bool value)
{
return ShowExperimentalTopSurfaceContoningOptions ? value : true;
}
static constexpr int normalize_top_surface_contoning_polygonization_mode(int mode)
{
return mode == int(ContoningPolygonizationMarchingSquares) ?
int(ContoningPolygonizationMarchingSquares) :
DefaultTopSurfaceContoningPolygonizationMode;
}
static constexpr int effective_top_surface_contoning_polygonization_mode(int mode)
{
return normalize_top_surface_contoning_polygonization_mode(mode);
}
static bool effective_top_surface_contoning_surface_scatter_enabled(bool td_adjustment,
bool surface_scatter,
bool td_effective_alpha)
@@ -444,6 +474,7 @@ struct TextureMappingZone
bool top_surface_contoning_supersampled_cells_enabled = DefaultTopSurfaceContoningSupersampledCellsEnabled;
bool top_surface_contoning_polygonize_color_regions_enabled = DefaultTopSurfaceContoningPolygonizeColorRegionsEnabled;
bool top_surface_contoning_fast_mode_enabled = DefaultTopSurfaceContoningFastModeEnabled;
int top_surface_contoning_polygonization_mode = DefaultTopSurfaceContoningPolygonizationMode;
int top_surface_contoning_polygonize_resolution = DefaultTopSurfaceContoningPolygonizeResolution;
bool top_surface_contoning_surface_anchored_stacks_enabled = DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled;
bool top_surface_contoning_surface_anchored_stack_optimizations_enabled = DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled;
@@ -603,6 +634,18 @@ struct TextureMappingZone
top_surface_contoning_supersampled_cells_enabled);
}
bool effective_top_surface_contoning_fast_mode_enabled() const
{
return TextureMappingZone::effective_top_surface_contoning_fast_mode_enabled(
top_surface_contoning_fast_mode_enabled);
}
int effective_top_surface_contoning_polygonization_mode() const
{
return TextureMappingZone::effective_top_surface_contoning_polygonization_mode(
top_surface_contoning_polygonization_mode);
}
bool effective_top_surface_contoning_surface_scatter_enabled() const
{
return TextureMappingZone::effective_top_surface_contoning_surface_scatter_enabled(
@@ -639,13 +682,15 @@ struct TextureMappingZone
top_surface_contoning_replace_top_perimeters_with_infill = false;
top_surface_contoning_recolor_surrounding_perimeters = false;
top_surface_contoning_perimeter_mode = DefaultTopSurfaceContoningPerimeterMode;
top_surface_contoning_flat_surface_infill_mode = DefaultTopSurfaceContoningFlatSurfaceInfillMode;
top_surface_contoning_flat_surface_infill_mode =
stored_top_surface_contoning_flat_surface_infill_mode(top_surface_contoning_flat_surface_infill_mode);
top_surface_contoning_surface_anchored_stacks_enabled = true;
top_surface_contoning_surface_anchored_stack_optimizations_enabled = true;
top_surface_contoning_beam_search_stack_expansion_enabled = true;
top_surface_contoning_layer_phase_enabled = false;
top_surface_contoning_blue_noise_error_diffusion_enabled = false;
top_surface_contoning_supersampled_cells_enabled = false;
top_surface_contoning_fast_mode_enabled = true;
} else if (top_surface_contoning_replace_top_perimeters_with_infill) {
top_surface_contoning_recolor_surrounding_perimeters = false;
}
@@ -718,6 +763,7 @@ struct TextureMappingZone
top_surface_contoning_supersampled_cells_enabled = DefaultTopSurfaceContoningSupersampledCellsEnabled;
top_surface_contoning_polygonize_color_regions_enabled = DefaultTopSurfaceContoningPolygonizeColorRegionsEnabled;
top_surface_contoning_fast_mode_enabled = DefaultTopSurfaceContoningFastModeEnabled;
top_surface_contoning_polygonization_mode = DefaultTopSurfaceContoningPolygonizationMode;
top_surface_contoning_polygonize_resolution = DefaultTopSurfaceContoningPolygonizeResolution;
top_surface_contoning_surface_anchored_stacks_enabled = DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled;
top_surface_contoning_surface_anchored_stack_optimizations_enabled = DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled;

View File

@@ -2138,6 +2138,19 @@ static int texture_mapping_contoning_color_prediction_mode_from_choice_selection
}
}
static int texture_mapping_contoning_polygonization_mode_choice_selection(int mode)
{
return TextureMappingZone::effective_top_surface_contoning_polygonization_mode(mode) ==
int(TextureMappingZone::ContoningPolygonizationMarchingSquares) ? 1 : 0;
}
static int texture_mapping_contoning_polygonization_mode_from_choice_selection(int selection)
{
return selection == 1 ?
int(TextureMappingZone::ContoningPolygonizationMarchingSquares) :
TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode;
}
class TextureMappingAdvancedOptionsDialog : public wxDialog
{
public:
@@ -2197,6 +2210,7 @@ public:
bool top_surface_contoning_supersampled_cells_enabled,
bool top_surface_contoning_polygonize_color_regions_enabled,
bool top_surface_contoning_fast_mode_enabled,
int top_surface_contoning_polygonization_mode,
int top_surface_contoning_polygonize_resolution,
bool top_surface_contoning_surface_anchored_stacks_enabled,
bool top_surface_contoning_surface_anchored_stack_optimizations_enabled,
@@ -2849,30 +2863,47 @@ public:
evt.Skip();
queue_top_surface_contoning_message_resize_wrap();
});
auto *contoning_flat_infill_row = new wxBoxSizer(wxHORIZONTAL);
contoning_flat_infill_row->Add(new wxStaticText(m_top_surface_contoning_panel, wxID_ANY, _L("Infill type")),
0,
wxALIGN_CENTER_VERTICAL | wxRIGHT,
gap);
wxArrayString contoning_flat_infill_choices;
auto add_contoning_flat_infill_choice = [&](const wxString &label, int mode) {
contoning_flat_infill_choices.Add(label);
m_top_surface_contoning_flat_surface_infill_modes.push_back(mode);
};
add_contoning_flat_infill_choice(_L("Default (Boundary Skin variable width)"),
int(TextureMappingZone::ContoningFlatSurfaceInfillDefault));
add_contoning_flat_infill_choice(_L("Rectilinear"),
int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinear));
if (TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions) {
auto *contoning_flat_infill_row = new wxBoxSizer(wxHORIZONTAL);
contoning_flat_infill_row->Add(new wxStaticText(m_top_surface_contoning_panel, wxID_ANY, _L("Flat surface infill mode")),
0,
wxALIGN_CENTER_VERTICAL | wxRIGHT,
gap);
wxArrayString contoning_flat_infill_choices;
contoning_flat_infill_choices.Add(_L("Default (Boundary Skin variable width)"));
contoning_flat_infill_choices.Add(_L("Rectilinear"));
contoning_flat_infill_choices.Add(_L("Concentric"));
contoning_flat_infill_choices.Add(_L("Boundary Skin (fixed width)"));
contoning_flat_infill_choices.Add(_L("Boundary Skin (variable width)"));
contoning_flat_infill_choices.Add(_L("Spiral"));
contoning_flat_infill_choices.Add(_L("Boundary Skin Hybrid"));
contoning_flat_infill_choices.Add(_L("Rectilinear with Boundary"));
m_top_surface_contoning_flat_surface_infill_choice =
new wxChoice(m_top_surface_contoning_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, contoning_flat_infill_choices);
m_top_surface_contoning_flat_surface_infill_choice->SetSelection(
std::clamp(top_surface_contoning_flat_surface_infill_mode,
int(TextureMappingZone::ContoningFlatSurfaceInfillDefault),
int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinearWithBoundary)));
contoning_flat_infill_row->Add(m_top_surface_contoning_flat_surface_infill_choice, 1, wxEXPAND);
top_surface_contoning_root->Add(contoning_flat_infill_row, 0, wxEXPAND | wxTOP, gap);
add_contoning_flat_infill_choice(_L("Concentric"),
int(TextureMappingZone::ContoningFlatSurfaceInfillConcentric));
add_contoning_flat_infill_choice(_L("Boundary Skin (fixed width)"),
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinFixed));
add_contoning_flat_infill_choice(_L("Boundary Skin (variable width)"),
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinVariable));
add_contoning_flat_infill_choice(_L("Spiral"),
int(TextureMappingZone::ContoningFlatSurfaceInfillSpiral));
add_contoning_flat_infill_choice(_L("Boundary Skin Hybrid"),
int(TextureMappingZone::ContoningFlatSurfaceInfillBoundarySkinHybrid));
add_contoning_flat_infill_choice(_L("Rectilinear with Boundary"),
int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinearWithBoundary));
}
m_top_surface_contoning_flat_surface_infill_choice =
new wxChoice(m_top_surface_contoning_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, contoning_flat_infill_choices);
const int stored_flat_infill_mode =
TextureMappingZone::stored_top_surface_contoning_flat_surface_infill_mode(top_surface_contoning_flat_surface_infill_mode);
const auto flat_infill_mode_it = std::find(m_top_surface_contoning_flat_surface_infill_modes.begin(),
m_top_surface_contoning_flat_surface_infill_modes.end(),
stored_flat_infill_mode);
m_top_surface_contoning_flat_surface_infill_choice->SetSelection(
flat_infill_mode_it != m_top_surface_contoning_flat_surface_infill_modes.end() ?
int(flat_infill_mode_it - m_top_surface_contoning_flat_surface_infill_modes.begin()) :
0);
contoning_flat_infill_row->Add(m_top_surface_contoning_flat_surface_infill_choice, 1, wxEXPAND);
top_surface_contoning_root->Add(contoning_flat_infill_row, 0, wxEXPAND | wxTOP, gap);
top_surface_box->Add(m_top_surface_contoning_panel, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap);
m_top_surface_image_fixed_coloring_filaments_checkbox =
new wxCheckBox(top_surface_page, wxID_ANY, _L("Fixed top-surface coloring filaments"));
@@ -3065,16 +3096,35 @@ public:
0,
wxEXPAND | wxTOP | wxBOTTOM,
gap / 2);
m_top_surface_contoning_fast_mode_checkbox =
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("Fast mode"));
m_top_surface_contoning_fast_mode_checkbox->SetValue(top_surface_contoning_fast_mode_enabled);
m_top_surface_contoning_fast_mode_checkbox->SetMinSize(
wxSize(-1, std::max(m_top_surface_contoning_fast_mode_checkbox->GetBestSize().GetHeight(), FromDIP(24))));
contoning_checkboxes_root->Add(m_top_surface_contoning_fast_mode_checkbox,
m_top_surface_contoning_polygonization_mode_panel = new wxPanel(m_top_surface_contoning_checkboxes_panel, wxID_ANY);
auto *contoning_polygonization_mode_row = new wxBoxSizer(wxHORIZONTAL);
m_top_surface_contoning_polygonization_mode_panel->SetSizer(contoning_polygonization_mode_row);
contoning_polygonization_mode_row->Add(new wxStaticText(m_top_surface_contoning_polygonization_mode_panel, wxID_ANY, _L("Technique")),
0,
wxALIGN_CENTER_VERTICAL | wxRIGHT,
gap);
wxArrayString contoning_polygonization_mode_choices;
contoning_polygonization_mode_choices.Add(_L("Vector-border shared Gaussian partition"));
contoning_polygonization_mode_choices.Add(_L("Marching squares"));
m_top_surface_contoning_polygonization_mode_choice =
new wxChoice(m_top_surface_contoning_polygonization_mode_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, contoning_polygonization_mode_choices);
m_top_surface_contoning_polygonization_mode_choice->SetSelection(
texture_mapping_contoning_polygonization_mode_choice_selection(top_surface_contoning_polygonization_mode));
contoning_polygonization_mode_row->Add(m_top_surface_contoning_polygonization_mode_choice, 1, wxEXPAND);
contoning_checkboxes_root->Add(m_top_surface_contoning_polygonization_mode_panel,
0,
wxEXPAND | wxTOP | wxBOTTOM,
gap / 2);
if (TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions) {
m_top_surface_contoning_fast_mode_checkbox =
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("Fast mode"));
m_top_surface_contoning_fast_mode_checkbox->SetValue(top_surface_contoning_fast_mode_enabled);
m_top_surface_contoning_fast_mode_checkbox->SetMinSize(
wxSize(-1, std::max(m_top_surface_contoning_fast_mode_checkbox->GetBestSize().GetHeight(), FromDIP(24))));
contoning_checkboxes_root->Add(m_top_surface_contoning_fast_mode_checkbox,
0,
wxEXPAND | wxTOP | wxBOTTOM,
gap / 2);
m_top_surface_contoning_surface_anchored_stacks_checkbox =
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("Surface-anchored stacks"));
m_top_surface_contoning_surface_anchored_stacks_checkbox->SetValue(top_surface_contoning_surface_anchored_stacks_enabled);
@@ -3581,13 +3631,12 @@ public:
}
int top_surface_contoning_flat_surface_infill_mode() const
{
if (!TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions)
return TextureMappingZone::DefaultTopSurfaceContoningFlatSurfaceInfillMode;
return m_top_surface_contoning_flat_surface_infill_choice != nullptr ?
std::clamp(m_top_surface_contoning_flat_surface_infill_choice->GetSelection(),
int(TextureMappingZone::ContoningFlatSurfaceInfillDefault),
int(TextureMappingZone::ContoningFlatSurfaceInfillRectilinearWithBoundary)) :
TextureMappingZone::DefaultTopSurfaceContoningFlatSurfaceInfillMode;
if (m_top_surface_contoning_flat_surface_infill_choice != nullptr) {
const int selection = m_top_surface_contoning_flat_surface_infill_choice->GetSelection();
if (selection >= 0 && size_t(selection) < m_top_surface_contoning_flat_surface_infill_modes.size())
return m_top_surface_contoning_flat_surface_infill_modes[size_t(selection)];
}
return TextureMappingZone::DefaultTopSurfaceContoningFlatSurfaceInfillMode;
}
bool top_surface_contoning_layer_phase_enabled() const
{
@@ -3627,10 +3676,19 @@ public:
}
bool top_surface_contoning_fast_mode_enabled() const
{
if (!TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions)
return true;
return m_top_surface_contoning_fast_mode_checkbox != nullptr ?
m_top_surface_contoning_fast_mode_checkbox->GetValue() :
TextureMappingZone::DefaultTopSurfaceContoningFastModeEnabled;
}
int top_surface_contoning_polygonization_mode() const
{
return m_top_surface_contoning_polygonization_mode_choice != nullptr ?
texture_mapping_contoning_polygonization_mode_from_choice_selection(
m_top_surface_contoning_polygonization_mode_choice->GetSelection()) :
TextureMappingZone::DefaultTopSurfaceContoningPolygonizationMode;
}
int top_surface_contoning_polygonize_resolution() const
{
if (m_top_surface_contoning_polygonize_resolution_choice == nullptr)
@@ -4581,6 +4639,10 @@ private:
m_top_surface_contoning_polygonize_resolution_panel->Show(polygonize_color_regions);
if (m_top_surface_contoning_polygonize_resolution_choice != nullptr)
m_top_surface_contoning_polygonize_resolution_choice->Enable(polygonize_color_regions);
if (m_top_surface_contoning_polygonization_mode_panel != nullptr)
m_top_surface_contoning_polygonization_mode_panel->Show(polygonize_color_regions);
if (m_top_surface_contoning_polygonization_mode_choice != nullptr)
m_top_surface_contoning_polygonization_mode_choice->Enable(polygonize_color_regions);
if (m_top_surface_contoning_surface_anchored_stacks_checkbox != nullptr) {
m_top_surface_contoning_surface_anchored_stacks_checkbox->Show(contoning);
m_top_surface_contoning_surface_anchored_stacks_checkbox->Enable(contoning);
@@ -4666,6 +4728,7 @@ private:
wxStaticText *m_top_surface_contoning_pattern_recommendation_text {nullptr};
wxStaticText *m_top_surface_contoning_shell_warning_text {nullptr};
wxChoice *m_top_surface_contoning_flat_surface_infill_choice {nullptr};
std::vector<int> m_top_surface_contoning_flat_surface_infill_modes;
wxPanel *m_top_surface_contoning_checkboxes_panel {nullptr};
wxCheckBox *m_top_surface_contoning_color_lower_surfaces_checkbox {nullptr};
wxCheckBox *m_top_surface_contoning_only_one_perimeter_around_shell_infill_checkbox {nullptr};
@@ -4680,6 +4743,8 @@ private:
wxCheckBox *m_top_surface_contoning_supersampled_cells_checkbox {nullptr};
wxCheckBox *m_top_surface_contoning_polygonize_color_regions_checkbox {nullptr};
wxCheckBox *m_top_surface_contoning_fast_mode_checkbox {nullptr};
wxPanel *m_top_surface_contoning_polygonization_mode_panel {nullptr};
wxChoice *m_top_surface_contoning_polygonization_mode_choice {nullptr};
wxPanel *m_top_surface_contoning_polygonize_resolution_panel {nullptr};
wxChoice *m_top_surface_contoning_polygonize_resolution_choice {nullptr};
wxCheckBox *m_top_surface_contoning_surface_anchored_stacks_checkbox {nullptr};
@@ -9716,6 +9781,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
updated.top_surface_contoning_supersampled_cells_enabled,
updated.top_surface_contoning_polygonize_color_regions_enabled,
updated.top_surface_contoning_fast_mode_enabled,
updated.top_surface_contoning_polygonization_mode,
updated.top_surface_contoning_polygonize_resolution,
updated.top_surface_contoning_surface_anchored_stacks_enabled,
updated.top_surface_contoning_surface_anchored_stack_optimizations_enabled,
@@ -9800,6 +9866,8 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
dlg.top_surface_contoning_polygonize_color_regions_enabled();
updated.top_surface_contoning_fast_mode_enabled =
dlg.top_surface_contoning_fast_mode_enabled();
updated.top_surface_contoning_polygonization_mode =
dlg.top_surface_contoning_polygonization_mode();
updated.top_surface_contoning_polygonize_resolution =
dlg.top_surface_contoning_polygonize_resolution();
updated.top_surface_contoning_surface_anchored_stacks_enabled =