mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-24 15:13:58 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_custom_gcode_detection
This commit is contained in:
commit
c7771a576b
73 changed files with 2263 additions and 2165 deletions
|
@ -40,7 +40,7 @@ void BridgeDetector::initialize()
|
|||
this->angle = -1.;
|
||||
|
||||
// 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(this->expolygons, float(this->spacing));
|
||||
|
||||
// Detect possible anchoring edges of this bridging region.
|
||||
// Detect what edges lie on lower slices by turning bridge contour and holes
|
||||
|
|
|
@ -57,6 +57,7 @@ err:
|
|||
}
|
||||
#endif /* CLIPPER_UTILS_DEBUG */
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
void scaleClipperPolygon(ClipperLib::Path &polygon)
|
||||
{
|
||||
CLIPPERUTILS_PROFILE_FUNC();
|
||||
|
@ -98,6 +99,7 @@ void unscaleClipperPolygons(ClipperLib::Paths &polygons)
|
|||
pit->Y >>= CLIPPER_OFFSET_POWER_OF_2;
|
||||
}
|
||||
}
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// legacy code from Clipper documentation
|
||||
|
@ -222,8 +224,10 @@ ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polylines &input)
|
|||
|
||||
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// scale input
|
||||
scaleClipperPolygons(input);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
|
||||
// perform offset
|
||||
ClipperLib::ClipperOffset co;
|
||||
|
@ -231,14 +235,20 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
|
|||
co.ArcTolerance = miterLimit;
|
||||
else
|
||||
co.MiterLimit = miterLimit;
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled = delta;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||
co.AddPaths(input, joinType, endType);
|
||||
ClipperLib::Paths retval;
|
||||
co.Execute(retval, delta_scaled);
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// unscale output
|
||||
unscaleClipperPolygons(retval);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -257,14 +267,24 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
|||
{
|
||||
// printf("new ExPolygon offset\n");
|
||||
// 1) Offset the outer contour.
|
||||
const float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled = delta;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ClipperLib::Paths contours;
|
||||
{
|
||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(expolygon.contour);
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
scaleClipperPolygon(input);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound)
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
else
|
||||
co.MiterLimit = miterLimit;
|
||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||
|
@ -278,17 +298,23 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
|||
holes.reserve(expolygon.holes.size());
|
||||
for (Polygons::const_iterator it_hole = expolygon.holes.begin(); it_hole != expolygon.holes.end(); ++ it_hole) {
|
||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath_reversed(*it_hole);
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
scaleClipperPolygon(input);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound)
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
else
|
||||
co.MiterLimit = miterLimit;
|
||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||
co.AddPath(input, joinType, ClipperLib::etClosedPolygon);
|
||||
ClipperLib::Paths out;
|
||||
co.Execute(out, - delta_scaled);
|
||||
holes.insert(holes.end(), out.begin(), out.end());
|
||||
append(holes, std::move(out));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +331,9 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
|||
}
|
||||
|
||||
// 4) Unscale the output.
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
unscaleClipperPolygons(output);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -315,7 +343,11 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
|||
ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delta,
|
||||
ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
const float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled = delta;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
// Offsetted ExPolygons before they are united.
|
||||
ClipperLib::Paths contours_cummulative;
|
||||
contours_cummulative.reserve(expolygons.size());
|
||||
|
@ -327,10 +359,16 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
|
|||
ClipperLib::Paths contours;
|
||||
{
|
||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(it_expoly->contour);
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
scaleClipperPolygon(input);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound)
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
else
|
||||
co.MiterLimit = miterLimit;
|
||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||
|
@ -351,10 +389,16 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
|
|||
{
|
||||
for (Polygons::const_iterator it_hole = it_expoly->holes.begin(); it_hole != it_expoly->holes.end(); ++ it_hole) {
|
||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath_reversed(*it_hole);
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
scaleClipperPolygon(input);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound)
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ArcTolerance = miterLimit;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
else
|
||||
co.MiterLimit = miterLimit;
|
||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||
|
@ -413,8 +457,10 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
|
|||
output = std::move(contours_cummulative);
|
||||
}
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// 4) Unscale the output.
|
||||
unscaleClipperPolygons(output);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -425,8 +471,10 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
|
|||
// read input
|
||||
ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polygons);
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// scale input
|
||||
scaleClipperPolygons(input);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
|
||||
// prepare ClipperOffset object
|
||||
ClipperLib::ClipperOffset co;
|
||||
|
@ -435,8 +483,13 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
|
|||
} else {
|
||||
co.MiterLimit = miterLimit;
|
||||
}
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled1 = delta1 * float(CLIPPER_OFFSET_SCALE);
|
||||
float delta_scaled2 = delta2 * float(CLIPPER_OFFSET_SCALE);
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
float delta_scaled1 = delta1;
|
||||
float delta_scaled2 = delta2;
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.ShortestEdgeLength = double(std::max(std::abs(delta_scaled1), std::abs(delta_scaled2)) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR);
|
||||
|
||||
// perform first offset
|
||||
|
@ -450,8 +503,10 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
|
|||
ClipperLib::Paths retval;
|
||||
co.Execute(retval, delta_scaled2);
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// unscale output
|
||||
unscaleClipperPolygons(retval);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -789,8 +844,10 @@ void safety_offset(ClipperLib::Paths* paths)
|
|||
{
|
||||
CLIPPERUTILS_PROFILE_FUNC();
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// scale input
|
||||
scaleClipperPolygons(*paths);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
|
||||
// perform offset (delta = scale 1e-05)
|
||||
ClipperLib::ClipperOffset co;
|
||||
|
@ -816,7 +873,11 @@ void safety_offset(ClipperLib::Paths* paths)
|
|||
CLIPPERUTILS_PROFILE_BLOCK(safety_offset_Execute);
|
||||
// offset outside by 10um
|
||||
ClipperLib::Paths out_this;
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE));
|
||||
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||
co.Execute(out_this, ccw ? 10.f : -10.f);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
if (! ccw) {
|
||||
// Reverse the resulting contours once again.
|
||||
for (ClipperLib::Paths::iterator it = out_this.begin(); it != out_this.end(); ++ it)
|
||||
|
@ -830,8 +891,10 @@ void safety_offset(ClipperLib::Paths* paths)
|
|||
}
|
||||
*paths = std::move(out);
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// unscale output
|
||||
unscaleClipperPolygons(*paths);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
}
|
||||
|
||||
Polygons top_level_islands(const Slic3r::Polygons &polygons)
|
||||
|
@ -925,8 +988,10 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v
|
|||
|
||||
// Add a new point to the output, scale by CLIPPER_OFFSET_SCALE and round to ClipperLib::cInt.
|
||||
auto add_offset_point = [&out](Vec2d pt) {
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
pt *= double(CLIPPER_OFFSET_SCALE);
|
||||
pt += Vec2d(0.5 - (pt.x() < 0), 0.5 - (pt.y() < 0));
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
pt += Vec2d(0.5 - (pt.x() < 0), 0.5 - (pt.y() < 0));
|
||||
out.emplace_back(ClipperLib::cInt(pt.x()), ClipperLib::cInt(pt.y()));
|
||||
};
|
||||
|
||||
|
@ -1075,8 +1140,10 @@ Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::v
|
|||
clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
||||
}
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// 4) Unscale the output.
|
||||
unscaleClipperPolygons(output);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
return ClipperPaths_to_Slic3rPolygons(output);
|
||||
}
|
||||
|
||||
|
@ -1119,8 +1186,10 @@ for (const std::vector<float>& ds : deltas)
|
|||
clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
||||
}
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// 4) Unscale the output.
|
||||
unscaleClipperPolygons(output);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
return ClipperPaths_to_Slic3rPolygons(output);
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1221,9 @@ for (const std::vector<float>& ds : deltas)
|
|||
#endif /* NDEBUG */
|
||||
|
||||
// 3) Subtract holes from the contours.
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
unscaleClipperPolygons(contours);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ExPolygons output;
|
||||
if (holes.empty()) {
|
||||
output.reserve(contours.size());
|
||||
|
@ -1160,7 +1231,9 @@ for (const std::vector<float>& ds : deltas)
|
|||
output.emplace_back(ClipperPath_to_Slic3rPolygon(path));
|
||||
} else {
|
||||
ClipperLib::Clipper clipper;
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
unscaleClipperPolygons(holes);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
clipper.AddPaths(contours, ClipperLib::ptSubject, true);
|
||||
clipper.AddPaths(holes, ClipperLib::ptClip, true);
|
||||
ClipperLib::PolyTree polytree;
|
||||
|
@ -1200,7 +1273,9 @@ ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector<s
|
|||
#endif /* NDEBUG */
|
||||
|
||||
// 3) Subtract holes from the contours.
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
unscaleClipperPolygons(contours);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
ExPolygons output;
|
||||
if (holes.empty()) {
|
||||
output.reserve(contours.size());
|
||||
|
@ -1208,7 +1283,9 @@ ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector<s
|
|||
output.emplace_back(ClipperPath_to_Slic3rPolygon(path));
|
||||
} else {
|
||||
ClipperLib::Clipper clipper;
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
unscaleClipperPolygons(holes);
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
clipper.AddPaths(contours, ClipperLib::ptSubject, true);
|
||||
clipper.AddPaths(holes, ClipperLib::ptClip, true);
|
||||
ClipperLib::PolyTree polytree;
|
||||
|
|
|
@ -12,17 +12,23 @@ using ClipperLib::jtMiter;
|
|||
using ClipperLib::jtRound;
|
||||
using ClipperLib::jtSquare;
|
||||
|
||||
// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library
|
||||
// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset,
|
||||
// which is optionally executed by other functions (union, intersection, diff).
|
||||
// This scaling (cca 130t) is applied over the usual SCALING_FACTOR.
|
||||
// By the way, is the scalling for offset needed at all?
|
||||
// The reason to apply this scaling may be to match the resolution of the double mantissa.
|
||||
#define CLIPPER_OFFSET_POWER_OF_2 17
|
||||
// 2^17=131072
|
||||
#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2)
|
||||
#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1)
|
||||
#define CLIPPER_MAX_COORD_UNSCALED (ClipperLib::hiRange / CLIPPER_OFFSET_SCALE)
|
||||
#define CLIPPERUTILS_UNSAFE_OFFSET
|
||||
|
||||
// #define CLIPPERUTILS_OFFSET_SCALE
|
||||
|
||||
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||
// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library
|
||||
// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset,
|
||||
// which is optionally executed by other functions (union, intersection, diff).
|
||||
// This scaling (cca 130t) is applied over the usual SCALING_FACTOR.
|
||||
// By the way, is the scalling for offset needed at all?
|
||||
// The reason to apply this scaling may be to match the resolution of the double mantissa.
|
||||
#define CLIPPER_OFFSET_POWER_OF_2 17
|
||||
// 2^17=131072
|
||||
#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2)
|
||||
#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1)
|
||||
#define CLIPPER_MAX_COORD_UNSCALED (ClipperLib::hiRange / CLIPPER_OFFSET_SCALE)
|
||||
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -47,8 +53,11 @@ ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType,
|
|||
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float 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)
|
||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||
|
||||
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||
inline Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||
|
||||
// offset Polylines
|
||||
inline Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
|
||||
|
@ -65,13 +74,18 @@ inline Slic3r::Polygons offset(const Slic3r::ExPolygons &expolygons, const float
|
|||
{ 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)
|
||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||
|
||||
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||
|
||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||
{ 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)
|
||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
||||
|
||||
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
|
@ -81,6 +95,8 @@ Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1,
|
|||
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||
|
||||
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1,
|
||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
|
@ -319,6 +335,7 @@ void safety_offset(ClipperLib::Paths* paths);
|
|||
|
||||
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
||||
|
||||
ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::vector<float> &deltas, double miter_limit);
|
||||
Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||
Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||
ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||
|
|
|
@ -471,8 +471,8 @@ bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src,
|
|||
{
|
||||
t_config_option_key opt_key = opt_key_src;
|
||||
std::string value = value_src;
|
||||
// Both opt_key and value may be modified by _handle_legacy().
|
||||
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by _handle_legacy().
|
||||
// Both opt_key and value may be modified by handle_legacy().
|
||||
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
||||
this->handle_legacy(opt_key, value);
|
||||
if (opt_key.empty())
|
||||
// Ignore the option.
|
||||
|
|
|
@ -1967,8 +1967,9 @@ public:
|
|||
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
||||
// Thus the virtual method getInt() is used to retrieve the enum value.
|
||||
template<typename ENUM>
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return this->option<ConfigOptionEnum<ENUM>>(opt_key)->value; }
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||
|
||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||
|
|
|
@ -217,6 +217,28 @@ inline Polygons to_polygons(const ExPolygons &src)
|
|||
return polygons;
|
||||
}
|
||||
|
||||
inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygon &src)
|
||||
{
|
||||
ConstPolygonPtrs polygons;
|
||||
polygons.reserve(src.holes.size() + 1);
|
||||
polygons.emplace_back(&src.contour);
|
||||
for (const Polygon &hole : src.holes)
|
||||
polygons.emplace_back(&hole);
|
||||
return polygons;
|
||||
}
|
||||
|
||||
inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygons &src)
|
||||
{
|
||||
ConstPolygonPtrs polygons;
|
||||
polygons.reserve(number_polygons(src));
|
||||
for (const ExPolygon &expoly : src) {
|
||||
polygons.emplace_back(&expoly.contour);
|
||||
for (const Polygon &hole : expoly.holes)
|
||||
polygons.emplace_back(&hole);
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
|
||||
inline Polygons to_polygons(ExPolygon &&src)
|
||||
{
|
||||
Polygons polygons;
|
||||
|
|
|
@ -24,11 +24,11 @@ void FillConcentric::_fill_surface_single(
|
|||
this->spacing = unscale<double>(distance);
|
||||
}
|
||||
|
||||
Polygons loops = to_polygons(std::move(expolygon));
|
||||
Polygons last = loops;
|
||||
Polygons loops = to_polygons(expolygon);
|
||||
ExPolygons last { std::move(expolygon) };
|
||||
while (! last.empty()) {
|
||||
last = offset2(last, -(distance + min_spacing/2), +min_spacing/2);
|
||||
append(loops, last);
|
||||
last = offset2_ex(last, -(distance + min_spacing/2), +min_spacing/2);
|
||||
append(loops, to_polygons(last));
|
||||
}
|
||||
|
||||
// generate paths from the outermost to the innermost, to avoid
|
||||
|
|
|
@ -58,7 +58,7 @@ void FillLine::_fill_surface_single(
|
|||
pts.push_back(it->a);
|
||||
pts.push_back(it->b);
|
||||
}
|
||||
Polylines polylines = intersection_pl(polylines_src, offset(to_polygons(expolygon), scale_(0.02)), false);
|
||||
Polylines polylines = intersection_pl(polylines_src, offset(expolygon, scale_(0.02)), false);
|
||||
|
||||
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
|
||||
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
|
||||
|
|
|
@ -238,13 +238,14 @@ Flow support_material_flow(const PrintObject *object, float layer_height)
|
|||
|
||||
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
|
||||
{
|
||||
const auto &width = (object->print()->config().first_layer_extrusion_width.value > 0) ? object->print()->config().first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
||||
const PrintConfig &print_config = object->print()->config();
|
||||
const auto &width = (print_config.first_layer_extrusion_width.value > 0) ? print_config.first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
||||
return Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(width.value > 0) ? width : object->config().extrusion_width,
|
||||
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
|
||||
(layer_height > 0.f) ? layer_height : float(object->config().first_layer_height.get_abs_value(object->config().layer_height.value)));
|
||||
float(print_config.nozzle_diameter.get_at(object->config().support_material_extruder-1)),
|
||||
(layer_height > 0.f) ? layer_height : float(print_config.first_layer_height.get_abs_value(object->config().layer_height.value)));
|
||||
}
|
||||
|
||||
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
|
||||
|
|
|
@ -1111,7 +1111,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
|||
// Write some terse information on the slicing parameters.
|
||||
const PrintObject *first_object = print.objects().front();
|
||||
const double layer_height = first_object->config().layer_height.value;
|
||||
const double first_layer_height = first_object->config().first_layer_height.get_abs_value(layer_height);
|
||||
const double first_layer_height = print.config().first_layer_height.get_abs_value(layer_height);
|
||||
for (const PrintRegion* region : print.regions()) {
|
||||
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
|
||||
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
|
||||
|
@ -1778,6 +1778,10 @@ namespace ProcessLayer
|
|||
else {
|
||||
gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id);
|
||||
gcode += "\n";
|
||||
//FIXME Tell G-code writer that M600 filled the extruder, thus the G-code writer shall reset the extruder to unretracted state after
|
||||
// return from M600. Thus the G-code generated by the following line is ignored.
|
||||
// see GH issue #6362
|
||||
gcodegen.writer().unretract();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1087,11 +1087,13 @@ bool
|
|||
MedialAxis::validate_edge(const VD::edge_type* edge)
|
||||
{
|
||||
// prevent overflows and detect almost-infinite edges
|
||||
#ifndef CLIPPERLIB_INT32
|
||||
if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||
std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||
std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||
std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
|
||||
return false;
|
||||
#endif // CLIPPERLIB_INT32
|
||||
|
||||
// construct the line representing this edge of the Voronoi diagram
|
||||
const Line line(
|
||||
|
|
|
@ -216,7 +216,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
|
|||
break;
|
||||
}
|
||||
// Grown by 3mm.
|
||||
Polygons polys = offset(to_polygons(bridges[i].expolygon), margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
||||
Polygons polys = offset(bridges[i].expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
||||
if (idx_island == -1) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
|
||||
} else {
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
namespace Slic3r {
|
||||
|
||||
class Polygon;
|
||||
typedef std::vector<Polygon> Polygons;
|
||||
using Polygons = std::vector<Polygon>;
|
||||
using PolygonPtrs = std::vector<Polygon*>;
|
||||
using ConstPolygonPtrs = std::vector<const Polygon*>;
|
||||
|
||||
class Polygon : public MultiPoint
|
||||
{
|
||||
|
|
|
@ -296,6 +296,13 @@ void Preset::normalize(DynamicPrintConfig &config)
|
|||
if (auto *gap_fill_enabled = config.option<ConfigOptionBool>("gap_fill_enabled", false); gap_fill_enabled)
|
||||
gap_fill_enabled->value = false;
|
||||
}
|
||||
if (auto *first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height", false); first_layer_height && first_layer_height->percent)
|
||||
if (const auto *layer_height = config.option<ConfigOptionFloat>("layer_height", false); layer_height) {
|
||||
// Legacy conversion - first_layer_height moved from PrintObject setting to a Print setting, thus we are getting rid of the dependency
|
||||
// of first_layer_height on PrintObject specific layer_height. Covert the first layer heigth to an absolute value.
|
||||
first_layer_height->value = first_layer_height->get_abs_value(layer_height->value);
|
||||
first_layer_height->percent = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config)
|
||||
|
@ -427,7 +434,7 @@ const std::vector<std::string>& Preset::print_options()
|
|||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_style",
|
||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
||||
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
||||
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
||||
|
|
|
@ -995,10 +995,8 @@ void PrintConfigDef::init_fff_params()
|
|||
def->label = L("First layer height");
|
||||
def->category = L("Layers and Perimeters");
|
||||
def->tooltip = L("When printing with very low layer heights, you might still want to print a thicker "
|
||||
"bottom layer to improve adhesion and tolerance for non perfect build plates. "
|
||||
"This can be expressed as an absolute value or as a percentage (for example: 150%) "
|
||||
"over the default layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
"bottom layer to improve adhesion and tolerance for non perfect build plates.");
|
||||
def->sidetext = L("mm");
|
||||
def->ratio_over = "layer_height";
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0.35, false));
|
||||
|
||||
|
@ -2366,6 +2364,16 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(-1));
|
||||
|
||||
def = this->add("support_material_closing_radius", coFloat);
|
||||
def->label = L("Closing radius");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("For snug supports, the support regions will be merged using morphological closing operation."
|
||||
" Gaps smaller than the closing radius will be filled in.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(2));
|
||||
|
||||
def = this->add("support_material_interface_spacing", coFloat);
|
||||
def->label = L("Interface pattern spacing");
|
||||
def->category = L("Support material");
|
||||
|
@ -3618,7 +3626,7 @@ std::string FullPrintConfig::validate()
|
|||
return "--layer-height must be a multiple of print resolution";
|
||||
|
||||
// --first-layer-height
|
||||
if (this->get_abs_value("first_layer_height") <= 0)
|
||||
if (first_layer_height.value <= 0)
|
||||
return "Invalid value for --first-layer-height";
|
||||
|
||||
// --filament-diameter
|
||||
|
|
|
@ -496,7 +496,6 @@ public:
|
|||
ConfigOptionBool dont_support_bridges;
|
||||
ConfigOptionFloat elefant_foot_compensation;
|
||||
ConfigOptionFloatOrPercent extrusion_width;
|
||||
ConfigOptionFloatOrPercent first_layer_height;
|
||||
ConfigOptionBool infill_only_where_needed;
|
||||
// Force the generation of solid shells between adjacent materials/volumes.
|
||||
ConfigOptionBool interface_shells;
|
||||
|
@ -530,6 +529,8 @@ public:
|
|||
ConfigOptionFloatOrPercent support_material_interface_speed;
|
||||
ConfigOptionEnum<SupportMaterialPattern> support_material_pattern;
|
||||
ConfigOptionEnum<SupportMaterialInterfacePattern> support_material_interface_pattern;
|
||||
// Morphological closing of support areas. Only used for "sung" supports.
|
||||
ConfigOptionFloat support_material_closing_radius;
|
||||
// Spacing between support material lines (the hatching distance).
|
||||
ConfigOptionFloat support_material_spacing;
|
||||
ConfigOptionFloat support_material_speed;
|
||||
|
@ -553,7 +554,6 @@ protected:
|
|||
OPT_PTR(dont_support_bridges);
|
||||
OPT_PTR(elefant_foot_compensation);
|
||||
OPT_PTR(extrusion_width);
|
||||
OPT_PTR(first_layer_height);
|
||||
OPT_PTR(infill_only_where_needed);
|
||||
OPT_PTR(interface_shells);
|
||||
OPT_PTR(layer_height);
|
||||
|
@ -579,6 +579,7 @@ protected:
|
|||
OPT_PTR(support_material_interface_extruder);
|
||||
OPT_PTR(support_material_interface_layers);
|
||||
OPT_PTR(support_material_bottom_interface_layers);
|
||||
OPT_PTR(support_material_closing_radius);
|
||||
OPT_PTR(support_material_interface_spacing);
|
||||
OPT_PTR(support_material_interface_speed);
|
||||
OPT_PTR(support_material_pattern);
|
||||
|
@ -947,6 +948,7 @@ public:
|
|||
ConfigOptionFloat first_layer_acceleration;
|
||||
ConfigOptionInts first_layer_bed_temperature;
|
||||
ConfigOptionFloatOrPercent first_layer_extrusion_width;
|
||||
ConfigOptionFloatOrPercent first_layer_height;
|
||||
ConfigOptionFloatOrPercent first_layer_speed;
|
||||
ConfigOptionInts first_layer_temperature;
|
||||
ConfigOptionInts full_fan_speed_layer;
|
||||
|
@ -1022,6 +1024,7 @@ protected:
|
|||
OPT_PTR(first_layer_acceleration);
|
||||
OPT_PTR(first_layer_bed_temperature);
|
||||
OPT_PTR(first_layer_extrusion_width);
|
||||
OPT_PTR(first_layer_height);
|
||||
OPT_PTR(first_layer_speed);
|
||||
OPT_PTR(first_layer_temperature);
|
||||
OPT_PTR(full_fan_speed_layer);
|
||||
|
|
|
@ -591,6 +591,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "support_material_style"
|
||||
|| opt_key == "support_material_xy_spacing"
|
||||
|| opt_key == "support_material_spacing"
|
||||
|| opt_key == "support_material_closing_radius"
|
||||
|| opt_key == "support_material_synchronize_layers"
|
||||
|| opt_key == "support_material_threshold"
|
||||
|| opt_key == "support_material_with_sheath"
|
||||
|
|
|
@ -64,9 +64,9 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||
coordf_t object_height,
|
||||
const std::vector<unsigned int> &object_extruders)
|
||||
{
|
||||
coordf_t first_layer_height = (object_config.first_layer_height.value <= 0) ?
|
||||
coordf_t first_layer_height = (print_config.first_layer_height.value <= 0) ?
|
||||
object_config.layer_height.value :
|
||||
object_config.first_layer_height.get_abs_value(object_config.layer_height.value);
|
||||
print_config.first_layer_height.get_abs_value(object_config.layer_height.value);
|
||||
// If object_config.support_material_extruder == 0 resp. object_config.support_material_interface_extruder == 0,
|
||||
// print_config.nozzle_diameter.get_at(size_t(-1)) returns the 0th nozzle diameter,
|
||||
// which is consistent with the requirement that if support_material_extruder == 0 resp. support_material_interface_extruder == 0,
|
||||
|
|
|
@ -672,6 +672,7 @@ struct SupportGridParams {
|
|||
grid_resolution(object_config.support_material_spacing.value + support_material_flow.spacing()),
|
||||
support_angle(Geometry::deg2rad(object_config.support_material_angle.value)),
|
||||
extrusion_width(support_material_flow.spacing()),
|
||||
support_material_closing_radius(object_config.support_material_closing_radius.value),
|
||||
expansion_to_slice(coord_t(support_material_flow.scaled_spacing() / 2 + 5)),
|
||||
expansion_to_propagate(-3) {}
|
||||
|
||||
|
@ -679,6 +680,7 @@ struct SupportGridParams {
|
|||
double grid_resolution;
|
||||
double support_angle;
|
||||
double extrusion_width;
|
||||
double support_material_closing_radius;
|
||||
coord_t expansion_to_slice;
|
||||
coord_t expansion_to_propagate;
|
||||
};
|
||||
|
@ -694,7 +696,9 @@ public:
|
|||
const SupportGridParams ¶ms) :
|
||||
m_style(params.style),
|
||||
m_support_polygons(support_polygons), m_trimming_polygons(trimming_polygons),
|
||||
m_support_spacing(params.grid_resolution), m_support_angle(params.support_angle)
|
||||
m_support_spacing(params.grid_resolution), m_support_angle(params.support_angle),
|
||||
m_extrusion_width(params.extrusion_width),
|
||||
m_support_material_closing_radius(params.support_material_closing_radius)
|
||||
{
|
||||
switch (m_style) {
|
||||
case smsGrid:
|
||||
|
@ -878,9 +882,10 @@ public:
|
|||
return out;
|
||||
}
|
||||
case smsSnug:
|
||||
// Just close the gaps.
|
||||
float thr = scaled<float>(0.5);
|
||||
return smooth_outward(offset(offset_ex(*m_support_polygons, thr), - thr), thr);
|
||||
// Merge the support polygons by applying morphological closing and inwards smoothing.
|
||||
auto closing_distance = scaled<float>(m_support_material_closing_radius);
|
||||
auto smoothing_distance = scaled<float>(m_extrusion_width);
|
||||
return smooth_outward(offset(offset_ex(*m_support_polygons, closing_distance), - closing_distance), smoothing_distance);
|
||||
}
|
||||
assert(false);
|
||||
return Polygons();
|
||||
|
@ -1128,6 +1133,9 @@ private:
|
|||
coordf_t m_support_angle;
|
||||
// X spacing of the support lines parallel with the Y axis.
|
||||
coordf_t m_support_spacing;
|
||||
coordf_t m_extrusion_width;
|
||||
// For snug supports: Morphological closing of support areas.
|
||||
coordf_t m_support_material_closing_radius;
|
||||
|
||||
#ifdef SUPPORT_USE_AGG_RASTERIZER
|
||||
Vec2i m_grid_size;
|
||||
|
@ -3178,7 +3186,7 @@ struct MyLayerExtruded
|
|||
MyLayerExtruded& operator=(MyLayerExtruded &&rhs) {
|
||||
this->layer = rhs.layer;
|
||||
this->extrusions = std::move(rhs.extrusions);
|
||||
this->m_polygons_to_extrude = std::move(m_polygons_to_extrude);
|
||||
this->m_polygons_to_extrude = std::move(rhs.m_polygons_to_extrude);
|
||||
rhs.layer = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#define ENABLE_GCODE_WINDOW (1 && ENABLE_2_4_0_ALPHA0)
|
||||
// Enable exporting lines M73 for remaining time to next printer stop to gcode
|
||||
#define ENABLE_EXTENDED_M73_LINES (1 && ENABLE_VALIDATE_CUSTOM_GCODE)
|
||||
// Enable a modified version of automatic downscale on load of objects too big
|
||||
#define ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG (1 && ENABLE_2_4_0_ALPHA0)
|
||||
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
|
|
@ -511,20 +511,22 @@ void TriangleMesh::merge(const TriangleMesh &mesh)
|
|||
//FIXME This could be extremely slow! Use it for tiny meshes only!
|
||||
ExPolygons TriangleMesh::horizontal_projection() const
|
||||
{
|
||||
Polygons pp;
|
||||
pp.reserve(this->stl.stats.number_of_facets);
|
||||
ClipperLib::Paths paths;
|
||||
Polygon p;
|
||||
p.points.assign(3, Point());
|
||||
auto delta = scaled<float>(0.01);
|
||||
std::vector<float> deltas { delta, delta, delta };
|
||||
paths.reserve(this->stl.stats.number_of_facets);
|
||||
for (const stl_facet &facet : this->stl.facet_start) {
|
||||
Polygon p;
|
||||
p.points.resize(3);
|
||||
p.points[0] = Point::new_scale(facet.vertex[0](0), facet.vertex[0](1));
|
||||
p.points[1] = Point::new_scale(facet.vertex[1](0), facet.vertex[1](1));
|
||||
p.points[2] = Point::new_scale(facet.vertex[2](0), facet.vertex[2](1));
|
||||
p.make_counter_clockwise(); // do this after scaling, as winding order might change while doing that
|
||||
pp.emplace_back(p);
|
||||
p.make_counter_clockwise();
|
||||
paths.emplace_back(mittered_offset_path_scaled(p.points, deltas, 3.));
|
||||
}
|
||||
|
||||
// the offset factor was tuned using groovemount.stl
|
||||
return union_ex(offset(pp, scale_(0.01)), true);
|
||||
return ClipperPaths_to_Slic3rExPolygons(paths);
|
||||
}
|
||||
|
||||
// 2D convex hull of a 3D mesh projected into the Z=0 plane.
|
||||
|
@ -1797,7 +1799,7 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, const float clos
|
|||
|
||||
// append to the supplied collection
|
||||
if (safety_offset > 0)
|
||||
expolygons_append(*slices, offset2_ex(union_(loops, false), +safety_offset, -safety_offset));
|
||||
expolygons_append(*slices, offset2_ex(union_ex(loops, false), +safety_offset, -safety_offset));
|
||||
else
|
||||
expolygons_append(*slices, union_ex(loops, false));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue