WIP Organic supports intefaces: bugfixes
This commit is contained in:
Vojtech Bubnik 2023-05-08 10:25:28 +02:00
parent 1e7a3216ca
commit c838fc92fc
2 changed files with 29 additions and 21 deletions

View File

@ -137,7 +137,8 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
if (! intermediate_layers.empty() && support_params.has_interfaces()) {
// For all intermediate layers, collect top contact surfaces, which are not further than support_material_interface_layers.
BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_interface_layers() in parallel - start";
const bool snug_supports = config.support_material_style.value != smsGrid;
const bool snug_supports = config.support_material_style.value == smsSnug;
const bool smooth_supports = config.support_material_style.value != smsGrid;
SupportGeneratorLayersPtr &interface_layers = base_and_interface_layers.first;
SupportGeneratorLayersPtr &base_interface_layers = base_and_interface_layers.second;
interface_layers.assign(intermediate_layers.size(), nullptr);
@ -147,7 +148,7 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
const auto minimum_island_radius = support_params.support_material_interface_flow.scaled_spacing() / support_params.interface_density;
const auto closing_distance = smoothing_distance; // scaled<float>(config.support_material_closing_radius.value);
// Insert a new layer into base_interface_layers, if intersection with base exists.
auto insert_layer = [&layer_storage, snug_supports, closing_distance, smoothing_distance, minimum_island_radius](
auto insert_layer = [&layer_storage, smooth_supports, closing_distance, smoothing_distance, minimum_island_radius](
SupportGeneratorLayer &intermediate_layer, Polygons &bottom, Polygons &&top, SupportGeneratorLayer *top_interface_layer,
const Polygons *subtract, SupporLayerType type) -> SupportGeneratorLayer* {
bool has_top_interface = top_interface_layer && ! top_interface_layer->polygons.empty();
@ -156,14 +157,16 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
append(bottom, std::move(top));
// Merge top / bottom interfaces. For snug supports, merge using closing distance and regularize (close concave corners).
bottom = intersection(
snug_supports ?
smooth_supports ?
smooth_outward(closing(std::move(bottom), closing_distance + minimum_island_radius, closing_distance, SUPPORT_SURFACES_OFFSET_PARAMETERS), smoothing_distance) :
union_safety_offset(std::move(bottom)),
intermediate_layer.polygons);
if (has_top_interface)
if (has_top_interface) {
// Don't trim the precomputed Organic supports top interface with base layer
// as the precomputed top interface likely expands over multiple tree tips.
bottom = union_(std::move(top_interface_layer->polygons), bottom);
top_interface_layer->polygons.clear();
}
if (! bottom.empty()) {
//FIXME Remove non-printable tiny islands, let them be printed using the base support.
//bottom = opening(std::move(bottom), minimum_island_radius);
@ -253,13 +256,8 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
auto resolve_same_layer = [](SupportGeneratorLayersPtr &layers, int &idx, coordf_t print_z) -> SupportGeneratorLayer* {
if (! layers.empty()) {
idx = idx_higher_or_equal(layers, idx, [print_z](const SupportGeneratorLayer *layer) { return layer->print_z > print_z - EPSILON; });
if (idx < int(layers.size()) && layers[idx]->print_z < print_z + EPSILON) {
SupportGeneratorLayer *l = layers[idx];
// Remove the layer from the source container, as it will be consumed here: It will be merged
// with the newly produced interfaces.
layers[idx] = nullptr;
return l;
}
if (idx < int(layers.size()) && layers[idx]->print_z < print_z + EPSILON)
return layers[idx];
}
return nullptr;
};
@ -284,11 +282,14 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
// Compress contact_out, remove the nullptr items.
// The parallel_for above may not have merged all the interface and base_interface layers
// generated by the Organic supports code, do it here.
auto merge_remove_nulls = [](SupportGeneratorLayersPtr &in1, SupportGeneratorLayersPtr &in2) {
size_t nonzeros = std::count_if(in1.begin(), in1.end(), [](auto *l) { return l != nullptr; }) +
std::count_if(in2.begin(), in2.end(), [](auto *l) { return l != nullptr; });
remove_nulls(in1);
remove_nulls(in2);
auto merge_remove_empty = [](SupportGeneratorLayersPtr &in1, SupportGeneratorLayersPtr &in2) {
auto remove_empty = [](SupportGeneratorLayersPtr &vec) {
vec.erase(
std::remove_if(vec.begin(), vec.end(), [](const SupportGeneratorLayer *ptr) { return ptr == nullptr || ptr->polygons.empty(); }),
vec.end());
};
remove_empty(in1);
remove_empty(in2);
if (in2.empty())
return std::move(in1);
else if (in1.empty())
@ -299,8 +300,8 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
return std::move(out);
}
};
interface_layers = merge_remove_nulls(interface_layers, top_interface_layers);
base_interface_layers = merge_remove_nulls(base_interface_layers, top_base_interface_layers);
interface_layers = merge_remove_empty(interface_layers, top_interface_layers);
base_interface_layers = merge_remove_empty(base_interface_layers, top_base_interface_layers);
BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_interface_layers() in parallel - end";
}

View File

@ -1119,7 +1119,7 @@ public:
void add_roof_build_plate(Polygons &&overhang_areas, size_t dtt_roof)
{
std::lock_guard<std::mutex> lock(m_mutex_layer_storage);
this->add_roof_unguarded(std::move(overhang_areas), 0, dtt_roof);
this->add_roof_unguarded(std::move(overhang_areas), 0, std::min(dtt_roof, this->support_parameters.num_top_interface_layers));
}
// called by sample_overhang_area()
@ -1204,6 +1204,8 @@ public:
private:
void add_roof_unguarded(Polygons &&new_roofs, const size_t insert_layer_idx, const size_t dtt_roof)
{
assert(support_parameters.has_top_contacts);
assert(dtt_roof <= support_parameters.num_top_interface_layers);
SupportGeneratorLayersPtr &layers =
dtt_roof == 0 ? this->top_contacts :
dtt_roof <= support_parameters.num_top_interface_layers_only() ? this->top_interfaces : this->top_base_interfaces;
@ -4413,8 +4415,13 @@ static void draw_branches(
bottom_extra_slices.back().polygons, volumes.getPlaceableAreas(0, layer_begin - LayerIndex(bottom_extra_slices.size()), [] {}));
if (area(this_bottom_contacts) < support_area_min)
bottom_extra_slices.pop_back();
else if (config.settings.support_floor_layers > 0)
bottom_contacts.emplace_back(std::move(this_bottom_contacts));
else {
// At least a fraction of the tree bottom is considered to be supported.
if (config.settings.support_floor_layers > 0)
// Turn this fraction of the tree bottom into a contact layer.
bottom_contacts.emplace_back(std::move(this_bottom_contacts));
break;
}
}
if (config.settings.support_floor_layers > 0)
for (int i = int(bottom_extra_slices.size()) - 2; i >= 0; -- i)