mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-27 15:32:02 +08:00
medial_axis changes from review
This commit is contained in:
parent
ad3b2879e8
commit
9a827d1a8b
@ -606,6 +606,17 @@ MedialAxis::fusion_corners(ThickPolylines &pp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MedialAxis::extends_line_both_side(ThickPolylines& pp) {
|
||||||
|
const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION);
|
||||||
|
for (size_t i = 0; i < pp.size(); ++i) {
|
||||||
|
ThickPolyline& polyline = pp[i];
|
||||||
|
this->extends_line(polyline, anchors, this->min_width);
|
||||||
|
polyline.reverse();
|
||||||
|
this->extends_line(polyline, anchors, this->min_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width)
|
MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width)
|
||||||
{
|
{
|
||||||
@ -722,6 +733,11 @@ void
|
|||||||
MedialAxis::main_fusion(ThickPolylines& pp)
|
MedialAxis::main_fusion(ThickPolylines& pp)
|
||||||
{
|
{
|
||||||
//int idf = 0;
|
//int idf = 0;
|
||||||
|
|
||||||
|
bool changes = true;
|
||||||
|
map<Point, double> coeff_angle_cache;
|
||||||
|
while (changes) {
|
||||||
|
concatThickPolylines(pp);
|
||||||
//reoder pp by length (ascending) It's really important to do that to avoid building the line from the width insteand of the length
|
//reoder pp by length (ascending) It's really important to do that to avoid building the line from the width insteand of the length
|
||||||
std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) {
|
std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) {
|
||||||
bool ahas0 = a.width.front() == 0 || a.width.back() == 0;
|
bool ahas0 = a.width.front() == 0 || a.width.back() == 0;
|
||||||
@ -730,10 +746,6 @@ MedialAxis::main_fusion(ThickPolylines& pp)
|
|||||||
if (!ahas0 && bhas0) return false;
|
if (!ahas0 && bhas0) return false;
|
||||||
return a.length() < b.length();
|
return a.length() < b.length();
|
||||||
});
|
});
|
||||||
|
|
||||||
bool changes = true;
|
|
||||||
map<Point, double> coeff_angle_cache;
|
|
||||||
while (changes) {
|
|
||||||
changes = false;
|
changes = false;
|
||||||
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];
|
||||||
@ -962,12 +974,12 @@ MedialAxis::main_fusion(ThickPolylines& pp)
|
|||||||
//Add last point
|
//Add last point
|
||||||
polyline.points.push_back(best_candidate->points[idx_point]);
|
polyline.points.push_back(best_candidate->points[idx_point]);
|
||||||
polyline.width.push_back(best_candidate->width[idx_point]);
|
polyline.width.push_back(best_candidate->width[idx_point]);
|
||||||
//select if an end opccur
|
//select if an end occur
|
||||||
polyline.endpoints.second &= best_candidate->endpoints.second;
|
polyline.endpoints.second &= best_candidate->endpoints.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//select if an end opccur
|
//select if an end occur
|
||||||
polyline.endpoints.second &= best_candidate->endpoints.second;
|
polyline.endpoints.second &= best_candidate->endpoints.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,17 +1030,6 @@ MedialAxis::main_fusion(ThickPolylines& pp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changes) {
|
|
||||||
concatThickPolylines(pp);
|
|
||||||
///reorder, in case of change
|
|
||||||
std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) {
|
|
||||||
bool ahas0 = a.width.front() == 0 || a.width.back() == 0;
|
|
||||||
bool bhas0 = b.width.front() == 0 || b.width.back() == 0;
|
|
||||||
if (ahas0 && !bhas0) return true;
|
|
||||||
if (!ahas0 && bhas0) return false;
|
|
||||||
return a.length() < b.length();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1239,7 +1240,7 @@ MedialAxis::remove_too_short_polylines(ThickPolylines& pp, const coord_t min_siz
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shortest_idx >= 0 && shortest_idx < pp.size()) {
|
if (shortest_idx < pp.size()) {
|
||||||
pp.erase(pp.begin() + shortest_idx);
|
pp.erase(pp.begin() + shortest_idx);
|
||||||
changes = true;
|
changes = true;
|
||||||
}
|
}
|
||||||
@ -1255,7 +1256,7 @@ MedialAxis::ensure_not_overextrude(ThickPolylines& pp)
|
|||||||
double surface = 0;
|
double surface = 0;
|
||||||
double volume = 0;
|
double volume = 0;
|
||||||
for (ThickPolyline& polyline : pp) {
|
for (ThickPolyline& polyline : pp) {
|
||||||
for (ThickLine l : polyline.thicklines()) {
|
for (ThickLine &l : polyline.thicklines()) {
|
||||||
surface += l.length() * (l.a_width + l.b_width) / 2;
|
surface += l.length() * (l.a_width + l.b_width) / 2;
|
||||||
double width_mean = (l.a_width + l.b_width) / 2;
|
double width_mean = (l.a_width + l.b_width) / 2;
|
||||||
volume += height * (width_mean - height * (1. - 0.25 * PI)) * l.length();
|
volume += height * (width_mean - height * (1. - 0.25 * PI)) * l.length();
|
||||||
@ -1269,8 +1270,8 @@ MedialAxis::ensure_not_overextrude(ThickPolylines& pp)
|
|||||||
double perimeterRoundGap = bounds.contour.length() * height * (1 - 0.25*PI) * 0.5;
|
double perimeterRoundGap = bounds.contour.length() * height * (1 - 0.25*PI) * 0.5;
|
||||||
// add holes "perimeter gaps"
|
// add holes "perimeter gaps"
|
||||||
double holesGaps = 0;
|
double holesGaps = 0;
|
||||||
for (auto hole = bounds.holes.begin(); hole != bounds.holes.end(); ++hole) {
|
for (const Polygon &hole : bounds.holes) {
|
||||||
holesGaps += hole->length() * height * (1 - 0.25*PI) * 0.5;
|
holesGaps += hole.length() * height * (1 - 0.25*PI) * 0.5;
|
||||||
}
|
}
|
||||||
boundsVolume += perimeterRoundGap + holesGaps;
|
boundsVolume += perimeterRoundGap + holesGaps;
|
||||||
|
|
||||||
@ -1278,7 +1279,7 @@ MedialAxis::ensure_not_overextrude(ThickPolylines& pp)
|
|||||||
//reduce width
|
//reduce width
|
||||||
double reduce_by = boundsVolume / volume;
|
double reduce_by = boundsVolume / volume;
|
||||||
for (ThickPolyline& polyline : pp) {
|
for (ThickPolyline& polyline : pp) {
|
||||||
for (ThickLine l : polyline.thicklines()) {
|
for (ThickLine &l : polyline.thicklines()) {
|
||||||
l.a_width *= reduce_by;
|
l.a_width *= reduce_by;
|
||||||
l.b_width *= reduce_by;
|
l.b_width *= reduce_by;
|
||||||
}
|
}
|
||||||
@ -1291,8 +1292,7 @@ MedialAxis::simplify_polygon_frontier()
|
|||||||
{
|
{
|
||||||
|
|
||||||
//simplify the boundary between us and the bounds.
|
//simplify the boundary between us and the bounds.
|
||||||
//int firstIdx = 0;
|
//it will remove every point in the surface contour that aren't on the bounds contour
|
||||||
//while (firstIdx < contour.points.size() && bounds.contour.contains(contour.points[firstIdx])) firstIdx++;
|
|
||||||
ExPolygon simplified_poly = this->surface;
|
ExPolygon simplified_poly = this->surface;
|
||||||
if (&this->surface != &this->bounds) {
|
if (&this->surface != &this->bounds) {
|
||||||
bool need_intersect = false;
|
bool need_intersect = false;
|
||||||
@ -1410,14 +1410,8 @@ MedialAxis::build(ThickPolylines* polylines_out)
|
|||||||
//fusion right-angle corners.
|
//fusion right-angle corners.
|
||||||
fusion_corners(pp);
|
fusion_corners(pp);
|
||||||
|
|
||||||
if (do_not_overextrude) {
|
if (stop_at_min_width) {
|
||||||
const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION);
|
extends_line_both_side(pp);
|
||||||
for (size_t i = 0; i < pp.size(); ++i) {
|
|
||||||
ThickPolyline& polyline = pp[i];
|
|
||||||
extends_line(polyline, anchors, min_width);
|
|
||||||
polyline.reverse();
|
|
||||||
extends_line(polyline, anchors, min_width);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//reduce extrusion when it's too thin to be printable
|
//reduce extrusion when it's too thin to be printable
|
||||||
@ -1445,14 +1439,8 @@ MedialAxis::build(ThickPolylines* polylines_out)
|
|||||||
|
|
||||||
// Loop through all returned polylines in order to extend their endpoints to the
|
// Loop through all returned polylines in order to extend their endpoints to the
|
||||||
// expolygon boundaries
|
// expolygon boundaries
|
||||||
if (!do_not_overextrude) {
|
if (!stop_at_min_width) {
|
||||||
const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION);
|
extends_line_both_side(pp);
|
||||||
for (size_t i = 0; i < pp.size(); ++i) {
|
|
||||||
ThickPolyline& polyline = pp[i];
|
|
||||||
extends_line(polyline, anchors, min_width);
|
|
||||||
polyline.reverse();
|
|
||||||
extends_line(polyline, anchors, min_width);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//{
|
//{
|
||||||
// stringstream stri;
|
// stringstream stri;
|
||||||
|
@ -17,14 +17,14 @@ namespace Slic3r {
|
|||||||
|
|
||||||
class MedialAxis {
|
class MedialAxis {
|
||||||
public:
|
public:
|
||||||
Lines lines; //lines is here only to avoid appassing it in argument of amny method. Initialized in polyline_from_voronoi.
|
Lines lines; //lines is here only to avoid passing it in argument of many methods. Initialized in polyline_from_voronoi.
|
||||||
ExPolygon expolygon;
|
ExPolygon expolygon;
|
||||||
const ExPolygon& bounds;
|
const ExPolygon& bounds;
|
||||||
const ExPolygon& surface;
|
const ExPolygon& surface;
|
||||||
const double max_width;
|
const double max_width;
|
||||||
const double min_width;
|
const double min_width;
|
||||||
const double height;
|
const double height;
|
||||||
bool do_not_overextrude = true;
|
bool stop_at_min_width = true;
|
||||||
MedialAxis(const ExPolygon &_expolygon, const ExPolygon &_bounds, const double _max_width, const double _min_width, const double _height)
|
MedialAxis(const ExPolygon &_expolygon, const ExPolygon &_bounds, const double _max_width, const double _min_width, const double _height)
|
||||||
: surface(_expolygon), bounds(_bounds), max_width(_max_width), min_width(_min_width), height(_height) {
|
: surface(_expolygon), bounds(_bounds), max_width(_max_width), min_width(_min_width), height(_height) {
|
||||||
};
|
};
|
||||||
@ -53,6 +53,7 @@ namespace Slic3r {
|
|||||||
void fusion_curve(ThickPolylines &pp);
|
void fusion_curve(ThickPolylines &pp);
|
||||||
void main_fusion(ThickPolylines& pp);
|
void main_fusion(ThickPolylines& pp);
|
||||||
void fusion_corners(ThickPolylines &pp);
|
void fusion_corners(ThickPolylines &pp);
|
||||||
|
void extends_line_both_side(ThickPolylines& pp);
|
||||||
void extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width);
|
void extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width);
|
||||||
void remove_too_thin_extrusion(ThickPolylines& pp);
|
void remove_too_thin_extrusion(ThickPolylines& pp);
|
||||||
void concatenate_polylines_with_crossing(ThickPolylines& pp);
|
void concatenate_polylines_with_crossing(ThickPolylines& pp);
|
||||||
|
@ -286,7 +286,7 @@ void PerimeterGenerator::process()
|
|||||||
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, (float)(min_width / 2));
|
||||||
if (thin.size() != 1) continue; // impossible error, growing a single polygon can't create multiple or 0.
|
assert(thin.size() == 1);
|
||||||
ExPolygons anchor = intersection_ex(offset_ex(half_thin, (float)(min_width / 2) +
|
ExPolygons anchor = intersection_ex(offset_ex(half_thin, (float)(min_width / 2) +
|
||||||
(float)(ext_perimeter_width / 2), jtSquare), no_thin_zone, true);
|
(float)(ext_perimeter_width / 2), jtSquare), no_thin_zone, true);
|
||||||
ExPolygons bounds = union_ex(thin, anchor, true);
|
ExPolygons bounds = union_ex(thin, anchor, true);
|
||||||
|
@ -132,7 +132,7 @@ bool remove_degenerate(Polylines &polylines);
|
|||||||
|
|
||||||
|
|
||||||
/// ThickPolyline : a polyline with a width for each point
|
/// ThickPolyline : a polyline with a width for each point
|
||||||
/// This calss has a vector of coordf_t, it must be the same size than points.
|
/// This class has a vector of coordf_t, it must be the same size as points.
|
||||||
/// it's used to store the size of the line at this point.
|
/// it's used to store the size of the line at this point.
|
||||||
/// Also, the endpoint let us know if the front() and back() of the polyline
|
/// Also, the endpoint let us know if the front() and back() of the polyline
|
||||||
/// join something or is a dead-end.
|
/// join something or is a dead-end.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user