Parallelized PrintObject::detect_surfaces_type()

This commit is contained in:
bubnikv 2017-03-07 21:46:45 +01:00
parent 65c024f7cf
commit dfba2cb6b2

View File

@ -365,8 +365,10 @@ void PrintObject::detect_surfaces_type()
{ {
BOOST_LOG_TRIVIAL(info) << "Detecting solid surfaces..."; BOOST_LOG_TRIVIAL(info) << "Detecting solid surfaces...";
bool interface_shells = this->config.interface_shells.value;
for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) { for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region; BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) { for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) {
LayerRegion *layerm = this->layers[idx_layer]->get_region(idx_region); LayerRegion *layerm = this->layers[idx_layer]->get_region(idx_region);
@ -374,10 +376,17 @@ void PrintObject::detect_surfaces_type()
} }
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) { std::vector<Surfaces> surfaces_new;
if (interface_shells)
surfaces_new.assign(this->layers.size(), Surfaces());
tbb::parallel_for(
tbb::blocked_range<size_t>(0, this->layers.size()),
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
// BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z;
Layer *layer = this->layers[idx_layer]; Layer *layer = this->layers[idx_layer];
LayerRegion *layerm = layer->get_region(idx_region); LayerRegion *layerm = layer->get_region(idx_region);
BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z;
// comparison happens against the *full* slices (considering all regions) // comparison happens against the *full* slices (considering all regions)
// unless internal shells are requested // unless internal shells are requested
Layer *upper_layer = idx_layer + 1 < this->layer_count() ? this->get_layer(idx_layer + 1) : NULL; Layer *upper_layer = idx_layer + 1 < this->layer_count() ? this->get_layer(idx_layer + 1) : NULL;
@ -393,7 +402,7 @@ void PrintObject::detect_surfaces_type()
if (upper_layer) { if (upper_layer) {
// Config value $self->config->interface_shells is true, if a support is separated from the object // Config value $self->config->interface_shells is true, if a support is separated from the object
// by a soluble material (for example a PVA plastic). // by a soluble material (for example a PVA plastic).
Polygons upper_slices = this->config.interface_shells.value ? Polygons upper_slices = interface_shells ?
to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) : to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) :
to_polygons(upper_layer->slices); to_polygons(upper_layer->slices);
surfaces_append(top, surfaces_append(top,
@ -427,7 +436,7 @@ void PrintObject::detect_surfaces_type()
// lying on other slices not belonging to this region // lying on other slices not belonging to this region
//FIXME Vojtech: config.internal_shells or config.interface_shells? Is it some legacy code? //FIXME Vojtech: config.internal_shells or config.interface_shells? Is it some legacy code?
// Why shall multiple regions over soluble support be treated specially? // Why shall multiple regions over soluble support be treated specially?
if (this->config.interface_shells.value) { if (interface_shells) {
// non-bridging bottom surfaces: any part of this layer lying // non-bridging bottom surfaces: any part of this layer lying
// on something else, excluding those lying on our own region // on something else, excluding those lying on our own region
surfaces_append( surfaces_append(
@ -457,21 +466,21 @@ void PrintObject::detect_surfaces_type()
// and top surfaces; let's do an intersection to discover them and consider them // and top surfaces; let's do an intersection to discover them and consider them
// as bottom surfaces (to allow for bridge detection) // as bottom surfaces (to allow for bridge detection)
if (! top.empty() && ! bottom.empty()) { if (! top.empty() && ! bottom.empty()) {
// Polygons overlapping = intersection(to_polygons(top), to_polygons(bottom)); // Polygons overlapping = intersection(to_polygons(top), to_polygons(bottom));
// Slic3r::debugf " layer %d contains %d membrane(s)\n", $layerm->layer->id, scalar(@$overlapping) // Slic3r::debugf " layer %d contains %d membrane(s)\n", $layerm->layer->id, scalar(@$overlapping)
// if $Slic3r::debug; // if $Slic3r::debug;
Polygons top_polygons = to_polygons(STDMOVE(top)); Polygons top_polygons = to_polygons(std::move(top));
top.clear(); top.clear();
surfaces_append(top, surfaces_append(top,
#if 0 #if 0
offset2_ex(diff(top_polygons, to_polygons(bottom), true), -offset, offset), offset2_ex(diff(top_polygons, to_polygons(bottom), true), -offset, offset),
#else #else
diff_ex(top_polygons, to_polygons(bottom), false), diff_ex(top_polygons, to_polygons(bottom), false),
#endif #endif
stTop); stTop);
} }
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{ {
static int iRun = 0; static int iRun = 0;
std::vector<std::pair<Slic3r::ExPolygons, SVG::ExPolygonAttributes>> expolygons_with_attributes; std::vector<std::pair<Slic3r::ExPolygons, SVG::ExPolygonAttributes>> expolygons_with_attributes;
@ -480,34 +489,45 @@ void PrintObject::detect_surfaces_type()
expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black"))); expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black")));
SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes); SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes);
} }
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// save surfaces to layer // save surfaces to layer
layerm->slices.surfaces.clear(); Surfaces &surfaces_out = interface_shells ? surfaces_new[idx_layer] : layerm->slices.surfaces;
surfaces_out.clear();
// find internal surfaces (difference between top/bottom surfaces and others) // find internal surfaces (difference between top/bottom surfaces and others)
{ {
Polygons topbottom = to_polygons(top); Polygons topbottom = to_polygons(top);
polygons_append(topbottom, to_polygons(bottom)); polygons_append(topbottom, to_polygons(bottom));
layerm->slices.append( surfaces_append(surfaces_out,
#if 0 #if 0
offset2_ex(diff(layerm_slices_surfaces, topbottom, true), -offset, offset), offset2_ex(diff(layerm_slices_surfaces, topbottom, true), -offset, offset),
#else #else
diff_ex(layerm_slices_surfaces, topbottom, false), diff_ex(layerm_slices_surfaces, topbottom, false),
#endif #endif
stInternal); stInternal);
} }
layerm->slices.append(STDMOVE(top)); surfaces_append(surfaces_out, std::move(top));
layerm->slices.append(STDMOVE(bottom)); surfaces_append(surfaces_out, std::move(bottom));
// Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n", // Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n",
// $layerm->layer->id, scalar(@bottom), scalar(@top), scalar(@internal) if $Slic3r::debug; // $layerm->layer->id, scalar(@bottom), scalar(@top), scalar(@internal) if $Slic3r::debug;
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_slices_to_svg_debug("detect_surfaces_type-final"); layerm->export_region_slices_to_svg_debug("detect_surfaces_type-final");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
} // for each layer of a region }
}
); // for each layer of a region
if (interface_shells) {
// Move surfaces_new to layerm->slices.surfaces
for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++ idx_layer)
this->layers[idx_layer]->get_region(idx_region)->slices.surfaces = std::move(surfaces_new[idx_layer]);
}
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - end";
// Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces. // Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces.
for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) { for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) {
@ -642,7 +662,7 @@ PrintObject::discover_vertical_shells()
polygons_append(newholes, to_polygons(neighbor_layer.regions[idx_region]->fill_expolygons)); polygons_append(newholes, to_polygons(neighbor_layer.regions[idx_region]->fill_expolygons));
if (hole_first) { if (hole_first) {
hole_first = false; hole_first = false;
polygons_append(holes, STDMOVE(newholes)); polygons_append(holes, std::move(newholes));
} }
else if (! holes.empty()) { else if (! holes.empty()) {
holes = intersection(holes, newholes); holes = intersection(holes, newholes);