clipperutil.offset params go from float to double

As clipper used doubl anyway, it shouldn't impact anything,
just avoiding int64->float->double destructive conversion.
This commit is contained in:
supermerill 2019-04-05 22:36:21 +02:00
parent c03564f218
commit 41c5d32744
16 changed files with 116 additions and 116 deletions

View File

@ -40,7 +40,7 @@ void BridgeDetector::initialize()
this->angle = -1.; this->angle = -1.;
// Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors. // Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors.
Polygons grown = offset(to_polygons(this->expolygons), float(this->spacing)); Polygons grown = offset(to_polygons(this->expolygons), this->spacing);
// Detect possible anchoring edges of this bridging region. // Detect possible anchoring edges of this bridging region.
// Detect what edges lie on lower slices by turning bridge contour and holes // Detect what edges lie on lower slices by turning bridge contour and holes
@ -86,7 +86,7 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
/* Outset the bridge expolygon by half the amount we used for detecting anchors; /* Outset the bridge expolygon by half the amount we used for detecting anchors;
we'll use this one to clip our test lines and be sure that their endpoints we'll use this one to clip our test lines and be sure that their endpoints
are inside the anchors and not on their contours leading to false negatives. */ are inside the anchors and not on their contours leading to false negatives. */
Polygons clip_area = offset(this->expolygons, 0.5f * float(this->spacing)); Polygons clip_area = offset(this->expolygons, 0.5f * this->spacing);
/* we'll now try several directions using a rudimentary visibility check: /* we'll now try several directions using a rudimentary visibility check:
bridge in several directions and then sum the length of lines having both bridge in several directions and then sum the length of lines having both
@ -229,7 +229,7 @@ Polygons BridgeDetector::coverage(double angle, bool precise) const {
// Outset the bridge expolygon by half the amount we used for detecting anchors; // Outset the bridge expolygon by half the amount we used for detecting anchors;
// we'll use this one to generate our trapezoids and be sure that their vertices // we'll use this one to generate our trapezoids and be sure that their vertices
// are inside the anchors and not on their contours leading to false negatives. // are inside the anchors and not on their contours leading to false negatives.
for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * float(this->spacing))) { for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * this->spacing)) {
// Compute trapezoids according to a vertical orientation // Compute trapezoids according to a vertical orientation
Polygons trapezoids; Polygons trapezoids;
if (!precise) expoly.get_trapezoids2(&trapezoids, PI / 2); if (!precise) expoly.get_trapezoids2(&trapezoids, PI / 2);
@ -316,7 +316,7 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
if (angle == -1) angle = this->angle; if (angle == -1) angle = this->angle;
if (angle == -1) return; if (angle == -1) return;
Polygons grown_lower = offset(this->lower_slices.expolygons, float(this->spacing)); Polygons grown_lower = offset(this->lower_slices.expolygons, this->spacing);
for (ExPolygons::const_iterator it_expoly = this->expolygons.begin(); it_expoly != this->expolygons.end(); ++ it_expoly) { for (ExPolygons::const_iterator it_expoly = this->expolygons.begin(); it_expoly != this->expolygons.end(); ++ it_expoly) {
// get unsupported bridge edges (both contour and holes) // get unsupported bridge edges (both contour and holes)

View File

@ -201,7 +201,7 @@ ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polylines &input)
return retval; return retval;
} }
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit) ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const double delta, ClipperLib::JoinType joinType, double miterLimit)
{ {
// scale input // scale input
scaleClipperPolygons(input); scaleClipperPolygons(input);
@ -212,7 +212,7 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
co.ArcTolerance = miterLimit; co.ArcTolerance = miterLimit;
else else
co.MiterLimit = miterLimit; co.MiterLimit = miterLimit;
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE); double delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR)); co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
co.AddPaths(input, joinType, endType); co.AddPaths(input, joinType, endType);
ClipperLib::Paths retval; ClipperLib::Paths retval;
@ -223,7 +223,7 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
return retval; return retval;
} }
ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit) ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType, const double delta, ClipperLib::JoinType joinType, double miterLimit)
{ {
ClipperLib::Paths paths; ClipperLib::Paths paths;
paths.push_back(std::move(input)); paths.push_back(std::move(input));
@ -233,12 +233,12 @@ ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType,
// This is a safe variant of the polygon offset, tailored for a single ExPolygon: // This is a safe variant of the polygon offset, tailored for a single ExPolygon:
// a single polygon with multiple non-overlapping holes. // a single polygon with multiple non-overlapping holes.
// Each contour and hole is offsetted separately, then the holes are subtracted from the outer contours. // Each contour and hole is offsetted separately, then the holes are subtracted from the outer contours.
ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const double delta,
ClipperLib::JoinType joinType, double miterLimit) ClipperLib::JoinType joinType, double miterLimit)
{ {
// printf("new ExPolygon offset\n"); // printf("new ExPolygon offset\n");
// 1) Offset the outer contour. // 1) Offset the outer contour.
const float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE); const double delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
ClipperLib::Paths contours; ClipperLib::Paths contours;
{ {
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(expolygon.contour); ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(expolygon.contour);
@ -293,10 +293,10 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
// This is a safe variant of the polygons offset, tailored for multiple ExPolygons. // This is a safe variant of the polygons offset, tailored for multiple ExPolygons.
// It is required, that the input expolygons do not overlap and that the holes of each ExPolygon don't intersect with their respective outer contours. // It is required, that the input expolygons do not overlap and that the holes of each ExPolygon don't intersect with their respective outer contours.
// Each ExPolygon is offsetted separately, then the offsetted ExPolygons are united. // Each ExPolygon is offsetted separately, then the offsetted ExPolygons are united.
ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const double delta,
ClipperLib::JoinType joinType, double miterLimit) ClipperLib::JoinType joinType, double miterLimit)
{ {
const float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE); const double delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
// Offsetted ExPolygons before they are united. // Offsetted ExPolygons before they are united.
ClipperLib::Paths contours_cummulative; ClipperLib::Paths contours_cummulative;
contours_cummulative.reserve(expolygons.size()); contours_cummulative.reserve(expolygons.size());
@ -400,7 +400,7 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
} }
ClipperLib::Paths ClipperLib::Paths
_offset2(const Polygons &polygons, const float delta1, const float delta2, _offset2(const Polygons &polygons, const double delta1, const double delta2,
const ClipperLib::JoinType joinType, const double miterLimit) const ClipperLib::JoinType joinType, const double miterLimit)
{ {
// read input // read input
@ -416,8 +416,8 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
} else { } else {
co.MiterLimit = miterLimit; co.MiterLimit = miterLimit;
} }
float delta_scaled1 = delta1 * float(CLIPPER_OFFSET_SCALE); double delta_scaled1 = delta1 * float(CLIPPER_OFFSET_SCALE);
float delta_scaled2 = delta2 * float(CLIPPER_OFFSET_SCALE); double delta_scaled2 = delta2 * float(CLIPPER_OFFSET_SCALE);
co.ShortestEdgeLength = double(std::max(std::abs(delta_scaled1), std::abs(delta_scaled2)) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR); co.ShortestEdgeLength = double(std::max(std::abs(delta_scaled1), std::abs(delta_scaled2)) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR);
// perform first offset // perform first offset
@ -437,7 +437,7 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
} }
Polygons Polygons
offset2(const Polygons &polygons, const float delta1, const float delta2, offset2(const Polygons &polygons, const double delta1, const double delta2,
const ClipperLib::JoinType joinType, const double miterLimit) const ClipperLib::JoinType joinType, const double miterLimit)
{ {
// perform offset // perform offset
@ -448,7 +448,7 @@ offset2(const Polygons &polygons, const float delta1, const float delta2,
} }
ExPolygons ExPolygons
offset2_ex(const Polygons &polygons, const float delta1, const float delta2, offset2_ex(const Polygons &polygons, const double delta1, const double delta2,
const ClipperLib::JoinType joinType, const double miterLimit) const ClipperLib::JoinType joinType, const double miterLimit)
{ {
// perform offset // perform offset
@ -460,8 +460,8 @@ offset2_ex(const Polygons &polygons, const float delta1, const float delta2,
//FIXME Vojtech: This functon may likely be optimized to avoid some of the Slic3r to Clipper //FIXME Vojtech: This functon may likely be optimized to avoid some of the Slic3r to Clipper
// conversions and unnecessary Clipper calls. // conversions and unnecessary Clipper calls.
ExPolygons offset2_ex(const ExPolygons &expolygons, const float delta1, ExPolygons offset2_ex(const ExPolygons &expolygons, const double delta1,
const float delta2, ClipperLib::JoinType joinType, double miterLimit) const double delta2, ClipperLib::JoinType joinType, double miterLimit)
{ {
Polygons polys; Polygons polys;
for (const ExPolygon &expoly : expolygons) for (const ExPolygon &expoly : expolygons)

View File

@ -42,46 +42,46 @@ Slic3r::Polylines ClipperPaths_to_Slic3rPolylines(const ClipperLib::Paths &inpu
Slic3r::ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input); Slic3r::ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input);
// offset Polygons // offset Polygons
ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit); ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType, const double delta, ClipperLib::JoinType joinType, double miterLimit);
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit); ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const double delta, ClipperLib::JoinType joinType, double miterLimit);
inline Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
inline Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
// offset Polylines // offset Polylines
inline Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3) inline Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polyline), ClipperLib::etOpenButt, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polyline), ClipperLib::etOpenButt, delta, joinType, miterLimit)); }
inline Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3) inline Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polylines), ClipperLib::etOpenButt, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polylines), ClipperLib::etOpenButt, delta, joinType, miterLimit)); }
// offset expolygons and surfaces // offset expolygons and surfaces
ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType, double miterLimit); ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const double delta, ClipperLib::JoinType joinType, double miterLimit);
ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType, double miterLimit); ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const double delta, ClipperLib::JoinType joinType, double miterLimit);
inline Slic3r::Polygons offset(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::Polygons offset(const Slic3r::ExPolygon &expolygon, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rPolygons(_offset(expolygon, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rPolygons(_offset(expolygon, delta, joinType, miterLimit)); }
inline Slic3r::Polygons offset(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::Polygons offset(const Slic3r::ExPolygons &expolygons, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rPolygons(_offset(expolygons, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygon &polygon, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygon, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rExPolygons(_offset(expolygon, delta, joinType, miterLimit)); }
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3) inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const double delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygons, delta, joinType, miterLimit)); } { return ClipperPaths_to_Slic3rExPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1, ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const double delta1,
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const double delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1, Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const double delta1,
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const double delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1, Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const double delta1,
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const double delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1, Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const double delta1,
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const double delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
Slic3r::Polygons _clipper(ClipperLib::ClipType clipType, Slic3r::Polygons _clipper(ClipperLib::ClipType clipType,

View File

@ -52,7 +52,7 @@ ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCo
void ExtrusionPath::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const void ExtrusionPath::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const
{ {
polygons_append(out, offset(this->polyline, float(scale_(this->width/2)) + scaled_epsilon)); polygons_append(out, offset(this->polyline, double(scale_(this->width/2)) + scaled_epsilon));
} }
void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const
@ -60,7 +60,7 @@ void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scale
// Instantiating the Flow class to get the line spacing. // Instantiating the Flow class to get the line spacing.
// Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler. // Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler.
Flow flow(this->width, this->height, 0.f, is_bridge(this->role())); Flow flow(this->width, this->height, 0.f, is_bridge(this->role()));
polygons_append(out, offset(this->polyline, 0.5f * float(flow.scaled_spacing()) + scaled_epsilon)); polygons_append(out, offset(this->polyline, 0.5f * double(flow.scaled_spacing()) + scaled_epsilon));
} }
bool bool

View File

@ -57,7 +57,7 @@ Fill* Fill::new_from_type(const std::string &type)
Polylines Fill::fill_surface(const Surface *surface, const FillParams &params) Polylines Fill::fill_surface(const Surface *surface, const FillParams &params)
{ {
// Perform offset. // Perform offset.
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(0 - 0.5 * this->spacing))); Slic3r::ExPolygons expp = offset_ex(surface->expolygon, double(scale_(0 - 0.5 * this->spacing)));
// Create the infills for each of the regions. // Create the infills for each of the regions.
Polylines polylines_out; Polylines polylines_out;
for (size_t i = 0; i < expp.size(); ++ i) for (size_t i = 0; i < expp.size(); ++ i)

View File

@ -81,7 +81,7 @@ void FillConcentricWGapFill::fill_surface_extrusion(const Surface *surface, cons
ExtrusionEntitiesPtr &out) { ExtrusionEntitiesPtr &out) {
// Perform offset. // Perform offset.
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(0 - 0.5 * this->spacing))); Slic3r::ExPolygons expp = offset_ex(surface->expolygon, double(scale_(0 - 0.5 * this->spacing)));
// Create the infills for each of the regions. // Create the infills for each of the regions.
Polylines polylines_out; Polylines polylines_out;
for (size_t i = 0; i < expp.size(); ++i) { for (size_t i = 0; i < expp.size(); ++i) {

View File

@ -1482,9 +1482,9 @@ Polylines FillStars::fill_surface(const Surface *surface, const FillParams &para
FillParams params3 = params2; FillParams params3 = params2;
params3.dont_connect = true; params3.dont_connect = true;
Polylines polylines_out; Polylines polylines_out;
if (! fill_surface_by_lines(surface, params2, 0.f, 0., polylines_out) || if (! fill_surface_by_lines(surface, params2, 0.f, 0.f, polylines_out) ||
! fill_surface_by_lines(surface, params2, float(M_PI / 3.), 0., polylines_out) || ! fill_surface_by_lines(surface, params2, float(M_PI / 3.), 0.f, polylines_out) ||
! fill_surface_by_lines(surface, params3, float(2. * M_PI / 3.), 0.5 * this->spacing / params2.density, polylines_out)) { ! fill_surface_by_lines(surface, params3, float(2. * M_PI / 3.), float(0.5 * this->spacing / params2.density), polylines_out)) {
printf("FillStars::fill_surface() failed to fill a region.\n"); printf("FillStars::fill_surface() failed to fill a region.\n");
} }
return polylines_out; return polylines_out;
@ -1623,7 +1623,7 @@ Polylines FillScatteredRectilinear::fill_surface(const Surface *surface, const F
Polylines polylines_out; Polylines polylines_out;
// Offset the pattern randomly using the current layer index as the generator // Offset the pattern randomly using the current layer index as the generator
float offset = randomFloatFromSeed((uint32_t) layer_id) * 0.5f * (float) this->spacing; float offset = randomFloatFromSeed((uint32_t) layer_id) * 0.5f * this->spacing;
if (!fill_surface_by_lines(surface, params, 0.f, offset, polylines_out)) { if (!fill_surface_by_lines(surface, params, 0.f, offset, polylines_out)) {
printf("FillScatteredRectilinear::fill_surface() failed to fill a region.\n"); printf("FillScatteredRectilinear::fill_surface() failed to fill a region.\n");

View File

@ -138,10 +138,10 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
if (surface.has_pos_top()) { if (surface.has_pos_top()) {
// Collect the top surfaces, inflate them and trim them by the bottom surfaces. // Collect the top surfaces, inflate them and trim them by the bottom surfaces.
// This gives the priority to bottom surfaces. // This gives the priority to bottom surfaces.
surfaces_append(top, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface); surfaces_append(top, offset_ex(surface.expolygon, double(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
} else if (surface.has_pos_bottom() && (!surface.has_mod_bridge() || lower_layer == NULL)) { } else if (surface.has_pos_bottom() && (!surface.has_mod_bridge() || lower_layer == NULL)) {
// Grown by 3mm. // Grown by 3mm.
surfaces_append(bottom, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface); surfaces_append(bottom, offset_ex(surface.expolygon, double(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
} else if (surface.has_pos_bottom() && surface.has_mod_bridge()) { } else if (surface.has_pos_bottom() && surface.has_mod_bridge()) {
if (! surface.empty()) if (! surface.empty())
bridges.push_back(surface); bridges.push_back(surface);

View File

@ -606,7 +606,7 @@ MedialAxis::fusion_corners(ThickPolylines &pp)
void void
MedialAxis::extends_line_both_side(ThickPolylines& pp) { MedialAxis::extends_line_both_side(ThickPolylines& pp) {
const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), (float)-SCALED_RESOLUTION, (float)SCALED_RESOLUTION); const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), double(-SCALED_RESOLUTION), double(SCALED_RESOLUTION));
for (size_t i = 0; i < pp.size(); ++i) { for (size_t i = 0; i < pp.size(); ++i) {
ThickPolyline& polyline = pp[i]; ThickPolyline& polyline = pp[i];
this->extends_line(polyline, anchors, this->min_width); this->extends_line(polyline, anchors, this->min_width);

View File

@ -123,7 +123,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
{ {
// grow our environment slightly in order for simplify_by_visibility() // grow our environment slightly in order for simplify_by_visibility()
// to work best by considering moves on boundaries valid as well // to work best by considering moves on boundaries valid as well
ExPolygonCollection grown_env(offset_ex(env.m_env.expolygons, float(+SCALED_EPSILON))); ExPolygonCollection grown_env(offset_ex(env.m_env.expolygons, double(+SCALED_EPSILON)));
if (island_idx == -1) { if (island_idx == -1) {
/* If 'from' or 'to' are not inside our env, they were connected using the /* If 'from' or 'to' are not inside our env, they were connected using the

View File

@ -70,7 +70,7 @@ void PerimeterGenerator::process()
// lower layer, so we take lower slices and offset them by half the nozzle diameter used // lower layer, so we take lower slices and offset them by half the nozzle diameter used
// in the current layer // in the current layer
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder-1); double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder-1);
this->_lower_slices_p = offset(*this->lower_slices, float(scale_(+nozzle_diameter/2))); this->_lower_slices_p = offset(*this->lower_slices, double(scale_(+nozzle_diameter/2)));
} }
// we need to process each island separately because we might have different // we need to process each island separately because we might have different
@ -90,7 +90,7 @@ void PerimeterGenerator::process()
ExPolygons unsupported = diff_ex(last, this->lower_slices->expolygons, true); ExPolygons unsupported = diff_ex(last, this->lower_slices->expolygons, true);
if (!unsupported.empty()) { if (!unsupported.empty()) {
//remove small overhangs //remove small overhangs
ExPolygons unsupported_filtered = offset2_ex(unsupported, -(float)(perimeter_spacing), (float)(perimeter_spacing)); ExPolygons unsupported_filtered = offset2_ex(unsupported, double(-perimeter_spacing), double(perimeter_spacing));
if (!unsupported_filtered.empty()) { if (!unsupported_filtered.empty()) {
//to_draw.insert(to_draw.end(), last.begin(), last.end()); //to_draw.insert(to_draw.end(), last.begin(), last.end());
//extract only the useful part of the lower layer. The safety offset is really needed here. //extract only the useful part of the lower layer. The safety offset is really needed here.
@ -128,7 +128,7 @@ void PerimeterGenerator::process()
} }
} }
unsupported_filtered = intersection_ex(last, unsupported_filtered = intersection_ex(last,
offset2_ex(unsupported_filtered, (float)-perimeter_spacing / 2, (float)perimeter_spacing * 3 / 2)); offset2_ex(unsupported_filtered, double(-perimeter_spacing / 2), double(perimeter_spacing * 3 / 2)));
if (this->config->no_perimeter_unsupported_algo == npuaFilled) { if (this->config->no_perimeter_unsupported_algo == npuaFilled) {
for (ExPolygon &expol : unsupported_filtered) { for (ExPolygon &expol : unsupported_filtered) {
//check if the holes won't be covered by the upper layer //check if the holes won't be covered by the upper layer
@ -153,7 +153,7 @@ void PerimeterGenerator::process()
if (intersection_ex(ExPolygons() = { expol }, ExPolygons() = { all_surfaces[surface_idx_other].expolygon }).size() > 0) { if (intersection_ex(ExPolygons() = { expol }, ExPolygons() = { all_surfaces[surface_idx_other].expolygon }).size() > 0) {
//this means that other_surf was inside an expol holes //this means that other_surf was inside an expol holes
//as we removed them, we need to add a new one //as we removed them, we need to add a new one
ExPolygons new_poly = offset2_ex(all_surfaces[surface_idx_other].expolygon, -(float)perimeter_spacing * 2, (float)perimeter_spacing); ExPolygons new_poly = offset2_ex(all_surfaces[surface_idx_other].expolygon, double(-perimeter_spacing * 2), double(perimeter_spacing));
if (new_poly.size() == 1) { if (new_poly.size() == 1) {
all_surfaces[surface_idx_other].expolygon = new_poly[0]; all_surfaces[surface_idx_other].expolygon = new_poly[0];
expol.holes.push_back(new_poly[0].contour); expol.holes.push_back(new_poly[0].contour);
@ -193,7 +193,7 @@ void PerimeterGenerator::process()
//FIXME: it overlap inside unsuppported not-bridgeable area! //FIXME: it overlap inside unsuppported not-bridgeable area!
double overlap = scale_(this->config->get_abs_value("infill_overlap", unscale<double>(perimeter_spacing))); double overlap = scale_(this->config->get_abs_value("infill_overlap", unscale<double>(perimeter_spacing)));
//bridgeable_simplified = offset2_ex(bridgeable_simplified, (float)-perimeter_spacing, (float)perimeter_spacing * 2); //bridgeable_simplified = offset2_ex(bridgeable_simplified, (double)-perimeter_spacing, (double)perimeter_spacing * 2);
//ExPolygons unbridgeable = offset_ex(diff_ex(unsupported, bridgeable_simplified), perimeter_spacing * 3 / 2); //ExPolygons unbridgeable = offset_ex(diff_ex(unsupported, bridgeable_simplified), perimeter_spacing * 3 / 2);
//ExPolygons unbridgeable = intersection_ex(unsupported, diff_ex(unsupported_filtered, offset_ex(bridgeable_simplified, ext_perimeter_width / 2))); //ExPolygons unbridgeable = intersection_ex(unsupported, diff_ex(unsupported_filtered, offset_ex(bridgeable_simplified, ext_perimeter_width / 2)));
//unbridgeable = offset2_ex(unbridgeable, -ext_perimeter_width, ext_perimeter_width); //unbridgeable = offset2_ex(unbridgeable, -ext_perimeter_width, ext_perimeter_width);
@ -218,7 +218,7 @@ void PerimeterGenerator::process()
////put the bridge area inside the unsupported_filtered variable ////put the bridge area inside the unsupported_filtered variable
//unsupported_filtered = intersection_ex(last, //unsupported_filtered = intersection_ex(last,
// diff_ex( // diff_ex(
// offset_ex(bridgeable_simplified, (float)perimeter_spacing / 2), // offset_ex(bridgeable_simplified, (double)perimeter_spacing / 2),
// unbridgeable // unbridgeable
// ) // )
// ); // );
@ -310,7 +310,7 @@ void PerimeterGenerator::process()
} }
if (!bridgeable_simplified.empty()) if (!bridgeable_simplified.empty())
bridgeable_simplified = offset_ex(bridgeable_simplified, (float)perimeter_spacing / 1.9f); bridgeable_simplified = offset_ex(bridgeable_simplified, double(perimeter_spacing) / 1.9);
if (!bridgeable_simplified.empty()) { if (!bridgeable_simplified.empty()) {
//offset by perimeter spacing because the simplify may have reduced it a bit. //offset by perimeter spacing because the simplify may have reduced it a bit.
overhangs_unsupported = diff_ex(overhangs_unsupported, bridgeable_simplified); overhangs_unsupported = diff_ex(overhangs_unsupported, bridgeable_simplified);
@ -346,7 +346,7 @@ void PerimeterGenerator::process()
if (i == 0) { if (i == 0) {
// compute next onion, without taking care of thin_walls : destroy too thin areas. // compute next onion, without taking care of thin_walls : destroy too thin areas.
if (!this->config->thin_walls) if (!this->config->thin_walls)
next_onion = offset_ex(last, -(float)(ext_perimeter_width / 2)); next_onion = offset_ex(last, double( - ext_perimeter_width / 2));
// look for thin walls // look for thin walls
@ -358,7 +358,7 @@ void PerimeterGenerator::process()
-(float)(ext_perimeter_width / 2 + ext_min_spacing / 2 - 1), -(float)(ext_perimeter_width / 2 + ext_min_spacing / 2 - 1),
+(float)(ext_min_spacing / 2 - 1)); +(float)(ext_min_spacing / 2 - 1));
// detect edge case where a curve can be split in multiple small chunks. // detect edge case where a curve can be split in multiple small chunks.
ExPolygons no_thin_onion = offset_ex(last, -(float)(ext_perimeter_width / 2)); ExPolygons no_thin_onion = offset_ex(last, double( - ext_perimeter_width / 2));
float div = 2; float div = 2;
while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && no_thin_onion.size() + next_onion.size() > 3) { while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && no_thin_onion.size() + next_onion.size() > 3) {
div += 0.5; div += 0.5;
@ -377,28 +377,28 @@ void PerimeterGenerator::process()
// (actually, something larger than that still may exist due to mitering or other causes) // (actually, something larger than that still may exist due to mitering or other causes)
coord_t min_width = (coord_t)scale_(this->config->thin_walls_min_width.get_abs_value(this->ext_perimeter_flow.nozzle_diameter)); coord_t min_width = (coord_t)scale_(this->config->thin_walls_min_width.get_abs_value(this->ext_perimeter_flow.nozzle_diameter));
ExPolygons no_thin_zone = offset_ex(next_onion, (float)(ext_perimeter_width / 2), jtSquare); ExPolygons no_thin_zone = offset_ex(next_onion, double(ext_perimeter_width / 2), jtSquare);
// medial axis requires non-overlapping geometry // medial axis requires non-overlapping geometry
ExPolygons thin_zones = diff_ex(last, no_thin_zone, true); ExPolygons thin_zones = diff_ex(last, no_thin_zone, true);
//don't use offset2_ex, because we don't want to merge the zones that have been separated. //don't use offset2_ex, because we don't want to merge the zones that have been separated.
//a very little bit of overlap can be created here with other thin polygons, but it's more useful than worisome. //a very little bit of overlap can be created here with other thin polygons, but it's more useful than worisome.
ExPolygons half_thins = offset_ex(thin_zones, (float)(-min_width / 2)); ExPolygons half_thins = offset_ex(thin_zones, double(-min_width / 2));
//simplify them //simplify them
for (ExPolygon &half_thin : half_thins) { for (ExPolygon &half_thin : half_thins) {
half_thin.remove_point_too_near((float)SCALED_RESOLUTION); half_thin.remove_point_too_near((float)SCALED_RESOLUTION);
} }
//we push the bits removed and put them into what we will use as our anchor //we push the bits removed and put them into what we will use as our anchor
if (half_thins.size() > 0) { if (half_thins.size() > 0) {
no_thin_zone = diff_ex(last, offset_ex(half_thins, (float)(min_width / 2) - (float) SCALED_EPSILON), true); no_thin_zone = diff_ex(last, offset_ex(half_thins, double(min_width / 2 - SCALED_EPSILON)), true);
} }
// compute a bit of overlap to anchor thin walls inside the print. // compute a bit of overlap to anchor thin walls inside the print.
for (ExPolygon &half_thin : half_thins) { for (ExPolygon &half_thin : half_thins) {
//growing back the polygon //growing back the polygon
ExPolygons thin = offset_ex(half_thin, (float)(min_width / 2)); ExPolygons thin = offset_ex(half_thin, double(min_width / 2));
assert(thin.size() <= 1); assert(thin.size() <= 1);
if (thin.empty()) continue; if (thin.empty()) continue;
coord_t overlap = (coord_t)scale_(this->config->thin_walls_overlap.get_abs_value(this->ext_perimeter_flow.nozzle_diameter)); coord_t overlap = (coord_t)scale_(this->config->thin_walls_overlap.get_abs_value(this->ext_perimeter_flow.nozzle_diameter));
ExPolygons anchor = intersection_ex(offset_ex(half_thin, (float)(min_width / 2) + ExPolygons anchor = intersection_ex(offset_ex(half_thin, double(min_width / 2) +
(float)(overlap), jtSquare), no_thin_zone, true); (float)(overlap), jtSquare), no_thin_zone, true);
ExPolygons bounds = union_ex(thin, anchor, true); ExPolygons bounds = union_ex(thin, anchor, true);
for (ExPolygon &bound : bounds) { for (ExPolygon &bound : bounds) {
@ -435,7 +435,7 @@ void PerimeterGenerator::process()
} else { } else {
// If "detect thin walls" is not enabled, this paths will be entered, which // If "detect thin walls" is not enabled, this paths will be entered, which
// leads to overflows, as in prusa3d/Slic3r GH #32 // leads to overflows, as in prusa3d/Slic3r GH #32
next_onion = offset_ex(last, -(float)(good_spacing)); next_onion = offset_ex(last, double( - good_spacing));
} }
// look for gaps // look for gaps
if (this->config->gap_fill_speed.value > 0 && this->config->gap_fill if (this->config->gap_fill_speed.value > 0 && this->config->gap_fill
@ -483,8 +483,8 @@ void PerimeterGenerator::process()
ExPolygons top_polygons = diff_ex(last, (upper_polygons), true); ExPolygons top_polygons = diff_ex(last, (upper_polygons), true);
ExPolygons inner_polygons = diff_ex(last, top_polygons, true); ExPolygons inner_polygons = diff_ex(last, top_polygons, true);
// increase a bit the inner space to fill the frontier between last and stored. // increase a bit the inner space to fill the frontier between last and stored.
stored = union_ex(stored, intersection_ex(offset_ex(top_polygons, (float)(perimeter_spacing / 2)), last)); stored = union_ex(stored, intersection_ex(offset_ex(top_polygons, double(perimeter_spacing / 2)), last));
last = intersection_ex(offset_ex(inner_polygons, (float)(perimeter_spacing / 2)), last); last = intersection_ex(offset_ex(inner_polygons, double(perimeter_spacing / 2)), last);
} }
@ -589,8 +589,8 @@ void PerimeterGenerator::process()
double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE); double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE);
double max = 2. * perimeter_spacing; double max = 2. * perimeter_spacing;
ExPolygons gaps_ex = diff_ex( ExPolygons gaps_ex = diff_ex(
offset2_ex(gaps, (float)-min / 2, (float)+min / 2), offset2_ex(gaps, double(-min / 2), double(+min / 2)),
offset2_ex(gaps, (float)-max / 2, (float)+max / 2), offset2_ex(gaps, double(-max / 2), double(+max / 2)),
true); true);
ThickPolylines polylines; ThickPolylines polylines;
for (const ExPolygon &ex : gaps_ex) { for (const ExPolygon &ex : gaps_ex) {

View File

@ -1766,7 +1766,7 @@ void Print::_make_brim(const PrintObjectPtrs &objects, ExtrusionEntityCollection
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing())); size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
for (size_t i = 0; i < num_loops; ++i) { for (size_t i = 0; i < num_loops; ++i) {
this->throw_if_canceled(); this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare); islands = offset(islands, double(flow.scaled_spacing()), jtSquare);
for (Polygon &poly : islands) { for (Polygon &poly : islands) {
// poly.simplify(SCALED_RESOLUTION); // poly.simplify(SCALED_RESOLUTION);
poly.points.push_back(poly.points.front()); poly.points.push_back(poly.points.front());
@ -1774,7 +1774,7 @@ void Print::_make_brim(const PrintObjectPtrs &objects, ExtrusionEntityCollection
p.pop_back(); p.pop_back();
poly.points = std::move(p); poly.points = std::move(p);
} }
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing()))); polygons_append(loops, offset(islands, -0.5f * double(flow.scaled_spacing())));
} }
loops = union_pt_chained(loops, false); loops = union_pt_chained(loops, false);
@ -1811,7 +1811,7 @@ void Print::_make_brim_ears(const PrintObjectPtrs &objects, ExtrusionEntityColle
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing())); size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
for (size_t i = 0; i < num_loops; ++i) { for (size_t i = 0; i < num_loops; ++i) {
this->throw_if_canceled(); this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare); islands = offset(islands, double(flow.scaled_spacing()), jtSquare);
for (Polygon &poly : islands) { for (Polygon &poly : islands) {
// poly.simplify(SCALED_RESOLUTION); // poly.simplify(SCALED_RESOLUTION);
poly.points.push_back(poly.points.front()); poly.points.push_back(poly.points.front());
@ -1819,7 +1819,7 @@ void Print::_make_brim_ears(const PrintObjectPtrs &objects, ExtrusionEntityColle
p.pop_back(); p.pop_back();
poly.points = std::move(p); poly.points = std::move(p);
} }
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing()))); polygons_append(loops, offset(islands, -0.5f * double(flow.scaled_spacing())));
} }
loops = union_pt_chained(loops, false); loops = union_pt_chained(loops, false);

View File

@ -178,7 +178,7 @@ private:
void generate_support_material(); void generate_support_material();
void _slice(const std::vector<coordf_t> &layer_height_profile); void _slice(const std::vector<coordf_t> &layer_height_profile);
void _offset_holes(float hole_delta, LayerRegion *layerm); void _offset_holes(double hole_delta, LayerRegion *layerm);
void _smooth_curves(LayerRegion *layerm); void _smooth_curves(LayerRegion *layerm);
std::string _fix_slicing_errors(); std::string _fix_slicing_errors();
void _simplify_slices(double distance); void _simplify_slices(double distance);

View File

@ -183,8 +183,8 @@ void PrintObject::make_perimeters()
// (it should either lay over our perimeters or outside this area) // (it should either lay over our perimeters or outside this area)
const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5); const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5);
const Polygons critical_area = diff( const Polygons critical_area = diff(
offset(slice.expolygon, float(- perimeters_thickness)), offset(slice.expolygon, double(- perimeters_thickness)),
offset(slice.expolygon, float(- perimeters_thickness - critical_area_depth)) offset(slice.expolygon, double(- perimeters_thickness - critical_area_depth))
); );
// check whether a portion of the upper slices falls inside the critical area // check whether a portion of the upper slices falls inside the critical area
const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area); const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area);
@ -675,7 +675,7 @@ ExPolygons fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, c
current_offset *= 2; current_offset *= 2;
if (next_coverage < 0.1) current_offset *= 2; if (next_coverage < 0.1) current_offset *= 2;
//create the bigger polygon and test it //create the bigger polygon and test it
ExPolygons bigger_polygon = offset_ex(polygon_to_check, (float)current_offset); ExPolygons bigger_polygon = offset_ex(polygon_to_check, double(current_offset));
if (bigger_polygon.size() != 1) { if (bigger_polygon.size() != 1) {
// Error, growing a single polygon result in many/no other => fallback to full coverage // Error, growing a single polygon result in many/no other => fallback to full coverage
return ExPolygons({ growing_area }); return ExPolygons({ growing_area });
@ -693,7 +693,7 @@ ExPolygons fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, c
uint32_t nb_opti_max = 6; uint32_t nb_opti_max = 6;
for (uint32_t i = 0; i < nb_opti_max; ++i){ for (uint32_t i = 0; i < nb_opti_max; ++i){
coord_t new_offset = (previous_offset + current_offset) / 2; coord_t new_offset = (previous_offset + current_offset) / 2;
ExPolygons bigger_polygon = offset_ex(polygon_to_check, (float)new_offset); ExPolygons bigger_polygon = offset_ex(polygon_to_check, double(new_offset));
if (bigger_polygon.size() != 1) { if (bigger_polygon.size() != 1) {
//Warn, growing a single polygon result in many/no other, use previous good result //Warn, growing a single polygon result in many/no other, use previous good result
break; break;
@ -763,8 +763,8 @@ void PrintObject::tag_under_bridge() {
if (layerm->region()->config().infill_dense_algo == dfaEnlarged) { if (layerm->region()->config().infill_dense_algo == dfaEnlarged) {
//expand the area a bit //expand the area a bit
intersect = offset_ex(intersect, (float)scale_(layerm->region()->config().external_infill_margin.get_abs_value( intersect = offset_ex(intersect, double(scale_(layerm->region()->config().external_infill_margin.get_abs_value(
region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1))))); region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1))))));
} else if (layerm->region()->config().infill_dense_algo == dfaAutoNotFull } else if (layerm->region()->config().infill_dense_algo == dfaAutoNotFull
|| layerm->region()->config().infill_dense_algo == dfaAutomatic){ || layerm->region()->config().infill_dense_algo == dfaAutomatic){
@ -781,15 +781,15 @@ void PrintObject::tag_under_bridge() {
ExPolygons cover_intersect; ExPolygons cover_intersect;
for (ExPolygon &expoly_tocover : intersect) { for (ExPolygon &expoly_tocover : intersect) {
ExPolygons temp = (fit_to_size(expoly_tocover, expoly_tocover, ExPolygons temp = (fit_to_size(expoly_tocover, expoly_tocover,
diff_ex(offset_ex(layerm->fill_no_overlap_expolygons, (float)layerm->flow(frInfill).scaled_width()), diff_ex(offset_ex(layerm->fill_no_overlap_expolygons, double(layerm->flow(frInfill).scaled_width())),
offset_ex(layerm->fill_no_overlap_expolygons, (float)-layerm->flow(frInfill).scaled_width())), offset_ex(layerm->fill_no_overlap_expolygons, double(-layerm->flow(frInfill).scaled_width()))),
surf.expolygon, surf.expolygon,
4 * layerm->flow(frInfill).scaled_width(), 0.01f)); 4 * layerm->flow(frInfill).scaled_width(), 0.01f));
cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end()); cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end());
} }
intersect = offset2_ex(cover_intersect, intersect = offset2_ex(cover_intersect,
(float)-layerm->flow(frInfill).scaled_width(), double(-layerm->flow(frInfill).scaled_width()),
(float)layerm->flow(frInfill).scaled_width() * 2); double(layerm->flow(frInfill).scaled_width() * 2));
} else { } else {
intersect.clear(); intersect.clear();
} }
@ -797,8 +797,8 @@ void PrintObject::tag_under_bridge() {
if (!intersect.empty()) { if (!intersect.empty()) {
ExPolygons sparse_surfaces = offset2_ex( ExPolygons sparse_surfaces = offset2_ex(
diff_ex(sparse_polys, intersect, true), diff_ex(sparse_polys, intersect, true),
(float)-layerm->flow(frInfill).scaled_width(), double(-layerm->flow(frInfill).scaled_width()),
(float)layerm->flow(frInfill).scaled_width()); double(layerm->flow(frInfill).scaled_width()));
ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true); ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true);
//assign (copy) //assign (copy)
sparse_polys = std::move(sparse_surfaces); sparse_polys = std::move(sparse_surfaces);
@ -1905,7 +1905,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
} }
if (num_volumes > 1) if (num_volumes > 1)
// Merge the islands using a positive / negative offset. // Merge the islands using a positive / negative offset.
expolygons = offset_ex(offset_ex(expolygons, float(scale_(EPSILON))), -float(scale_(EPSILON))); expolygons = offset_ex(offset_ex(expolygons, double(scale_(EPSILON))), double( - scale_(EPSILON)));
m_layers[layer_id]->regions()[region_id]->slices.append(std::move(expolygons), stPosInternal | stDensSparse); m_layers[layer_id]->regions()[region_id]->slices.append(std::move(expolygons), stPosInternal | stDensSparse);
} }
} }
@ -2038,7 +2038,7 @@ end:
} }
if (delta < 0.f) { if (delta < 0.f) {
// Apply the negative XY compensation. // Apply the negative XY compensation.
Polygons trimming = offset(layer->merged(float(EPSILON)), delta - float(EPSILON)); Polygons trimming = offset(layer->merged(double(EPSILON)), delta - double(EPSILON));
for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id)
layer->m_regions[region_id]->trim_surfaces(trimming); layer->m_regions[region_id]->trim_surfaces(trimming);
} }
@ -2058,7 +2058,7 @@ end:
size_t nsteps = size_t(steps); size_t nsteps = size_t(steps);
float step = elephant_foot_compensation / steps; float step = elephant_foot_compensation / steps;
for (size_t i = 0; i < nsteps; ++ i) { for (size_t i = 0; i < nsteps; ++ i) {
Polygons trimming_polygons = offset(layer->merged(float(EPSILON)), - step - float(EPSILON)); Polygons trimming_polygons = offset(layer->merged(float(EPSILON)), double(- step - EPSILON));
for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id)
layer->m_regions[region_id]->elephant_foot_compensation_step(elephant_foot_spacing[region_id] + step, trimming_polygons); layer->m_regions[region_id]->elephant_foot_compensation_step(elephant_foot_spacing[region_id] + step, trimming_polygons);
} }
@ -2072,7 +2072,7 @@ end:
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end"; BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end";
} }
void PrintObject::_offset_holes(float hole_delta, LayerRegion *layerm) { void PrintObject::_offset_holes(double hole_delta, LayerRegion *layerm) {
if (hole_delta != 0.f) { if (hole_delta != 0.f) {
ExPolygons polys = to_expolygons(std::move(layerm->slices.surfaces)); ExPolygons polys = to_expolygons(std::move(layerm->slices.surfaces));
ExPolygons new_polys; ExPolygons new_polys;
@ -2446,8 +2446,8 @@ void PrintObject::_make_perimeters()
// (it should either lay over our perimeters or outside this area) // (it should either lay over our perimeters or outside this area)
const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5); const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5);
const Polygons critical_area = diff( const Polygons critical_area = diff(
offset(slice.expolygon, float(- perimeters_thickness)), offset(slice.expolygon, double(- perimeters_thickness)),
offset(slice.expolygon, float(- perimeters_thickness - critical_area_depth)) offset(slice.expolygon, double(- perimeters_thickness - critical_area_depth))
); );
// check whether a portion of the upper slices falls inside the critical area // check whether a portion of the upper slices falls inside the critical area
const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area); const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area);

View File

@ -143,9 +143,9 @@ static std::vector<SLAAutoSupports::MyLayer> make_layers(
const float height = (layer_id>2 ? heights[layer_id-3] : heights[0]-(heights[1]-heights[0])); const float height = (layer_id>2 ? heights[layer_id-3] : heights[0]-(heights[1]-heights[0]));
const float layer_height = (layer_id!=0 ? heights[layer_id]-heights[layer_id-1] : heights[0]); const float layer_height = (layer_id!=0 ? heights[layer_id]-heights[layer_id-1] : heights[0]);
const float safe_angle = 5.f * (float(M_PI)/180.f); // smaller number - less supports const float safe_angle = 5.f * (float(M_PI)/180.f); // smaller number - less supports
const float between_layers_offset = float(scale_(layer_height / std::tan(safe_angle))); const double between_layers_offset = double(scale_(layer_height / std::tan(safe_angle)));
const float slope_angle = 75.f * (float(M_PI)/180.f); // smaller number - less supports const float slope_angle = 75.f * (float(M_PI)/180.f); // smaller number - less supports
const float slope_offset = float(scale_(layer_height / std::tan(slope_angle))); const double slope_offset = double(scale_(layer_height / std::tan(slope_angle)));
//FIXME This has a quadratic time complexity, it will be excessively slow for many tiny islands. //FIXME This has a quadratic time complexity, it will be excessively slow for many tiny islands.
for (SLAAutoSupports::Structure &top : layer_above.islands) { for (SLAAutoSupports::Structure &top : layer_above.islands) {
for (SLAAutoSupports::Structure &bottom : layer_below.islands) { for (SLAAutoSupports::Structure &bottom : layer_below.islands) {

View File

@ -1028,10 +1028,10 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
Polygons overhang_polygons; Polygons overhang_polygons;
Polygons contact_polygons; Polygons contact_polygons;
Polygons slices_margin_cached; Polygons slices_margin_cached;
float slices_margin_cached_offset = -1.; double slices_margin_cached_offset = -1.;
Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id-1]->slices.expolygons); Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id-1]->slices.expolygons);
// Offset of the lower layer, to trim the support polygons with to calculate dense supports. // Offset of the lower layer, to trim the support polygons with to calculate dense supports.
float no_interface_offset = 0.f; double no_interface_offset = 0.;
if (layer_id == 0) { if (layer_id == 0) {
// This is the first object layer, so the object is being printed on a raft and // This is the first object layer, so the object is being printed on a raft and
// we're here just to get the object footprint for the raft. // we're here just to get the object footprint for the raft.
@ -1045,8 +1045,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
for (LayerRegion *layerm : layer.regions()) { for (LayerRegion *layerm : layer.regions()) {
// Extrusion width accounts for the roundings of the extrudates. // Extrusion width accounts for the roundings of the extrudates.
// It is the maximum widh of the extrudate. // It is the maximum widh of the extrudate.
float fw = float(layerm->flow(frExternalPerimeter).scaled_width()); double fw = double(layerm->flow(frExternalPerimeter).scaled_width());
no_interface_offset = (no_interface_offset == 0.f) ? fw : std::min(no_interface_offset, fw); no_interface_offset = (no_interface_offset == 0.) ? fw : std::min(no_interface_offset, fw);
float lower_layer_offset = float lower_layer_offset =
(layer_id < m_object_config->support_material_enforce_layers.value) ? (layer_id < m_object_config->support_material_enforce_layers.value) ?
// Enforce a full possible support, ignore the overhang angle. // Enforce a full possible support, ignore the overhang angle.
@ -1163,12 +1163,12 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
//FIXME one should trim with the layer span colliding with the support layer, this layer //FIXME one should trim with the layer span colliding with the support layer, this layer
// may be lower than lower_layer, so the support area needed may need to be actually bigger! // may be lower than lower_layer, so the support area needed may need to be actually bigger!
// For the same reason, the non-bridging support area may be smaller than the bridging support area! // For the same reason, the non-bridging support area may be smaller than the bridging support area!
float slices_margin_offset = std::min(lower_layer_offset, float(scale_(m_gap_xy))); double slices_margin_offset = std::min(double(lower_layer_offset), double(scale_(m_gap_xy)));
if (slices_margin_cached_offset != slices_margin_offset) { if (slices_margin_cached_offset != slices_margin_offset) {
slices_margin_cached_offset = slices_margin_offset; slices_margin_cached_offset = slices_margin_offset;
slices_margin_cached = (slices_margin_offset == 0.f) ? slices_margin_cached = (slices_margin_offset == 0.f) ?
lower_layer_polygons : lower_layer_polygons :
offset2(to_polygons(lower_layer.slices.expolygons), - no_interface_offset * 0.5f, slices_margin_offset + no_interface_offset * 0.5f, SUPPORT_SURFACES_OFFSET_PARAMETERS); offset2(to_polygons(lower_layer.slices.expolygons), - no_interface_offset * 0.5, slices_margin_offset + no_interface_offset * 0.5, SUPPORT_SURFACES_OFFSET_PARAMETERS);
if (! buildplate_covered.empty()) { if (! buildplate_covered.empty()) {
// Trim the inflated contact surfaces by the top surfaces as well. // Trim the inflated contact surfaces by the top surfaces as well.
polygons_append(slices_margin_cached, buildplate_covered[layer_id]); polygons_append(slices_margin_cached, buildplate_covered[layer_id]);
@ -1180,7 +1180,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
diff_polygons = diff( diff_polygons = diff(
offset( offset(
diff_polygons, diff_polygons,
SUPPORT_MATERIAL_MARGIN / NUM_MARGIN_STEPS, double(SUPPORT_MATERIAL_MARGIN / NUM_MARGIN_STEPS),
ClipperLib::jtRound, ClipperLib::jtRound,
// round mitter limit // round mitter limit
scale_(0.05)), scale_(0.05)),
@ -1457,7 +1457,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
#endif #endif
// These are the overhang surfaces. They are touching the object and they are not expanded away from the object. // These are the overhang surfaces. They are touching the object and they are not expanded away from the object.
// Use a slight positive offset to overlap the touching regions. // Use a slight positive offset to overlap the touching regions.
polygons_append(polygons_new, offset(*top_contacts[contact_idx]->overhang_polygons, float(SCALED_EPSILON))); polygons_append(polygons_new, offset(*top_contacts[contact_idx]->overhang_polygons, double(SCALED_EPSILON)));
polygons_append(projection, union_(polygons_new)); polygons_append(projection, union_(polygons_new));
} }
if (projection.empty()) if (projection.empty())
@ -1512,7 +1512,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
layer_new.bridging = ! m_slicing_params.soluble_interface; layer_new.bridging = ! m_slicing_params.soluble_interface;
//FIXME how much to inflate the bottom surface, as it is being extruded with a bridging flow? The following line uses a normal flow. //FIXME how much to inflate the bottom surface, as it is being extruded with a bridging flow? The following line uses a normal flow.
//FIXME why is the offset positive? It will be trimmed by the object later on anyway, but then it just wastes CPU clocks. //FIXME why is the offset positive? It will be trimmed by the object later on anyway, but then it just wastes CPU clocks.
layer_new.polygons = offset(touching, float(m_support_material_flow.scaled_width()), SUPPORT_SURFACES_OFFSET_PARAMETERS); layer_new.polygons = offset(touching, double(m_support_material_flow.scaled_width()), SUPPORT_SURFACES_OFFSET_PARAMETERS);
if (! m_slicing_params.soluble_interface) { if (! m_slicing_params.soluble_interface) {
// Walk the top surfaces, snap the top of the new bottom surface to the closest top of the top surface, // Walk the top surfaces, snap the top of the new bottom surface to the closest top of the top surface,
// so there will be no support surfaces generated with thickness lower than m_support_layer_height_min. // so there will be no support surfaces generated with thickness lower than m_support_layer_height_min.
@ -1548,7 +1548,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
#endif /* SLIC3R_DEBUG */ #endif /* SLIC3R_DEBUG */
// Trim the already created base layers above the current layer intersecting with the new bottom contacts layer. // Trim the already created base layers above the current layer intersecting with the new bottom contacts layer.
//FIXME Maybe this is no more needed, as the overlapping base layers are trimmed by the bottom layers at the final stage? //FIXME Maybe this is no more needed, as the overlapping base layers are trimmed by the bottom layers at the final stage?
touching = offset(touching, float(SCALED_EPSILON)); touching = offset(touching, double(SCALED_EPSILON));
for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++ layer_id_above) { for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++ layer_id_above) {
const Layer &layer_above = *object.layers()[layer_id_above]; const Layer &layer_above = *object.layers()[layer_id_above];
if (layer_above.print_z > layer_new.print_z - EPSILON) if (layer_above.print_z > layer_new.print_z - EPSILON)
@ -1580,7 +1580,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
task_group.run([this, &projection, &projection_raw, &layer, &layer_support_area, layer_id] { task_group.run([this, &projection, &projection_raw, &layer, &layer_support_area, layer_id] {
// Remove the areas that touched from the projection that will continue on next, lower, top surfaces. // Remove the areas that touched from the projection that will continue on next, lower, top surfaces.
// Polygons trimming = union_(to_polygons(layer.slices.expolygons), touching, true); // Polygons trimming = union_(to_polygons(layer.slices.expolygons), touching, true);
Polygons trimming = offset(layer.slices.expolygons, float(SCALED_EPSILON)); Polygons trimming = offset(layer.slices.expolygons, double(SCALED_EPSILON));
projection = diff(projection_raw, trimming, false); projection = diff(projection_raw, trimming, false);
#ifdef SLIC3R_DEBUG #ifdef SLIC3R_DEBUG
{ {
@ -2653,7 +2653,7 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
// solution should be found to achieve both goals // solution should be found to achieve both goals
// Store the trimmed polygons into a separate polygon set, so the original infill area remains intact for // Store the trimmed polygons into a separate polygon set, so the original infill area remains intact for
// "modulate by layer thickness". // "modulate by layer thickness".
top_contact_layer.set_polygons_to_extrude(diff(top_contact_layer.layer->polygons, offset(loop_lines, float(circle_radius * 1.1)))); top_contact_layer.set_polygons_to_extrude(diff(top_contact_layer.layer->polygons, offset(loop_lines, double(circle_radius * 1.1))));
// Transform loops into ExtrusionPath objects. // Transform loops into ExtrusionPath objects.
extrusion_entities_append_paths( extrusion_entities_append_paths(
@ -2808,7 +2808,7 @@ void modulate_extrusion_by_overlapping_layers(
for (int i_overlapping_layer = int(n_overlapping_layers) - 1; i_overlapping_layer >= 0; -- i_overlapping_layer) { for (int i_overlapping_layer = int(n_overlapping_layers) - 1; i_overlapping_layer >= 0; -- i_overlapping_layer) {
const PrintObjectSupportMaterial::MyLayer &overlapping_layer = *overlapping_layers[i_overlapping_layer]; const PrintObjectSupportMaterial::MyLayer &overlapping_layer = *overlapping_layers[i_overlapping_layer];
ExtrusionPathFragment &frag = path_fragments[i_overlapping_layer]; ExtrusionPathFragment &frag = path_fragments[i_overlapping_layer];
Polygons polygons_trimming = offset(union_ex(overlapping_layer.polygons), float(scale_(0.5*extrusion_width))); Polygons polygons_trimming = offset(union_ex(overlapping_layer.polygons), double(scale_(0.5*extrusion_width)));
frag.polylines = intersection_pl(path_fragments.back().polylines, polygons_trimming, false); frag.polylines = intersection_pl(path_fragments.back().polylines, polygons_trimming, false);
path_fragments.back().polylines = diff_pl(path_fragments.back().polylines, polygons_trimming, false); path_fragments.back().polylines = diff_pl(path_fragments.back().polylines, polygons_trimming, false);
// Adjust the extrusion parameters for a reduced layer height and a non-bridging flow (nozzle_dmr = -1, does not matter). // Adjust the extrusion parameters for a reduced layer height and a non-bridging flow (nozzle_dmr = -1, does not matter).
@ -3049,14 +3049,14 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// find centerline of the external loop/extrusions // find centerline of the external loop/extrusions
ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ? ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ?
// union_ex(base_polygons, true) : // union_ex(base_polygons, true) :
offset2_ex(to_infill_polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)) : offset2_ex(to_infill_polygons, double(SCALED_EPSILON), double(- SCALED_EPSILON)) :
offset2_ex(to_infill_polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width())); offset2_ex(to_infill_polygons, double(SCALED_EPSILON), double(- SCALED_EPSILON - 0.5*flow.scaled_width()));
if (! to_infill.empty() && with_sheath) { if (! to_infill.empty() && with_sheath) {
// Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove. // Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove.
// TODO: use brim ordering algorithm // TODO: use brim ordering algorithm
to_infill_polygons = to_polygons(to_infill); to_infill_polygons = to_polygons(to_infill);
// TODO: use offset2_ex() // TODO: use offset2_ex()
to_infill = offset_ex(to_infill, float(- 0.4 * flow.scaled_spacing())); to_infill = offset_ex(to_infill, double(- 0.4 * flow.scaled_spacing()));
extrusion_entities_append_paths( extrusion_entities_append_paths(
support_layer.support_fills.entities, support_layer.support_fills.entities,
to_polylines(std::move(to_infill_polygons)), to_polylines(std::move(to_infill_polygons)),
@ -3111,7 +3111,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// Destination // Destination
support_layer.support_fills.entities, support_layer.support_fills.entities,
// Regions to fill // Regions to fill
offset2_ex(raft_layer.polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)), offset2_ex(raft_layer.polygons, double(SCALED_EPSILON), double(- SCALED_EPSILON)),
// Filler and its parameters // Filler and its parameters
filler, density, filler, density,
// Extrusion parameters // Extrusion parameters
@ -3267,8 +3267,8 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// find centerline of the external loop/extrusions // find centerline of the external loop/extrusions
ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ? ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ?
// union_ex(base_polygons, true) : // union_ex(base_polygons, true) :
offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON)) : offset2_ex(base_layer.polygons_to_extrude(), double(SCALED_EPSILON), double(- SCALED_EPSILON)) :
offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width())); offset2_ex(base_layer.polygons_to_extrude(), double(SCALED_EPSILON), double(- SCALED_EPSILON - 0.5*flow.scaled_width()));
if (base_layer.layer->bottom_z < EPSILON) { if (base_layer.layer->bottom_z < EPSILON) {
if (this->m_object_config->support_material_solid_first_layer.value) { if (this->m_object_config->support_material_solid_first_layer.value) {
// Base flange (the 1st layer). // Base flange (the 1st layer).
@ -3290,7 +3290,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// TODO: use brim ordering algorithm // TODO: use brim ordering algorithm
Polygons to_infill_polygons = to_polygons(to_infill); Polygons to_infill_polygons = to_polygons(to_infill);
// TODO: use offset2_ex() // TODO: use offset2_ex()
to_infill = offset_ex(to_infill, - 0.4 * float(flow.scaled_spacing())); to_infill = offset_ex(to_infill, double(- 0.4 * flow.scaled_spacing()));
extrusion_entities_append_paths( extrusion_entities_append_paths(
base_layer.extrusions.entities, base_layer.extrusions.entities,
to_polylines(std::move(to_infill_polygons)), to_polylines(std::move(to_infill_polygons)),