From afacf0c99d2e26b29303ef6acef8cde8505ab4d4 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 9 Mar 2017 20:40:06 +0100 Subject: [PATCH] Parallelized process_external_surfaces --- xs/src/libslic3r/Layer.cpp | 7 +++++++ xs/src/libslic3r/Layer.hpp | 3 ++- xs/src/libslic3r/LayerRegion.cpp | 8 +++++--- xs/src/libslic3r/PrintObject.cpp | 16 +++++----------- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp index 77bc74892..722b539e5 100644 --- a/xs/src/libslic3r/Layer.cpp +++ b/xs/src/libslic3r/Layer.cpp @@ -419,4 +419,11 @@ Layer::detect_surfaces_type() } } +void +Layer::process_external_surfaces() +{ + for (LayerRegion* &layerm : this->regions) + layerm->process_external_surfaces(); +} + } diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp index 278927e15..29405258e 100644 --- a/xs/src/libslic3r/Layer.hpp +++ b/xs/src/libslic3r/Layer.hpp @@ -61,7 +61,7 @@ class LayerRegion void prepare_fill_surfaces(); void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces); void make_fill(); - void process_external_surfaces(const Layer* lower_layer); + void process_external_surfaces(); double infill_area_threshold() const; private: @@ -111,6 +111,7 @@ class Layer { void make_perimeters(); void make_fills(); void detect_surfaces_type(); + void process_external_surfaces(); protected: size_t _id; // sequential number of layer, 0-based diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index 42809d0ae..b7d9058fe 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -65,8 +65,10 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* g.process(); } +// This function reads lower_layer->slices and writes this->bridged and this->fill_surfaces, +// so it's thread-safe. void -LayerRegion::process_external_surfaces(const Layer* lower_layer) +LayerRegion::process_external_surfaces() { const Surfaces &surfaces = this->fill_surfaces.surfaces; const double margin = scale_(EXTERNAL_INFILL_MARGIN); @@ -82,10 +84,10 @@ LayerRegion::process_external_surfaces(const Layer* lower_layer) also, supply the original expolygon instead of the grown one, because in case of very thin (but still working) anchors, the grown expolygon would go beyond them */ double angle = -1; - if (lower_layer != NULL && surface->is_bridge()) { + if (this->layer()->lower_layer != NULL && surface->is_bridge()) { BridgeDetector bd( surface->expolygon, - lower_layer->slices, + this->layer()->lower_layer->slices, this->flow(frInfill, true).scaled_width() ); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index be38fda0a..b8ab9cdbf 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -371,17 +371,11 @@ PrintObject::detect_surfaces_type() void PrintObject::process_external_surfaces() { - FOREACH_REGION(this->_print, region) { - size_t region_id = region - this->_print->regions.begin(); - - FOREACH_LAYER(this, layer_it) { - const Layer* lower_layer = (layer_it == this->layers.begin()) - ? NULL - : *(layer_it-1); - - (*layer_it)->get_region(region_id)->process_external_surfaces(lower_layer); - } - } + parallelize( + std::queue(std::deque(this->layers.begin(), this->layers.end())), // cast LayerPtrs to std::queue + boost::bind(&Slic3r::Layer::process_external_surfaces, _1), + this->_print->config.threads.value + ); } /* This method applies bridge flow to the first internal solid layer above