diff --git a/src/libslic3r/ExPolygonCollection.hpp b/src/libslic3r/ExPolygonCollection.hpp index 4c181cd6a..099a6a112 100644 --- a/src/libslic3r/ExPolygonCollection.hpp +++ b/src/libslic3r/ExPolygonCollection.hpp @@ -13,12 +13,12 @@ typedef std::vector ExPolygonCollections; class ExPolygonCollection { - public: +public: ExPolygons expolygons; - ExPolygonCollection() {}; + ExPolygonCollection() {} ExPolygonCollection(const ExPolygon &expolygon); - ExPolygonCollection(const ExPolygons &expolygons) : expolygons(expolygons) {}; + ExPolygonCollection(const ExPolygons &expolygons) : expolygons(expolygons) {} operator Points() const; operator Polygons() const; operator ExPolygons&(); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index efcf15ad5..65264c9cd 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -117,11 +117,11 @@ 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.expolygons.size() + layer2->slices.expolygons.size()); - for (const ExPolygon &expoly : layer1->slices.expolygons) + polys.reserve(layer1->slices.size() + layer2->slices.size()); + for (const ExPolygon &expoly : layer1->slices) //FIXME no holes? polys.emplace_back(expoly.contour); - for (const ExPolygon &expoly : layer2->slices.expolygons) + for (const ExPolygon &expoly : layer2->slices) //FIXME no holes? polys.emplace_back(expoly.contour); polygons_per_layer[i] = union_(polys); @@ -130,8 +130,8 @@ Polygons AvoidCrossingPerimeters::collect_contours_all_layers(const PrintObjectP if (object->layers().size() & 1) { const Layer *layer = object->layers().back(); Polygons polys; - polys.reserve(layer->slices.expolygons.size()); - for (const ExPolygon &expoly : layer->slices.expolygons) + polys.reserve(layer->slices.size()); + for (const ExPolygon &expoly : layer->slices) //FIXME no holes? polys.emplace_back(expoly.contour); polygons_per_layer.back() = union_(polys); @@ -1802,11 +1802,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.expolygons.size(); - std::vector layer_surface_bboxes; - layer_surface_bboxes.reserve(n_slices); - for (const ExPolygon &expoly : layer.slices.expolygons) - layer_surface_bboxes.push_back(get_extents(expoly.contour)); + size_t n_slices = layer.slices.size(); + const std::vector &layer_surface_bboxes = layer.slices_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; @@ -1822,7 +1819,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.expolygons[i].contour.contains(point); + layer.slices[i].contour.contains(point); }; for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) { @@ -2418,7 +2415,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou static int iRun = 0; SVG svg(debug_out_path("GCode_extrude_loop-%d.svg", iRun ++)); if (m_layer->lower_layer != NULL) - svg.draw(m_layer->lower_layer->slices.expolygons); + svg.draw(m_layer->lower_layer->slices); for (size_t i = 0; i < loop.paths.size(); ++ i) svg.draw(loop.paths[i].as_polyline(), "red"); Polylines polylines; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 94f114a26..74deabf3e 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.expolygons.clear(); - this->slices.expolygons.reserve(slices.size()); + this->slices.clear(); + this->slices.reserve(slices.size()); // prepare ordering points Points ordering_points; @@ -61,7 +61,7 @@ void Layer::make_slices() // populate slices vector for (size_t i : order) - this->slices.expolygons.push_back(std::move(slices[i])); + this->slices.push_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. @@ -70,7 +70,7 @@ void Layer::merge_slices() if (m_regions.size() == 1) { // 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.expolygons, stInternal); + m_regions.front()->slices.set(this->slices, stInternal); } else { for (LayerRegion *layerm : m_regions) // without safety offset, artifacts are generated (GH #2494) diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 539ae3925..9a4297ce5 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -110,7 +110,8 @@ public: // 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. - ExPolygonCollection slices; + ExPolygons slices; + std::vector slices_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 d13549bf4..0ff59d35f 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -140,7 +140,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.expolygons); + lower_layer_covered_tmp = to_polygons(lower_layer->slices); } if (! lower_layer_covered->empty()) voids = diff(voids, *lower_layer_covered); diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp index 8cd71e697..c0d9e65a7 100644 --- a/src/libslic3r/PerimeterGenerator.hpp +++ b/src/libslic3r/PerimeterGenerator.hpp @@ -3,7 +3,6 @@ #include "libslic3r.h" #include -#include "ExPolygonCollection.hpp" #include "Flow.hpp" #include "Polygon.hpp" #include "PrintConfig.hpp" @@ -15,7 +14,7 @@ class PerimeterGenerator { public: // Inputs: const SurfaceCollection *slices; - const ExPolygonCollection *lower_slices; + const ExPolygons *lower_slices; double layer_height; int layer_id; Flow perimeter_flow; @@ -45,7 +44,7 @@ public: ExtrusionEntityCollection* gap_fill, // Infills without the gap fills SurfaceCollection* fill_surfaces) - : slices(slices), lower_slices(NULL), layer_height(layer_height), + : slices(slices), lower_slices(nullptr), layer_height(layer_height), layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow), overhang_flow(flow), solid_infill_flow(flow), config(config), object_config(object_config), print_config(print_config), diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a5800b007..245b79e80 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -328,17 +328,6 @@ unsigned int Print::num_object_instances() const return instances; } -void Print::_simplify_slices(double distance) -{ - for (PrintObject *object : m_objects) { - for (Layer *layer : object->m_layers) { - layer->slices.simplify(distance); - for (LayerRegion *layerm : layer->regions()) - layerm->slices.simplify(distance); - } - } -} - double Print::max_allowed_layer_height() const { double nozzle_diameter_max = 0.; @@ -1593,7 +1582,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.expolygons) + for (const ExPolygon &expoly : layer->slices) // Collect the outer contour points only, ignore holes for the calculation of the convex hull. append(object_points, expoly.contour.points); } @@ -1704,7 +1693,7 @@ void Print::_make_brim() Polygons islands; for (PrintObject *object : m_objects) { Polygons object_islands; - for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons) + for (ExPolygon &expoly : object->m_layers.front()->slices) 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 5cb13039c..ce616a150 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -180,7 +180,6 @@ private: void _slice(const std::vector &layer_height_profile); std::string _fix_slicing_errors(); void _simplify_slices(double distance); - void _make_perimeters(); bool has_support_material() const; void detect_surfaces_type(); void process_external_surfaces(); @@ -383,7 +382,6 @@ private: void _make_skirt(); void _make_brim(); void _make_wipe_tower(); - void _simplify_slices(double distance); // Declared here to have access to Model / ModelObject / ModelInstance static void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 575ae60e3..d87e63c27 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -117,6 +117,19 @@ void PrintObject::slice() // Simplify slices if required. if (m_print->config().resolution) this->_simplify_slices(scale_(this->print()->config().resolution)); + // Update bounding boxes + tbb::parallel_for( + tbb::blocked_range(0, m_layers.size()), + [this](const tbb::blocked_range& range) { + 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)); + } + }); if (m_layers.empty()) throw std::runtime_error("No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n"); this->set_done(posSlice); @@ -865,7 +878,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.expolygons), voids); + surfaces_covered[layer_idx] = diff(to_polygons(this->m_layers[layer_idx]->slices), voids); } } ); @@ -975,8 +988,8 @@ void PrintObject::discover_vertical_shells() polygons_append(cache.holes, offset(offset_ex(layer.slices, 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.expolygons)); - svg.draw(layer.slices.expolygons, "blue"); + Slic3r::SVG svg(debug_out_path("discover_vertical_shells-extra-holes-%d.svg", debug_idx), get_extents(layer.slices)); + svg.draw(layer.slices, "blue"); svg.draw(union_ex(cache.holes), "red"); svg.draw_outline(union_ex(cache.holes), "black", "blue", scale_(0.05)); svg.Close(); @@ -2141,7 +2154,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.expolygons.empty()) { + while (! m_layers.empty() && m_layers.front()->slices.empty()) { delete m_layers.front(); m_layers.erase(m_layers.begin()); m_layers.front()->lower_layer = nullptr; @@ -2168,115 +2181,17 @@ void PrintObject::_simplify_slices(double distance) Layer *layer = m_layers[layer_idx]; for (size_t region_idx = 0; region_idx < layer->m_regions.size(); ++ region_idx) layer->m_regions[region_idx]->slices.simplify(distance); - layer->slices.simplify(distance); + { + ExPolygons simplified; + for (const ExPolygon& expoly : layer->slices) + expoly.simplify(distance, &simplified); + layer->slices = std::move(simplified); + } } }); BOOST_LOG_TRIVIAL(debug) << "Slicing objects - siplifying slices in parallel - end"; } -void PrintObject::_make_perimeters() -{ - if (! this->set_started(posPerimeters)) - return; - - BOOST_LOG_TRIVIAL(info) << "Generating perimeters..." << log_memory_info(); - - // merge slices if they were split into types - if (this->typed_slices) { - for (Layer *layer : m_layers) - layer->merge_slices(); - this->typed_slices = false; - this->invalidate_step(posPrepareInfill); - } - - // compare each layer to the one below, and mark those slices needing - // one additional inner perimeter, like the top of domed objects- - - // this algorithm makes sure that at least one perimeter is overlapping - // but we don't generate any extra perimeter if fill density is zero, as they would be floating - // inside the object - infill_only_where_needed should be the method of choice for printing - // hollow objects - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { - const PrintRegion ®ion = *m_print->regions()[region_id]; - if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2) - continue; - - BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - start"; - tbb::parallel_for( - tbb::blocked_range(0, m_layers.size() - 1), - [this, ®ion, region_id](const tbb::blocked_range& range) { - for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { - LayerRegion &layerm = *m_layers[layer_idx]->regions()[region_id]; - const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->regions()[region_id]; - const Polygons upper_layerm_polygons = upper_layerm.slices; - // Filter upper layer polygons in intersection_ppl by their bounding boxes? - // my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ]; - const double total_loop_length = total_length(upper_layerm_polygons); - const coord_t perimeter_spacing = layerm.flow(frPerimeter).scaled_spacing(); - const Flow ext_perimeter_flow = layerm.flow(frExternalPerimeter); - const coord_t ext_perimeter_width = ext_perimeter_flow.scaled_width(); - const coord_t ext_perimeter_spacing = ext_perimeter_flow.scaled_spacing(); - - for (Surface &slice : layerm.slices.surfaces) { - for (;;) { - // compute the total thickness of perimeters - const coord_t perimeters_thickness = ext_perimeter_width/2 + ext_perimeter_spacing/2 - + (region.config().perimeters-1 + slice.extra_perimeters) * perimeter_spacing; - // define a critical area where we don't want the upper slice to fall into - // (it should either lay over our perimeters or outside this area) - const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5); - const Polygons critical_area = diff( - offset(slice.expolygon, float(- perimeters_thickness)), - offset(slice.expolygon, float(- perimeters_thickness - critical_area_depth)) - ); - // check whether a portion of the upper slices falls inside the critical area - const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area); - // only add an additional loop if at least 30% of the slice loop would benefit from it - if (total_length(intersection) <= total_loop_length*0.3) - break; - /* - if (0) { - require "Slic3r/SVG.pm"; - Slic3r::SVG::output( - "extra.svg", - no_arrows => 1, - expolygons => union_ex($critical_area), - polylines => [ map $_->split_at_first_point, map $_->p, @{$upper_layerm->slices} ], - ); - } - */ - ++ slice.extra_perimeters; - } - #ifdef DEBUG - if (slice.extra_perimeters > 0) - printf(" adding %d more perimeter(s) at layer %zu\n", slice.extra_perimeters, layer_idx); - #endif - } - } - }); - BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - end"; - } - - BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start"; - tbb::parallel_for( - tbb::blocked_range(0, m_layers.size()), - [this](const tbb::blocked_range& range) { - for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) - m_layers[layer_idx]->make_perimeters(); - } - ); - 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); -} - // Only active if config->infill_only_where_needed. This step trims the sparse infill, // so it acts as an internal support. It maintains all other infill types intact. // Here the internal surfaces and perimeters have to be supported by the sparse infill. @@ -2302,7 +2217,7 @@ void PrintObject::clip_fill_surfaces() // Detect things that we need to support. // Cummulative slices. Polygons slices; - polygons_append(slices, layer->slices.expolygons); + polygons_append(slices, layer->slices); // Cummulative fill surfaces. Polygons fill_surfaces; // Solid surfaces to be supported. diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index a6648f108..179b35f59 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -445,8 +445,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.expolygons.size()); - for (const ExPolygon &expoly : layer.slices.expolygons) + out.reserve(out.size() + layer.slices.size()); + for (const ExPolygon &expoly : layer.slices) out.emplace_back(expoly.contour); return out; } @@ -907,9 +907,13 @@ namespace SupportMaterialInternal { polyline.extend_start(fw); polyline.extend_end(fw); // Is the straight perimeter segment supported at both sides? - if (lower_layer.slices.contains(polyline.first_point()) && lower_layer.slices.contains(polyline.last_point())) - // Offset a polyline into a thick line. - polygons_append(bridges, offset(polyline, 0.5f * w + 10.f)); + 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())) { + // Offset a polyline into a thick line. + polygons_append(bridges, offset(polyline, 0.5f * w + 10.f)); + break; + } } bridges = union_(bridges); } @@ -994,7 +998,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.expolygons, scale_(0.01))); + polygons_append(covered, offset(lower_layer.slices, scale_(0.01))); covered = union_(covered, false); // don't apply the safety offset. } } @@ -1023,7 +1027,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.expolygons); + Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id-1]->slices); // 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) { @@ -1162,7 +1166,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.expolygons), - no_interface_offset * 0.5f, slices_margin_offset + no_interface_offset * 0.5f, SUPPORT_SURFACES_OFFSET_PARAMETERS); + offset2(to_polygons(lower_layer.slices), - 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]); @@ -1468,7 +1472,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta svg.draw(union_ex(top, false), "blue", 0.5f); svg.draw(union_ex(projection_raw, true), "red", 0.5f); svg.draw_outline(union_ex(projection_raw, true), "red", "blue", scale_(0.1f)); - svg.draw(layer.slices.expolygons, "green", 0.5f); + svg.draw(layer.slices, "green", 0.5f); } #endif /* SLIC3R_DEBUG */ @@ -1568,8 +1572,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta Polygons &layer_support_area = layer_support_areas[layer_id]; 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.expolygons), touching, true); - Polygons trimming = offset(layer.slices.expolygons, float(SCALED_EPSILON)); + // Polygons trimming = union_(to_polygons(layer.slices), touching, true); + Polygons trimming = offset(layer.slices, float(SCALED_EPSILON)); projection = diff(projection_raw, trimming, false); #ifdef SLIC3R_DEBUG { @@ -2101,7 +2105,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.expolygons, gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS)); + polygons_append(polygons_trimming, offset(object_layer.slices, 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. @@ -2214,7 +2218,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.expolygons, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS)); + offset(m_object->layers().front()->slices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS)); if (contacts != nullptr) columns_base->polygons = diff(columns_base->polygons, interface_polygons); } diff --git a/xs/xsp/Layer.xsp b/xs/xsp/Layer.xsp index fc94d5115..6f3164707 100644 --- a/xs/xsp/Layer.xsp +++ b/xs/xsp/Layer.xsp @@ -3,6 +3,7 @@ %{ #include #include "libslic3r/Layer.hpp" +#include "libslic3r/ExPolygonCollection.hpp" %} %name{Slic3r::Layer::Region} class LayerRegion { @@ -59,8 +60,8 @@ Ref get_region(int idx); Ref add_region(PrintRegion* print_region); - Ref slices() - %code%{ RETVAL = &THIS->slices; %}; + ExPolygonCollection* slices() + %code%{ RETVAL = new ExPolygonCollection(THIS->slices); %}; int ptr() %code%{ RETVAL = (int)(intptr_t)THIS; %}; @@ -108,8 +109,8 @@ Ref get_region(int idx); Ref add_region(PrintRegion* print_region); - Ref slices() - %code%{ RETVAL = &THIS->slices; %}; + ExPolygonCollection* slices() + %code%{ RETVAL = new ExPolygonCollection(THIS->slices); %}; void export_region_slices_to_svg(const char *path); void export_region_fill_surfaces_to_svg(const char *path); diff --git a/xs/xsp/PerimeterGenerator.xsp b/xs/xsp/PerimeterGenerator.xsp index 2e8213795..07059de61 100644 --- a/xs/xsp/PerimeterGenerator.xsp +++ b/xs/xsp/PerimeterGenerator.xsp @@ -19,7 +19,7 @@ ~PerimeterGenerator(); void set_lower_slices(ExPolygonCollection* lower_slices) - %code{% THIS->lower_slices = lower_slices; %}; + %code{% THIS->lower_slices = &lower_slices->expolygons; %}; void set_layer_id(int layer_id) %code{% THIS->layer_id = layer_id; %}; void set_perimeter_flow(Flow* flow)