One more fix for Organic supports & Raft :

Raft was not generated at all with Organic supports enabled, but
no trees produced.
This commit is contained in:
Vojtech Bubnik 2023-02-28 17:40:05 +01:00
parent 94d463b645
commit 2959de40ae
2 changed files with 152 additions and 129 deletions

View file

@ -2954,7 +2954,7 @@ SupportGeneratorLayersPtr generate_raft_base(
Polygons columns;
Polygons first_layer;
if (columns_base != nullptr) {
if (columns_base->print_z > slicing_params.raft_contact_top_z - EPSILON) {
if (columns_base->bottom_print_z() > slicing_params.raft_interface_top_z - EPSILON) {
// Classic supports with colums above the raft interface.
base = columns_base->polygons;
columns = base;

View file

@ -993,6 +993,30 @@ inline SupportGeneratorLayer& layer_allocate(
return layer_initialize(layer_storage.back(), layer_type, slicing_params, config, layer_idx);
}
int generate_raft_contact(
const PrintObject &print_object,
const TreeSupportSettings &config,
SupportGeneratorLayersPtr &top_contacts,
SupportGeneratorLayerStorage &layer_storage)
{
int raft_contact_layer_idx = -1;
if (print_object.has_raft() && print_object.layer_count() > 0) {
// Produce raft contact layer outside of the tree support loop, so that no trees will be generated for the raft contact layer.
// Raft layers supporting raft contact interface will be produced by the classic raft generator.
// Find the raft contact layer.
raft_contact_layer_idx = int(config.raft_layers.size()) - 1;
while (raft_contact_layer_idx > 0 && config.raft_layers[raft_contact_layer_idx] > print_object.slicing_parameters().raft_contact_top_z + EPSILON)
-- raft_contact_layer_idx;
// Create the raft contact layer.
SupportGeneratorLayer &raft_contact_layer = layer_allocate(layer_storage, SupporLayerType::TopContact, print_object.slicing_parameters(), config, raft_contact_layer_idx);
top_contacts[raft_contact_layer_idx] = &raft_contact_layer;
const ExPolygons &lslices = print_object.get_layer(0)->lslices;
double expansion = print_object.config().raft_expansion.value;
raft_contact_layer.polygons = expansion > 0 ? expand(lslices, scaled<float>(expansion)) : to_polygons(lslices);
}
return raft_contact_layer_idx;
}
using SupportElements = std::deque<SupportElement>;
/*!
* \brief Creates the initial influence areas (that can later be propagated down) by placing them below the overhang.
@ -1066,24 +1090,7 @@ static void generate_initial_areas(
const size_t num_raft_layers = config.raft_layers.size();
const size_t num_support_layers = size_t(std::max(0, int(print_object.layer_count()) + int(num_raft_layers) - int(z_distance_delta)));
const size_t first_support_layer = std::max(int(num_raft_layers) - int(z_distance_delta), 1);
size_t first_tree_layer = 0;
size_t raft_contact_layer_idx = std::numeric_limits<size_t>::max();
if (num_raft_layers > 0 && print_object.layer_count() > 0) {
// Produce raft contact layer outside of the tree support loop, so that no trees will be generated for the raft contact layer.
// Raft layers supporting raft contact interface will be produced by the classic raft generator.
// Find the raft contact layer.
raft_contact_layer_idx = config.raft_layers.size() - 1;
while (raft_contact_layer_idx > 0 && config.raft_layers[raft_contact_layer_idx] > print_object.slicing_parameters().raft_contact_top_z + EPSILON)
-- raft_contact_layer_idx;
// Create the raft contact layer.
SupportGeneratorLayer &raft_contact_layer = layer_allocate(layer_storage, SupporLayerType::TopContact, print_object.slicing_parameters(), config, raft_contact_layer_idx);
top_contacts[raft_contact_layer_idx] = &raft_contact_layer;
const ExPolygons &lslices = print_object.get_layer(0)->lslices;
double expansion = print_object.config().raft_expansion.value;
raft_contact_layer.polygons = expansion > 0 ? expand(lslices, scaled<float>(expansion)) : to_polygons(lslices);
first_tree_layer = print_object.slicing_parameters().raft_layers() - 1;
}
const int raft_contact_layer_idx = generate_raft_contact(print_object, config, top_contacts, layer_storage);
std::mutex mutex_layer_storage, mutex_movebounds;
std::vector<std::unordered_set<Point, PointHash>> already_inserted(num_support_layers);
@ -1436,13 +1443,15 @@ static void generate_initial_areas(
}
});
if (raft_contact_layer_idx >= 0) {
const size_t first_tree_layer = print_object.slicing_parameters().raft_layers() - 1;
// Remove tree tips that start below the raft contact,
// remove interface layers below the raft contact.
for (size_t i = 0; i < first_tree_layer; ++i) {
top_contacts[i] = nullptr;
move_bounds[i].clear();
}
if (raft_contact_layer_idx != std::numeric_limits<size_t>::max() && print_object.config().raft_expansion.value > 0) {
if (raft_contact_layer_idx >= 0 && print_object.config().raft_expansion.value > 0) {
// If any tips at first_tree_layer now are completely inside the expanded raft layer, remove them as well before they are propagated to the ground.
Polygons &raft_polygons = top_contacts[raft_contact_layer_idx]->polygons;
EdgeGrid::Grid grid(get_extents(raft_polygons).inflated(SCALED_EPSILON));
@ -1479,6 +1488,7 @@ static void generate_initial_areas(
#endif
}
}
}
static unsigned int move_inside(const Polygons &polygons, Point &from, int distance = 0, int64_t maxDist2 = std::numeric_limits<int64_t>::max())
{
@ -4203,9 +4213,15 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume
std::vector<Polygons> overhangs = generate_overhangs(config, *print.get_object(processing.second.front()), throw_on_cancel);
// ### Precalculate avoidances, collision etc.
size_t num_support_layers = precalculate(print, overhangs, processing.first, processing.second, volumes, throw_on_cancel);
if (num_support_layers == 0)
continue;
SupportGeneratorLayerStorage layer_storage;
SupportGeneratorLayersPtr top_contacts;
SupportGeneratorLayersPtr bottom_contacts;
SupportGeneratorLayersPtr top_interface_layers;
SupportGeneratorLayersPtr intermediate_layers;
if (size_t num_support_layers = precalculate(print, overhangs, processing.first, processing.second, volumes, throw_on_cancel);
num_support_layers > 0) {
auto t_precalc = std::chrono::high_resolution_clock::now();
@ -4213,11 +4229,10 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume
std::vector<SupportElements> move_bounds(num_support_layers);
// ### Place tips of the support tree
SupportGeneratorLayersPtr bottom_contacts(num_support_layers, nullptr);
SupportGeneratorLayersPtr top_contacts(num_support_layers, nullptr);
SupportGeneratorLayersPtr top_interface_layers(num_support_layers, nullptr);
SupportGeneratorLayersPtr intermediate_layers(num_support_layers, nullptr);
SupportGeneratorLayerStorage layer_storage;
top_contacts .assign(num_support_layers, nullptr);
bottom_contacts .assign(num_support_layers, nullptr);
top_interface_layers.assign(num_support_layers, nullptr);
intermediate_layers .assign(num_support_layers, nullptr);
for (size_t mesh_idx : processing.second)
generate_initial_areas(*print.get_object(mesh_idx), volumes, config, overhangs, move_bounds, top_contacts, top_interface_layers, layer_storage, throw_on_cancel);
@ -4276,6 +4291,12 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume
// BOOST_LOG_TRIVIAL(error) << "Why ask questions when you already know the answer twice.\n (This is not a real bug, please dont report it.)";
move_bounds.clear();
} else {
top_contacts.assign(config.raft_layers.size(), nullptr);
if (generate_raft_contact(print_object, config, top_contacts, layer_storage) < 0)
// No raft.
continue;
}
auto remove_undefined_layers = [](SupportGeneratorLayersPtr &layers) {
layers.erase(std::remove_if(layers.begin(), layers.end(), [](const SupportGeneratorLayer* ptr) { return ptr == nullptr; }), layers.end());
@ -4343,7 +4364,9 @@ void fff_tree_support_generate(PrintObject &print_object, std::function<void()>
break;
++idx;
}
FFFTreeSupport::generate_support_areas(*print_object.print(), BuildVolume(Pointfs{ Vec2d{ -300., -300. }, Vec2d{ -300., +300. }, Vec2d{ +300., +300. }, Vec2d{ +300., -300. } }, 0.), { idx }, throw_on_cancel);
FFFTreeSupport::generate_support_areas(*print_object.print(),
BuildVolume(Pointfs{ Vec2d{ -300., -300. }, Vec2d{ -300., +300. }, Vec2d{ +300., +300. }, Vec2d{ +300., -300. } }, 0.), { idx },
throw_on_cancel);
}
} // namespace Slic3r