From 9f7a5c7a6f93e3383c596e18c7258cfc96bf7262 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 28 Mar 2017 13:25:10 +0200 Subject: Some beautification and C++11 adaptation. --- xs/src/libslic3r/BridgeDetector.cpp | 53 ++++++++++------------ xs/src/libslic3r/Flow.hpp | 12 ++--- xs/src/libslic3r/Print.hpp | 11 ++--- xs/src/libslic3r/PrintObject.cpp | 87 +++++++++++++------------------------ xs/src/libslic3r/PrintRegion.cpp | 22 +++------- 5 files changed, 69 insertions(+), 116 deletions(-) (limited to 'xs') diff --git a/xs/src/libslic3r/BridgeDetector.cpp b/xs/src/libslic3r/BridgeDetector.cpp index fa27134dc..8ed38b7e9 100644 --- a/xs/src/libslic3r/BridgeDetector.cpp +++ b/xs/src/libslic3r/BridgeDetector.cpp @@ -15,7 +15,7 @@ BridgeDetector::BridgeDetector( lower_slices(_lower_slices), spacing(_spacing) { - this->expolygons_owned.push_back(STDMOVE(_expolygon)); + this->expolygons_owned.push_back(std::move(_expolygon)); initialize(); } @@ -211,49 +211,40 @@ Polygons BridgeDetector::coverage(double angle) const Polygons covered; if (angle != -1) { - // Get anchors, convert them to Polygons and rotate them. Polygons anchors = to_polygons(this->_anchor_regions); polygons_rotate(anchors, PI/2.0 - angle); - for (ExPolygons::const_iterator it_expoly = this->expolygons.begin(); it_expoly != this->expolygons.end(); ++ it_expoly) - { + for (ExPolygon expolygon : this->expolygons) { // Clone our expolygon and rotate it so that we work with vertical lines. - ExPolygon expolygon = *it_expoly; - expolygon.rotate(PI/2.0 - angle); - - /* Outset the bridge expolygon by half the amount we used for detecting anchors; - we'll use this one to generate our trapezoids and be sure that their vertices - are inside the anchors and not on their contours leading to false negatives. */ - ExPolygons grown = offset_ex(expolygon, 0.5f * float(this->spacing)); - - // Compute trapezoids according to a vertical orientation - Polygons trapezoids; - for (ExPolygons::const_iterator it = grown.begin(); it != grown.end(); ++it) - it->get_trapezoids2(&trapezoids, PI/2.0); - - for (Polygons::iterator trapezoid = trapezoids.begin(); trapezoid != trapezoids.end(); ++trapezoid) { - Lines supported = intersection_ln(trapezoid->lines(), anchors); - size_t n_supported = 0; - // not nice, we need a more robust non-numeric check - for (size_t i = 0; i < supported.size(); ++i) - if (supported[i].length() >= this->spacing) - ++ n_supported; - if (n_supported >= 2) - covered.push_back(STDMOVE(*trapezoid)); + expolygon.rotate(PI/2.0 - angle); + // Outset the bridge expolygon by half the amount we used for detecting anchors; + // we'll use this one to generate our trapezoids and be sure that their vertices + // are inside the anchors and not on their contours leading to false negatives. + for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * float(this->spacing))) { + // Compute trapezoids according to a vertical orientation + Polygons trapezoids; + expoly.get_trapezoids2(&trapezoids, PI/2.0); + for (const Polygon &trapezoid : trapezoids) { + // not nice, we need a more robust non-numeric check + size_t n_supported = 0; + for (const Line &supported_line : intersection_ln(trapezoid.lines(), anchors)) + if (supported_line.length() >= this->spacing) + ++ n_supported; + if (n_supported >= 2) + covered.push_back(std::move(trapezoid)); + } } } // Unite the trapezoids before rotation, as the rotation creates tiny gaps and intersections between the trapezoids // instead of exact overlaps. covered = union_(covered); - // Intersect trapezoids with actual bridge area to remove extra margins and append it to result. polygons_rotate(covered, -(PI/2.0 - angle)); covered = intersection(covered, to_polygons(this->expolygons)); - - /* - if (0) { +#if 0 + { my @lines = map @{$_->lines}, @$trapezoids; $_->rotate(-(PI/2 - $angle), [0,0]) for @lines; @@ -266,7 +257,7 @@ Polygons BridgeDetector::coverage(double angle) const lines => \@lines, ); } - */ +#endif } return covered; } diff --git a/xs/src/libslic3r/Flow.hpp b/xs/src/libslic3r/Flow.hpp index a3ff4b6b6..118273067 100644 --- a/xs/src/libslic3r/Flow.hpp +++ b/xs/src/libslic3r/Flow.hpp @@ -45,15 +45,9 @@ public: float spacing() const; float spacing(const Flow &other) const; double mm3_per_mm() const; - coord_t scaled_width() const { - return scale_(this->width); - }; - coord_t scaled_spacing() const { - return scale_(this->spacing()); - }; - coord_t scaled_spacing(const Flow &other) const { - return scale_(this->spacing(other)); - }; + coord_t scaled_width() const { return coord_t(scale_(this->width)); }; + coord_t scaled_spacing() const { return coord_t(scale_(this->spacing())); }; + coord_t scaled_spacing(const Flow &other) const { return coord_t(scale_(this->spacing(other))); }; static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio); static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge); diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 3398260e3..e1f386fc9 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -53,17 +53,18 @@ class PrintRegion { friend class Print; - public: +public: PrintRegionConfig config; - Print* print(); + Print* print() { return this->_print; } Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const; + coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const; - private: +private: Print* _print; - PrintRegion(Print* print); - ~PrintRegion(); + PrintRegion(Print* print) : _print(print) {} + ~PrintRegion() {} }; diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 3a4ba6630..43caa2ed4 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -365,17 +365,22 @@ void PrintObject::detect_surfaces_type() { BOOST_LOG_TRIVIAL(info) << "Detecting solid surfaces..."; + // Interface shells: the intersecting parts are treated as self standing objects supporting each other. + // Each of the objects will have a full number of top / bottom layers, even if these top / bottom layers + // are completely hidden inside a collective body of intersecting parts. + // This is useful if one of the parts is to be dissolved, or if it is transparent and the internal shells + // should be visible. bool interface_shells = this->config.interface_shells.value; for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) { BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start"; #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->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial"); - } + for (Layer *layer : this->layers) + layer->regions[idx_region]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial"); #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ + // If interface shells are allowed, the region->surfaces cannot be overwritten as they may be used by other threads. + // Cache the result of the following parallel_loop. std::vector surfaces_new; if (interface_shells) surfaces_new.assign(this->layers.size(), Surfaces()); @@ -383,14 +388,23 @@ void PrintObject::detect_surfaces_type() tbb::parallel_for( tbb::blocked_range(0, this->layers.size()), [this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range& range) { + // If we have raft layers, consider bottom layer as a bridge just like any other bottom surface lying on the void. + SurfaceType surface_type_bottom_1st = + (this->config.raft_layers.value > 0 && this->config.support_material_contact_distance.value > 0) ? + stBottomBridge : stBottom; + // If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating + // the support from the print. + SurfaceType surface_type_bottom_other = + (this->config.support_material.value && this->config.support_material_contact_distance.value == 0) ? + stBottom : stBottomBridge; 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]; LayerRegion *layerm = layer->get_region(idx_region); // comparison happens against the *full* slices (considering all regions) // unless internal shells are requested - Layer *upper_layer = idx_layer + 1 < this->layer_count() ? this->get_layer(idx_layer + 1) : NULL; - Layer *lower_layer = idx_layer > 0 ? this->get_layer(idx_layer - 1) : NULL; + Layer *upper_layer = idx_layer + 1 < this->layer_count() ? this->get_layer(idx_layer + 1) : nullptr; + Layer *lower_layer = idx_layer > 0 ? this->get_layer(idx_layer - 1) : nullptr; // collapse very narrow parts (using the safety offset in the diff is not enough) float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f; @@ -400,8 +414,6 @@ void PrintObject::detect_surfaces_type() // of current layer and upper one) Surfaces top; if (upper_layer) { - // 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). Polygons upper_slices = interface_shells ? to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) : to_polygons(upper_layer->slices); @@ -412,54 +424,25 @@ void PrintObject::detect_surfaces_type() // if no upper layer, all surfaces of this one are solid // we clone surfaces because we're going to clear the slices collection top = layerm->slices.surfaces; - for (Surfaces::iterator it = top.begin(); it != top.end(); ++ it) - it->surface_type = stTop; + for (Surface &surface : top) + surface.surface_type = stTop; } - // find bottom surfaces (difference between current surfaces - // of current layer and lower one) + // Find bottom surfaces (difference between current surfaces of current layer and lower one). Surfaces bottom; if (lower_layer) { - // If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating - // the support from the print. - SurfaceType surface_type_bottom = - (this->config.support_material.value && this->config.support_material_contact_distance.value == 0) ? - stBottom : stBottomBridge; - // Any surface lying on the void is a true bottom bridge (an overhang) - surfaces_append( - bottom, - offset2_ex( - diff(layerm_slices_surfaces, to_polygons(lower_layer->slices), true), - -offset, offset), - surface_type_bottom); - // if user requested internal shells, we need to identify surfaces - // lying on other slices not belonging to this region - //FIXME Vojtech: config.internal_shells or config.interface_shells? Is it some legacy code? - // Why shall multiple regions over soluble support be treated specially? - if (interface_shells) { - // non-bridging bottom surfaces: any part of this layer lying - // on something else, excluding those lying on our own region - surfaces_append( - bottom, - offset2_ex( - diff( - intersection(layerm_slices_surfaces, to_polygons(lower_layer->slices)), // supported - to_polygons(lower_layer->get_region(idx_region)->slices.surfaces), - true), - -offset, offset), - stBottom); - } + Polygons lower_slices = interface_shells ? + to_polygons(lower_layer->get_region(idx_region)->slices.surfaces) : + to_polygons(lower_layer->slices); + surfaces_append(bottom, + offset2_ex(diff(layerm_slices_surfaces, lower_slices, true), -offset, offset), + surface_type_bottom_other); } else { // if no lower layer, all surfaces of this one are solid // we clone surfaces because we're going to clear the slices collection bottom = layerm->slices.surfaces; - // if we have raft layers, consider bottom layer as a bridge - // just like any other bottom surface lying on the void - SurfaceType surface_type_bottom = - (this->config.raft_layers.value > 0 && this->config.support_material_contact_distance.value > 0) ? - stBottomBridge : stBottom; - for (Surfaces::iterator it = bottom.begin(); it != bottom.end(); ++ it) - it->surface_type = surface_type_bottom; + for (Surface &surface : bottom) + surface.surface_type = surface_type_bottom_1st; } // now, if the object contained a thin membrane, we could have overlapping bottom @@ -472,11 +455,7 @@ void PrintObject::detect_surfaces_type() Polygons top_polygons = to_polygons(std::move(top)); top.clear(); surfaces_append(top, - #if 0 - offset2_ex(diff(top_polygons, to_polygons(bottom), true), -offset, offset), - #else diff_ex(top_polygons, to_polygons(bottom), false), - #endif stTop); } @@ -500,11 +479,7 @@ void PrintObject::detect_surfaces_type() Polygons topbottom = to_polygons(top); polygons_append(topbottom, to_polygons(bottom)); surfaces_append(surfaces_out, - #if 0 - offset2_ex(diff(layerm_slices_surfaces, topbottom, true), -offset, offset), - #else diff_ex(layerm_slices_surfaces, topbottom, false), - #endif stInternal); } diff --git a/xs/src/libslic3r/PrintRegion.cpp b/xs/src/libslic3r/PrintRegion.cpp index e6ef456bc..4874c71bc 100644 --- a/xs/src/libslic3r/PrintRegion.cpp +++ b/xs/src/libslic3r/PrintRegion.cpp @@ -2,21 +2,6 @@ namespace Slic3r { -PrintRegion::PrintRegion(Print* print) - : _print(print) -{ -} - -PrintRegion::~PrintRegion() -{ -} - -Print* -PrintRegion::print() -{ - return this->_print; -} - Flow PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const { @@ -65,4 +50,11 @@ PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_la return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, bridge ? (float)this->config.bridge_flow_ratio : 0.0); } +coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const +{ + return (print_config.nozzle_diameter.get_at(this->config.perimeter_extruder.value - 1) + + print_config.nozzle_diameter.get_at(this->config.infill_extruder.value - 1) + + print_config.nozzle_diameter.get_at(this->config.solid_infill_extruder.value - 1)) / 3.; +} + } -- cgit v1.2.3