OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::Arachne::WallToolPaths Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Arachne/WallToolPaths.hpp>

Collaboration diagram for Slic3r::Arachne::WallToolPaths:

Public Types

using ExtrusionLineSet = ankerl::unordered_dense::set<std::pair<const ExtrusionLine *, const ExtrusionLine *>, boost::hash<std::pair<const ExtrusionLine *, const ExtrusionLine *>>>

Public Member Functions

 WallToolPaths (const Polygons &outline, coord_t bead_width_0, coord_t bead_width_x, size_t inset_count, coord_t wall_0_inset, coordf_t layer_height, const WallToolPathsParams &params)
const std::vector< VariableWidthLines > & generate ()
const std::vector< VariableWidthLines > & getToolPaths ()
void separateOutInnerContour ()
const Polygons & getInnerContour ()

Static Public Member Functions

static bool removeEmptyToolPaths (std::vector< VariableWidthLines > &toolpaths)
static ExtrusionLineSet getRegionOrder (const std::vector< ExtrusionLine * > &input, bool outer_to_inner)

Protected Member Functions

void removeSmallLines (std::vector< VariableWidthLines > &toolpaths)

Static Protected Member Functions

static void stitchToolPaths (std::vector< VariableWidthLines > &toolpaths, coord_t bead_width_x)
static void simplifyToolPaths (std::vector< VariableWidthLines > &toolpaths, const WallToolPathsParams &params)

Private Attributes

const Polygons & outline
coord_t bead_width_0
coord_t bead_width_x
size_t inset_count
coord_t wall_0_inset
coordf_t layer_height
bool print_thin_walls
coord_t min_feature_size
coord_t min_bead_width
double small_area_length
coord_t wall_transition_filter_deviation
 The allowed line width deviation induced by filtering.
bool toolpaths_generated
std::vector< VariableWidthLines > toolpaths
Polygons inner_contour
const WallToolPathsParams m_params

Detailed Description

Member Typedef Documentation

◆ ExtrusionLineSet

using Slic3r::Arachne::WallToolPaths::ExtrusionLineSet = ankerl::unordered_dense::set<std::pair<const ExtrusionLine *, const ExtrusionLine *>, boost::hash<std::pair<const ExtrusionLine *, const ExtrusionLine *>>>

Constructor & Destructor Documentation

◆ WallToolPaths()

Slic3r::Arachne::WallToolPaths::WallToolPaths ( const Polygons & outline,
coord_t bead_width_0,
coord_t bead_width_x,
size_t inset_count,
coord_t wall_0_inset,
coordf_t layer_height,
const WallToolPathsParams & params )

A class that creates the toolpaths given an outline, nominal bead width and maximum amount of walls

Parameters
outlineAn outline of the area in which the ToolPaths are to be generated
bead_width_0The bead width of the first wall used in the generation of the toolpaths
bead_width_xThe bead width of the inner walls used in the generation of the toolpaths
inset_countThe maximum number of parallel extrusion lines that make up the wall
wall_0_insetHow far to inset the outer wall, to make it adhere better to other walls.
98 , min_feature_size(scaled<coord_t>(params.min_feature_size))
99 , min_bead_width(scaled<coord_t>(params.min_bead_width))
100 , small_area_length(static_cast<double>(bead_width_0) / 2.)
101 , wall_transition_filter_deviation(scaled<coord_t>(params.wall_transition_filter_deviation))
102 , toolpaths_generated(false)
103 , m_params(params)
104{
105}
const Polygons & outline
Definition WallToolPaths.hpp:134
coord_t min_feature_size
Definition WallToolPaths.hpp:141
coord_t bead_width_x
Definition WallToolPaths.hpp:136
coord_t bead_width_0
Definition WallToolPaths.hpp:135
size_t inset_count
Definition WallToolPaths.hpp:137
coordf_t layer_height
Definition WallToolPaths.hpp:139
coord_t min_bead_width
Definition WallToolPaths.hpp:142
coord_t wall_transition_filter_deviation
The allowed line width deviation induced by filtering.
Definition WallToolPaths.hpp:144
coord_t wall_0_inset
Definition WallToolPaths.hpp:138
bool print_thin_walls
Definition WallToolPaths.hpp:140
double small_area_length
Definition WallToolPaths.hpp:143
const WallToolPathsParams m_params
Definition WallToolPaths.hpp:148
bool toolpaths_generated
Definition WallToolPaths.hpp:145
constexpr bool fill_outline_gaps
Definition WallToolPaths.hpp:23
BoundingBox scaled(const BoundingBoxf &bb)
Definition BoundingBox.hpp:284

References bead_width_0, bead_width_x, Slic3r::Arachne::fill_outline_gaps, inset_count, layer_height, m_params, min_bead_width, min_feature_size, outline, print_thin_walls, Slic3r::scaled(), small_area_length, toolpaths_generated, wall_0_inset, and wall_transition_filter_deviation.

Here is the call graph for this function:

Member Function Documentation

◆ generate()

const std::vector< VariableWidthLines > & Slic3r::Arachne::WallToolPaths::generate ( )

Generates the Toolpaths

Returns
A reference to the newly create ToolPaths
493{
494 if (this->inset_count < 1)
495 return toolpaths;
496
497 const coord_t smallest_segment = m_params.wall_maximum_resolution;
498 const coord_t allowed_distance = m_params.wall_maximum_deviation;
499 const coord_t epsilon_offset = (allowed_distance / 2) - 1;
500 const double transitioning_angle = Geometry::deg2rad(m_params.wall_transition_angle);
501 const coord_t discretization_step_size = scaled<coord_t>(0.8);
502
503 // Simplify outline for boost::voronoi consumption. Absolutely no self intersections or near-self intersections allowed:
504 // TODO: Open question: Does this indeed fix all (or all-but-one-in-a-million) cases for manifold but otherwise possibly complex polygons?
505 Polygons prepared_outline = offset(offset(offset(outline, -epsilon_offset), epsilon_offset * 2), -epsilon_offset);
506 simplify(prepared_outline, smallest_segment, allowed_distance);
507 fixSelfIntersections(epsilon_offset, prepared_outline);
508 removeDegenerateVerts(prepared_outline);
509 removeColinearEdges(prepared_outline, 0.005);
510 // Removing collinear edges may introduce self intersections, so we need to fix them again
511 fixSelfIntersections(epsilon_offset, prepared_outline);
512 removeDegenerateVerts(prepared_outline);
513 removeSmallAreas(prepared_outline, small_area_length * small_area_length, false);
514
515 // The functions above could produce intersecting polygons that could cause a crash inside Arachne.
516 // Applying Clipper union should be enough to get rid of this issue.
517 // Clipper union also fixed an issue in Arachne that in post-processing Voronoi diagram, some edges
518 // didn't have twin edges. (a non-planar Voronoi diagram probably caused this).
519 prepared_outline = union_(prepared_outline);
520
521 if (area(prepared_outline) <= 0) {
522 assert(toolpaths.empty());
523 return toolpaths;
524 }
525
526 const float external_perimeter_extrusion_width = Flow::rounded_rectangle_extrusion_width_from_spacing(unscale<float>(bead_width_0), float(this->layer_height));
527 const float perimeter_extrusion_width = Flow::rounded_rectangle_extrusion_width_from_spacing(unscale<float>(bead_width_x), float(this->layer_height));
528
529 const coord_t wall_transition_length = scaled<coord_t>(this->m_params.wall_transition_length);
530
531 const double wall_split_middle_threshold = std::clamp(2. * unscaled<double>(this->min_bead_width) / external_perimeter_extrusion_width - 1., 0.01, 0.99); // For an uneven nr. of lines: When to split the middle wall into two.
532 const double wall_add_middle_threshold = std::clamp(unscaled<double>(this->min_bead_width) / perimeter_extrusion_width, 0.01, 0.99); // For an even nr. of lines: When to add a new middle in between the innermost two walls.
533
534 const int wall_distribution_count = this->m_params.wall_distribution_count;
535 const size_t max_bead_count = (inset_count < std::numeric_limits<coord_t>::max() / 2) ? 2 * inset_count : std::numeric_limits<coord_t>::max();
536 const auto beading_strat = BeadingStrategyFactory::makeStrategy
537 (
540 wall_transition_length,
541 transitioning_angle,
545 wall_split_middle_threshold,
546 wall_add_middle_threshold,
547 max_bead_count,
549 wall_distribution_count
550 );
551 const coord_t transition_filter_dist = scaled<coord_t>(100.f);
552 const coord_t allowed_filter_deviation = wall_transition_filter_deviation;
553 SkeletalTrapezoidation wall_maker
554 (
555 prepared_outline,
556 *beading_strat,
557 beading_strat->getTransitioningAngle(),
558 discretization_step_size,
559 transition_filter_dist,
560 allowed_filter_deviation,
561 wall_transition_length
562 );
563 wall_maker.generateToolpaths(toolpaths);
564
566
568
570
572
574 assert(std::is_sorted(toolpaths.cbegin(), toolpaths.cend(),
575 [](const VariableWidthLines& l, const VariableWidthLines& r)
576 {
577 return l.front().inset_idx < r.front().inset_idx;
578 }) && "WallToolPaths should be sorted from the outer 0th to inner_walls");
579 toolpaths_generated = true;
580 return toolpaths;
581}
static BeadingStrategyPtr makeStrategy(coord_t preferred_bead_width_outer=scaled< coord_t >(0.0005), coord_t preferred_bead_width_inner=scaled< coord_t >(0.0005), coord_t preferred_transition_length=scaled< coord_t >(0.0004), float transitioning_angle=M_PI/4.0, bool print_thin_walls=false, coord_t min_bead_width=0, coord_t min_feature_size=0, double wall_split_middle_threshold=0.5, double wall_add_middle_threshold=0.5, coord_t max_bead_count=0, coord_t outer_wall_offset=0, int inward_distributed_center_wall_count=2, double minimum_variable_line_width=0.5)
Definition BeadingStrategyFactory.cpp:20
static bool removeEmptyToolPaths(std::vector< VariableWidthLines > &toolpaths)
Definition WallToolPaths.cpp:802
static void stitchToolPaths(std::vector< VariableWidthLines > &toolpaths, coord_t bead_width_x)
Definition WallToolPaths.cpp:583
std::vector< VariableWidthLines > toolpaths
Definition WallToolPaths.hpp:146
void separateOutInnerContour()
Definition WallToolPaths.cpp:738
static void simplifyToolPaths(std::vector< VariableWidthLines > &toolpaths, const WallToolPathsParams &params)
Definition WallToolPaths.cpp:712
void removeSmallLines(std::vector< VariableWidthLines > &toolpaths)
Definition WallToolPaths.cpp:694
static float rounded_rectangle_extrusion_width_from_spacing(float spacing, float height)
Definition Flow.cpp:215
int64_t coord_t
Definition libslic3r.h:48
void removeSmallAreas(Polygons &thiss, const double min_area_size, const bool remove_holes)
Definition WallToolPaths.cpp:370
void removeDegenerateVerts(Polygons &thiss)
Definition WallToolPaths.cpp:331
void fixSelfIntersections(const coord_t epsilon, Polygons &thiss)
Definition WallToolPaths.cpp:285
std::vector< ExtrusionLine > VariableWidthLines
Definition ExtrusionLine.hpp:290
void removeColinearEdges(Polygon &poly, const double max_deviation_angle)
Definition WallToolPaths.cpp:417
void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const int64_t allowed_error_distance_squared)
Definition WallToolPaths.cpp:107
constexpr T deg2rad(const T angle)
Definition Geometry.hpp:312
Slic3r::Polygons union_(const Slic3r::Polygons &subject)
Definition ClipperUtils.cpp:801
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:511
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582
constexpr Eigen::Matrix< Tout, 2, EigenArgs... > unscaled(const Slic3r::Point &v) noexcept
Definition Arrange.cpp:81
T unscale(Q v)
Definition libslic3r.h:138

References Slic3r::area(), bead_width_0, bead_width_x, Slic3r::Geometry::deg2rad(), Slic3r::Arachne::fixSelfIntersections(), Slic3r::Arachne::SkeletalTrapezoidation::generateToolpaths(), inset_count, layer_height, m_params, Slic3r::Arachne::BeadingStrategyFactory::makeStrategy(), min_bead_width, min_feature_size, Slic3r::offset(), outline, print_thin_walls, Slic3r::Arachne::removeColinearEdges(), Slic3r::Arachne::removeDegenerateVerts(), removeEmptyToolPaths(), Slic3r::Arachne::removeSmallAreas(), removeSmallLines(), Slic3r::Flow::rounded_rectangle_extrusion_width_from_spacing(), Slic3r::scaled(), separateOutInnerContour(), Slic3r::Arachne::simplify(), simplifyToolPaths(), small_area_length, stitchToolPaths(), toolpaths, toolpaths_generated, Slic3r::union_(), Slic3r::unscale(), Slic3r::unscaled(), wall_0_inset, and wall_transition_filter_deviation.

Referenced by getInnerContour(), and getToolPaths().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInnerContour()

const Polygons & Slic3r::Arachne::WallToolPaths::getInnerContour ( )

Gets the inner contour of the area which is inside of the generated tool paths.

If the walls haven't been generated yet, this will lazily call the generate() function to generate the walls with variable width. The resulting polygon will snugly match the inside of the variable-width walls where the walls get limited by the LimitedBeadingStrategy to a maximum wall count. If there are no walls, the outline will be returned.

Returns
The inner contour of the generated walls.
790{
792 {
793 generate();
794 }
795 else if(inset_count == 0)
796 {
797 return outline;
798 }
799 return inner_contour;
800}
Polygons inner_contour
Definition WallToolPaths.hpp:147
const std::vector< VariableWidthLines > & generate()
Definition WallToolPaths.cpp:492

References generate(), inner_contour, inset_count, outline, and toolpaths_generated.

Here is the call graph for this function:

◆ getRegionOrder()

WallToolPaths::ExtrusionLineSet Slic3r::Arachne::WallToolPaths::getRegionOrder ( const std::vector< ExtrusionLine * > & input,
bool outer_to_inner )
static

Get the order constraints of the insets when printing walls per region / hole. Each returned pair consists of adjacent wall lines where the left has an inset_idx one lower than the right.

Odd walls should always go after their enclosing wall polygons.

Parameters
outer_to_innerWhether the wall polygons with a lower inset_idx should go before those with a higher one.

Get the order constraints of the insets when printing walls per region / hole. Each returned pair consists of adjacent wall lines where the left has an inset_idx one lower than the right.

Odd walls follow the same order as even ones, so that the centre line of a narrow wall is an inner wall like any other when printing inner to outer.

Parameters
outer_to_innerWhether the wall polygons with a lower inset_idx should go before those with a higher one.
821{
822 ExtrusionLineSet order_requirements;
823 // We build a grid where we map toolpath vertex locations to toolpaths,
824 // so that we can easily find which two toolpaths are next to each other,
825 // which is the requirement for there to be an order constraint.
826 //
827 // We use a PointGrid rather than a LineGrid to save on computation time.
828 // In very rare cases two insets might lie next to each other without having neighboring vertices, e.g.
829 // \ .
830 // | / .
831 // | / .
832 // || .
833 // | \ .
834 // | \ .
835 // / .
836 // However, because of how Arachne works this will likely never be the case for two consecutive insets.
837 // On the other hand one could imagine that two consecutive insets of a very large circle
838 // could be simplify()ed such that the remaining vertices of the two insets don't align.
839 // In those cases the order requirement is not captured,
840 // which means that the PathOrderOptimizer *might* result in a violation of the user set path order.
841 // This problem is expected to be not so severe and happen very sparsely.
842
843 coord_t max_line_w = 0u;
844 for (const ExtrusionLine *line : input) // compute max_line_w
845 for (const ExtrusionJunction &junction : *line)
846 max_line_w = std::max(max_line_w, junction.w);
847 if (max_line_w == 0u)
848 return order_requirements;
849
850 struct LineLoc
851 {
852 ExtrusionJunction j;
853 const ExtrusionLine *line;
854 };
855 struct Locator
856 {
857 Point operator()(const LineLoc &elem) { return elem.j.p; }
858 };
859
860 // How much farther two verts may be apart due to corners.
861 // This distance must be smaller than 2, because otherwise
862 // we could create an order requirement between e.g.
863 // wall 2 of one region and wall 3 of another region,
864 // while another wall 3 of the first region would lie in between those two walls.
865 // However, higher values are better against the limitations of using a PointGrid rather than a LineGrid.
866 constexpr float diagonal_extension = 1.9f;
867 const auto searching_radius = coord_t(max_line_w * diagonal_extension);
868 using GridT = SparsePointGrid<LineLoc, Locator>;
869 GridT grid(searching_radius);
870
871 for (const ExtrusionLine *line : input)
872 for (const ExtrusionJunction &junction : *line) grid.insert(LineLoc{junction, line});
873 for (const std::pair<const SquareGrid::GridPoint, LineLoc> &pair : grid) {
874 const LineLoc &lineloc_here = pair.second;
875 const ExtrusionLine *here = lineloc_here.line;
876 Point loc_here = pair.second.j.p;
877 std::vector<LineLoc> nearby_verts = grid.getNearby(loc_here, searching_radius);
878 for (const LineLoc &lineloc_nearby : nearby_verts) {
879 const ExtrusionLine *nearby = lineloc_nearby.line;
880 if (nearby == here)
881 continue;
882 if (nearby->inset_idx == here->inset_idx)
883 continue;
884 if (nearby->inset_idx > here->inset_idx + 1)
885 continue; // not directly adjacent
886 if (here->inset_idx > nearby->inset_idx + 1)
887 continue; // not directly adjacent
888 if (!shorter_then(loc_here - lineloc_nearby.j.p, (lineloc_here.j.w + lineloc_nearby.j.w) / 2 * diagonal_extension))
889 continue; // points are too far away from each other
890 if ((nearby->inset_idx < here->inset_idx) == outer_to_inner) {
891 order_requirements.emplace(std::make_pair(nearby, here));
892 } else {
893 assert((nearby->inset_idx > here->inset_idx) == outer_to_inner);
894 order_requirements.emplace(std::make_pair(here, nearby));
895 }
896 }
897 }
898 return order_requirements;
899}
ankerl::unordered_dense::set< std::pair< const ExtrusionLine *, const ExtrusionLine * >, boost::hash< std::pair< const ExtrusionLine *, const ExtrusionLine * > > > ExtrusionLineSet
Definition WallToolPaths.hpp:99
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
bool shorter_then(const Point &p0, const coord_t len)
Definition Point.hpp:486
std::vector< ArithmeticOnly< T > > grid(const T &start, const T &stop, const T &stride)
A set of equidistant values starting from 'start' (inclusive), ending in the closest multiple of 'str...
Definition MTUtils.hpp:127

References Slic3r::grid(), Slic3r::Arachne::ExtrusionLine::inset_idx, and Slic3r::shorter_then().

Here is the call graph for this function:

◆ getToolPaths()

const std::vector< VariableWidthLines > & Slic3r::Arachne::WallToolPaths::getToolPaths ( )

Gets the toolpaths, if this called before generate() it will first generate the Toolpaths

Returns
a reference to the toolpaths
732{
734 return generate();
735 return toolpaths;
736}

References generate(), toolpaths, and toolpaths_generated.

Referenced by Slic3r::FillConcentric::_fill_surface_single(), Slic3r::FillSpiralInset::_fill_surface_single(), and Slic3r::FillConcentricInternal::fill_surface_extrusion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ removeEmptyToolPaths()

bool Slic3r::Arachne::WallToolPaths::removeEmptyToolPaths ( std::vector< VariableWidthLines > & toolpaths)
static

Removes empty paths from the toolpaths

Parameters
toolpathsthe VariableWidthPaths generated with generate()
Returns
true if there are still paths left. If all toolpaths were removed it returns false
803{
804 toolpaths.erase(std::remove_if(toolpaths.begin(), toolpaths.end(), [](const VariableWidthLines& lines)
805 {
806 return lines.empty();
807 }), toolpaths.end());
808 return toolpaths.empty();
809}

References toolpaths.

Referenced by generate().

Here is the caller graph for this function:

◆ removeSmallLines()

void Slic3r::Arachne::WallToolPaths::removeSmallLines ( std::vector< VariableWidthLines > & toolpaths)
protected

Remove polylines shorter than half the smallest line width along that polyline.

695{
696 for (VariableWidthLines &inset : toolpaths) {
697 for (size_t line_idx = 0; line_idx < inset.size(); line_idx++) {
698 ExtrusionLine &line = inset[line_idx];
699 coord_t min_width = std::numeric_limits<coord_t>::max();
700 for (const ExtrusionJunction &j : line)
701 min_width = std::min(min_width, j.w);
702 // Only use min_length_factor for non-topmost, to prevent top gaps. Otherwise use default value.
703 if (line.is_odd && !line.is_closed && shorterThan(line, m_params.is_top_or_bottom_layer ? (min_width / 2) : (min_width * m_params.min_length_factor))) { // remove line
704 line = std::move(inset.back());
705 inset.erase(--inset.end());
706 line_idx--; // reconsider the current position
707 }
708 }
709 }
710}
PointType size() const
Definition BoundingBox.cpp:178
bool shorterThan(const T &shape, const coord_t check_length)
Definition WallToolPaths.cpp:681
BoundingBox inset(BoundingBox box, const Point &by)
Definition IMEXArrange.cpp:38

References Slic3r::Arachne::ExtrusionLine::is_closed, Slic3r::Arachne::ExtrusionLine::is_odd, m_params, Slic3r::Arachne::shorterThan(), Slic3r::BoundingBoxBase< PointType, APointsType >::size(), and toolpaths.

Referenced by generate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ separateOutInnerContour()

void Slic3r::Arachne::WallToolPaths::separateOutInnerContour ( )

Compute the inner contour of the walls. This contour indicates where the walled area ends and its infill begins. The inside can then be filled, e.g. with skin/infill for the walls of a part, or with a pattern in the case of infill with extra infill walls.

739{
740 //We'll remove all 0-width paths from the original toolpaths and store them separately as polygons.
741 std::vector<VariableWidthLines> actual_toolpaths;
742 actual_toolpaths.reserve(toolpaths.size()); //A bit too much, but the correct order of magnitude.
743 std::vector<VariableWidthLines> contour_paths;
744 contour_paths.reserve(toolpaths.size() / inset_count);
745 inner_contour.clear();
746 for (const VariableWidthLines &inset : toolpaths) {
747 if (inset.empty())
748 continue;
749 bool is_contour = false;
750 for (const ExtrusionLine &line : inset) {
751 for (const ExtrusionJunction &j : line) {
752 if (j.w == 0)
753 is_contour = true;
754 else
755 is_contour = false;
756 break;
757 }
758 }
759
760 if (is_contour) {
761#ifdef DEBUG
762 for (const ExtrusionLine &line : inset)
763 for (const ExtrusionJunction &j : line)
764 assert(j.w == 0);
765#endif // DEBUG
766 for (const ExtrusionLine &line : inset) {
767 if (line.is_odd)
768 continue; // odd lines don't contribute to the contour
769 else if (line.is_closed) // sometimes an very small even polygonal wall is not stitched into a polygon
770 inner_contour.emplace_back(line.toPolygon());
771 }
772 } else {
773 actual_toolpaths.emplace_back(inset);
774 }
775 }
776 if (!actual_toolpaths.empty())
777 toolpaths = std::move(actual_toolpaths); // Filtered out the 0-width paths.
778 else
779 toolpaths.clear();
780
781 //The output walls from the skeletal trapezoidation have no known winding order, especially if they are joined together from polylines.
782 //They can be in any direction, clockwise or counter-clockwise, regardless of whether the shapes are positive or negative.
783 //To get a correct shape, we need to make the outside contour positive and any holes inside negative.
784 //This can be done by applying the even-odd rule to the shape. This rule is not sensitive to the winding order of the polygon.
785 //The even-odd rule would be incorrect if the polygon self-intersects, but that should never be generated by the skeletal trapezoidation.
787}
@ pftEvenOdd
Definition ClipperUtils.hpp:23

References inner_contour, inset_count, Slic3r::pftEvenOdd, toolpaths, and Slic3r::union_().

Referenced by generate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ simplifyToolPaths()

void Slic3r::Arachne::WallToolPaths::simplifyToolPaths ( std::vector< VariableWidthLines > & toolpaths,
const WallToolPathsParams & params )
staticprotected

Simplifies the variable-width toolpaths by calling the simplify on every line in the toolpath using the provided settings.

Parameters
toolpathsThe toolpaths vector to simplify
paramsThe settings as provided by the user
Returns
713{
714 const int64_t maximum_resolution = params.wall_maximum_resolution;
715 const int64_t maximum_deviation = params.wall_maximum_deviation;
716
717 const int64_t smallest_line_segment_squared = maximum_resolution * maximum_resolution;
718 const int64_t allowed_error_distance_squared = maximum_deviation * maximum_deviation;
719
720 const int64_t maximum_extrusion_area_deviation = Slic3r::Arachne::meshfix_maximum_extrusion_area_deviation(); // unit: μm²
721
722 for (VariableWidthLines& lines : toolpaths)
723 {
724 for (ExtrusionLine& line : lines)
725 {
726 line.simplify(smallest_line_segment_squared, allowed_error_distance_squared, maximum_extrusion_area_deviation);
727 }
728 }
729}
coord_t meshfix_maximum_extrusion_area_deviation()
Definition WallToolPaths.hpp:26

References Slic3r::Arachne::meshfix_maximum_extrusion_area_deviation(), toolpaths, Slic3r::Arachne::WallToolPathsParams::wall_maximum_deviation, and Slic3r::Arachne::WallToolPathsParams::wall_maximum_resolution.

Referenced by generate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stitchToolPaths()

void Slic3r::Arachne::WallToolPaths::stitchToolPaths ( std::vector< VariableWidthLines > & toolpaths,
coord_t bead_width_x )
staticprotected

Stitch the polylines together and form closed polygons.

Works on both toolpaths and inner contours simultaneously.

584{
585 const coord_t stitch_distance = bead_width_x - 1; //In 0-width contours, junctions can cause up to 1-line-width gaps. Don't stitch more than 1 line width.
586
587 for (unsigned int wall_idx = 0; wall_idx < toolpaths.size(); wall_idx++) {
588 VariableWidthLines& wall_lines = toolpaths[wall_idx];
589
590 VariableWidthLines stitched_polylines;
591 VariableWidthLines closed_polygons;
592 PolylineStitcher<VariableWidthLines, ExtrusionLine, ExtrusionJunction>::stitch(wall_lines, stitched_polylines, closed_polygons, stitch_distance);
593#ifdef ARACHNE_STITCH_PATCH_DEBUG
594 for (const ExtrusionLine& line : stitched_polylines) {
595 if ( ! line.is_odd && line.polylineLength() > 3 * stitch_distance && line.size() > 3) {
596 BOOST_LOG_TRIVIAL(error) << "Some even contour lines could not be closed into polygons!";
597 assert(false && "Some even contour lines could not be closed into polygons!");
598 BoundingBox aabb;
599 for (auto line2 : wall_lines)
600 for (auto j : line2)
601 aabb.merge(j.p);
602 {
603 static int iRun = 0;
604 SVG svg(debug_out_path("contours_before.svg-%d.png", iRun), aabb);
605 std::array<const char *, 8> colors = {"gray", "black", "blue", "green", "lime", "purple", "red", "yellow"};
606 size_t color_idx = 0;
607 for (auto& inset : toolpaths)
608 for (auto& line2 : inset) {
609 // svg.writePolyline(line2.toPolygon(), col);
610
611 Polygon poly = line2.toPolygon();
612 Point last = poly.front();
613 for (size_t idx = 1 ; idx < poly.size(); idx++) {
614 Point here = poly[idx];
615 svg.draw(Line(last, here), colors[color_idx]);
616// svg.draw_text((last + here) / 2, std::to_string(line2.junctions[idx].region_id).c_str(), "black");
617 last = here;
618 }
619 svg.draw(poly[0], colors[color_idx]);
620 // svg.nextLayer();
621 // svg.writePoints(poly, true, 0.1);
622 // svg.nextLayer();
623 color_idx = (color_idx + 1) % colors.size();
624 }
625 }
626 {
627 static int iRun = 0;
628 SVG svg(debug_out_path("contours-%d.svg", iRun), aabb);
629 for (auto& inset : toolpaths)
630 for (auto& line2 : inset)
631 svg.draw_outline(line2.toPolygon(), "gray");
632 for (auto& line2 : stitched_polylines) {
633 const char *col = line2.is_odd ? "gray" : "red";
634 if ( ! line2.is_odd)
635 std::cerr << "Non-closed even wall of size: " << line2.size() << " at " << line2.front().p << "\n";
636 if ( ! line2.is_odd)
637 svg.draw(line2.front().p);
638 Polygon poly = line2.toPolygon();
639 Point last = poly.front();
640 for (size_t idx = 1 ; idx < poly.size(); idx++)
641 {
642 Point here = poly[idx];
643 svg.draw(Line(last, here), col);
644 last = here;
645 }
646 }
647 for (auto line2 : closed_polygons)
648 svg.draw(line2.toPolygon());
649 }
650 }
651 }
652#endif // ARACHNE_STITCH_PATCH_DEBUG
653 wall_lines = stitched_polylines; // replace input toolpaths with stitched polylines
654
655 for (ExtrusionLine& wall_polygon : closed_polygons)
656 {
657 if (wall_polygon.junctions.empty())
658 {
659 continue;
660 }
661
662 // PolylineStitcher, in some cases, produced closed extrusion (polygons),
663 // but the endpoints differ by a small distance. So we reconnect them.
664 // FIXME Lukas H.: Investigate more deeply why it is happening.
665 if (wall_polygon.junctions.front().p != wall_polygon.junctions.back().p &&
666 (wall_polygon.junctions.back().p - wall_polygon.junctions.front().p).cast<double>().norm() < stitch_distance) {
667 wall_polygon.junctions.emplace_back(wall_polygon.junctions.front());
668 }
669 wall_polygon.is_closed = true;
670 wall_lines.emplace_back(std::move(wall_polygon)); // add stitched polygons to result
671 }
672#ifdef DEBUG
673 for (ExtrusionLine& line : wall_lines)
674 {
675 assert(line.inset_idx == wall_idx);
676 }
677#endif // DEBUG
678 }
679}
static void stitch(const Paths &lines, Paths &result_lines, Paths &result_polygons, coord_t max_stitch_distance=scaled< coord_t >(0.1), coord_t snap_distance=scaled< coord_t >(0.01))
Definition PolylineStitcher.hpp:61
void poly(std::vector< std::pair< Vec2d, Vec2d > > &out, std::initializer_list< Vec2d > p)
Definition DesignSketchTool.cpp:7751
std::string debug_out_path(const char *name,...)
Definition utils.cpp:382
Slic3r::Polygon Polygon
Definition Emboss.cpp:101

References bead_width_x, Slic3r::debug_out_path(), Slic3r::SVG::draw(), Slic3r::SVG::draw_outline(), Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::Arachne::PolylineStitcher< Paths, Path, Junction >::stitch(), and toolpaths.

Referenced by generate().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ bead_width_0

coord_t Slic3r::Arachne::WallToolPaths::bead_width_0
private

Referenced by WallToolPaths(), and generate().

◆ bead_width_x

coord_t Slic3r::Arachne::WallToolPaths::bead_width_x
private

◆ inner_contour

Polygons Slic3r::Arachne::WallToolPaths::inner_contour
private

◆ inset_count

size_t Slic3r::Arachne::WallToolPaths::inset_count
private

◆ layer_height

coordf_t Slic3r::Arachne::WallToolPaths::layer_height
private

Referenced by WallToolPaths(), and generate().

◆ m_params

const WallToolPathsParams Slic3r::Arachne::WallToolPaths::m_params
private

◆ min_bead_width

coord_t Slic3r::Arachne::WallToolPaths::min_bead_width
private

Referenced by WallToolPaths(), and generate().

◆ min_feature_size

coord_t Slic3r::Arachne::WallToolPaths::min_feature_size
private

Referenced by WallToolPaths(), and generate().

◆ outline

const Polygons& Slic3r::Arachne::WallToolPaths::outline
private

◆ print_thin_walls

bool Slic3r::Arachne::WallToolPaths::print_thin_walls
private

Referenced by WallToolPaths(), and generate().

◆ small_area_length

double Slic3r::Arachne::WallToolPaths::small_area_length
private

Referenced by WallToolPaths(), and generate().

◆ toolpaths

std::vector<VariableWidthLines> Slic3r::Arachne::WallToolPaths::toolpaths
private

◆ toolpaths_generated

bool Slic3r::Arachne::WallToolPaths::toolpaths_generated
private

◆ wall_0_inset

coord_t Slic3r::Arachne::WallToolPaths::wall_0_inset
private

Referenced by WallToolPaths(), and generate().

◆ wall_transition_filter_deviation

coord_t Slic3r::Arachne::WallToolPaths::wall_transition_filter_deviation
private

The allowed line width deviation induced by filtering.

Referenced by WallToolPaths(), and generate().


The documentation for this class was generated from the following files: