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

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xs/src/libslic3r/Fill/FillBase.cpp4
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear2.cpp87
-rw-r--r--xs/src/libslic3r/PrintObject.cpp10
-rw-r--r--xs/src/libslic3r/Surface.hpp9
4 files changed, 97 insertions, 13 deletions
diff --git a/xs/src/libslic3r/Fill/FillBase.cpp b/xs/src/libslic3r/Fill/FillBase.cpp
index 6cd508acb..d19615aa9 100644
--- a/xs/src/libslic3r/Fill/FillBase.cpp
+++ b/xs/src/libslic3r/Fill/FillBase.cpp
@@ -69,10 +69,10 @@ coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
assert(width >= 0);
assert(distance > 0);
// floor(width / distance)
- coord_t number_of_intervals = width / distance;
+ coord_t number_of_intervals = (width - EPSILON) / distance;
coord_t distance_new = (number_of_intervals == 0) ?
distance :
- (width / number_of_intervals);
+ ((width - EPSILON) / number_of_intervals);
const coordf_t factor = coordf_t(distance_new) / coordf_t(distance);
assert(factor > 1. - 1e-5);
// How much could the extrusion width be increased? By 20%.
diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.cpp b/xs/src/libslic3r/Fill/FillRectilinear2.cpp
index 20709cbde..766f389b0 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear2.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear2.cpp
@@ -768,6 +768,74 @@ static inline void emit_perimeter_segment_on_vertical_line(
out.points.push_back(Point(il.pos, itsct2.pos()));
}
+//TBD: For precise infill, measure the area of a slab spanned by an infill line.
+/*
+static inline float measure_outer_contour_slab(
+ const ExPolygonWithOffset &poly_with_offset,
+ const std::vector<SegmentedIntersectionLine> &segs,
+ size_t i_vline,
+ size_t iIntersection)
+{
+ const SegmentedIntersectionLine &il = segs[i_vline];
+ const SegmentIntersection &itsct = il.intersections[i_vline];
+ const SegmentIntersection &itsct2 = il.intersections[iIntersection2];
+ const Polygon &poly = poly_with_offset.contour((itsct.iContour);
+ myassert(itsct.is_outer());
+ myassert(itsct2.is_outer());
+ myassert(itsct.type != itsct2.type);
+ myassert(itsct.iContour == itsct2.iContour);
+ if (! itsct.is_outer() || ! itsct2.is_outer() || itsct.type == itsct2.type || itsct.iContour != itsct2.iContour)
+ // Error, return zero area.
+ return 0.f;
+
+ // Find possible connection points on the previous / next vertical line.
+ int iPrev = intersection_on_prev_vertical_line(poly_with_offset, segs, i_vline, itsct.iContour, i_intersection);
+ int iNext = intersection_on_next_vertical_line(poly_with_offset, segs, i_vline, itsct.iContour, i_intersection);
+ // Find possible connection points on the same vertical line.
+ int iAbove = iBelow = -1;
+ // Does the perimeter intersect the current vertical line above intrsctn?
+ for (size_t i = i_intersection + 1; i + 1 < seg.intersections.size(); ++ i)
+ if (seg.intersections[i].iContour == itsct.iContour)
+ { iAbove = i; break; }
+ // Does the perimeter intersect the current vertical line below intrsctn?
+ for (int i = int(i_intersection) - 1; i > 0; -- i)
+ if (seg.intersections[i].iContour == itsct.iContour)
+ { iBelow = i; break; }
+
+ if (iSegAbove != -1 && seg.intersections[iAbove].type == SegmentIntersection::OUTER_HIGH) {
+ // Invalidate iPrev resp. iNext, if the perimeter crosses the current vertical line earlier than iPrev resp. iNext.
+ // The perimeter contour orientation.
+ const Polygon &poly = poly_with_offset.contour(itsct.iContour);
+ {
+ int d_horiz = (iPrev == -1) ? std::numeric_limits<int>::max() :
+ distance_of_segmens(poly, segs[i_vline-1].intersections[iPrev].iSegment, itsct.iSegment, true);
+ int d_down = (iBelow == -1) ? std::numeric_limits<int>::max() :
+ distance_of_segmens(poly, iSegBelow, itsct.iSegment, true);
+ int d_up = (iAbove == -1) ? std::numeric_limits<int>::max() :
+ distance_of_segmens(poly, iSegAbove, itsct.iSegment, true);
+ if (intrsctn_type_prev == INTERSECTION_TYPE_OTHER_VLINE_OK && d_horiz > std::min(d_down, d_up))
+ // The vertical crossing comes eralier than the prev crossing.
+ // Disable the perimeter going back.
+ intrsctn_type_prev = INTERSECTION_TYPE_OTHER_VLINE_NOT_FIRST;
+ if (d_up > std::min(d_horiz, d_down))
+ // The horizontal crossing comes earlier than the vertical crossing.
+ vert_seg_dir_valid_mask &= ~DIR_BACKWARD;
+ }
+ {
+ int d_horiz = (iNext == -1) ? std::numeric_limits<int>::max() :
+ distance_of_segmens(poly, itsct.iSegment, segs[i_vline+1].intersections[iNext].iSegment, true);
+ int d_down = (iSegBelow == -1) ? std::numeric_limits<int>::max() :
+ distance_of_segmens(poly, itsct.iSegment, iSegBelow, true);
+ int d_up = (iSegAbove == -1) ? std::numeric_limits<int>::max() :
+ distance_of_segmens(poly, itsct.iSegment, iSegAbove, true);
+ if (d_up > std::min(d_horiz, d_down))
+ // The horizontal crossing comes earlier than the vertical crossing.
+ vert_seg_dir_valid_mask &= ~DIR_FORWARD;
+ }
+ }
+}
+*/
+
enum DirectionMask
{
DIR_FORWARD = 1,
@@ -826,7 +894,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// Intersect a set of euqally spaced vertical lines wiht expolygon.
// n_vlines = ceil(bbox_width / line_spacing)
size_t n_vlines = (bounding_box.max.x - bounding_box.min.x + line_spacing - 1) / line_spacing;
- coord_t x0 = bounding_box.min.x + line_spacing / 2;
+ coord_t x0 = bounding_box.min.x + (line_spacing + SCALED_EPSILON) / 2;
#ifdef SLIC3R_DEBUG
static int iRun = 0;
@@ -1111,13 +1179,20 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
svg.Close();
#endif /* SLIC3R_DEBUG */
- // Mark an outer only chord as consumed, so there will be no tiny pieces emitted.
+ // For each outer only chords, measure their maximum distance to the bow of the outer contour.
+ // Mark an outer only chord as consumed, if the distance is low.
for (size_t i_vline = 0; i_vline < segs.size(); ++ i_vline) {
SegmentedIntersectionLine &seg = segs[i_vline];
- for (size_t i = 0; i + 1 < seg.intersections.size(); ++ i) {
- if (seg.intersections[i].type == SegmentIntersection::OUTER_LOW &&
- seg.intersections[i+1].type == SegmentIntersection::OUTER_HIGH)
- seg.intersections[i].consumed_vertical_up = true;
+ for (size_t i_intersection = 0; i_intersection + 1 < seg.intersections.size(); ++ i_intersection) {
+ if (seg.intersections[i_intersection].type == SegmentIntersection::OUTER_LOW &&
+ seg.intersections[i_intersection+1].type == SegmentIntersection::OUTER_HIGH) {
+ bool consumed = false;
+// if (full_infill) {
+// measure_outer_contour_slab(poly_with_offset, segs, i_vline, i_ntersection);
+// } else
+ consumed = true;
+ seg.intersections[i_intersection].consumed_vertical_up = consumed;
+ }
}
}
diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp
index 64a46c06c..f19caadc9 100644
--- a/xs/src/libslic3r/PrintObject.cpp
+++ b/xs/src/libslic3r/PrintObject.cpp
@@ -498,6 +498,7 @@ PrintObject::discover_vertical_shells()
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
ExPolygons shell_ex;
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
+ float min_perimeter_infill_spacing = float(infill_line_spacing) * 1.05f;
if (1)
{
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
@@ -531,13 +532,13 @@ PrintObject::discover_vertical_shells()
polygons_append(shell, neighbor_layer.perimeter_expolygons.expolygons);
if (n > int(idx_layer)) {
// Collect top surfaces.
- polygons_append(shell, to_polygons(neighbor_region.slices.filter_by_type(stTop)));
- polygons_append(shell, to_polygons(neighbor_region.fill_surfaces.filter_by_type(stTop)));
+ polygons_append(shell, offset(to_expolygons(neighbor_region.slices.filter_by_type(stTop)), min_perimeter_infill_spacing));
+ polygons_append(shell, offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_type(stTop)), min_perimeter_infill_spacing));
}
else if (n < int(idx_layer)) {
// Collect bottom and bottom bridge surfaces.
- polygons_append(shell, to_polygons(neighbor_region.slices.filter_by_types(surfaces_bottom, 2)));
- polygons_append(shell, to_polygons(neighbor_region.fill_surfaces.filter_by_types(surfaces_bottom, 2)));
+ polygons_append(shell, offset(to_expolygons(neighbor_region.slices.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
+ polygons_append(shell, offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
}
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
@@ -615,7 +616,6 @@ PrintObject::discover_vertical_shells()
Polygons shell_before = shell;
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
#if 1
- float min_perimeter_infill_spacing = float(infill_line_spacing) * 1.05f;
// Intentionally inflate a bit more than how much the region has been shrunk,
// so there will be some overlap between this solid infill and the other infill regions (mainly the sparse infill).
shell = offset2(shell, - 0.5f * min_perimeter_infill_spacing, 0.8f * min_perimeter_infill_spacing,
diff --git a/xs/src/libslic3r/Surface.hpp b/xs/src/libslic3r/Surface.hpp
index 9ef710741..d87c9b695 100644
--- a/xs/src/libslic3r/Surface.hpp
+++ b/xs/src/libslic3r/Surface.hpp
@@ -97,6 +97,15 @@ inline Polygons to_polygons(const SurfacesPtr &src)
return polygons;
}
+inline ExPolygons to_expolygons(const SurfacesPtr &src)
+{
+ ExPolygons expolygons;
+ expolygons.reserve(src.size());
+ for (SurfacesPtr::const_iterator it = src.begin(); it != src.end(); ++it)
+ expolygons.push_back((*it)->expolygon);
+ return expolygons;
+}
+
// Count a nuber of polygons stored inside the vector of expolygons.
// Useful for allocating space for polygons when converting expolygons to polygons.
inline size_t number_polygons(const Surfaces &surfaces)