diff options
author | bubnikv <bubnikv@gmail.com> | 2016-11-11 13:13:36 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2016-11-11 13:13:36 +0300 |
commit | c2d5b32ee20489c1da9141ebee63003b1f3ba723 (patch) | |
tree | 03d94885f29686825e109062130bea58c2ec1864 | |
parent | 4460b5ce50c7160cd922972a190c27bf4381ffbd (diff) |
Changed the logic of the "ensure vertical wall thickness" feature
slightly by inflating the projected top/bottom/bottom bridge surfaces
before they are added into a surface. This ensures, that the possible
projected infill areas merge with the perimeter supporting areas,
but the perimeter supporting areas will not be inflated on their own,
if there is no touching projection of a top/bottom/bottom bridge
surface.
-rw-r--r-- | xs/src/libslic3r/Fill/FillBase.cpp | 4 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillRectilinear2.cpp | 87 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintObject.cpp | 10 | ||||
-rw-r--r-- | xs/src/libslic3r/Surface.hpp | 9 |
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) |