Fix of "Problem with larger brim overlapping "

https://github.com/prusa3d/Slic3r/issues/373
This commit is contained in:
bubnikv 2017-07-07 16:40:23 +02:00
parent 434f538919
commit 774c69e3c6
5 changed files with 76 additions and 73 deletions

View file

@ -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();
}
}

View file

@ -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()
{

View file

@ -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();

View file

@ -230,6 +230,7 @@ _constant()
Clone<Flow> skirt_flow();
void _make_skirt();
void _make_brim();
bool has_wipe_tower();
void _clear_wipe_tower();