Optimizations for surface-anchored stacks. Make sure full pattern length is always used in top-surface coloring

This commit is contained in:
sentientstardust
2026-05-30 19:47:05 +01:00
parent 07d1a85464
commit d6323f3924
4 changed files with 372 additions and 37 deletions

View File

@@ -1,6 +1,7 @@
#include <assert.h>
#include <stdio.h>
#include <array>
#include <atomic>
#include <condition_variable>
#include <exception>
#include <map>
@@ -504,6 +505,7 @@ struct TopSurfaceImageRegionPlan {
bool contoning_polygonize_color_regions_enabled = false;
int contoning_polygonize_resolution = TextureMappingZone::DefaultTopSurfaceContoningPolygonizeResolution;
bool contoning_surface_anchored_stacks_enabled = false;
bool contoning_surface_anchored_stack_optimizations_enabled = TextureMappingZone::DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled;
bool contoning_td_adjustment_enabled = TextureMappingZone::DefaultTopSurfaceContoningTdAdjustmentEnabled;
bool contoning_surface_scatter_enabled = TextureMappingZone::DefaultTopSurfaceContoningSurfaceScatterEnabled;
bool contoning_beer_lambert_rgb_correction_enabled = TextureMappingZone::DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled;
@@ -1102,11 +1104,45 @@ static int top_surface_image_contoning_local_stack_layers_at_point(const Point &
return layers;
}
static ExPolygons top_surface_image_contoning_clean_area(ExPolygons &&component_area,
const ExPolygons &clip_area,
const ExPolygons &blocked_area,
float min_feature_mm,
const ThrowIfCanceled *throw_if_canceled)
static void top_surface_image_contoning_remove_collinear_points(Polygon &polygon)
{
if (polygon.points.size() < 3)
return;
Points points;
points.reserve(polygon.points.size());
for (const Point &point : polygon.points)
if (points.empty() || points.back() != point)
points.emplace_back(point);
if (points.size() >= 2 && points.front() == points.back())
points.pop_back();
bool changed = true;
while (changed && points.size() >= 3) {
changed = false;
Points filtered;
filtered.reserve(points.size());
for (size_t idx = 0; idx < points.size(); ++idx) {
const Point &prev = points[(idx + points.size() - 1) % points.size()];
const Point &point = points[idx];
const Point &next = points[(idx + 1) % points.size()];
if (point == prev || point == next || int128::orient(prev, point, next) == 0) {
changed = true;
continue;
}
filtered.emplace_back(point);
}
points = std::move(filtered);
}
polygon.points = std::move(points);
}
static ExPolygons top_surface_image_contoning_clean_area_impl(ExPolygons &&component_area,
const ExPolygons &clip_area,
const ExPolygons &blocked_area,
float min_feature_mm,
const ThrowIfCanceled *throw_if_canceled)
{
if (component_area.empty())
return {};
@@ -1142,10 +1178,166 @@ static ExPolygons top_surface_image_contoning_clean_area(ExPolygons &&component_
return filtered.empty() ? ExPolygons() : top_surface_clip_union_ex(filtered);
}
struct TopSurfaceImageContoningCleanupGroup {
BoundingBox bbox;
ExPolygons area;
};
struct TopSurfaceImageContoningCleanupItem {
BoundingBox bbox;
ExPolygon area;
};
static void top_surface_image_contoning_merge_cleanup_group(std::vector<TopSurfaceImageContoningCleanupGroup> &groups,
size_t group_idx,
const ThrowIfCanceled *throw_if_canceled)
{
bool merged = true;
while (merged && group_idx < groups.size()) {
merged = false;
for (size_t idx = 0; idx < groups.size(); ++idx) {
if (idx == group_idx)
continue;
if (!groups[group_idx].bbox.defined || !groups[idx].bbox.defined ||
!groups[group_idx].bbox.overlap(groups[idx].bbox))
continue;
check_canceled(throw_if_canceled);
groups[group_idx].bbox.merge(groups[idx].bbox);
append(groups[group_idx].area, std::move(groups[idx].area));
groups.erase(groups.begin() + idx);
if (idx < group_idx)
--group_idx;
merged = true;
break;
}
}
}
static std::vector<ExPolygons> top_surface_image_contoning_cleanup_groups(ExPolygons &&component_area,
coord_t grouping_margin,
const ThrowIfCanceled *throw_if_canceled)
{
std::vector<TopSurfaceImageContoningCleanupItem> items;
items.reserve(component_area.size());
for (ExPolygon &expolygon : component_area) {
check_canceled(throw_if_canceled);
BoundingBox bbox = get_extents(expolygon);
if (bbox.defined && grouping_margin > 0)
bbox.offset(double(grouping_margin));
items.push_back({ bbox, std::move(expolygon) });
}
std::sort(items.begin(), items.end(), [](const TopSurfaceImageContoningCleanupItem &lhs,
const TopSurfaceImageContoningCleanupItem &rhs) {
if (lhs.bbox.defined != rhs.bbox.defined)
return lhs.bbox.defined;
if (!lhs.bbox.defined)
return false;
return std::make_tuple(lhs.bbox.min.x(), lhs.bbox.min.y(), lhs.bbox.max.x(), lhs.bbox.max.y()) <
std::make_tuple(rhs.bbox.min.x(), rhs.bbox.min.y(), rhs.bbox.max.x(), rhs.bbox.max.y());
});
std::vector<TopSurfaceImageContoningCleanupGroup> active;
std::vector<TopSurfaceImageContoningCleanupGroup> groups;
active.reserve(items.size());
groups.reserve(items.size());
for (TopSurfaceImageContoningCleanupItem &item : items) {
check_canceled(throw_if_canceled);
if (!item.bbox.defined) {
TopSurfaceImageContoningCleanupGroup group;
group.bbox = item.bbox;
group.area.emplace_back(std::move(item.area));
groups.emplace_back(std::move(group));
continue;
}
for (size_t idx = 0; idx < active.size();) {
if (active[idx].bbox.defined && active[idx].bbox.max.x() < item.bbox.min.x()) {
groups.emplace_back(std::move(active[idx]));
active.erase(active.begin() + idx);
} else {
++idx;
}
}
size_t group_idx = active.size();
for (size_t idx = 0; idx < active.size(); ++idx) {
if (active[idx].bbox.defined && active[idx].bbox.overlap(item.bbox)) {
group_idx = idx;
break;
}
}
if (group_idx == active.size()) {
TopSurfaceImageContoningCleanupGroup group;
group.bbox = item.bbox;
group.area.emplace_back(std::move(item.area));
active.emplace_back(std::move(group));
group_idx = active.size() - 1;
} else {
active[group_idx].bbox.merge(item.bbox);
active[group_idx].area.emplace_back(std::move(item.area));
}
top_surface_image_contoning_merge_cleanup_group(active, group_idx, throw_if_canceled);
}
for (TopSurfaceImageContoningCleanupGroup &group : active)
groups.emplace_back(std::move(group));
std::vector<ExPolygons> out;
out.reserve(groups.size());
for (TopSurfaceImageContoningCleanupGroup &group : groups)
if (!group.area.empty())
out.emplace_back(std::move(group.area));
return out;
}
static ExPolygons top_surface_image_contoning_clean_area(ExPolygons &&component_area,
const ExPolygons &clip_area,
const ExPolygons &blocked_area,
float min_feature_mm,
bool cleanup_optimizations_enabled,
const ThrowIfCanceled *throw_if_canceled)
{
if (!cleanup_optimizations_enabled || component_area.size() <= 1)
return top_surface_image_contoning_clean_area_impl(std::move(component_area),
clip_area,
blocked_area,
min_feature_mm,
throw_if_canceled);
const float closing_radius = float(scale_(std::clamp(min_feature_mm * 0.18f, 0.05f, 0.45f)));
const double tolerance = scale_(std::clamp(min_feature_mm * 0.12f, 0.03f, 0.25f));
const coord_t grouping_margin =
std::max<coord_t>(0, coord_t(std::ceil(double(closing_radius) + tolerance + double(SCALED_EPSILON))));
std::vector<ExPolygons> groups =
top_surface_image_contoning_cleanup_groups(std::move(component_area), grouping_margin, throw_if_canceled);
if (groups.empty())
return {};
if (groups.size() == 1)
return top_surface_image_contoning_clean_area_impl(std::move(groups.front()),
clip_area,
blocked_area,
min_feature_mm,
throw_if_canceled);
ExPolygons out;
for (ExPolygons &group : groups) {
check_canceled(throw_if_canceled);
ExPolygons cleaned = top_surface_image_contoning_clean_area_impl(std::move(group),
clip_area,
blocked_area,
min_feature_mm,
throw_if_canceled);
append(out, std::move(cleaned));
}
return out;
}
struct TopSurfaceImageContoningVectorLabel {
std::vector<unsigned int> bottom_to_top;
std::array<float, 3> rgb { { 0.f, 0.f, 0.f } };
std::array<float, 3> oklab { { 0.f, 0.f, 0.f } };
int valid_depth { 0 };
bool repeat_allowed { false };
};
struct TopSurfaceImageContoningVectorRegion {
@@ -1249,6 +1441,7 @@ struct TopSurfaceImageContoningStackPlanKey {
bool blue_noise { false };
bool polygonize { false };
int polygonize_resolution { 1 };
bool surface_anchored_stack_optimizations { false };
bool td_adjustment { false };
bool surface_scatter { false };
bool beer_lambert_rgb_correction { false };
@@ -1282,6 +1475,7 @@ struct TopSurfaceImageContoningStackPlanKey {
blue_noise,
polygonize,
polygonize_resolution,
surface_anchored_stack_optimizations,
td_adjustment,
surface_scatter,
beer_lambert_rgb_correction,
@@ -1312,6 +1506,7 @@ struct TopSurfaceImageContoningStackPlanKey {
rhs.blue_noise,
rhs.polygonize,
rhs.polygonize_resolution,
rhs.surface_anchored_stack_optimizations,
rhs.td_adjustment,
rhs.surface_scatter,
rhs.beer_lambert_rgb_correction,
@@ -1689,6 +1884,7 @@ static ExPolygons top_surface_image_contoning_area_from_grid_label(const std::ve
const ExPolygons &clip_area,
const ExPolygons &blocked_area,
float min_feature_mm,
bool cleanup_optimizations_enabled,
const ThrowIfCanceled *throw_if_canceled)
{
ExPolygons cells;
@@ -1730,7 +1926,12 @@ static ExPolygons top_surface_image_contoning_area_from_grid_label(const std::ve
}
for (const TopSurfaceImageContoningGridRect &rect : active)
top_surface_image_contoning_append_grid_rect(cells, rect, min_x, min_y, step, bbox);
return top_surface_image_contoning_clean_area(std::move(cells), clip_area, blocked_area, min_feature_mm, throw_if_canceled);
return top_surface_image_contoning_clean_area(std::move(cells),
clip_area,
blocked_area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
}
static ExPolygons top_surface_image_contoning_polygonized_area_from_grid_label(const std::vector<int> &grid,
@@ -1744,6 +1945,7 @@ static ExPolygons top_surface_image_contoning_polygonized_area_from_grid_label(c
const ExPolygons &clip_area,
const ExPolygons &blocked_area,
float min_feature_mm,
bool cleanup_optimizations_enabled,
const ThrowIfCanceled *throw_if_canceled)
{
if (grid.empty() || cols <= 0 || rows <= 0 || grid.size() != size_t(cols) * size_t(rows))
@@ -1771,11 +1973,18 @@ static ExPolygons top_surface_image_contoning_polygonized_area_from_grid_label(c
}
if (polygon.points.size() >= 3 && polygon.points.front() == polygon.points.back())
polygon.points.pop_back();
if (cleanup_optimizations_enabled)
top_surface_image_contoning_remove_collinear_points(polygon);
if (polygon.points.size() >= 3)
cells.emplace_back(std::move(polygon));
}
return top_surface_image_contoning_clean_area(std::move(cells), clip_area, blocked_area, min_feature_mm, throw_if_canceled);
return top_surface_image_contoning_clean_area(std::move(cells),
clip_area,
blocked_area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
}
static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_contoning_component_regions_from_grid(
@@ -1791,6 +2000,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
const ExPolygons &area,
float min_feature_mm,
bool polygonize_color_regions,
bool cleanup_optimizations_enabled,
bool lower_surface,
const ThrowIfCanceled *throw_if_canceled)
{
@@ -1807,15 +2017,22 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
return regions;
std::vector<int> component_grid(label_grid.size(), -1);
std::vector<int> valid_grid(label_grid.size(), -1);
std::vector<int> cell_counts(size_t(max_component_id) + 1, 0);
for (size_t idx = 0; idx < label_grid.size(); ++idx) {
const int label = label_grid[idx];
if (label < 0 || label >= int(labels.size()))
continue;
const std::vector<unsigned int> &bottom_to_top = labels[size_t(label)].bottom_to_top;
const TopSurfaceImageContoningVectorLabel &label_data = labels[size_t(label)];
const std::vector<unsigned int> &bottom_to_top = label_data.bottom_to_top;
if (bottom_to_top.empty())
continue;
const int pattern_depth = depth % int(bottom_to_top.size());
const int valid_depth = label_data.valid_depth > 0 ? label_data.valid_depth : int(bottom_to_top.size());
if (depth >= valid_depth)
continue;
const int pattern_depth = label_data.repeat_allowed ? depth % int(bottom_to_top.size()) : depth;
if (pattern_depth < 0 || pattern_depth >= int(bottom_to_top.size()))
continue;
const unsigned int component_id =
lower_surface ?
bottom_to_top[size_t(pattern_depth)] :
@@ -1823,6 +2040,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
if (component_id == 0 || component_id > max_component_id)
continue;
component_grid[idx] = int(component_id);
valid_grid[idx] = 1;
++cell_counts[size_t(component_id)];
}
@@ -1838,6 +2056,23 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
return lhs < rhs;
});
const ExPolygons empty_blocked_area;
ExPolygons valid_area = top_surface_image_contoning_area_from_grid_label(valid_grid,
cols,
rows,
1,
min_x,
min_y,
step,
bbox,
area,
empty_blocked_area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
if (valid_area.empty())
return regions;
ExPolygons taken;
for (int component_id : component_order) {
check_canceled(throw_if_canceled);
@@ -1851,9 +2086,10 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
min_y,
step,
bbox,
area,
valid_area,
taken,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled) :
top_surface_image_contoning_area_from_grid_label(component_grid,
cols,
@@ -1863,9 +2099,10 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
min_y,
step,
bbox,
area,
valid_area,
taken,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
if (component_area.empty())
continue;
@@ -1880,7 +2117,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
if (!regions.empty()) {
check_canceled(throw_if_canceled);
ExPolygons covered = top_surface_clip_union_ex(taken);
ExPolygons leftover = top_surface_clip_diff_ex(area, covered, ApplySafetyOffset::Yes);
ExPolygons leftover = top_surface_clip_diff_ex(valid_area, covered, ApplySafetyOffset::Yes);
if (!leftover.empty()) {
append(regions.front().area, std::move(leftover));
regions.front().area = top_surface_clip_union_ex(regions.front().area);
@@ -1902,6 +2139,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
const ExPolygons &area,
float min_feature_mm,
bool polygonize_color_regions,
bool cleanup_optimizations_enabled,
const ThrowIfCanceled *throw_if_canceled)
{
std::vector<TopSurfaceImageContoningVectorRegion> regions;
@@ -1943,6 +2181,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
area,
empty_blocked_area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled) :
top_surface_image_contoning_area_from_grid_label(label_grid,
cols,
@@ -1955,6 +2194,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
area,
empty_blocked_area,
min_feature_mm,
cleanup_optimizations_enabled,
throw_if_canceled);
if (label_area.empty())
continue;
@@ -2351,6 +2591,8 @@ static std::optional<TopSurfaceImageContoningSolvedLabel> top_surface_image_cont
label_data.bottom_to_top = stack.bottom_to_top;
label_data.rgb = *stack_rgb;
label_data.oklab = color_solver_oklab_from_srgb(*stack_rgb);
label_data.valid_depth = std::max(visible_layers, int(stack.bottom_to_top.size()));
label_data.repeat_allowed = visible_layers > int(stack.bottom_to_top.size());
label = int(labels.size());
labels.emplace_back(std::move(label_data));
label_by_stack.emplace(label_key, label);
@@ -2699,37 +2941,74 @@ static void top_surface_image_contoning_solve_anchored_region(
anchored_region.union_area,
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_surface_anchored_stack_optimizations_enabled,
throw_if_canceled);
anchored_region.depth_regions.resize(size_t(source_context.stack_layers));
std::vector<int> active_depths;
active_depths.reserve(size_t(source_context.stack_layers));
for (int depth = 0; depth < source_context.stack_layers; ++depth) {
check_canceled(throw_if_canceled);
top_surface_image_contoning_report_anchored_progress(object,
source_layer,
source_surface,
L("processing"),
depth + 1,
source_context.stack_layers);
if (depth >= int(anchored_region.depth_areas.size()) ||
anchored_region.depth_areas[size_t(depth)].empty())
continue;
anchored_region.depth_regions[size_t(depth)] =
top_surface_image_contoning_component_regions_from_grid(grid,
cols,
rows,
labels,
depth,
min_x,
min_y,
step,
bbox,
anchored_region.union_area,
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
throw_if_canceled);
if (depth < int(anchored_region.depth_areas.size()) &&
!anchored_region.depth_areas[size_t(depth)].empty())
active_depths.emplace_back(depth);
}
if (active_depths.empty())
return;
auto build_depth_regions = [&](int depth) {
check_canceled(throw_if_canceled);
return top_surface_image_contoning_component_regions_from_grid(grid,
cols,
rows,
labels,
depth,
min_x,
min_y,
step,
bbox,
anchored_region.union_area,
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_surface_anchored_stack_optimizations_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
throw_if_canceled);
};
top_surface_image_contoning_report_anchored_progress(object,
source_layer,
source_surface,
L("processing"),
0,
int(active_depths.size()));
if (active_depths.size() <= 1) {
const int depth = active_depths.front();
anchored_region.depth_regions[size_t(depth)] = build_depth_regions(depth);
} else {
std::atomic<int> completed_depths { 0 };
tbb::parallel_for(tbb::blocked_range<size_t>(0, active_depths.size(), 1),
[&](const tbb::blocked_range<size_t> &range) {
for (size_t idx = range.begin(); idx != range.end(); ++idx) {
const int depth = active_depths[idx];
anchored_region.depth_regions[size_t(depth)] = build_depth_regions(depth);
const int completed = ++completed_depths;
if (completed == int(active_depths.size()) || (completed & 3) == 0)
top_surface_image_contoning_report_anchored_progress(object,
source_layer,
source_surface,
L("processing"),
completed,
int(active_depths.size()));
}
});
}
top_surface_image_contoning_report_anchored_progress(object,
source_layer,
source_surface,
L("processing"),
int(active_depths.size()),
int(active_depths.size()));
}
static std::shared_ptr<TopSurfaceImageContoningAnchoredSurfacePlan> top_surface_image_contoning_build_anchored_surface_plan(
@@ -2907,6 +3186,7 @@ static TopSurfaceImageContoningStackPlanKey top_surface_image_contoning_anchored
key.polygonize_resolution = plan.contoning_polygonize_color_regions_enabled ?
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(plan.contoning_polygonize_resolution) :
1;
key.surface_anchored_stack_optimizations = plan.contoning_surface_anchored_stack_optimizations_enabled;
key.td_adjustment = plan.contoning_td_adjustment_enabled;
key.surface_scatter = plan.contoning_surface_scatter_enabled;
key.beer_lambert_rgb_correction = plan.contoning_beer_lambert_rgb_correction_enabled;
@@ -3181,6 +3461,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
area,
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_surface_anchored_stack_optimizations_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
throw_if_canceled);
@@ -3426,6 +3707,7 @@ static TopSurfaceImageContoningStackPlanKey top_surface_image_contoning_stack_pl
key.polygonize_resolution = plan.contoning_polygonize_color_regions_enabled ?
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(plan.contoning_polygonize_resolution) :
1;
key.surface_anchored_stack_optimizations = plan.contoning_surface_anchored_stack_optimizations_enabled;
key.td_adjustment = plan.contoning_td_adjustment_enabled;
key.surface_scatter = plan.contoning_surface_scatter_enabled;
key.beer_lambert_rgb_correction = plan.contoning_beer_lambert_rgb_correction_enabled;
@@ -3513,6 +3795,7 @@ static std::vector<TopSurfaceImageContoningVectorRegion> top_surface_image_conto
area,
plan.contoning_min_feature_mm,
plan.contoning_polygonize_color_regions_enabled,
plan.contoning_surface_anchored_stack_optimizations_enabled,
source_surface == TopSurfaceImageSourceSurface::Bottom &&
plan.contoning_td_adjustment_enabled,
throw_if_canceled);
@@ -4108,6 +4391,9 @@ static std::vector<TopSurfaceImageRegionPlan> top_surface_image_region_plans(
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(zone->top_surface_contoning_polygonize_resolution);
plan.contoning_surface_anchored_stacks_enabled =
zone->effective_top_surface_contoning_surface_anchored_stacks_enabled();
plan.contoning_surface_anchored_stack_optimizations_enabled =
plan.contoning_surface_anchored_stacks_enabled &&
zone->effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled();
plan.contoning_beam_search_stack_expansion_enabled =
zone->effective_top_surface_contoning_beam_search_stack_expansion_enabled();
plan.contoning_td_adjustment_enabled = zone->top_surface_contoning_td_adjustment_enabled;

View File

@@ -1163,6 +1163,8 @@ bool TextureMappingZone::operator==(const TextureMappingZone &rhs) const
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() &&
effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled() ==
rhs.effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled() &&
top_surface_contoning_td_adjustment_enabled == rhs.top_surface_contoning_td_adjustment_enabled &&
top_surface_contoning_surface_scatter_enabled == rhs.top_surface_contoning_surface_scatter_enabled &&
top_surface_contoning_beer_lambert_rgb_correction_enabled == rhs.top_surface_contoning_beer_lambert_rgb_correction_enabled &&
@@ -1570,6 +1572,8 @@ std::string TextureMappingManager::serialize_entries()
TextureMappingZone::normalize_top_surface_contoning_polygonize_resolution(zone.top_surface_contoning_polygonize_resolution);
texture["top_surface_contoning_surface_anchored_stacks_enabled"] =
zone.effective_top_surface_contoning_surface_anchored_stacks_enabled();
texture["top_surface_contoning_surface_anchored_stack_optimizations_enabled"] =
zone.effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled();
texture["top_surface_contoning_td_adjustment_enabled"] =
zone.top_surface_contoning_td_adjustment_enabled;
texture["top_surface_contoning_surface_scatter_enabled"] =
@@ -1879,6 +1883,9 @@ void TextureMappingManager::load_entries(const std::string &serialized,
zone.top_surface_contoning_surface_anchored_stacks_enabled =
texture.value("top_surface_contoning_surface_anchored_stacks_enabled",
TextureMappingZone::DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled);
zone.top_surface_contoning_surface_anchored_stack_optimizations_enabled =
texture.value("top_surface_contoning_surface_anchored_stack_optimizations_enabled",
TextureMappingZone::DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled);
zone.top_surface_contoning_td_adjustment_enabled =
texture.value("top_surface_contoning_td_adjustment_enabled",
TextureMappingZone::DefaultTopSurfaceContoningTdAdjustmentEnabled);

View File

@@ -201,6 +201,7 @@ struct TextureMappingZone
static constexpr bool DefaultTopSurfaceContoningPolygonizeColorRegionsEnabled = true;
static constexpr int DefaultTopSurfaceContoningPolygonizeResolution = 4;
static constexpr bool DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled = false;
static constexpr bool DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled = true;
static constexpr bool DefaultTopSurfaceContoningTdAdjustmentEnabled = true;
static constexpr bool DefaultTopSurfaceContoningSurfaceScatterEnabled = false;
static constexpr bool DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled = false;
@@ -285,6 +286,11 @@ struct TextureMappingZone
return ShowExperimentalTopSurfaceContoningOptions && value;
}
static bool effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled(bool value)
{
return ShowExperimentalTopSurfaceContoningOptions ? value : true;
}
static bool effective_top_surface_contoning_beam_search_stack_expansion_enabled(bool value)
{
return ShowExperimentalTopSurfaceContoningOptions ? value : true;
@@ -401,6 +407,7 @@ struct TextureMappingZone
bool top_surface_contoning_polygonize_color_regions_enabled = DefaultTopSurfaceContoningPolygonizeColorRegionsEnabled;
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;
bool top_surface_contoning_td_adjustment_enabled = DefaultTopSurfaceContoningTdAdjustmentEnabled;
bool top_surface_contoning_surface_scatter_enabled = DefaultTopSurfaceContoningSurfaceScatterEnabled;
bool top_surface_contoning_beer_lambert_rgb_correction_enabled = DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled;
@@ -523,6 +530,12 @@ struct TextureMappingZone
top_surface_contoning_surface_anchored_stacks_enabled);
}
bool effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled() const
{
return TextureMappingZone::effective_top_surface_contoning_surface_anchored_stack_optimizations_enabled(
top_surface_contoning_surface_anchored_stack_optimizations_enabled);
}
bool effective_top_surface_contoning_beam_search_stack_expansion_enabled() const
{
return TextureMappingZone::effective_top_surface_contoning_beam_search_stack_expansion_enabled(
@@ -565,6 +578,7 @@ struct TextureMappingZone
top_surface_contoning_perimeter_mode = DefaultTopSurfaceContoningPerimeterMode;
top_surface_contoning_flat_surface_infill_mode = DefaultTopSurfaceContoningFlatSurfaceInfillMode;
top_surface_contoning_surface_anchored_stacks_enabled = false;
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;
@@ -638,6 +652,7 @@ struct TextureMappingZone
top_surface_contoning_polygonize_color_regions_enabled = DefaultTopSurfaceContoningPolygonizeColorRegionsEnabled;
top_surface_contoning_polygonize_resolution = DefaultTopSurfaceContoningPolygonizeResolution;
top_surface_contoning_surface_anchored_stacks_enabled = DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled;
top_surface_contoning_surface_anchored_stack_optimizations_enabled = DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled;
top_surface_contoning_td_adjustment_enabled = DefaultTopSurfaceContoningTdAdjustmentEnabled;
top_surface_contoning_surface_scatter_enabled = DefaultTopSurfaceContoningSurfaceScatterEnabled;
top_surface_contoning_beer_lambert_rgb_correction_enabled = DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled;

View File

@@ -2105,6 +2105,7 @@ public:
bool top_surface_contoning_polygonize_color_regions_enabled,
int top_surface_contoning_polygonize_resolution,
bool top_surface_contoning_surface_anchored_stacks_enabled,
bool top_surface_contoning_surface_anchored_stack_optimizations_enabled,
bool top_surface_contoning_beam_search_stack_expansion_enabled,
bool top_surface_contoning_td_adjustment_enabled,
bool top_surface_contoning_surface_scatter_enabled,
@@ -2970,6 +2971,16 @@ public:
0,
wxEXPAND | wxTOP | wxBOTTOM,
gap / 2);
m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox =
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("Surface-anchored stack optimizations"));
m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox->SetValue(
top_surface_contoning_surface_anchored_stack_optimizations_enabled);
m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox->SetMinSize(
wxSize(-1, std::max(m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox->GetBestSize().GetHeight(), FromDIP(24))));
contoning_checkboxes_root->Add(m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox,
0,
wxEXPAND | wxTOP | wxBOTTOM,
gap / 2);
m_top_surface_contoning_beam_search_stack_expansion_checkbox =
new wxCheckBox(m_top_surface_contoning_checkboxes_panel, wxID_ANY, _L("Use beam search for stack expansion"));
m_top_surface_contoning_beam_search_stack_expansion_checkbox->SetValue(top_surface_contoning_beam_search_stack_expansion_enabled);
@@ -3528,6 +3539,14 @@ public:
TextureMappingZone::DefaultTopSurfaceContoningSurfaceAnchoredStacksEnabled :
m_top_surface_contoning_surface_anchored_stacks_checkbox->GetValue();
}
bool top_surface_contoning_surface_anchored_stack_optimizations_enabled() const
{
if (!TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions)
return true;
return m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox == nullptr ?
TextureMappingZone::DefaultTopSurfaceContoningSurfaceAnchoredStackOptimizationsEnabled :
m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox->GetValue();
}
bool top_surface_contoning_beam_search_stack_expansion_enabled() const
{
if (!TextureMappingZone::ShowExperimentalTopSurfaceContoningOptions)
@@ -4447,6 +4466,10 @@ private:
m_top_surface_contoning_surface_anchored_stacks_checkbox->Show(contoning);
m_top_surface_contoning_surface_anchored_stacks_checkbox->Enable(contoning);
}
if (m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox != nullptr) {
m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox->Show(contoning);
m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox->Enable(contoning && surface_anchored_stacks);
}
if (m_top_surface_contoning_beam_search_stack_expansion_checkbox != nullptr) {
m_top_surface_contoning_beam_search_stack_expansion_checkbox->Show(contoning);
m_top_surface_contoning_beam_search_stack_expansion_checkbox->Enable(contoning);
@@ -4540,6 +4563,7 @@ private:
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};
wxCheckBox *m_top_surface_contoning_surface_anchored_stack_optimizations_checkbox {nullptr};
wxCheckBox *m_top_surface_contoning_beam_search_stack_expansion_checkbox {nullptr};
wxCheckBox *m_top_surface_contoning_td_adjustment_checkbox {nullptr};
wxCheckBox *m_top_surface_contoning_surface_scatter_checkbox {nullptr};
@@ -9574,6 +9598,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
updated.top_surface_contoning_polygonize_color_regions_enabled,
updated.top_surface_contoning_polygonize_resolution,
updated.top_surface_contoning_surface_anchored_stacks_enabled,
updated.top_surface_contoning_surface_anchored_stack_optimizations_enabled,
updated.top_surface_contoning_beam_search_stack_expansion_enabled,
updated.top_surface_contoning_td_adjustment_enabled,
updated.top_surface_contoning_surface_scatter_enabled,
@@ -9655,6 +9680,8 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
dlg.top_surface_contoning_polygonize_resolution();
updated.top_surface_contoning_surface_anchored_stacks_enabled =
dlg.top_surface_contoning_surface_anchored_stacks_enabled();
updated.top_surface_contoning_surface_anchored_stack_optimizations_enabled =
dlg.top_surface_contoning_surface_anchored_stack_optimizations_enabled();
updated.top_surface_contoning_beam_search_stack_expansion_enabled =
dlg.top_surface_contoning_beam_search_stack_expansion_enabled();
updated.top_surface_contoning_td_adjustment_enabled =