From 79f5a16536150bf045a1327f5ab5c3c9d58f4390 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 17 Nov 2016 23:22:59 +0100 Subject: [PATCH] Reverted the perimeter generator to not save the perimeter areas. These could be calculated from the fill areas if needed. On the other side, the non-classified (non-split) fill areas are stored now for use in the "ensure vertical wall thickness" feature, also the non-split fill areas are re-used when recalculating the infills. This is safer than trying to stitch the fill region together from the classified fragments. Modified the "ensure vertical wall thickness" feature to use the non-split fill areas instead of perimeter areas for the calculation of non-supported regions. This is cheaper as the fill areas contain roughly half the edges. --- lib/Slic3r/Print/Object.pm | 18 +++-- t/perimeters.t | 3 +- xs/src/libslic3r/GCode/PressureEqualizer.cpp | 2 +- xs/src/libslic3r/Layer.cpp | 73 +++++--------------- xs/src/libslic3r/Layer.hpp | 12 ++-- xs/src/libslic3r/LayerRegion.cpp | 19 ++--- xs/src/libslic3r/PerimeterGenerator.cpp | 23 ++---- xs/src/libslic3r/PerimeterGenerator.hpp | 5 +- xs/src/libslic3r/PrintObject.cpp | 35 +++++++--- xs/src/libslic3r/Surface.hpp | 9 +++ xs/xsp/Layer.xsp | 7 +- xs/xsp/PerimeterGenerator.xsp | 4 +- 12 files changed, 94 insertions(+), 116 deletions(-) diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index ab390fd3a..8fd2bf4cf 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -259,7 +259,7 @@ sub slice { } } - # merge all regions' slices to get islands + # Merge all regions' slices to get islands, chain them by a shortest path. $layer->make_slices; } @@ -367,6 +367,9 @@ sub _slice_region { return $mesh->slice($z); } +# 1) Merges typed region slices into stInternal type. +# 2) Increases an "extra perimeters" counter at region slices where needed. +# 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal). sub make_perimeters { my $self = shift; @@ -377,7 +380,8 @@ sub make_perimeters { $self->set_step_started(STEP_PERIMETERS); $self->print->status_cb->(20, "Generating perimeters"); - # merge slices if they were split into types + # Merge region slices if they were split into types. + # FIXME this is using a safety offset, so the region slices will be slightly bigger with each iteration. if ($self->typed_slices) { $_->merge_slices for @{$self->layers}; $self->set_typed_slices(0); @@ -487,11 +491,12 @@ sub prepare_infill { $self->set_step_started(STEP_PREPARE_INFILL); $self->print->status_cb->(30, "Preparing infill"); - # this will assign a type (top/bottom/internal) to $layerm->slices - # and transform $layerm->fill_surfaces from expolygon - # to typed top/bottom/internal surfaces; + # This will assign a type (top/bottom/internal) to $layerm->slices. + # Then the classifcation of $layerm->slices is transfered onto + # the $layerm->fill_surfaces by clipping $layerm->fill_surfaces + # by the cummulative area of the previous $layerm->fill_surfaces. $self->detect_surfaces_type; - # Mark the object to have the slices classified (typed, which also means they are split based on whether they are supported, bridging, top layers etc.) + # Mark the object to have the region slices classified (typed, which also means they are split based on whether they are supported, bridging, top layers etc.) $self->set_typed_slices(1); # Decide what surfaces are to be filled. @@ -615,6 +620,7 @@ sub infill { ); ### we could free memory now, but this would make this step not idempotent + ### Vojtech: Cannot release the fill_surfaces, they are used by the support generator. ### $_->fill_surfaces->clear for map @{$_->regions}, @{$object->layers}; $self->set_step_done(STEP_INFILL); diff --git a/t/perimeters.t b/t/perimeters.t index 8e815b215..47b844887 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -34,7 +34,7 @@ use Slic3r::Test; expolygon => $_, )) for @$expolygons; - my ($region_config, $object_config, $print_config, $loops, $gap_fill, $perimeter_surfaces, $fill_surfaces); + my ($region_config, $object_config, $print_config, $loops, $gap_fill, $fill_surfaces); my $g = Slic3r::Layer::PerimeterGenerator->new( # input: $slices, @@ -47,7 +47,6 @@ use Slic3r::Test; # output: ($loops = Slic3r::ExtrusionPath::Collection->new), ($gap_fill = Slic3r::ExtrusionPath::Collection->new), - ($perimeter_surfaces = Slic3r::Surface::Collection->new), ($fill_surfaces = Slic3r::Surface::Collection->new), ); $g->config->apply_dynamic($config); diff --git a/xs/src/libslic3r/GCode/PressureEqualizer.cpp b/xs/src/libslic3r/GCode/PressureEqualizer.cpp index 0ae95ab43..eab93aa9d 100644 --- a/xs/src/libslic3r/GCode/PressureEqualizer.cpp +++ b/xs/src/libslic3r/GCode/PressureEqualizer.cpp @@ -264,7 +264,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC if (rate < 40.f) { printf("Extremely low flow rate: %f. Line %d, Length: %f, extrusion: %f Old position: (%f, %f, %f), new position: (%f, %f, %f)\n", rate, - line_idx, + int(line_idx), sqrt(len2), sqrt((diff[3]*diff[3])/len2), m_current_pos[0], m_current_pos[1], m_current_pos[2], new_pos[0], new_pos[1], new_pos[2]); diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp index 0e1937cbb..492eb8be4 100644 --- a/xs/src/libslic3r/Layer.cpp +++ b/xs/src/libslic3r/Layer.cpp @@ -103,8 +103,7 @@ Layer::make_slices() } else { Polygons slices_p; FOREACH_LAYERREGION(this, layerm) { - Polygons region_slices_p = (*layerm)->slices; - slices_p.insert(slices_p.end(), region_slices_p.begin(), region_slices_p.end()); + polygons_append(slices_p, to_polygons((*layerm)->slices)); } union_(slices_p, &slices); } @@ -123,9 +122,8 @@ Layer::make_slices() Slic3r::Geometry::chained_path(ordering_points, order); // populate slices vector - for (std::vector::const_iterator it = order.begin(); it != order.end(); ++it) { - this->slices.expolygons.push_back(slices[*it]); - } + for (std::vector::const_iterator it = order.begin(); it != order.end(); ++it) + this->slices.expolygons.push_back(STDMOVE(slices[*it])); } void @@ -200,68 +198,35 @@ Layer::make_perimeters() if (layerms.size() == 1) { // optimization (*layerm)->fill_surfaces.surfaces.clear(); - (*layerm)->perimeter_surfaces.surfaces.clear(); - (*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->perimeter_surfaces, &(*layerm)->fill_surfaces); - this->perimeter_expolygons.expolygons.clear(); - for (Surfaces::const_iterator it = (*layerm)->perimeter_surfaces.surfaces.begin(); it != (*layerm)->perimeter_surfaces.surfaces.end(); ++ it) - this->perimeter_expolygons.expolygons.push_back(it->expolygon); + (*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->fill_surfaces); + (*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces); } else { - // group slices (surfaces) according to number of extra perimeters - std::map slices; // extra_perimeters => [ surface, surface... ] - for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) { - for (Surfaces::iterator s = (*l)->slices.surfaces.begin(); s != (*l)->slices.surfaces.end(); ++s) { - slices[s->extra_perimeters].push_back(*s); - } - } - - // merge the surfaces assigned to each group SurfaceCollection new_slices; - for (std::map::const_iterator it = slices.begin(); it != slices.end(); ++it) { - ExPolygons expp = union_ex(it->second, true); - for (ExPolygons::iterator ex = expp.begin(); ex != expp.end(); ++ex) { - Surface s = it->second.front(); // clone type and extra_perimeters - s.expolygon = *ex; - new_slices.surfaces.push_back(s); + { + // group slices (surfaces) according to number of extra perimeters + std::map slices; // extra_perimeters => [ surface, surface... ] + for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) { + for (Surfaces::iterator s = (*l)->slices.surfaces.begin(); s != (*l)->slices.surfaces.end(); ++s) { + slices[s->extra_perimeters].push_back(*s); + } } + // merge the surfaces assigned to each group + for (std::map::const_iterator it = slices.begin(); it != slices.end(); ++it) + surfaces_append(new_slices.surfaces, union_ex(it->second, true), it->second.front()); } // make perimeters - SurfaceCollection perimeter_surfaces; SurfaceCollection fill_surfaces; - (*layerm)->make_perimeters(new_slices, &perimeter_surfaces, &fill_surfaces); - // Copy the perimeter surfaces to the layer's surfaces before splitting them into the regions. - this->perimeter_expolygons.expolygons.clear(); - for (Surfaces::const_iterator it = perimeter_surfaces.surfaces.begin(); it != perimeter_surfaces.surfaces.end(); ++ it) - this->perimeter_expolygons.expolygons.push_back(it->expolygon); + (*layerm)->make_perimeters(new_slices, &fill_surfaces); // assign fill_surfaces to each layer if (!fill_surfaces.surfaces.empty()) { for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) { // Separate the fill surfaces. - ExPolygons expp = intersection_ex( - fill_surfaces, - (*l)->slices - ); + ExPolygons expp = intersection_ex(to_polygons(fill_surfaces), (*l)->slices); + (*l)->fill_expolygons = expp; (*l)->fill_surfaces.surfaces.clear(); - - for (ExPolygons::iterator ex = expp.begin(); ex != expp.end(); ++ex) { - Surface s = fill_surfaces.surfaces.front(); // clone type and extra_perimeters - s.expolygon = *ex; - (*l)->fill_surfaces.surfaces.push_back(s); - } - - // Separate the perimeter surfaces. - expp = intersection_ex( - perimeter_surfaces, - (*l)->slices - ); - (*l)->perimeter_surfaces.surfaces.clear(); - - for (ExPolygons::iterator ex = expp.begin(); ex != expp.end(); ++ex) { - Surface s = fill_surfaces.surfaces.front(); // clone type and extra_perimeters - s.expolygon = *ex; - (*l)->perimeter_surfaces.surfaces.push_back(s); - } + surfaces_append((*l)->fill_surfaces.surfaces, STDMOVE(expp), fill_surfaces.surfaces.front()); } } } diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp index 375d8ac9f..14957dd1c 100644 --- a/xs/src/libslic3r/Layer.hpp +++ b/xs/src/libslic3r/Layer.hpp @@ -36,8 +36,11 @@ class LayerRegion // collection of extrusion paths/loops filling gaps ExtrusionEntityCollection thin_fills; + // Unspecified fill polygons, used for overhang detection ("ensure vertical wall thickness feature") + // and for re-starting of infills. + ExPolygons fill_expolygons; // collection of surfaces for infill generation - SurfaceCollection fill_surfaces; + SurfaceCollection fill_surfaces; // Collection of perimeter surfaces. This is a cached result of diff(slices, fill_surfaces). // While not necessary, the memory consumption is meager and it speeds up calculation. @@ -63,7 +66,7 @@ class LayerRegion void merge_slices(); void slices_to_fill_surfaces_clipped(); void prepare_fill_surfaces(); - void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* perimeter_surfaces, SurfaceCollection* fill_surfaces); + void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces); void process_external_surfaces(const Layer* lower_layer); double infill_area_threshold() const; @@ -103,10 +106,9 @@ public: // 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. ExPolygonCollection slices; - // Surfaces of the perimeters including their gap fill. - ExPolygonCollection perimeter_expolygons; - size_t region_count() const; const LayerRegion* get_region(int idx) const { return this->regions.at(idx); } diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index 115cba61d..a236c0389 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -58,7 +58,8 @@ void LayerRegion::slices_to_fill_surfaces_clipped() // in place. However we're now only using its boundaries (which are invariant) // so we're safe. This guarantees idempotence of prepare_infill() also in case // that combine_infill() turns some fill_surface into VOID surfaces. - Polygons fill_boundaries = to_polygons(STDMOVE(this->fill_surfaces)); +// Polygons fill_boundaries = to_polygons(STDMOVE(this->fill_surfaces)); + Polygons fill_boundaries = to_polygons(this->fill_expolygons); this->fill_surfaces.surfaces.clear(); for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++ surface) surfaces_append( @@ -68,7 +69,7 @@ void LayerRegion::slices_to_fill_surfaces_clipped() } void -LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* perimeter_surfaces, SurfaceCollection* fill_surfaces) +LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces) { this->perimeters.clear(); this->thin_fills.clear(); @@ -85,7 +86,6 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* // output: &this->perimeters, &this->thin_fills, - perimeter_surfaces, fill_surfaces ); @@ -367,15 +367,10 @@ LayerRegion::prepare_fill_surfaces() // if no solid layers are requested, turn top/bottom surfaces to internal if (this->region()->config.top_solid_layers == 0) { - for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) { - if (surface->surface_type == stTop) { - if (this->layer()->object()->config.infill_only_where_needed) { - surface->surface_type = stInternalVoid; - } else { - surface->surface_type = stInternal; - } - } - } + for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) + if (surface->surface_type == stTop) + surface->surface_type = (this->layer()->object()->config.infill_only_where_needed) ? + stInternalVoid : stInternal; } if (this->region()->config.bottom_solid_layers == 0) { for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) { diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index af6447e7b..acdff127b 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -246,15 +246,6 @@ PerimeterGenerator::process() if (!entities.empty()) this->loops->append(entities); } // for each loop of an island - - { - //FIXME how about the gaps? - // Calculate the region of surface->expolygon covered by the perimeters and their gap fills. - // The perimeters will later be used to calculate the object skin. - ExPolygons expp = diff_ex((Polygons)surface->expolygon, last, true); - for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) - this->perimeter_surfaces->surfaces.push_back(Surface(stPerimeter, *ex)); - } // fill gaps if (!gaps.empty()) { @@ -322,15 +313,15 @@ PerimeterGenerator::process() // collapse too narrow infill areas coord_t min_perimeter_infill_spacing = ispacing * (1 - INSET_OVERLAP_TOLERANCE); - expp = offset2_ex( - pp, - -inset -min_perimeter_infill_spacing/2, - +min_perimeter_infill_spacing/2 - ); // append infill areas to fill_surfaces - for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) - this->fill_surfaces->surfaces.push_back(Surface(stInternal, *ex)); // use a bogus surface type + surfaces_append( + this->fill_surfaces->surfaces, + offset2_ex( + pp, + -inset -min_perimeter_infill_spacing/2, + +min_perimeter_infill_spacing/2), + stInternal); } } // for each island } diff --git a/xs/src/libslic3r/PerimeterGenerator.hpp b/xs/src/libslic3r/PerimeterGenerator.hpp index 09289a2d4..0e7fbd3e4 100644 --- a/xs/src/libslic3r/PerimeterGenerator.hpp +++ b/xs/src/libslic3r/PerimeterGenerator.hpp @@ -52,7 +52,6 @@ public: // Outputs: ExtrusionEntityCollection* loops; ExtrusionEntityCollection* gap_fill; - SurfaceCollection* perimeter_surfaces; SurfaceCollection* fill_surfaces; PerimeterGenerator( @@ -68,15 +67,13 @@ public: ExtrusionEntityCollection* loops, // Gaps without the thin walls ExtrusionEntityCollection* gap_fill, - // Perimeters including their gap fills - SurfaceCollection* perimeter_surfaces, // Infills without the gap fills SurfaceCollection* fill_surfaces) : slices(slices), lower_slices(NULL), 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), - loops(loops), gap_fill(gap_fill), perimeter_surfaces(perimeter_surfaces), fill_surfaces(fill_surfaces), + loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces), _ext_mm3_per_mm(-1), _mm3_per_mm(-1), _mm3_per_mm_overhang(-1) {}; void process(); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index a8dc4050a..3808a545e 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -313,7 +313,7 @@ PrintObject::has_support_material() const } // This function analyzes slices of a region (SurfaceCollection slices). -// Each slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface. +// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface. // Initially all slices are of type S_TYPE_INTERNAL. // Slices are compared against the top / bottom slices and regions and classified to the following groups: // S_TYPE_TOP - Part of a region, which is not covered by any upper layer. This surface will be filled with a top solid infill. @@ -325,14 +325,12 @@ void PrintObject::detect_surfaces_type() { // Slic3r::debugf "Detecting solid surfaces...\n"; for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) { - // Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces. +#ifdef SLIC3R_DEBUG_SLICE_PROCESSING for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) { LayerRegion *layerm = this->layers[idx_layer]->get_region(idx_region); - layerm->slices_to_fill_surfaces_clipped(); -#ifdef SLIC3R_DEBUG_SLICE_PROCESSING layerm->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial"); -#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ } +#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) { Layer *layer = this->layers[idx_layer]; @@ -526,6 +524,7 @@ PrintObject::discover_vertical_shells() coord_t infill_line_spacing = solid_infill_flow.scaled_spacing(); // Find a union of perimeters below / above this surface to guarantee a minimum shell thickness. Polygons shell; + Polygons holes; #ifdef SLIC3R_DEBUG_SLICE_PROCESSING ExPolygons shell_ex; #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ @@ -561,16 +560,31 @@ PrintObject::discover_vertical_shells() cache_top_regions[idx_layer % n_extra_top_layers].valid = false; if (n_extra_bottom_layers > 0 && idx_layer > 0) cache_bottom_regions[(idx_layer - 1) % n_extra_bottom_layers].valid = false; + bool hole_first = true; for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n) if (n >= 0 && n < (int)this->layers.size()) { Layer &neighbor_layer = *this->layers[n]; LayerRegion &neighbor_region = *neighbor_layer.get_region(int(idx_region)); - polygons_append(shell, neighbor_layer.perimeter_expolygons.expolygons); + Polygons newholes; + for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) + polygons_append(newholes, to_polygons(neighbor_layer.get_region(idx_region)->fill_expolygons)); + if (hole_first) { + hole_first = false; + polygons_append(holes, STDMOVE(newholes)); + } + else if (! holes.empty()) { + holes = intersection(holes, newholes); + } + size_t n_shell_old = shell.size(); if (n > int(idx_layer)) { // Collect top surfaces. DiscoverVerticalShellsCacheEntry &cache = cache_top_regions[n % n_extra_top_layers]; if (! cache.valid) { cache.valid = true; + // neighbor_region.slices contain the source top regions, + // so one would think that they encompass the top fill_surfaces. But the fill_surfaces could have been + // expanded before, therefore they may protrude out of neighbor_region.slices's top surfaces. + //FIXME one should probably use the cummulative top surfaces over all regions here. cache.slices = offset(to_expolygons(neighbor_region.slices.filter_by_type(stTop)), min_perimeter_infill_spacing); cache.fill_surfaces = offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_type(stTop)), min_perimeter_infill_spacing); } @@ -582,6 +596,7 @@ PrintObject::discover_vertical_shells() DiscoverVerticalShellsCacheEntry &cache = cache_bottom_regions[n % n_extra_bottom_layers]; if (! cache.valid) { cache.valid = true; + //FIXME one should probably use the cummulative top surfaces over all regions here. cache.slices = offset(to_expolygons(neighbor_region.slices.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing); cache.fill_surfaces = offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing); } @@ -590,7 +605,8 @@ PrintObject::discover_vertical_shells() } // Running the union_ using the Clipper library piece by piece is cheaper // than running the union_ all at once. - shell = union_(shell, false); + if (n_shell_old < shell.size()) + shell = union_(shell, false); } #ifdef SLIC3R_DEBUG_SLICE_PROCESSING { @@ -613,8 +629,8 @@ PrintObject::discover_vertical_shells() #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ } - if (shell.empty()) - continue; + //if (shell.empty()) + // continue; #ifdef SLIC3R_DEBUG_SLICE_PROCESSING { @@ -660,6 +676,7 @@ PrintObject::discover_vertical_shells() const SurfaceType surfaceTypesInternal[] = { stInternal, stInternalVoid, stInternalSolid }; const Polygons polygonsInternal = to_polygons(layerm->fill_surfaces.filter_by_types(surfaceTypesInternal, 2)); shell = intersection(shell, polygonsInternal, true); + polygons_append(shell, diff(polygonsInternal, holes)); if (shell.empty()) continue; diff --git a/xs/src/libslic3r/Surface.hpp b/xs/src/libslic3r/Surface.hpp index d87c9b695..adf71cc06 100644 --- a/xs/src/libslic3r/Surface.hpp +++ b/xs/src/libslic3r/Surface.hpp @@ -97,6 +97,15 @@ inline Polygons to_polygons(const SurfacesPtr &src) return polygons; } +inline ExPolygons to_expolygons(const Surfaces &src) +{ + ExPolygons expolygons; + expolygons.reserve(src.size()); + for (Surfaces::const_iterator it = src.begin(); it != src.end(); ++it) + expolygons.push_back(it->expolygon); + return expolygons; +} + inline ExPolygons to_expolygons(const SurfacesPtr &src) { ExPolygons expolygons; diff --git a/xs/xsp/Layer.xsp b/xs/xsp/Layer.xsp index 19e8f8a6d..3a20f3a02 100644 --- a/xs/xsp/Layer.xsp +++ b/xs/xsp/Layer.xsp @@ -32,8 +32,8 @@ %code%{ RETVAL = THIS->flow(role, bridge, width); %}; void merge_slices(); void prepare_fill_surfaces(); - void make_perimeters(SurfaceCollection* slices, SurfaceCollection* perimeter_surfaces, SurfaceCollection* fill_surfaces) - %code%{ THIS->make_perimeters(*slices, perimeter_surfaces, fill_surfaces); %}; + void make_perimeters(SurfaceCollection* slices, SurfaceCollection* fill_surfaces) + %code%{ THIS->make_perimeters(*slices, fill_surfaces); %}; double infill_area_threshold(); void export_region_slices_to_svg(const char *path); @@ -80,9 +80,6 @@ Ref slices() %code%{ RETVAL = &THIS->slices; %}; - Ref perimeter_expolygons() - %code%{ RETVAL = &THIS->perimeter_expolygons; %}; - int ptr() %code%{ RETVAL = (int)(intptr_t)THIS; %}; diff --git a/xs/xsp/PerimeterGenerator.xsp b/xs/xsp/PerimeterGenerator.xsp index b8c3edf69..2e8213795 100644 --- a/xs/xsp/PerimeterGenerator.xsp +++ b/xs/xsp/PerimeterGenerator.xsp @@ -10,12 +10,12 @@ StaticPrintConfig* region_config, StaticPrintConfig* object_config, StaticPrintConfig* print_config, ExtrusionEntityCollection* loops, ExtrusionEntityCollection* gap_fill, - SurfaceCollection* perimeter_surfaces, SurfaceCollection* fill_surfaces) + SurfaceCollection* fill_surfaces) %code{% RETVAL = new PerimeterGenerator(slices, layer_height, *flow, dynamic_cast(region_config), dynamic_cast(object_config), dynamic_cast(print_config), - loops, gap_fill, perimeter_surfaces, fill_surfaces); %}; + loops, gap_fill, fill_surfaces); %}; ~PerimeterGenerator(); void set_lower_slices(ExPolygonCollection* lower_slices)