Skip to content

Commit

Permalink
Trimming support base layer with brim.
Browse files Browse the repository at this point in the history
Fixes Brim destroyed by support aka. Enable supports on top of brim #1156
Fixes Brim Priority/Support on Brim #713
Fixes Phantom Support columns interfere with brim #3396
Fixes false generation of brim when supports are used #3395

This is a work in progress, as the brim generator currently produces
different brim areas from what the support generator expects.
  • Loading branch information
bubnikv committed Feb 23, 2021
1 parent 8ba230d commit 055d232
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 19 deletions.
9 changes: 1 addition & 8 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "wipe_tower_y"
|| opt_key == "wipe_tower_rotation_angle") {
steps.emplace_back(psSkirt);
} else if (
opt_key == "brim_width"
|| opt_key == "brim_offset"
|| opt_key == "brim_type") {
steps.emplace_back(psBrim);
steps.emplace_back(psSkirt);
} else if (
opt_key == "nozzle_diameter"
|| opt_key == "resolution"
Expand Down Expand Up @@ -1191,8 +1185,7 @@ bool Print::has_skirt() const

bool Print::has_brim() const
{
return std::any_of(m_objects.begin(), m_objects.end(),
[](PrintObject *object) { return object->config().brim_type != btNoBrim && object->config().brim_width.value > 0.; });
return std::any_of(m_objects.begin(), m_objects.end(), [](PrintObject *object) { return object->has_brim(); });
}

static inline bool sequential_print_horizontal_clearance_valid(const Print &print)
Expand Down
21 changes: 12 additions & 9 deletions src/libslic3r/Print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,15 @@ class PrintObject : public PrintObjectBaseWithState<Print, PrintObjectStep, posC

// Bounding box is used to align the object infill patterns, and to calculate attractor for the rear seam.
// The bounding box may not be quite snug.
BoundingBox bounding_box() const { return BoundingBox(Point(- m_size.x() / 2, - m_size.y() / 2), Point(m_size.x() / 2, m_size.y() / 2)); }
BoundingBox bounding_box() const { return BoundingBox(Point(- m_size.x() / 2, - m_size.y() / 2), Point(m_size.x() / 2, m_size.y() / 2)); }
// Height is used for slicing, for sorting the objects by height for sequential printing and for checking vertical clearence in sequential print mode.
// The height is snug.
coord_t height() const { return m_size.z(); }
coord_t height() const { return m_size.z(); }
// Centering offset of the sliced mesh from the scaled and rotated mesh of the model.
const Point& center_offset() const { return m_center_offset; }
const Point& center_offset() const { return m_center_offset; }

bool has_brim() const { return this->config().brim_type != btNoBrim && this->config().brim_width.value > 0.; }


// adds region_id, too, if necessary
void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) {
Expand All @@ -199,14 +202,14 @@ class PrintObject : public PrintObjectBaseWithState<Print, PrintObjectStep, posC
const Layer* get_first_layer_bellow_printz(coordf_t print_z, coordf_t epsilon) const;

// print_z: top of the layer; slice_z: center of the layer.
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);

size_t support_layer_count() const { return m_support_layers.size(); }
void clear_support_layers();
SupportLayer* get_support_layer(int idx) { return m_support_layers[idx]; }
SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z);
size_t support_layer_count() const { return m_support_layers.size(); }
void clear_support_layers();
SupportLayer* get_support_layer(int idx) { return m_support_layers[idx]; }
SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z);
SupportLayerPtrs::iterator insert_support_layer(SupportLayerPtrs::iterator pos, size_t id, coordf_t height, coordf_t print_z, coordf_t slice_z);
void delete_support_layer(int idx);
void delete_support_layer(int idx);

// Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters.
// Returns true, if the layer_height_profile was changed.
Expand Down
8 changes: 7 additions & 1 deletion src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,13 @@ bool PrintObject::invalidate_state_by_config_options(
std::vector<PrintObjectStep> steps;
bool invalidated = false;
for (const t_config_option_key &opt_key : opt_keys) {
if ( opt_key == "perimeters"
if ( opt_key == "brim_width"
|| opt_key == "brim_offset"
|| opt_key == "brim_type") {
// Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial);
} else if (
opt_key == "perimeters"
|| opt_key == "extra_perimeters"
|| opt_key == "gap_fill_enabled"
|| opt_key == "gap_fill_speed"
Expand Down
40 changes: 39 additions & 1 deletion src/libslic3r/SupportMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "SupportMaterial.hpp"
#include "Fill/FillBase.hpp"
#include "Geometry.hpp"
#include "Point.hpp"

#include <cmath>
#include <memory>
Expand Down Expand Up @@ -496,7 +497,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
// If raft is to be generated, the 1st top_contact layer will contain the 1st object layer silhouette with holes filled.
// There is also a 1st intermediate layer containing bases of support columns.
// Inflate the bases of the support columns and create the raft base under the object.
MyLayersPtr raft_layers = this->generate_raft_base(top_contacts, interface_layers, intermediate_layers, layer_storage);
MyLayersPtr raft_layers = this->generate_raft_base(object, top_contacts, interface_layers, intermediate_layers, layer_storage);

#ifdef SLIC3R_DEBUG
for (const MyLayer *l : interface_layers)
Expand Down Expand Up @@ -2498,11 +2499,41 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
}

PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raft_base(
const PrintObject &object,
const MyLayersPtr &top_contacts,
const MyLayersPtr &interface_layers,
const MyLayersPtr &base_layers,
MyLayerStorage &layer_storage) const
{
// If there is brim to be generated, calculate the trimming regions.
Polygons brim;
if (object.has_brim()) {
// Calculate the area covered by the brim.
const BrimType brim_type = object.config().brim_type;
const bool brim_outer = brim_type == btOuterOnly || brim_type == btOuterAndInner;
const bool brim_inner = brim_type == btInnerOnly || brim_type == btOuterAndInner;
const auto brim_offset = scaled<float>(object.config().brim_offset.value + object.config().brim_width.value);
for (const ExPolygon &ex : object.layers().front()->lslices) {
if (brim_outer && brim_inner)
polygons_append(brim, offset(ex, brim_offset));
else {
if (brim_outer)
polygons_append(brim, offset(ex.contour, brim_offset, ClipperLib::jtRound, float(scale_(0.1))));
else
brim.emplace_back(ex.contour);
if (brim_inner) {
Polygons holes = ex.holes;
polygons_reverse(holes);
holes = offset(holes, - brim_offset, ClipperLib::jtRound, float(scale_(0.1)));
polygons_reverse(holes);
polygons_append(brim, std::move(holes));
} else
polygons_append(brim, ex.holes);
}
}
brim = union_(brim);
}

// How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
const float inflate_factor_fine = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine;
Expand Down Expand Up @@ -2581,6 +2612,13 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
offset(m_object->layers().front()->lslices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS));
if (contacts != nullptr)
columns_base->polygons = diff(columns_base->polygons, interface_polygons);
if (! brim.empty()) {
columns_base->polygons = diff(columns_base->polygons, brim);
if (contacts)
contacts->polygons = diff(contacts->polygons, brim);
if (interfaces)
interfaces->polygons = diff(interfaces->polygons, brim);
}
}

return raft_layers;
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/SupportMaterial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class PrintObjectSupportMaterial
// Generate raft layers, also expand the 1st support layer
// in case there is no raft layer to improve support adhesion.
MyLayersPtr generate_raft_base(
const PrintObject &object,
const MyLayersPtr &top_contacts,
const MyLayersPtr &interface_layers,
const MyLayersPtr &base_layers,
Expand Down

0 comments on commit 055d232

Please sign in to comment.