Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base type interfaces for soluble interface supports #6017

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 68 additions & 37 deletions src/libslic3r/SupportMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,13 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
union_ex(l->polygons, false));
#endif // SLIC3R_DEBUG

#ifdef SLIC3R_DEBUG
for (MyLayersPtr::const_iterator it = base_interface_layers.begin(); it != base_interface_layers.end(); ++ it)
Slic3r::SVG::export_expolygons(
debug_out_path("support-base-interface-layers-%d-%lf.svg", iRun, (*it)->print_z),
union_ex((*it)->polygons, false));
#endif /* SLIC3R_DEBUG */

/*
// Clip with the pillars.
if (! shape.empty()) {
Expand Down Expand Up @@ -786,7 +793,7 @@ namespace SupportMaterialInternal {
{
for (const ExtrusionPath &ep : loop.paths)
if (ep.role() == erOverhangPerimeter && ! ep.polyline.empty())
return int(ep.size()) >= (ep.is_closed() ? 3 : 2);
return ep.size() >= (ep.is_closed() ? 3 : 2);
return false;
}
static bool has_bridging_perimeters(const ExtrusionEntityCollection &perimeters)
Expand Down Expand Up @@ -961,7 +968,8 @@ static int Test()
return 0;
}
static int run_support_test = Test();
#endif /* SLIC3R_DEBUG */
#endif /* SLIC3R_DEBUG
*/

// Generate top contact layers supporting overhangs.
// For a soluble interface material synchronize the layer heights with the object, otherwise leave the layer height undefined.
Expand Down Expand Up @@ -1133,7 +1141,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
// Subtracting them as they are may leave unwanted narrow
// residues of diff_polygons that would then be supported.
diff_polygons = diff(diff_polygons,
offset(union_(to_polygons(std::move(blockers[layer_id]))), float(1000.*SCALED_EPSILON)));
offset(union_(to_polygons(std::move(blockers[layer_id]))),
1000.*SCALED_EPSILON));
}

#ifdef SLIC3R_DEBUG
Expand Down Expand Up @@ -1586,7 +1595,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
});

Polygons &layer_support_area = layer_support_areas[layer_id];
task_group.run([this, &projection, &projection_raw, &layer, &layer_support_area] {
task_group.run([this, &projection, &projection_raw, &layer, &layer_support_area, layer_id] {
// Remove the areas that touched from the projection that will continue on next, lower, top surfaces.
// Polygons trimming = union_(to_polygons(layer.slices), touching, true);
Polygons trimming = offset(layer.lslices, float(SCALED_EPSILON));
Expand Down Expand Up @@ -1669,25 +1678,24 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
template<typename IteratorType, typename IndexType, typename FN_HIGHER_EQUAL>
IndexType idx_higher_or_equal(IteratorType begin, IteratorType end, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal)
{
auto size = int(end - begin);
if (size == 0) {
if (vec.empty()) {
idx = 0;
} else if (idx == IndexType(-1)) {
// First of the batch of layers per thread pool invocation. Use binary search.
int idx_low = 0;
int idx_high = std::max(0, size - 1);
int idx_high = std::max(0, int(vec.size()) - 1);
while (idx_low + 1 < idx_high) {
int idx_mid = (idx_low + idx_high) / 2;
if (fn_higher_equal(begin[idx_mid]))
if (fn_higher_equal(vec[idx_mid]))
idx_high = idx_mid;
else
idx_low = idx_mid;
}
idx = fn_higher_equal(begin[idx_low]) ? idx_low :
(fn_higher_equal(begin[idx_high]) ? idx_high : size);
idx = fn_higher_equal(vec[idx_low]) ? idx_low :
(fn_higher_equal(vec[idx_high]) ? idx_high : vec.size());
} else {
// For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search.
while (int(idx) < size && ! fn_higher_equal(begin[idx]))
while (idx < vec.size() && ! fn_higher_equal(vec[idx]))
++ idx;
}
return idx;
Expand All @@ -1703,44 +1711,38 @@ IndexType idx_higher_or_equal(const std::vector<T>& vec, IndexType idx, FN_HIGHE
// If no vec item with Z value <= of an internal threshold of fn_lower_equal is found, return -1.
// If the initial idx is < -1, then use binary search.
// Otherwise search linearly downwards.
template<typename IT, typename FN_LOWER_EQUAL>
int idx_lower_or_equal(IT begin, IT end, int idx, FN_LOWER_EQUAL fn_lower_equal)
template<typename T, typename FN_LOWER_EQUAL>
int idx_lower_or_equal(const std::vector<T*> &vec, int idx, FN_LOWER_EQUAL fn_lower_equal)
{
auto size = int(end - begin);
if (size == 0) {
if (vec.empty()) {
idx = -1;
} else if (idx < -1) {
// First of the batch of layers per thread pool invocation. Use binary search.
int idx_low = 0;
int idx_high = std::max(0, size - 1);
int idx_high = std::max(0, int(vec.size()) - 1);
while (idx_low + 1 < idx_high) {
int idx_mid = (idx_low + idx_high) / 2;
if (fn_lower_equal(begin[idx_mid]))
if (fn_lower_equal(vec[idx_mid]))
idx_low = idx_mid;
else
idx_high = idx_mid;
}
idx = fn_lower_equal(begin[idx_high]) ? idx_high :
(fn_lower_equal(begin[idx_low ]) ? idx_low : -1);
idx = fn_lower_equal(vec[idx_high]) ? idx_high :
(fn_lower_equal(vec[idx_low ]) ? idx_low : -1);
} else {
// For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search.
while (idx >= 0 && ! fn_lower_equal(begin[idx]))
while (idx >= 0 && ! fn_lower_equal(vec[idx]))
-- idx;
}
return idx;
}
template<typename T, typename FN_LOWER_EQUAL>
int idx_lower_or_equal(const std::vector<T*> &vec, int idx, FN_LOWER_EQUAL fn_lower_equal)
{
return idx_lower_or_equal(vec.begin(), vec.end(), idx, fn_lower_equal);
}

// Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them.
void PrintObjectSupportMaterial::trim_top_contacts_by_bottom_contacts(
const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const
{
tbb::parallel_for(tbb::blocked_range<int>(0, int(top_contacts.size())),
[&bottom_contacts, &top_contacts](const tbb::blocked_range<int>& range) {
[this, &object, &bottom_contacts, &top_contacts](const tbb::blocked_range<int>& range) {
int idx_bottom_overlapping_first = -2;
// For all top contact layers, counting downwards due to the way idx_higher_or_equal caches the last index to avoid repeated binary search.
for (int idx_top = range.end() - 1; idx_top >= range.begin(); -- idx_top) {
Expand Down Expand Up @@ -1969,7 +1971,7 @@ void PrintObjectSupportMaterial::generate_base_layers(
BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_base_layers() in parallel - start";
tbb::parallel_for(
tbb::blocked_range<size_t>(0, intermediate_layers.size()),
[&object, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_support_areas](const tbb::blocked_range<size_t>& range) {
[this, &object, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_support_areas](const tbb::blocked_range<size_t>& range) {
// index -2 means not initialized yet, -1 means intialized and decremented to 0 and then -1.
int idx_top_contact_above = -2;
int idx_bottom_contact_overlapping = -2;
Expand Down Expand Up @@ -2124,7 +2126,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
// Find the overlapping object layers including the extra above / below gap.
coordf_t z_threshold = support_layer.print_z - support_layer.height - gap_extra_below + EPSILON;
idx_object_layer_overlapping = idx_higher_or_equal(
object.layers().begin(), object.layers().end(), idx_object_layer_overlapping,
object.layers(), idx_object_layer_overlapping,
[z_threshold](const Layer *layer){ return layer->print_z >= z_threshold; });
// Collect all the object layers intersecting with this layer.
Polygons polygons_trimming;
Expand Down Expand Up @@ -2259,6 +2261,7 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
const MyLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts,
MyLayersPtr &intermediate_layers,
size_t number_base_interface_layers,
MyLayerStorage &layer_storage) const
{
// my $area_threshold = $self->interface_flow->scaled_spacing ** 2;
Expand Down Expand Up @@ -2338,13 +2341,15 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
}
}
// Move idx_top_contact_first up until above the current print_z.
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const MyLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON
// FIX Avoid aditional excess layers (make it mirrow symmetric to the bottonm coding)
// idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const MyLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const MyLayer *layer){ return layer->bottom_z >= intermediate_layer.print_z; }); // - EPSILON
// Collect the top contact areas above this intermediate layer, below top_z.
Polygons polygons_top_contact_projected_interface;
Polygons polygons_top_contact_projected_base;
for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++ idx_top_contact) {
const MyLayer &top_contact_layer = *top_contacts[idx_top_contact];
//FIXME maybe this adds one interface layer in excess?
//FIXME maybe this adds one interface layer in excess? removed?
if (top_contact_layer.bottom_z - EPSILON > top_z)
break;
polygons_append(top_contact_layer.bottom_z - EPSILON > top_inteface_z ? polygons_top_contact_projected_base : polygons_top_contact_projected_interface, top_contact_layer.polygons);
Expand Down Expand Up @@ -2384,6 +2389,32 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
return base_and_interface_layers;
}

static inline void fill_expolygons_generate_paths(
ExtrusionEntitiesPtr &dst,
const ExPolygons &expolygons,
Fill *filler,
float density,
ExtrusionRole role,
const Flow &flow)
{
FillParams fill_params;
fill_params.density = density;
fill_params.dont_adjust = true;
for (const ExPolygon &expoly : expolygons) {
Surface surface(stInternal, expoly);
Polylines polylines;
try {
polylines = filler->fill_surface(&surface, fill_params);
} catch (InfillFailedException &) {
}
extrusion_entities_append_paths(
dst,
std::move(polylines),
role,
flow.mm3_per_mm(), flow.width, flow.height);
}
}

static inline void fill_expolygons_generate_paths(
ExtrusionEntitiesPtr &dst,
ExPolygons &&expolygons,
Expand Down Expand Up @@ -2973,7 +3004,7 @@ void modulate_extrusion_by_overlapping_layers(
}

void PrintObjectSupportMaterial::generate_toolpaths(
SupportLayerPtrs &support_layers,
const PrintObject &object,
const MyLayersPtr &raft_layers,
const MyLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts,
Expand Down Expand Up @@ -3049,7 +3080,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
{
assert(support_layer_id < raft_layers.size());
SupportLayer &support_layer = *support_layers[support_layer_id];
SupportLayer &support_layer = *object.support_layers()[support_layer_id];
assert(support_layer.support_fills.entities.empty());
MyLayer &raft_layer = *raft_layers[support_layer_id];

Expand Down Expand Up @@ -3146,7 +3177,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
MyLayerExtruded base_interface_layer;
std::vector<LayerCacheItem> overlaps;
};
std::vector<LayerCache> layer_caches(support_layers.size(), LayerCache());
std::vector<LayerCache> layer_caches(object.support_layers().size(), LayerCache());

tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
[this, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
Expand All @@ -3167,7 +3198,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
filler_support->set_bounding_box(bbox_object);
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
{
SupportLayer &support_layer = *support_layers[support_layer_id];
SupportLayer &support_layer = *object.support_layers()[support_layer_id];
LayerCache &layer_cache = layer_caches[support_layer_id];

// Find polygons with the same print_z.
Expand Down Expand Up @@ -3403,11 +3434,11 @@ void PrintObjectSupportMaterial::generate_toolpaths(
});

// Now modulate the support layer height in parallel.
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
[&support_layers, &layer_caches]
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers().size()),
[this, &object, &layer_caches]
(const tbb::blocked_range<size_t>& range) {
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id) {
SupportLayer &support_layer = *support_layers[support_layer_id];
SupportLayer &support_layer = *object.support_layers()[support_layer_id];
LayerCache &layer_cache = layer_caches[support_layer_id];
for (LayerCacheItem &layer_cache_item : layer_cache.overlaps) {
modulate_extrusion_by_overlapping_layers(layer_cache_item.layer_extruded->extrusions, *layer_cache_item.layer_extruded->layer, layer_cache_item.overlapping);
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/SupportMaterial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ class PrintObjectSupportMaterial
const MyLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts,
MyLayersPtr &intermediate_layers,
size_t number_base_interface_layers,
MyLayerStorage &layer_storage) const;


Expand All @@ -225,6 +226,7 @@ class PrintObjectSupportMaterial
void clip_with_shape();
*/

// New method needed for additional base interface support
// Produce the actual G-code.
void generate_toolpaths(
SupportLayerPtrs &support_layers,
Expand Down