diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index fd94f9a1d..879e098bf 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -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" @@ -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) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 5f2c19335..3820d3e0f 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -168,12 +168,15 @@ public: // 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) { @@ -199,14 +202,14 @@ public: 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. diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 6dc8478a5..3ea79fe9f 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -518,7 +518,13 @@ bool PrintObject::invalidate_state_by_config_options( std::vector 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" diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index e7685db1f..5268658dc 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -5,6 +5,7 @@ #include "SupportMaterial.hpp" #include "Fill/FillBase.hpp" #include "Geometry.hpp" +#include "Point.hpp" #include #include @@ -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) @@ -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(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; @@ -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; diff --git a/src/libslic3r/SupportMaterial.hpp b/src/libslic3r/SupportMaterial.hpp index 030d2219a..425013d90 100644 --- a/src/libslic3r/SupportMaterial.hpp +++ b/src/libslic3r/SupportMaterial.hpp @@ -196,6 +196,7 @@ private: // 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,