diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 433422d99..40ca7b074 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -122,21 +122,21 @@ Polygons AvoidCrossingPerimeters::collect_contours_all_layers(const PrintObjectP const Layer* layer1 = object->layers()[i * 2]; const Layer* layer2 = object->layers()[i * 2 + 1]; Polygons polys; - polys.reserve(layer1->slices.size() + layer2->slices.size()); - for (const ExPolygon &expoly : layer1->slices) + polys.reserve(layer1->lslices.size() + layer2->lslices.size()); + for (const ExPolygon &expoly : layer1->lslices) //FIXME no holes? polys.emplace_back(expoly.contour); - for (const ExPolygon &expoly : layer2->slices) + for (const ExPolygon &expoly : layer2->lslices) //FIXME no holes? polys.emplace_back(expoly.contour); polygons_per_layer[i] = union_(polys); - } - }); + } + }); if (object->layers().size() & 1) { const Layer *layer = object->layers().back(); Polygons polys; - polys.reserve(layer->slices.size()); - for (const ExPolygon &expoly : layer->slices) + polys.reserve(layer->lslices.size()); + for (const ExPolygon &expoly : layer->lslices) //FIXME no holes? polys.emplace_back(expoly.contour); polygons_per_layer.back() = union_(polys); @@ -2006,8 +2006,8 @@ void GCode::process_layer( // - for each island, we extrude perimeters first, unless user set the infill_first // option // (Still, we have to keep track of regions because we need to apply their config) - size_t n_slices = layer.slices.size(); - const std::vector &layer_surface_bboxes = layer.slices_bboxes; + size_t n_slices = layer.lslices.size(); + const std::vector &layer_surface_bboxes = layer.lslices_bboxes; // Traverse the slices in an increasing order of bounding box size, so that the islands inside another islands are tested first, // so we can just test a point inside ExPolygon::contour and we may skip testing the holes. std::vector slices_test_order; @@ -2023,7 +2023,7 @@ void GCode::process_layer( const BoundingBox &bbox = layer_surface_bboxes[i]; return point(0) >= bbox.min(0) && point(0) < bbox.max(0) && point(1) >= bbox.min(1) && point(1) < bbox.max(1) && - layer.slices[i].contour.contains(point); + layer.lslices[i].contour.contains(point); }; for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) { @@ -2155,7 +2155,7 @@ void GCode::process_layer( m_config.apply(instance_to_print.print_object.config(), true); m_layer = layers[instance_to_print.layer_id].layer(); if (m_config.avoid_crossing_perimeters) - m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->slices, true)); + m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->lslices, true)); if (this->config().gcode_label_objects) gcode += std::string("; printing object ") + instance_to_print.print_object.model_object()->name + " id:" + std::to_string(instance_to_print.layer_id) + " copy " + std::to_string(instance_to_print.instance_id) + "\n"; @@ -2476,7 +2476,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // Create the distance field for a layer below. const coord_t distance_field_resolution = coord_t(scale_(1.) + 0.5); *lower_layer_edge_grid = make_unique(); - (*lower_layer_edge_grid)->create(m_layer->lower_layer->slices, distance_field_resolution); + (*lower_layer_edge_grid)->create(m_layer->lower_layer->lslices, distance_field_resolution); (*lower_layer_edge_grid)->calculate_sdf(); #if 0 { diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 53a7f2fc4..505b01705 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -47,8 +47,8 @@ void Layer::make_slices() slices = union_ex(slices_p); } - this->slices.clear(); - this->slices.reserve(slices.size()); + this->lslices.clear(); + this->lslices.reserve(slices.size()); // prepare ordering points Points ordering_points; @@ -61,19 +61,21 @@ void Layer::make_slices() // populate slices vector for (size_t i : order) - this->slices.push_back(std::move(slices[i])); + this->lslices.emplace_back(std::move(slices[i])); } // Merge typed slices into untyped slices. This method is used to revert the effects of detect_surfaces_type() called for posPrepareInfill. void Layer::merge_slices() { - if (m_regions.size() == 1) { + if (m_regions.size() == 1 && (this->id() > 0 || this->object()->config().elefant_foot_compensation.value == 0)) { // Optimization, also more robust. Don't merge classified pieces of layerm->slices, // but use the non-split islands of a layer. For a single region print, these shall be equal. - m_regions.front()->slices.set(this->slices, stInternal); + // Don't use this optimization on 1st layer with Elephant foot compensation applied, as this->lslices are uncompensated, + // while regions are compensated. + m_regions.front()->slices.set(this->lslices, stInternal); } else { for (LayerRegion *layerm : m_regions) - // without safety offset, artifacts are generated (GH #2494) + // without safety offset, artifacts are generated (upstream Slic3r GH #2494) layerm->slices.set(union_ex(to_polygons(std::move(layerm->slices.surfaces)), true), stInternal); } } diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 9a4297ce5..b7725d11d 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -106,12 +106,16 @@ public: coordf_t print_z; // Z used for printing in unscaled coordinates coordf_t height; // layer height in unscaled coordinates - // collection of expolygons generated by slicing the original geometry; - // also known as 'islands' (all regions and surface types are merged here) - // The slices are chained by the shortest traverse distance and this traversal - // order will be recovered by the G-code generator. - ExPolygons slices; - std::vector slices_bboxes; + // Collection of expolygons generated by slicing the possibly multiple meshes of the source geometry + // (with possibly differing extruder ID and slicing parameters) and merged. + // For the first layer, if the ELephant foot compensation is applied, this lslice is uncompensated, therefore + // it includes the Elephant foot effect, thus it corresponds to the shape of the printed 1st layer. + // These lslices aka islands are chained by the shortest traverse distance and this traversal + // order will be applied by the G-code generator to the extrusions fitting into these lslices. + // These lslices are also used to detect overhangs and overlaps between successive layers, therefore it is important + // that the 1st lslice is not compensated by the Elephant foot compensation algorithm. + ExPolygons lslices; + std::vector lslices_bboxes; size_t region_count() const { return m_regions.size(); } const LayerRegion* get_region(int idx) const { return m_regions.at(idx); } diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 35acaf998..f4f0d6a5d 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -72,7 +72,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec if (this->layer()->lower_layer != nullptr) // Cummulative sum of polygons over all the regions. - g.lower_slices = &this->layer()->lower_layer->slices; + g.lower_slices = &this->layer()->lower_layer->lslices; g.layer_id = (int)this->layer()->id(); g.ext_perimeter_flow = this->flow(frExternalPerimeter); @@ -139,7 +139,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly // Remove voids from fill_boundaries, that are not supported by the layer below. if (lower_layer_covered == nullptr) { lower_layer_covered = &lower_layer_covered_tmp; - lower_layer_covered_tmp = to_polygons(lower_layer->slices); + lower_layer_covered_tmp = to_polygons(lower_layer->lslices); } if (! lower_layer_covered->empty()) voids = diff(voids, *lower_layer_covered); @@ -260,7 +260,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly // of very thin (but still working) anchors, the grown expolygon would go beyond them BridgeDetector bd( initial, - lower_layer->slices, + lower_layer->lslices, this->flow(frInfill, true).scaled_width() ); #ifdef SLIC3R_DEBUG diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1d4e69763..02d9da784 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1658,7 +1658,7 @@ void Print::_make_skirt() for (const Layer *layer : object->m_layers) { if (layer->print_z > skirt_height_z) break; - for (const ExPolygon &expoly : layer->slices) + for (const ExPolygon &expoly : layer->lslices) // Collect the outer contour points only, ignore holes for the calculation of the convex hull. append(object_points, expoly.contour.points); } @@ -1787,7 +1787,7 @@ void Print::_make_brim() Polygons islands; for (PrintObject *object : m_objects) { Polygons object_islands; - for (ExPolygon &expoly : object->m_layers.front()->slices) + for (ExPolygon &expoly : object->m_layers.front()->lslices) 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)); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 098049f1d..95c7b656a 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -182,7 +182,7 @@ private: void _slice(const std::vector &layer_height_profile); std::string _fix_slicing_errors(); - void _simplify_slices(double distance); + void simplify_slices(double distance); bool has_support_material() const; void detect_surfaces_type(); void process_external_surfaces(); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index bf97baaf6..8a59b6c3b 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -117,7 +117,7 @@ void PrintObject::slice() BOOST_LOG_TRIVIAL(info) << warning; // Simplify slices if required. if (m_print->config().resolution) - this->_simplify_slices(scale_(this->print()->config().resolution)); + this->simplify_slices(scale_(this->print()->config().resolution)); // Update bounding boxes tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), @@ -125,10 +125,10 @@ void PrintObject::slice() for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { m_print->throw_if_canceled(); Layer &layer = *m_layers[layer_idx]; - layer.slices_bboxes.clear(); - layer.slices_bboxes.reserve(layer.slices.size()); - for (const ExPolygon &expoly : layer.slices) - layer.slices_bboxes.emplace_back(get_extents(expoly)); + layer.lslices_bboxes.clear(); + layer.lslices_bboxes.reserve(layer.lslices.size()); + for (const ExPolygon &expoly : layer.lslices) + layer.lslices_bboxes.emplace_back(get_extents(expoly)); } }); if (m_layers.empty()) @@ -242,13 +242,6 @@ void PrintObject::make_perimeters() m_print->throw_if_canceled(); BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - end"; - /* - simplify slices (both layer and region slices), - we only need the max resolution for perimeters - ### This makes this method not-idempotent, so we keep it disabled for now. - ###$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION); - */ - this->set_done(posPerimeters); } @@ -692,7 +685,7 @@ void PrintObject::detect_surfaces_type() if (upper_layer) { Polygons upper_slices = interface_shells ? to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) : - to_polygons(upper_layer->slices); + to_polygons(upper_layer->lslices); surfaces_append(top, //FIXME implement offset2_ex working over ExPolygons, that should be a bit more efficient than calling offset_ex twice. offset_ex(offset_ex(diff_ex(layerm_slices_surfaces, upper_slices, true), -offset), offset), @@ -721,7 +714,7 @@ void PrintObject::detect_surfaces_type() surfaces_append( bottom, offset2_ex( - diff(layerm_slices_surfaces, to_polygons(lower_layer->slices), true), + diff(layerm_slices_surfaces, to_polygons(lower_layer->lslices), true), -offset, offset), surface_type_bottom_other); // if user requested internal shells, we need to identify surfaces @@ -733,7 +726,7 @@ void PrintObject::detect_surfaces_type() bottom, offset2_ex( diff( - intersection(layerm_slices_surfaces, to_polygons(lower_layer->slices)), // supported + intersection(layerm_slices_surfaces, to_polygons(lower_layer->lslices)), // supported to_polygons(lower_layer->get_region(idx_region)->slices.surfaces), true), -offset, offset), @@ -879,7 +872,7 @@ void PrintObject::process_external_surfaces() // Shrink the holes, let the layer above expand slightly inside the unsupported areas. polygons_append(voids, offset(surface.expolygon, unsupported_width)); } - surfaces_covered[layer_idx] = diff(to_polygons(this->m_layers[layer_idx]->slices), voids); + surfaces_covered[layer_idx] = diff(to_polygons(this->m_layers[layer_idx]->lslices), voids); } } ); @@ -985,8 +978,8 @@ void PrintObject::discover_vertical_shells() cache.bottom_surfaces = union_(cache.bottom_surfaces, false); // For a multi-material print, simulate perimeter / infill split as if only a single extruder has been used for the whole print. if (perimeter_offset > 0.) { - // The layer.slices are forced to merge by expanding them first. - polygons_append(cache.holes, offset(offset_ex(layer.slices, 0.3f * perimeter_min_spacing), - perimeter_offset - 0.3f * perimeter_min_spacing)); + // The layer.lslices are forced to merge by expanding them first. + polygons_append(cache.holes, offset(offset_ex(layer.lslices, 0.3f * perimeter_min_spacing), - perimeter_offset - 0.3f * perimeter_min_spacing)); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING { Slic3r::SVG svg(debug_out_path("discover_vertical_shells-extra-holes-%d.svg", debug_idx), get_extents(layer.slices)); @@ -1762,78 +1755,101 @@ end: ; BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - begin"; - tbb::parallel_for( - tbb::blocked_range(0, m_layers.size()), - [this, upscaled, clipped](const tbb::blocked_range& range) { - for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { - m_print->throw_if_canceled(); - Layer *layer = m_layers[layer_id]; - // Apply size compensation and perform clipping of multi-part objects. - float delta = float(scale_(m_config.xy_size_compensation.value)); - //FIXME only apply the compensation if no raft is enabled. - float elephant_foot_compensation = 0.f; - if (layer_id == 0 && m_config.raft_layers == 0) - // Only enable Elephant foot compensation if printing directly on the print bed. - elephant_foot_compensation = float(scale_(m_config.elefant_foot_compensation.value)); - if (layer->m_regions.size() == 1) { - // Optimized version for a single region layer. - if (layer_id == 0) { - if (delta > elephant_foot_compensation) { - delta -= elephant_foot_compensation; - elephant_foot_compensation = 0.f; - } else if (delta > 0) - elephant_foot_compensation -= delta; - } - if (delta != 0.f || elephant_foot_compensation > 0.f) { - // Single region, growing or shrinking. - LayerRegion *layerm = layer->m_regions.front(); - // Apply the XY compensation. - ExPolygons expolygons = (delta == 0.f) ? - to_expolygons(std::move(layerm->slices.surfaces)) : - offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta); - // Apply the elephant foot compensation. - if (elephant_foot_compensation > 0) - expolygons = union_ex(Slic3r::elephant_foot_compensation(expolygons, layerm->flow(frExternalPerimeter), unscale(elephant_foot_compensation))); - layerm->slices.set(std::move(expolygons), stInternal); - } - } else { - bool upscale = ! upscaled && delta > 0.f; - bool clip = ! clipped && m_config.clip_multipart_objects.value; - if (upscale || clip) { - // Multiple regions, growing or just clipping one region by the other. - // When clipping the regions, priority is given to the first regions. - Polygons processed; - for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) { - LayerRegion *layerm = layer->m_regions[region_id]; - ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces)); - if (upscale) - slices = offset_ex(std::move(slices), delta); - if (region_id > 0 && clip) - // Trim by the slices of already processed regions. - slices = diff_ex(to_polygons(std::move(slices)), processed); - if (clip && (region_id + 1 < layer->m_regions.size())) - // Collect the already processed regions to trim the to be processed regions. - polygons_append(processed, slices); - layerm->slices.set(std::move(slices), stInternal); - } - } - if (delta < 0.f || elephant_foot_compensation > 0.f) { - // Apply the negative XY compensation. - Polygons trimming; - static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); - if (elephant_foot_compensation > 0.f) { - trimming = to_polygons(Slic3r::elephant_foot_compensation(offset_ex(layer->merged(eps), std::min(delta, 0.f) - eps), - layer->m_regions.front()->flow(frExternalPerimeter), unscale(elephant_foot_compensation))); - } else - trimming = offset(layer->merged(float(SCALED_EPSILON)), delta - float(SCALED_EPSILON)); - for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) - layer->m_regions[region_id]->trim_surfaces(trimming); - } - } - // Merge all regions' slices to get islands, chain them by a shortest path. - layer->make_slices(); - } - }); + { + // Compensation value, scaled. + const float xy_compensation_scaled = float(scale_(m_config.xy_size_compensation.value)); + const float elephant_foot_compensation_scaled = (m_config.raft_layers == 0) ? + // Only enable Elephant foot compensation if printing directly on the print bed. + float(scale_(m_config.elefant_foot_compensation.value)) : + 0.f; + // Uncompensated slices for the first layer in case the Elephant foot compensation is applied. + ExPolygons lslices_1st_layer; + tbb::parallel_for( + tbb::blocked_range(0, m_layers.size()), + [this, upscaled, clipped, xy_compensation_scaled, elephant_foot_compensation_scaled, &lslices_1st_layer] + (const tbb::blocked_range& range) { + for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { + m_print->throw_if_canceled(); + Layer *layer = m_layers[layer_id]; + // Apply size compensation and perform clipping of multi-part objects. + float elfoot = (layer_id == 0) ? elephant_foot_compensation_scaled : 0.f; + if (layer->m_regions.size() == 1) { + assert(! upscaled); + assert(! clipped); + // Optimized version for a single region layer. + // Single region, growing or shrinking. + LayerRegion *layerm = layer->m_regions.front(); + if (elfoot > 0) { + // Apply the elephant foot compensation and store the 1st layer slices without the Elephant foot compensation applied. + lslices_1st_layer = to_expolygons(std::move(layerm->slices.surfaces)); + float delta = xy_compensation_scaled; + if (delta > elfoot) { + delta -= elfoot; + elfoot = 0.f; + } else if (delta > 0) + elfoot -= delta; + layerm->slices.set( + union_ex( + Slic3r::elephant_foot_compensation( + (delta == 0.f) ? lslices_1st_layer : offset_ex(lslices_1st_layer, delta), + layerm->flow(frExternalPerimeter), unscale(elfoot))), + stInternal); + if (xy_compensation_scaled != 0.f) + lslices_1st_layer = offset_ex(std::move(lslices_1st_layer), xy_compensation_scaled); + } else if (xy_compensation_scaled != 0.f) { + // Apply the XY compensation. + layerm->slices.set( + offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), xy_compensation_scaled), + stInternal); + } + } else { + bool upscale = ! upscaled && xy_compensation_scaled > 0.f; + bool clip = ! clipped && m_config.clip_multipart_objects.value; + if (upscale || clip) { + // Multiple regions, growing or just clipping one region by the other. + // When clipping the regions, priority is given to the first regions. + Polygons processed; + for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) { + LayerRegion *layerm = layer->m_regions[region_id]; + ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces)); + if (upscale) + slices = offset_ex(std::move(slices), xy_compensation_scaled); + if (region_id > 0 && clip) + // Trim by the slices of already processed regions. + slices = diff_ex(to_polygons(std::move(slices)), processed); + if (clip && (region_id + 1 < layer->m_regions.size())) + // Collect the already processed regions to trim the to be processed regions. + polygons_append(processed, slices); + layerm->slices.set(std::move(slices), stInternal); + } + } + if (xy_compensation_scaled < 0.f || elfoot > 0.f) { + // Apply the negative XY compensation. + Polygons trimming; + static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); + if (elfoot > 0.f) { + lslices_1st_layer = offset_ex(layer->merged(eps), std::min(xy_compensation_scaled, 0.f) - eps); + trimming = to_polygons(Slic3r::elephant_foot_compensation(lslices_1st_layer, + layer->m_regions.front()->flow(frExternalPerimeter), unscale(elfoot))); + } else + trimming = offset(layer->merged(float(SCALED_EPSILON)), xy_compensation_scaled - float(SCALED_EPSILON)); + for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) + layer->m_regions[region_id]->trim_surfaces(trimming); + } + } + // Merge all regions' slices to get islands, chain them by a shortest path. + layer->make_slices(); + } + }); + if (elephant_foot_compensation_scaled > 0.f) { + // The Elephant foot has been compensated, therefore the 1st layer's lslices are shrank with the Elephant foot compensation value. + // Store the uncompensated value there. + assert(! m_layers.empty()); + assert(m_layers.front()->id() == 0); + m_layers.front()->lslices = std::move(lslices_1st_layer); + } + } + m_print->throw_if_canceled(); BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end"; } @@ -2131,7 +2147,7 @@ std::string PrintObject::_fix_slicing_errors() BOOST_LOG_TRIVIAL(debug) << "Slicing objects - fixing slicing errors in parallel - end"; // remove empty layers from bottom - while (! m_layers.empty() && m_layers.front()->slices.empty()) { + while (! m_layers.empty() && (m_layers.front()->lslices.empty() || m_layers.front()->empty())) { delete m_layers.front(); m_layers.erase(m_layers.begin()); m_layers.front()->lower_layer = nullptr; @@ -2147,7 +2163,7 @@ std::string PrintObject::_fix_slicing_errors() // Simplify the sliced model, if "resolution" configuration parameter > 0. // The simplification is problematic, because it simplifies the slices independent from each other, // which makes the simplified discretization visible on the object surface. -void PrintObject::_simplify_slices(double distance) +void PrintObject::simplify_slices(double distance) { BOOST_LOG_TRIVIAL(debug) << "Slicing objects - siplifying slices in parallel - begin"; tbb::parallel_for( @@ -2160,9 +2176,9 @@ void PrintObject::_simplify_slices(double distance) layer->m_regions[region_idx]->slices.simplify(distance); { ExPolygons simplified; - for (const ExPolygon& expoly : layer->slices) + for (const ExPolygon &expoly : layer->lslices) expoly.simplify(distance, &simplified); - layer->slices = std::move(simplified); + layer->lslices = std::move(simplified); } } }); @@ -2194,7 +2210,7 @@ void PrintObject::clip_fill_surfaces() // Detect things that we need to support. // Cummulative slices. Polygons slices; - polygons_append(slices, layer->slices); + polygons_append(slices, layer->lslices); // Cummulative fill surfaces. Polygons fill_surfaces; // Solid surfaces to be supported. diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 179b35f59..1d98bb0e6 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -1,6 +1,5 @@ #include "ClipperUtils.hpp" #include "ExtrusionEntityCollection.hpp" -#include "PerimeterGenerator.hpp" #include "Layer.hpp" #include "Print.hpp" #include "SupportMaterial.hpp" @@ -445,8 +444,8 @@ Polygons collect_region_slices_by_type(const Layer &layer, SurfaceType surface_t Polygons collect_slices_outer(const Layer &layer) { Polygons out; - out.reserve(out.size() + layer.slices.size()); - for (const ExPolygon &expoly : layer.slices) + out.reserve(out.size() + layer.lslices.size()); + for (const ExPolygon &expoly : layer.lslices) out.emplace_back(expoly.contour); return out; } @@ -907,9 +906,9 @@ namespace SupportMaterialInternal { polyline.extend_start(fw); polyline.extend_end(fw); // Is the straight perimeter segment supported at both sides? - for (size_t i = 0; i < lower_layer.slices.size(); ++ i) - if (lower_layer.slices_bboxes[i].contains(polyline.first_point()) && lower_layer.slices_bboxes[i].contains(polyline.last_point()) && - lower_layer.slices[i].contains(polyline.first_point()) && lower_layer.slices[i].contains(polyline.last_point())) { + for (size_t i = 0; i < lower_layer.lslices.size(); ++ i) + if (lower_layer.lslices_bboxes[i].contains(polyline.first_point()) && lower_layer.lslices_bboxes[i].contains(polyline.last_point()) && + lower_layer.lslices[i].contains(polyline.first_point()) && lower_layer.lslices[i].contains(polyline.last_point())) { // Offset a polyline into a thick line. polygons_append(bridges, offset(polyline, 0.5f * w + 10.f)); break; @@ -998,7 +997,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ // inflate the polygons over and over. Polygons &covered = buildplate_covered[layer_id]; covered = buildplate_covered[layer_id - 1]; - polygons_append(covered, offset(lower_layer.slices, scale_(0.01))); + polygons_append(covered, offset(lower_layer.lslices, scale_(0.01))); covered = union_(covered, false); // don't apply the safety offset. } } @@ -1027,7 +1026,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ Polygons contact_polygons; Polygons slices_margin_cached; float slices_margin_cached_offset = -1.; - Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id-1]->slices); + Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id-1]->lslices); // Offset of the lower layer, to trim the support polygons with to calculate dense supports. float no_interface_offset = 0.f; if (layer_id == 0) { @@ -1166,7 +1165,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ slices_margin_cached_offset = slices_margin_offset; slices_margin_cached = (slices_margin_offset == 0.f) ? lower_layer_polygons : - offset2(to_polygons(lower_layer.slices), - no_interface_offset * 0.5f, slices_margin_offset + no_interface_offset * 0.5f, SUPPORT_SURFACES_OFFSET_PARAMETERS); + offset2(to_polygons(lower_layer.lslices), - no_interface_offset * 0.5f, slices_margin_offset + no_interface_offset * 0.5f, SUPPORT_SURFACES_OFFSET_PARAMETERS); if (! buildplate_covered.empty()) { // Trim the inflated contact surfaces by the top surfaces as well. polygons_append(slices_margin_cached, buildplate_covered[layer_id]); @@ -1573,7 +1572,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta 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.slices, float(SCALED_EPSILON)); + Polygons trimming = offset(layer.lslices, float(SCALED_EPSILON)); projection = diff(projection_raw, trimming, false); #ifdef SLIC3R_DEBUG { @@ -2105,7 +2104,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object( const Layer &object_layer = *object.layers()[i]; if (object_layer.print_z - object_layer.height > support_layer.print_z + gap_extra_above - EPSILON) break; - polygons_append(polygons_trimming, offset(object_layer.slices, gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS)); + polygons_append(polygons_trimming, offset(object_layer.lslices, gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS)); } if (! m_slicing_params.soluble_interface) { // Collect all bottom surfaces, which will be extruded with a bridging flow. @@ -2218,7 +2217,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf // Expand the bases of the support columns in the 1st layer. columns_base->polygons = diff( offset(columns_base->polygons, inflate_factor_1st_layer), - offset(m_object->layers().front()->slices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS)); + 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); }