Fix of "Problem with larger brim overlapping "
https://github.com/prusa3d/Slic3r/issues/373
This commit is contained in:
parent
434f538919
commit
774c69e3c6
@ -228,62 +228,16 @@ sub make_brim {
|
||||
$self->make_skirt;
|
||||
|
||||
return if $self->step_done(STEP_BRIM);
|
||||
|
||||
$self->set_step_started(STEP_BRIM);
|
||||
|
||||
# since this method must be idempotent, we clear brim paths *before*
|
||||
# checking whether we need to generate them
|
||||
$self->brim->clear;
|
||||
|
||||
if ($self->config->brim_width == 0) {
|
||||
$self->set_step_done(STEP_BRIM);
|
||||
return;
|
||||
if ($self->config->brim_width > 0) {
|
||||
$self->status_cb->(88, "Generating brim");
|
||||
$self->_make_brim;
|
||||
}
|
||||
$self->status_cb->(88, "Generating brim");
|
||||
|
||||
# brim is only printed on first layer and uses perimeter extruder
|
||||
my $first_layer_height = $self->skirt_first_layer_height;
|
||||
my $flow = $self->brim_flow;
|
||||
my $mm3_per_mm = $flow->mm3_per_mm;
|
||||
|
||||
my $grow_distance = $flow->scaled_width / 2;
|
||||
my @islands = (); # array of polygons
|
||||
foreach my $obj_idx (0 .. ($self->object_count - 1)) {
|
||||
my $object = $self->objects->[$obj_idx];
|
||||
my $layer0 = $object->get_layer(0);
|
||||
my @object_islands = (
|
||||
(map $_->contour, @{$layer0->slices}),
|
||||
);
|
||||
if (@{ $object->support_layers }) {
|
||||
my $support_layer0 = $object->support_layers->[0];
|
||||
push @object_islands,
|
||||
(map @{$_->polyline->grow($grow_distance)}, @{$support_layer0->support_fills})
|
||||
if $support_layer0->support_fills;
|
||||
}
|
||||
foreach my $copy (@{$object->_shifted_copies}) {
|
||||
push @islands, map { $_->translate(@$copy); $_ } map $_->clone, @object_islands;
|
||||
}
|
||||
}
|
||||
|
||||
my @loops = ();
|
||||
my $num_loops = sprintf "%.0f", $self->config->brim_width / $flow->width;
|
||||
for my $i (reverse 1 .. $num_loops) {
|
||||
# JT_SQUARE ensures no vertex is outside the given offset distance
|
||||
# -0.5 because islands are not represented by their centerlines
|
||||
# (first offset more, then step back - reverse order than the one used for
|
||||
# perimeters because here we're offsetting outwards)
|
||||
push @loops, @{offset2(\@islands, ($i + 0.5) * $flow->scaled_spacing, -1.0 * $flow->scaled_spacing, JT_SQUARE)};
|
||||
}
|
||||
|
||||
$self->brim->append(map Slic3r::ExtrusionLoop->new_from_paths(
|
||||
Slic3r::ExtrusionPath->new(
|
||||
polyline => Slic3r::Polygon->new(@$_)->split_at_first_point,
|
||||
role => EXTR_ROLE_SKIRT,
|
||||
mm3_per_mm => $mm3_per_mm,
|
||||
width => $flow->width,
|
||||
height => $first_layer_height,
|
||||
),
|
||||
), reverse @{union_pt_chained(\@loops)});
|
||||
|
||||
|
||||
$self->set_step_done(STEP_BRIM);
|
||||
}
|
||||
|
||||
|
@ -197,12 +197,12 @@ public:
|
||||
ExtrusionPaths paths;
|
||||
|
||||
ExtrusionLoop(ExtrusionLoopRole role = elrDefault) : m_loop_role(role) {};
|
||||
ExtrusionLoop(const ExtrusionPaths &paths, ExtrusionLoopRole role = elrDefault)
|
||||
: paths(paths), m_loop_role(role) {};
|
||||
ExtrusionLoop(const ExtrusionPath &path, ExtrusionLoopRole role = elrDefault)
|
||||
: m_loop_role(role) {
|
||||
this->paths.push_back(path);
|
||||
};
|
||||
ExtrusionLoop(const ExtrusionPaths &paths, ExtrusionLoopRole role = elrDefault) : paths(paths), m_loop_role(role) {};
|
||||
ExtrusionLoop(ExtrusionPaths &&paths, ExtrusionLoopRole role = elrDefault) : paths(std::move(paths)), m_loop_role(role) {};
|
||||
ExtrusionLoop(const ExtrusionPath &path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)
|
||||
{ this->paths.push_back(path); };
|
||||
ExtrusionLoop(const ExtrusionPath &&path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)
|
||||
{ this->paths.emplace_back(std::move(path)); };
|
||||
bool is_loop() const { return true; }
|
||||
bool can_reverse() const { return false; }
|
||||
ExtrusionLoop* clone() const { return new ExtrusionLoop (*this); }
|
||||
@ -243,49 +243,59 @@ private:
|
||||
inline void extrusion_paths_append(ExtrusionPaths &dst, Polylines &polylines, ExtrusionRole role, double mm3_per_mm, float width, float height)
|
||||
{
|
||||
dst.reserve(dst.size() + polylines.size());
|
||||
for (Polylines::const_iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
|
||||
if (it_polyline->is_valid()) {
|
||||
for (Polyline &polyline : polylines)
|
||||
if (polyline.is_valid()) {
|
||||
dst.push_back(ExtrusionPath(role, mm3_per_mm, width, height));
|
||||
dst.back().polyline = *it_polyline;
|
||||
dst.back().polyline = polyline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void extrusion_paths_append(ExtrusionPaths &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height)
|
||||
{
|
||||
dst.reserve(dst.size() + polylines.size());
|
||||
for (Polylines::const_iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
|
||||
if (it_polyline->is_valid()) {
|
||||
for (Polyline &polyline : polylines)
|
||||
if (polyline.is_valid()) {
|
||||
dst.push_back(ExtrusionPath(role, mm3_per_mm, width, height));
|
||||
dst.back().polyline = std::move(*it_polyline);
|
||||
dst.back().polyline = std::move(polyline);
|
||||
}
|
||||
}
|
||||
polylines.clear();
|
||||
}
|
||||
|
||||
inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &polylines, ExtrusionRole role, double mm3_per_mm, float width, float height)
|
||||
{
|
||||
dst.reserve(dst.size() + polylines.size());
|
||||
for (Polylines::const_iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
|
||||
if (it_polyline->is_valid()) {
|
||||
for (Polyline &polyline : polylines)
|
||||
if (polyline.is_valid()) {
|
||||
ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
|
||||
dst.push_back(extrusion_path);
|
||||
extrusion_path->polyline = *it_polyline;
|
||||
extrusion_path->polyline = polyline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height)
|
||||
{
|
||||
dst.reserve(dst.size() + polylines.size());
|
||||
for (Polylines::const_iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
|
||||
if (it_polyline->is_valid()) {
|
||||
for (Polyline &polyline : polylines)
|
||||
if (polyline.is_valid()) {
|
||||
ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
|
||||
dst.push_back(extrusion_path);
|
||||
extrusion_path->polyline = std::move(*it_polyline);
|
||||
extrusion_path->polyline = std::move(polyline);
|
||||
}
|
||||
polylines.clear();
|
||||
}
|
||||
|
||||
inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &&loops, ExtrusionRole role, double mm3_per_mm, float width, float height)
|
||||
{
|
||||
dst.reserve(dst.size() + loops.size());
|
||||
for (Polygon &poly : loops) {
|
||||
if (poly.is_valid()) {
|
||||
ExtrusionPath path(role, mm3_per_mm, width, height);
|
||||
path.polyline.points = std::move(poly.points);
|
||||
path.polyline.points.push_back(path.polyline.points.front());
|
||||
dst.emplace_back(new ExtrusionLoop(std::move(path)));
|
||||
}
|
||||
}
|
||||
polylines.clear();
|
||||
loops.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -901,6 +901,43 @@ void Print::_make_skirt()
|
||||
this->skirt.reverse();
|
||||
}
|
||||
|
||||
void Print::_make_brim()
|
||||
{
|
||||
// Brim is only printed on first layer and uses perimeter extruder.
|
||||
Flow flow = this->brim_flow();
|
||||
Polygons islands;
|
||||
for (PrintObject *object : this->objects) {
|
||||
Polygons object_islands;
|
||||
for (ExPolygon &expoly : object->layers.front()->slices.expolygons)
|
||||
object_islands.push_back(expoly.contour);
|
||||
if (! object->support_layers.empty())
|
||||
object->support_layers.front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
|
||||
islands.reserve(islands.size() + object_islands.size() * object->_shifted_copies.size());
|
||||
for (const Point &pt : object->_shifted_copies)
|
||||
for (Polygon &poly : object_islands) {
|
||||
islands.push_back(poly);
|
||||
islands.back().translate(pt);
|
||||
}
|
||||
}
|
||||
Polygons loops;
|
||||
size_t num_loops = size_t(floor(this->config.brim_width.value / flow.width));
|
||||
for (size_t i = 0; i < num_loops; ++ i) {
|
||||
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
|
||||
for (Polygon &poly : islands) {
|
||||
// poly.simplify(SCALED_RESOLUTION);
|
||||
poly.points.push_back(poly.points.front());
|
||||
Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
|
||||
p.pop_back();
|
||||
poly.points = std::move(p);
|
||||
}
|
||||
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
||||
}
|
||||
|
||||
loops = union_pt_chained(loops, false);
|
||||
std::reverse(loops.begin(), loops.end());
|
||||
extrusion_entities_append_loops(this->brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height()));
|
||||
}
|
||||
|
||||
// Wipe tower support.
|
||||
bool Print::has_wipe_tower()
|
||||
{
|
||||
|
@ -277,6 +277,7 @@ public:
|
||||
void auto_assign_extruders(ModelObject* model_object) const;
|
||||
|
||||
void _make_skirt();
|
||||
void _make_brim();
|
||||
|
||||
// Wipe tower support.
|
||||
bool has_wipe_tower();
|
||||
|
@ -230,6 +230,7 @@ _constant()
|
||||
Clone<Flow> skirt_flow();
|
||||
|
||||
void _make_skirt();
|
||||
void _make_brim();
|
||||
|
||||
bool has_wipe_tower();
|
||||
void _clear_wipe_tower();
|
||||
|
Loading…
Reference in New Issue
Block a user