Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Ranellucci <aar@cpan.org>2015-10-27 01:23:03 +0300
committerAlessandro Ranellucci <aar@cpan.org>2015-10-27 01:24:46 +0300
commit9fcec107373b6846f3775fe353c7ae29653cf9ac (patch)
tree745479a8dfd50c9f2d4ccbae9b886ab064710821 /xs/src/libslic3r
parent5b8ed7367a2a9148c215eafa53c7e13b30cd0c36 (diff)
Finished porting LayerRegion to C++
Diffstat (limited to 'xs/src/libslic3r')
-rw-r--r--xs/src/libslic3r/BridgeDetector.cpp36
-rw-r--r--xs/src/libslic3r/BridgeDetector.hpp4
-rw-r--r--xs/src/libslic3r/ClipperUtils.cpp22
-rw-r--r--xs/src/libslic3r/ClipperUtils.hpp8
-rw-r--r--xs/src/libslic3r/ExPolygonCollection.cpp6
-rw-r--r--xs/src/libslic3r/ExPolygonCollection.hpp1
-rw-r--r--xs/src/libslic3r/Layer.hpp5
-rw-r--r--xs/src/libslic3r/LayerRegion.cpp148
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.cpp24
-rw-r--r--xs/src/libslic3r/PolylineCollection.cpp6
-rw-r--r--xs/src/libslic3r/PolylineCollection.hpp1
-rw-r--r--xs/src/libslic3r/Print.hpp1
-rw-r--r--xs/src/libslic3r/PrintObject.cpp34
-rw-r--r--xs/src/libslic3r/Surface.cpp5
-rw-r--r--xs/src/libslic3r/Surface.hpp1
-rw-r--r--xs/src/libslic3r/SurfaceCollection.cpp6
-rw-r--r--xs/src/libslic3r/SurfaceCollection.hpp4
-rw-r--r--xs/src/libslic3r/libslic3r.h1
18 files changed, 273 insertions, 40 deletions
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
@@ -186,15 +186,11 @@ BridgeDetector::detect_angle()
}
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 <class SubjectType, class ClipType>
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<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_);
+template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_);
template <class SubjectType, class ResultType>
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 <class SubjectType>
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 <class SubjectType, class ResultType>
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 <class SubjectType, class ClipType>
+Slic3r::ExPolygons diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_ = false);
template <class SubjectType, class ResultType>
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 <class SubjectType>
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"
@@ -87,6 +88,146 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection*
}
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<SurfacesPtr> groups;
+ tb.group(&groups);
+
+ for (std::vector<SurfacesPtr>::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<SurfacesPtr> groups;
+ other.group(&groups);
+
+ for (std::vector<SurfacesPtr>::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()
{
/* Note: in order to make the psPrepareInfill step idempotent, we should never
@@ -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
@@ -341,13 +341,31 @@ PrintObject::has_support_material() const
}
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, &not_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 <class T> 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)