From 9fcec107373b6846f3775fe353c7ae29653cf9ac Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 26 Oct 2015 23:23:03 +0100 Subject: Finished porting LayerRegion to C++ --- xs/src/libslic3r/BridgeDetector.cpp | 36 +++++--- xs/src/libslic3r/BridgeDetector.hpp | 4 +- xs/src/libslic3r/ClipperUtils.cpp | 22 ++++- xs/src/libslic3r/ClipperUtils.hpp | 8 +- xs/src/libslic3r/ExPolygonCollection.cpp | 6 ++ xs/src/libslic3r/ExPolygonCollection.hpp | 1 + xs/src/libslic3r/Layer.hpp | 5 +- xs/src/libslic3r/LayerRegion.cpp | 148 +++++++++++++++++++++++++++++++ xs/src/libslic3r/PerimeterGenerator.cpp | 24 ++--- xs/src/libslic3r/PolylineCollection.cpp | 6 ++ xs/src/libslic3r/PolylineCollection.hpp | 1 + xs/src/libslic3r/Print.hpp | 1 + xs/src/libslic3r/PrintObject.cpp | 34 +++++-- xs/src/libslic3r/Surface.cpp | 5 ++ xs/src/libslic3r/Surface.hpp | 1 + xs/src/libslic3r/SurfaceCollection.cpp | 6 ++ xs/src/libslic3r/SurfaceCollection.hpp | 4 + xs/src/libslic3r/libslic3r.h | 1 + 18 files changed, 273 insertions(+), 40 deletions(-) (limited to 'xs/src/libslic3r') diff --git a/xs/src/libslic3r/BridgeDetector.cpp b/xs/src/libslic3r/BridgeDetector.cpp index da59a04d8..1dddf81ce 100644 --- a/xs/src/libslic3r/BridgeDetector.cpp +++ b/xs/src/libslic3r/BridgeDetector.cpp @@ -185,16 +185,12 @@ BridgeDetector::detect_angle() return true; } -void -BridgeDetector::coverage(Polygons* coverage) const -{ - if (this->angle == -1) return; - return this->coverage(angle, coverage); -} - void BridgeDetector::coverage(double angle, Polygons* coverage) const { + if (angle == -1) angle = this->angle; + if (angle == -1) return; + // Clone our expolygon and rotate it so that we work with vertical lines. ExPolygon expolygon = this->expolygon; expolygon.rotate(PI/2.0 - angle, Point(0,0)); @@ -263,19 +259,23 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const */ } -/* This method returns the bridge edges (as polylines) that are not supported - but would allow the entire bridge area to be bridged with detected angle - if supported too */ -void -BridgeDetector::unsupported_edges(Polylines* unsupported) const +Polygons +BridgeDetector::coverage(double angle) const { - if (this->angle == -1) return; - return this->unsupported_edges(this->angle, unsupported); + Polygons pp; + this->coverage(angle, &pp); + return pp; } +/* This method returns the bridge edges (as polylines) that are not supported + but would allow the entire bridge area to be bridged with detected angle + if supported too */ void BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const { + if (angle == -1) angle = this->angle; + if (angle == -1) return; + // get bridge edges (both contour and holes) Polylines bridge_edges; { @@ -319,6 +319,14 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const */ } +Polylines +BridgeDetector::unsupported_edges(double angle) const +{ + Polylines pp; + this->unsupported_edges(angle, &pp); + return pp; +} + #ifdef SLIC3RXS REGISTER_CLASS(BridgeDetector, "BridgeDetector"); #endif diff --git a/xs/src/libslic3r/BridgeDetector.hpp b/xs/src/libslic3r/BridgeDetector.hpp index ab2571289..c3af09542 100644 --- a/xs/src/libslic3r/BridgeDetector.hpp +++ b/xs/src/libslic3r/BridgeDetector.hpp @@ -18,10 +18,10 @@ class BridgeDetector { BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width); bool detect_angle(); - void coverage(Polygons* coverage) const; void coverage(double angle, Polygons* coverage) const; - void unsupported_edges(Polylines* unsupported) const; + Polygons coverage(double angle = -1) const; void unsupported_edges(double angle, Polylines* unsupported) const; + Polylines unsupported_edges(double angle = -1) const; private: Polylines _edges; // representing the supporting edges diff --git a/xs/src/libslic3r/ClipperUtils.cpp b/xs/src/libslic3r/ClipperUtils.cpp index baddd8f45..3d07891b1 100644 --- a/xs/src/libslic3r/ClipperUtils.cpp +++ b/xs/src/libslic3r/ClipperUtils.cpp @@ -212,6 +212,15 @@ offset(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float ClipperPaths_to_Slic3rExPolygons(output, retval); } +Slic3r::ExPolygons +offset_ex(const Slic3r::Polygons &polygons, const float delta, + double scale, ClipperLib::JoinType joinType, double miterLimit) +{ + Slic3r::ExPolygons expp; + offset(polygons, &expp, delta, scale, joinType, miterLimit); + return expp; +} + void offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1, const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit) @@ -472,13 +481,16 @@ diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_ return pp; } +template Slic3r::ExPolygons -diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_) +diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_) { Slic3r::ExPolygons expp; diff(subject, clip, &expp, safety_offset_); return expp; } +template Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_); +template Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_); template void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_) @@ -507,6 +519,14 @@ intersection(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, boo return pp; } +Slic3r::ExPolygons +intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_) +{ + Slic3r::ExPolygons expp; + intersection(subject, clip, &expp, safety_offset_); + return expp; +} + template bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_) { diff --git a/xs/src/libslic3r/ClipperUtils.hpp b/xs/src/libslic3r/ClipperUtils.hpp index 4a3ba2e5c..2b4e8c0b3 100644 --- a/xs/src/libslic3r/ClipperUtils.hpp +++ b/xs/src/libslic3r/ClipperUtils.hpp @@ -58,6 +58,9 @@ void offset(const Slic3r::Surface &surface, Slic3r::Surfaces* retval, const floa void offset(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3); +Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, + double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, + double miterLimit = 3); void offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, @@ -96,13 +99,16 @@ template void diff(const SubjectType &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_ = false); Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); -Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); + +template +Slic3r::ExPolygons diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_ = false); template void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false); Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); Slic3r::Polylines intersection(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); +Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); template bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); diff --git a/xs/src/libslic3r/ExPolygonCollection.cpp b/xs/src/libslic3r/ExPolygonCollection.cpp index 9ae7e8907..45f0df477 100644 --- a/xs/src/libslic3r/ExPolygonCollection.cpp +++ b/xs/src/libslic3r/ExPolygonCollection.cpp @@ -122,6 +122,12 @@ ExPolygonCollection::contours() const return contours; } +void +ExPolygonCollection::append(const ExPolygons &expp) +{ + this->expolygons.insert(this->expolygons.end(), expp.begin(), expp.end()); +} + #ifdef SLIC3RXS REGISTER_CLASS(ExPolygonCollection, "ExPolygon::Collection"); #endif diff --git a/xs/src/libslic3r/ExPolygonCollection.hpp b/xs/src/libslic3r/ExPolygonCollection.hpp index 4e6c366e2..ffb306c92 100644 --- a/xs/src/libslic3r/ExPolygonCollection.hpp +++ b/xs/src/libslic3r/ExPolygonCollection.hpp @@ -31,6 +31,7 @@ class ExPolygonCollection Polygon convex_hull() const; Lines lines() const; Polygons contours() const; + void append(const ExPolygons &expolygons); }; } diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp index 1c09b5f0f..7adaa0fbb 100644 --- a/xs/src/libslic3r/Layer.hpp +++ b/xs/src/libslic3r/Layer.hpp @@ -40,8 +40,7 @@ class LayerRegion // collection of expolygons representing the bridged areas (thus not // needing support material) - // (this could be just a Polygons object) - ExPolygonCollection bridged; + Polygons bridged; // collection of polylines representing the unsupported bridge edges PolylineCollection unsupported_bridge_edges; @@ -58,6 +57,8 @@ class LayerRegion void merge_slices(); void prepare_fill_surfaces(); void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces); + void process_external_surfaces(const Layer* lower_layer); + double infill_area_threshold() const; private: Layer *_layer; diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index ef6150015..4f874a2ea 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -1,4 +1,5 @@ #include "Layer.hpp" +#include "BridgeDetector.hpp" #include "ClipperUtils.hpp" #include "PerimeterGenerator.hpp" #include "Print.hpp" @@ -86,6 +87,146 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* g.process(); } +void +LayerRegion::process_external_surfaces(const Layer* lower_layer) +{ + const Surfaces &surfaces = this->fill_surfaces.surfaces; + const double margin = scale_(EXTERNAL_INFILL_MARGIN); + + SurfaceCollection bottom; + for (Surfaces::const_iterator surface = surfaces.begin(); surface != surfaces.end(); ++surface) { + if (!surface->is_bottom()) continue; + + ExPolygons grown = offset_ex(surface->expolygon, +margin); + + /* detect bridge direction before merging grown surfaces otherwise adjacent bridges + would get merged into a single one while they need different directions + 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) { + BridgeDetector bd( + surface->expolygon, + lower_layer->slices, + this->flow(frInfill, this->layer()->height, true).scaled_width() + ); + + #ifdef SLIC3R_DEBUG + printf("Processing bridge at layer %zu:\n", this->layer()->id(); + #endif + + if (bd.detect_angle() && this->layer()->object()->config.support_material) { + angle = bd.angle; + + Polygons coverage = bd.coverage(); + this->bridged.insert(this->bridged.end(), coverage.begin(), coverage.end()); + this->unsupported_bridge_edges.append(bd.unsupported_edges()); + } + } + + for (ExPolygons::const_iterator it = grown.begin(); it != grown.end(); ++it) { + Surface s = *surface; + s.expolygon = *it; + s.bridge_angle = angle; + bottom.surfaces.push_back(s); + } + } + + SurfaceCollection top; + for (Surfaces::const_iterator surface = surfaces.begin(); surface != surfaces.end(); ++surface) { + if (surface->surface_type != stTop) continue; + + // give priority to bottom surfaces + ExPolygons grown = diff_ex( + offset(surface->expolygon, +margin), + (Polygons)bottom + ); + for (ExPolygons::const_iterator it = grown.begin(); it != grown.end(); ++it) { + Surface s = *surface; + s.expolygon = *it; + top.surfaces.push_back(s); + } + } + + /* if we're slicing with no infill, we can't extend external surfaces + over non-existent infill */ + SurfaceCollection fill_boundaries; + if (this->region()->config.fill_density.value > 0) { + fill_boundaries = SurfaceCollection(surfaces); + } else { + for (Surfaces::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it) { + if (it->surface_type != stInternal) + fill_boundaries.surfaces.push_back(*it); + } + } + + // intersect the grown surfaces with the actual fill boundaries + SurfaceCollection new_surfaces; + { + // merge top and bottom in a single collection + SurfaceCollection tb = top; + tb.surfaces.insert(tb.surfaces.end(), bottom.surfaces.begin(), bottom.surfaces.end()); + + // group surfaces + std::vector groups; + tb.group(&groups); + + for (std::vector::const_iterator g = groups.begin(); g != groups.end(); ++g) { + Polygons subject; + for (SurfacesPtr::const_iterator s = g->begin(); s != g->end(); ++s) { + Polygons pp = **s; + subject.insert(subject.end(), pp.begin(), pp.end()); + } + + ExPolygons expp = intersection_ex( + subject, + (Polygons)fill_boundaries, + true // to ensure adjacent expolygons are unified + ); + + for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { + Surface s = *g->front(); + s.expolygon = *ex; + new_surfaces.surfaces.push_back(s); + } + } + } + + /* subtract the new top surfaces from the other non-top surfaces and re-add them */ + { + SurfaceCollection other; + for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) { + if (s->surface_type != stTop && !s->is_bottom()) + other.surfaces.push_back(*s); + } + + // group surfaces + std::vector groups; + other.group(&groups); + + for (std::vector::const_iterator g = groups.begin(); g != groups.end(); ++g) { + Polygons subject; + for (SurfacesPtr::const_iterator s = g->begin(); s != g->end(); ++s) { + Polygons pp = **s; + subject.insert(subject.end(), pp.begin(), pp.end()); + } + + ExPolygons expp = diff_ex( + subject, + (Polygons)new_surfaces + ); + + for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { + Surface s = *g->front(); + s.expolygon = *ex; + new_surfaces.surfaces.push_back(s); + } + } + } + + this->fill_surfaces = new_surfaces; +} + void LayerRegion::prepare_fill_surfaces() { @@ -123,6 +264,13 @@ LayerRegion::prepare_fill_surfaces() } } +double +LayerRegion::infill_area_threshold() const +{ + double ss = this->flow(frSolidInfill).scaled_spacing(); + return ss*ss; +} + #ifdef SLIC3RXS REGISTER_CLASS(LayerRegion, "Layer::Region"); #endif diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index a96848531..32662f59c 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -47,7 +47,7 @@ PerimeterGenerator::process() for (Surfaces::const_iterator surface = this->slices->surfaces.begin(); surface != this->slices->surfaces.end(); ++surface) { // detect how many perimeters must be generated for this island - short loop_number = this->config->perimeters + surface->extra_perimeters; + signed short loop_number = this->config->perimeters + surface->extra_perimeters; loop_number--; // 0-indexed loops Polygons gaps; @@ -60,7 +60,7 @@ PerimeterGenerator::process() Polylines thin_walls; // we loop one time more than needed in order to find gaps after the last perimeter was applied - for (unsigned short i = 0; i <= loop_number+1; ++i) { // outer loop is 0 + for (signed short i = 0; i <= loop_number+1; ++i) { // outer loop is 0 Polygons offsets; if (i == 0) { // the minimum thickness of a single loop is: @@ -166,16 +166,16 @@ PerimeterGenerator::process() } // nest loops: holes first - for (unsigned short d = 0; d <= loop_number; ++d) { + for (signed short d = 0; d <= loop_number; ++d) { PerimeterGeneratorLoops &holes_d = holes[d]; // loop through all holes having depth == d - for (unsigned short i = 0; i < holes_d.size(); ++i) { + for (signed short i = 0; i < holes_d.size(); ++i) { const PerimeterGeneratorLoop &loop = holes_d[i]; // find the hole loop that contains this one, if any - for (unsigned short t = d+1; t <= loop_number; ++t) { - for (unsigned short j = 0; j < holes[t].size(); ++j) { + for (signed short t = d+1; t <= loop_number; ++t) { + for (signed short j = 0; j < holes[t].size(); ++j) { PerimeterGeneratorLoop &candidate_parent = holes[t][j]; if (candidate_parent.polygon.contains(loop.polygon.first_point())) { candidate_parent.children.push_back(loop); @@ -187,8 +187,8 @@ PerimeterGenerator::process() } // if no hole contains this hole, find the contour loop that contains it - for (short t = loop_number; t >= 0; --t) { - for (unsigned short j = 0; j < contours[t].size(); ++j) { + for (signed short t = loop_number; t >= 0; --t) { + for (signed short j = 0; j < contours[t].size(); ++j) { PerimeterGeneratorLoop &candidate_parent = contours[t][j]; if (candidate_parent.polygon.contains(loop.polygon.first_point())) { candidate_parent.children.push_back(loop); @@ -203,16 +203,16 @@ PerimeterGenerator::process() } // nest contour loops - for (short d = loop_number; d >= 1; --d) { + for (signed short d = loop_number; d >= 1; --d) { PerimeterGeneratorLoops &contours_d = contours[d]; // loop through all contours having depth == d - for (unsigned short i = 0; i < contours_d.size(); ++i) { + for (signed short i = 0; i < contours_d.size(); ++i) { const PerimeterGeneratorLoop &loop = contours_d[i]; // find the contour loop that contains it - for (short t = d-1; t >= 0; --t) { - for (unsigned short j = 0; j < contours[t].size(); ++j) { + for (signed short t = d-1; t >= 0; --t) { + for (signed short j = 0; j < contours[t].size(); ++j) { PerimeterGeneratorLoop &candidate_parent = contours[t][j]; if (candidate_parent.polygon.contains(loop.polygon.first_point())) { candidate_parent.children.push_back(loop); diff --git a/xs/src/libslic3r/PolylineCollection.cpp b/xs/src/libslic3r/PolylineCollection.cpp index c2a142cf3..b7e34b670 100644 --- a/xs/src/libslic3r/PolylineCollection.cpp +++ b/xs/src/libslic3r/PolylineCollection.cpp @@ -50,6 +50,12 @@ PolylineCollection::leftmost_point() const return p; } +void +PolylineCollection::append(const Polylines &pp) +{ + this->polylines.insert(this->polylines.end(), pp.begin(), pp.end()); +} + #ifdef SLIC3RXS REGISTER_CLASS(PolylineCollection, "Polyline::Collection"); #endif diff --git a/xs/src/libslic3r/PolylineCollection.hpp b/xs/src/libslic3r/PolylineCollection.hpp index ace03ad37..d903b35c5 100644 --- a/xs/src/libslic3r/PolylineCollection.hpp +++ b/xs/src/libslic3r/PolylineCollection.hpp @@ -13,6 +13,7 @@ class PolylineCollection void chained_path(PolylineCollection* retval, bool no_reverse = false) const; void chained_path_from(Point start_near, PolylineCollection* retval, bool no_reverse = false) const; Point leftmost_point() const; + void append(const Polylines &polylines); }; } diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 9c8c1738f..c88dbbda9 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -135,6 +135,7 @@ class PrintObject bool invalidate_all_steps(); bool has_support_material() const; + void process_external_surfaces(); void bridge_over_infill(); private: diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 7c184c258..a405e320d 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -340,14 +340,32 @@ PrintObject::has_support_material() const || this->config.support_material_enforce_layers > 0; } +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); + } + } +} + +/* This method applies bridge flow to the first internal solid layer above + sparse infill */ void PrintObject::bridge_over_infill() { FOREACH_REGION(this->_print, region) { size_t region_id = region - this->_print->regions.begin(); - double fill_density = (*region)->config.fill_density.value; - if (fill_density == 100) continue; + // skip bridging in case there are no voids + if ((*region)->config.fill_density.value == 100) continue; // get bridge flow Flow bridge_flow = (*region)->flow( @@ -360,6 +378,7 @@ PrintObject::bridge_over_infill() ); FOREACH_LAYER(this, layer_it) { + // skip first layer if (layer_it == this->layers.begin()) continue; Layer* layer = *layer_it; @@ -379,7 +398,7 @@ PrintObject::bridge_over_infill() // iterate through lower layers spanned by bridge_flow double bottom_z = layer->print_z - bridge_flow.height; for (int i = (layer_it - this->layers.begin()) - 1; i >= 0; --i) { - Layer* lower_layer = this->layers[i]; + const Layer* lower_layer = this->layers[i]; // stop iterating if layer is lower than bottom_z if (lower_layer->print_z < bottom_z) break; @@ -390,19 +409,19 @@ PrintObject::bridge_over_infill() (*lower_layerm_it)->fill_surfaces.filter_by_type(stInternal, &lower_internal); // intersect such lower internal surfaces with the candidate solid surfaces - intersection(to_bridge_pp, lower_internal, &to_bridge_pp); + to_bridge_pp = intersection(to_bridge_pp, lower_internal); } // there's no point in bridging too thin/short regions { double min_width = bridge_flow.scaled_width() * 3; - offset2(to_bridge_pp, &to_bridge_pp, -min_width, +min_width); + to_bridge_pp = offset2(to_bridge_pp, -min_width, +min_width); } if (to_bridge_pp.empty()) continue; // convert into ExPolygons - union_(to_bridge_pp, &to_bridge); + to_bridge = union_ex(to_bridge_pp); } #ifdef SLIC3R_DEBUG @@ -410,8 +429,7 @@ PrintObject::bridge_over_infill() #endif // compute the remaning internal solid surfaces as difference - ExPolygons not_to_bridge; - diff(internal_solid, to_bridge, ¬_to_bridge, true); + ExPolygons not_to_bridge = diff_ex(internal_solid, to_bridge, true); // build the new collection of fill_surfaces { diff --git a/xs/src/libslic3r/Surface.cpp b/xs/src/libslic3r/Surface.cpp index e4625f799..e7d66c17b 100644 --- a/xs/src/libslic3r/Surface.cpp +++ b/xs/src/libslic3r/Surface.cpp @@ -2,6 +2,11 @@ namespace Slic3r { +Surface::operator Polygons() const +{ + return this->expolygon; +} + double Surface::area() const { diff --git a/xs/src/libslic3r/Surface.hpp b/xs/src/libslic3r/Surface.hpp index 28a90799a..a4a28a2c3 100644 --- a/xs/src/libslic3r/Surface.hpp +++ b/xs/src/libslic3r/Surface.hpp @@ -21,6 +21,7 @@ class Surface : surface_type(_surface_type), expolygon(_expolygon), thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0) {}; + operator Polygons() const; double area() const; bool is_solid() const; bool is_external() const; diff --git a/xs/src/libslic3r/SurfaceCollection.cpp b/xs/src/libslic3r/SurfaceCollection.cpp index 38c77ffd6..2e96d4b1e 100644 --- a/xs/src/libslic3r/SurfaceCollection.cpp +++ b/xs/src/libslic3r/SurfaceCollection.cpp @@ -111,6 +111,12 @@ SurfaceCollection::filter_by_type(SurfaceType type, Polygons* polygons) } } +void +SurfaceCollection::append(const SurfaceCollection &coll) +{ + this->surfaces.insert(this->surfaces.end(), coll.surfaces.begin(), coll.surfaces.end()); +} + #ifdef SLIC3RXS REGISTER_CLASS(SurfaceCollection, "Surface::Collection"); #endif diff --git a/xs/src/libslic3r/SurfaceCollection.hpp b/xs/src/libslic3r/SurfaceCollection.hpp index e2ced7f0e..40e36c5f0 100644 --- a/xs/src/libslic3r/SurfaceCollection.hpp +++ b/xs/src/libslic3r/SurfaceCollection.hpp @@ -11,6 +11,9 @@ class SurfaceCollection public: Surfaces surfaces; + SurfaceCollection() {}; + SurfaceCollection(const Surfaces &_surfaces) + : surfaces(_surfaces) {}; operator Polygons() const; operator ExPolygons() const; void simplify(double tolerance); @@ -19,6 +22,7 @@ class SurfaceCollection template bool any_bottom_contains(const T &item) const; SurfacesPtr filter_by_type(SurfaceType type); void filter_by_type(SurfaceType type, Polygons* polygons); + void append(const SurfaceCollection &coll); }; } diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index 87d98caf1..67ff6979c 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -16,6 +16,7 @@ #define LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER 0.15 #define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI #define INSET_OVERLAP_TOLERANCE 0.4 +#define EXTERNAL_INFILL_MARGIN 3 #define scale_(val) (val / SCALING_FACTOR) #define unscale(val) (val * SCALING_FACTOR) #define SCALED_EPSILON scale_(EPSILON) -- cgit v1.2.3