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:
Diffstat (limited to 'xs/src/libslic3r/LayerRegion.cpp')
-rw-r--r--xs/src/libslic3r/LayerRegion.cpp148
1 files changed, 148 insertions, 0 deletions
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