diff options
author | supermerill <merill@fr.fr> | 2018-08-09 19:33:11 +0300 |
---|---|---|
committer | supermerill <merill@fr.fr> | 2018-08-09 19:33:11 +0300 |
commit | 350a0c8f2759b172bb00687aba0c09e145308df4 (patch) | |
tree | 20b6df1c59979fed0fe7947d1c3026ce13d8ad6a | |
parent | 973a7a276a6809c5c17377bd6d6446306c28fd88 (diff) |
cleaningthin_wall_tests
-rw-r--r-- | xs/src/libslic3r/ExPolygon.cpp | 317 | ||||
-rw-r--r-- | xs/src/libslic3r/Geometry.cpp | 55 | ||||
-rw-r--r-- | xs/src/libslic3r/PerimeterGenerator.cpp | 32 | ||||
-rw-r--r-- | xs/src/libslic3r/Polyline.cpp | 54 |
4 files changed, 60 insertions, 398 deletions
diff --git a/xs/src/libslic3r/ExPolygon.cpp b/xs/src/libslic3r/ExPolygon.cpp index be61559ce..aa35d8817 100644 --- a/xs/src/libslic3r/ExPolygon.cpp +++ b/xs/src/libslic3r/ExPolygon.cpp @@ -206,14 +206,13 @@ void ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const append(*expolygons, this->simplify(tolerance)); } -int id = 0; - +/// remove point that are at SCALED_EPSILON * 2 distance. void remove_point_too_near(ThickPolyline* to_reduce) { const int32_t smallest = SCALED_EPSILON * 2; uint32_t id = 1; while (id < to_reduce->points.size() - 2) { - uint32_t newdist = min(to_reduce->points[id].distance_to(to_reduce->points[id + 1]) - , to_reduce->points[id + 1].distance_to(to_reduce->points[id + 2])); + uint32_t newdist = min(to_reduce->points[id].distance_to(to_reduce->points[id - 1]) + , to_reduce->points[id].distance_to(to_reduce->points[id + 1])); if (newdist < smallest) { to_reduce->points.erase(to_reduce->points.begin() + id); to_reduce->get_width().erase(to_reduce->get_width().begin() + id); @@ -221,9 +220,10 @@ void remove_point_too_near(ThickPolyline* to_reduce) { ++id; } } - // "fusion" } +/// add points from pattern to to_modify at the same % of the length +/// so not add if an other point is present at the correct position void add_point_same_percent(ThickPolyline* pattern, ThickPolyline* to_modify) { for (uint32_t idx_point = 1; idx_point < pattern->points.size() - 1; ++idx_point) { @@ -249,30 +249,24 @@ void add_point_same_percent(ThickPolyline* pattern, ThickPolyline* to_modify) { double percent_dist = (percent_length - percent_before) / (percent_length_other - percent_before); coordf_t new_width = to_modify->width2[idx_other - 1] * (1 - percent_dist); new_width += to_modify->width2[idx_other] * (percent_dist); - std::cout << idx_point << " new width : " << unscale(to_modify->width2[idx_other - 1]) << "->" << unscale(to_modify->width2[idx_other]) << ", " - << percent_before << "->" << percent_length << "->" << percent_length_other << " => " - << (1 - percent_dist) << " + " << ( percent_dist) - << " = 1? "<<((1 - percent_dist) + ( percent_dist)) - << ", res=" << unscale(new_width) << "\n"; Point new_point; new_point.x = to_modify->points[idx_other - 1].x * (1 - percent_dist); new_point.x += to_modify->points[idx_other].x * ( percent_dist); - std::cout << idx_point << " new x : " << unscale(to_modify->points[idx_other - 1].x) << "->" << unscale(to_modify->points[idx_other].x) << ", " - << percent_before << "->" << percent_length << "->" << percent_length_other << " => " << unscale(new_point.x) << "\n"; new_point.y = to_modify->points[idx_other - 1].y * (1 - percent_dist); new_point.y += to_modify->points[idx_other].y * ( percent_dist); - std::cout << idx_point << " new y : " << unscale(to_modify->points[idx_other - 1].y) << "->" << unscale(to_modify->points[idx_other].y) << ", " - << percent_before << "->" << percent_length << "->" << percent_length_other << " => " << unscale(new_point.y) << "\n"; to_modify->width2.insert(to_modify->width2.begin() + idx_other, new_width); to_modify->points.insert(to_modify->points.begin() + idx_other, new_point); } else if (percent_length_other > percent_length + percent_epsilon){ - std::cout << "Same point, " << percent_length_other << " < " << percent_length << " (epsilon=" << percent_epsilon << ")\n"; + // std::cout << "Same point, " << percent_length_other << " < " << percent_length << " (epsilon=" << percent_epsilon << ")\n"; } else { //impossible - std::cout << "Error, " << percent_length_other << " < " << percent_length << " and we are at the end (==1)\n"; + //std::cout << "Error, " << percent_length_other << " < " << percent_length << " and we are at the end (==1)\n"; } } } + +/// find the nearest angle in the contour (or 2 nearest if it's difficult to choose) +/// return 1 for an angle of 90° and 0 for an angle of 0° or 180° double get_coeff_from_angle_countour(Point &point, const ExPolygon &contour) { double nearestDist = point.distance_to(contour.contour.points.front()); Point nearest = contour.contour.points.front(); @@ -296,7 +290,7 @@ double get_coeff_from_angle_countour(Point &point, const ExPolygon &contour) { angle = min(nearest.ccw_angle(point_before, point_after), nearest.ccw_angle(point_after, point_before)); //compute the diff from 90° angle = abs(angle - PI / 2); - if (near != nearest && max(nearestDist, nearDist) < nearest.distance_to(near)) { + if (near != nearest && max(nearestDist, nearDist) + SCALED_EPSILON < nearest.distance_to(near)) { //not only nearest Point point_before = id_near == 0 ? contour.contour.points.back() : contour.contour.points[id_near - 1]; Point point_after = id_near == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_near + 1]; @@ -304,7 +298,8 @@ double get_coeff_from_angle_countour(Point &point, const ExPolygon &contour) { angle2 = abs(angle - PI / 2); angle = (angle + angle2) / 2; } - return sqrt(1-(angle/(PI/2))); + + return 1-(angle/(PI/2)); } void @@ -318,22 +313,12 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid ThickPolylines pp; ma.build(&pp); - //for (Lines lines : ma.lines) { - // cout << "lines " << lines.size() << ": "; - // for (Line line : lines) { - // cout << ", " << unscale(line.a.x) << ":" << unscale(line.a.y) << "->" << unscale(line.b.x) << ":" << unscale(line.b.y); - // } - // cout << "\n"; - //} - //cout << "\n"; - std::cout << " ###################### medial_axis " << layer_id << "_" << id << " #####################\n"; - stringstream stri; - stri << id << "-1-medial_axis" << layer_id << "_" << id << ".svg"; - SVG svg(stri.str()); - svg.draw(*this); - svg.draw(pp); - svg.Close(); - int id_f=0; + //stringstream stri; + //stri << id << "-1-medial_axis" << layer_id << "_" << id << ".svg"; + //SVG svg(stri.str()); + //svg.draw(*this); + //svg.draw(pp); + //svg.Close(); /* Find the maximum width returned; we're going to use this for validating and filtering the output segments. */ @@ -341,40 +326,15 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid for (ThickPolylines::const_iterator it = pp.begin(); it != pp.end(); ++it) max_w = fmaxf(max_w, *std::max_element(it->width2.begin(), it->width2.end())); - /* Aligned fusion: Fusion the bits at the end of lines by "increasing thickness" - * For that, we have to find other lines, - * and with a next point no more distant than the max width. - * Then, we can merge the bit from the first point to the second by following the mean. - */ - //for (ThickPolyline lines : pp) { - // std::cout << "lines " << lines.points.size() << ": "; - // for (Point pt : lines.points) { - // std::cout << unscale(pt.x) << ":" << unscale(pt.y) << "->"; - // } - // std::cout << "\n"; - //} - //reoder pp by length std::sort(pp.begin() + 4, pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { return a.length() > b.length(); }); - for (ThickPolyline& polyline : pp) { - if (polyline.endpoints.first && !polyline.endpoints.second) polyline.reverse(); - else if (!polyline.endpoints.first && !polyline.endpoints.second && polyline.first_point().x<polyline.last_point().x) polyline.reverse(); - } - std::sort(pp.begin() + 4, pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { - return a.last_point().x < b.last_point().x; }); - for (ThickPolyline& polyline : pp) { - if (polyline.endpoints.first && !polyline.endpoints.second) polyline.reverse(); - std::cout << "poly l:" << unscale(polyline.length()) << " " << polyline.endpoints.first << ": "; - for (Point pt : polyline.points) { - std::cout << unscale((int)(pt.x * 100) / 100.0) << ":" << unscale((int)(pt.y * 100) / 100.0) << "->"; - } - std::cout << " :"<< polyline.endpoints.second<< " =W> "; - for (coord_t pt : polyline.get_width()) { - std::cout << unscale(pt) << "-"; - } - std::cout << "\n"; - } concatThickPolylines(pp); + + // Aligned fusion: Fusion the bits at the end of lines by "increasing thickness" + // For that, we have to find other lines, + // and with a next point no more distant than the max width. + // Then, we can merge the bit from the first point to the second by following the mean. + // bool changes = true; while (changes) { changes = false; @@ -392,9 +352,7 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid int best_idx = 0; double dot_poly_branch = 0; double dot_candidate_branch = 0; - std::cout << " look at : " << i << " = " << unscale((int)(polyline.first_point().x * 100) / 100.0) << ":" << unscale((int)(polyline.first_point().y * 100) / 100.0) - <<"==>"<< unscale((int)(polyline.last_point().x * 100) / 100.0) << ":" << unscale((int)(polyline.last_point().y * 100) / 100.0) << "\n"; - + // find another polyline starting here for (size_t j = i + 1; j < pp.size(); ++j) { ThickPolyline& other = pp[j]; @@ -411,11 +369,6 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid } //only consider the other if the next point is near us - std::cout << " try : " << i << ":" << j << " : " << (polyline.points.size() < 2 && other.points.size() < 2) << - (!polyline.endpoints.second || !other.endpoints.second) << - (polyline.points.back().distance_to(other.points.back()) > max_width) << - (polyline.points.size() != other.points.size()) << - (abs(polyline.length() - other.length()) > max_width / 2) << "\n"; if (polyline.points.size() < 2 && other.points.size() < 2) continue; if (!polyline.endpoints.second || !other.endpoints.second) continue; if ((polyline.points.back().distance_to(other.points.back()) @@ -441,14 +394,10 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid int biggest_main_branch_id = 0; int biggest_main_branch_length = 0; for (size_t k = 0; k < pp.size(); ++k) { - std::cout << "try to find main : " << k << " ? " << i << " " << j << " "; - if (k == i | k == j) continue; ThickPolyline& other = pp[k]; - std::cout << " length=" << other.length() << " "; if (polyline.first_point().coincides_with(other.last_point())) { other.reverse(); - std::cout << " 1other.endpoints.second=" << other.endpoints.second << " " << biggest_main_branch_length << " <? " << other.length(); if (!other.endpoints.second) find_main_branch = true; else if (biggest_main_branch_length < other.length()) { @@ -456,7 +405,6 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid biggest_main_branch_length = other.length(); } } else if (polyline.first_point().coincides_with(other.first_point())) { - std::cout << " 2other.endpoints.second=" << other.endpoints.second << " " << biggest_main_branch_length << " <? " << other.length(); if (!other.endpoints.second) find_main_branch = true; else if (biggest_main_branch_length < other.length()) { @@ -464,7 +412,6 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid biggest_main_branch_length = other.length(); } } - std::cout << "\n"; if (find_main_branch) { //use this variable to store the good index and break to compute it biggest_main_branch_id = k; @@ -475,16 +422,13 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid // nothing -> it's impossible! dot_poly_branch = 0.707; dot_candidate_branch = 0.707; - std::cout << "no main branch... impossible!!\n"; } else if (!find_main_branch && (pp[biggest_main_branch_id].length() < polyline.length() || pp[biggest_main_branch_id].length() < other.length()) ){ //the main branch should have no endpoint or be bigger! //here, it have an endpoint, and is not the biggest -> bad! - std::cout << "no, the main is smaller than us\n"; continue; } else { //compute the dot (biggest_main_branch_id) - std::cout << "length poly " << unscale(polyline.length()) << ", candi " << unscale(other.length()) << ", main " << unscale(pp[biggest_main_branch_id].length()) << "\n"; Pointf v_poly(polyline.lines().front().vector().x, polyline.lines().front().vector().y); v_poly.scale(1 / std::sqrt(v_poly.x*v_poly.x + v_poly.y*v_poly.y)); Pointf v_candid(other.lines().front().vector().x, other.lines().front().vector().y); @@ -500,7 +444,6 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid //ie, don't merge 'T' but ok for 'Y', merge only lines of not disproportionate different length (ratio max: 4) if (dot_poly_branch < 0.1 || dot_candidate_branch < 0.1 || (polyline.length()>other.length() ? polyline.length() / other.length() : other.length() / polyline.length()) > 4) { - std::cout << "refuse fusion : " << dot_poly_branch << ", " << dot_candidate_branch << ", difflength=" << (polyline.length() > other.length() ? polyline.length() / other.length() : other.length() / polyline.length()) << "\n"; continue; } if (other_dot > best_dot) { @@ -508,49 +451,29 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid best_idx = j; best_dot = other_dot; } - /* if (best_value > polyline.points.back().distance_to(other.points.back())) { - best_candidate = &other; - best_idx = j; - best_value = polyline.points.back().distance_to(other.points.back()); - }*/ } if (best_candidate != nullptr) { - std::cout << "===== FUSION num " << id_f << " === \n"; - // delete very near points remove_point_too_near(&polyline); remove_point_too_near(best_candidate); // add point at the same pos than the other line to have a nicer fusion - std::cout << "polyline count : " << polyline.points.size() << ", candid count : " << best_candidate->points.size() << "\n"; add_point_same_percent(&polyline, best_candidate); - std::cout << "+candid : polyline count : " << polyline.points.size() << ", candid count : " << best_candidate->points.size() << "\n"; add_point_same_percent(best_candidate, &polyline); - std::cout << "+poly : polyline count : " << polyline.points.size() << ", candid count : " << best_candidate->points.size() - << " ,,,,, : " << polyline.width2.size() << ", candid : " << best_candidate->width2.size() << "\n"; - - - - - std::cout << " dot_poly_branch=" << dot_poly_branch << ", dot_candidate_branch=" << dot_candidate_branch << "\n"; //get the angle of the nearest points of the contour to see : _| (good) \_ (average) __(bad) - double coeff_angle_poly = get_coeff_from_angle_countour(polyline.points.back(), *this); - double coeff_angle_candi = get_coeff_from_angle_countour(best_candidate->points.back(), *this); - std::cout << "coeff_angle poly=" << coeff_angle_poly << ", candi" << coeff_angle_candi << "\n"; + //sqrt because the result are nicer this way: don't over-penalize /_ angles + //TODO: try if we can achieve a better result if we use a different algo if the angle is <90° + double coeff_angle_poly = (get_coeff_from_angle_countour(polyline.points.back(), *this)); + double coeff_angle_candi = (get_coeff_from_angle_countour(best_candidate->points.back(), *this)); //this will encourage to follow the curve, a little, because it's shorter near the center //without that, it tends to go to the outter rim. double weight_poly = 2 - polyline.length() / max(polyline.length(), best_candidate->length()); double weight_candi = 2 - best_candidate->length() / max(polyline.length(), best_candidate->length()); - std::cout << "weight_poly=" << weight_poly << ", weight_candi" << weight_candi; weight_poly *= coeff_angle_poly; weight_candi *= coeff_angle_candi; - std::cout << ", cubic weight_poly=" << weight_poly << ", weight_candi" << weight_candi - << " => poly:" << dot_poly_branch << "->" << dot_poly_branch * weight_poly - << ", candi:" << dot_candidate_branch << "->" << dot_candidate_branch * weight_candi - <<"\n"; //iterate the points // as voronoi should create symetric thing, we can iterate synchonously unsigned int idx_point = 1; @@ -563,20 +486,7 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid double newy = polyline.points[idx_point].y * dot_poly_branch*weight_poly + best_candidate->points[idx_point].y * dot_candidate_branch*weight_candi; polyline.points[idx_point].y = newy / (dot_poly_branch*weight_poly + dot_candidate_branch*weight_candi); //new width : the half of each width (the "external" part) + dist bewteen them ("inner" part) - std::cout << "try other comp " << dot_poly_branch + dot_candidate_branch << ", " - << unscale(polyline.get_width()[idx_point])*dot_poly_branch << " + " << unscale(best_candidate->get_width()[idx_point])*dot_candidate_branch - << ", min = " << min(dot_poly_branch, dot_candidate_branch) - << "\n"; - std::cout << "fusion! " << unscale(polyline.get_width()[idx_point]) << " + " << unscale(best_candidate->get_width()[idx_point]) - << ", dist = " << unscale(polyline.points[idx_point].distance_to(best_candidate->points[idx_point])) - << ", (s/2+s/2)+dist*2 = " << unscale( - (polyline.get_width()[idx_point]/2 + best_candidate->get_width()[idx_point]/2) +2 * polyline.points[idx_point].distance_to(best_candidate->points[idx_point])) - << "\n"; - - /* - polyline.width[idx_point] += best_candidate->width[idx_point]; - polyline.width[idx_point] /= 2; - polyline.width[idx_point] += polyline.points[idx_point].distance_to(best_candidate->points[idx_point]);*/ + // The width decrease with distance from the centerline. // This formula is what works the best, even if it's not perfect (created empirically). 0->3% error on a gap fill on some tests. //If someone find an other formula based on the properties of the voronoi algorithm used here, and it works better, please use it. @@ -586,34 +496,9 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid //value_from_current_width /= 4; double value_from_dist = 2 * polyline.points[idx_point].distance_to(best_candidate->points[idx_point]); value_from_dist *= sqrt(min(dot_poly_branch, dot_candidate_branch) / max(dot_poly_branch, dot_candidate_branch)); - std::cout << "my try value_from_current_width=" << value_from_current_width - << ", value_from_dist=" << value_from_dist - << "\n"; + polyline.get_width()[idx_point] = value_from_current_width + value_from_dist; - ////compute the dot for next point if available - // false good idea - //if (idx_point + 1 < polyline.points.size() && - // polyline.points[idx_point + 1].distance_to(best_candidate->points[idx_point + 1])) { - // Pointf v_poly(polyline.lines().front().vector().x, polyline.lines().front().vector().y); - // v_poly.scale(1 / std::sqrt(v_poly.x*v_poly.x + v_poly.y*v_poly.y)); - // Pointf v_candid(best_candidate->lines().front().vector().x, best_candidate->lines().front().vector().y); - // v_candid.scale(1 / std::sqrt(v_candid.x*v_candid.x + v_candid.y*v_candid.y)); - // Pointf v_previous(polyline.points[idx_point].x - polyline.points[idx_point - 1].x, - // polyline.points[idx_point].y - polyline.points[idx_point - 1].y); - // v_previous.scale(1 / std::sqrt(v_previous.x*v_previous.x + v_previous.y*v_previous.y)); - // dot_poly_branch = v_poly.x*v_previous.x + v_poly.y*v_previous.y; - // dot_candidate_branch = v_candid.x*v_previous.x + v_candid.y*v_previous.y; - // std::cout << "new dots: dot_poly_branch=" << dot_poly_branch << ", dot_candidate_branch=" << dot_candidate_branch << "\n"; - // if (dot_poly_branch < 0) dot_poly_branch = 0; - // if (dot_candidate_branch < 0) dot_candidate_branch = 0; - //} - - - //we take the width at front, it's siplier and the most reliable. - //polyline.get_width()[idx_point] = std::max(polyline.get_width().front(), best_candidate->get_width().front()); - std::cout << " == " << unscale(polyline.get_width()[idx_point]) << " ? " << unscale(polyline.get_width()[idx_point - 1]) - << "\n"; ++idx_point; } if (idx_point < best_candidate->points.size()) { @@ -669,41 +554,12 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid pp.erase(pp.begin() + best_idx); changes = true; - - stringstream stri2; - stri2 << id << "-2-medial_axis_fusioned_" << layer_id << "_" << id << "_f" << id_f++ << ".svg"; - SVG svg2(stri2.str()); - svg2.draw(*this); - svg2.draw(pp); - svg2.Close(); } } if (changes) concatThickPolylines(pp); - for (ThickPolyline& polyline : pp) { - std::cout << "poly(loop) l:" << unscale(polyline.length()) << " " << polyline.endpoints.first << ": "; - for (Point pt : polyline.points) { - std::cout << unscale((int)(pt.x * 100) / 100.0) << ":" << unscale((int)(pt.y * 100) / 100.0) << "->"; - } - std::cout << " :" << polyline.endpoints.second << " =W> "; - for (coord_t pt : polyline.get_width()) { - std::cout << unscale(pt) << "-"; - } - std::cout << "\n"; - } - } - - for (ThickPolyline& polyline : pp) { - std::cout << "poly(fus) l:" << unscale(polyline.length()) << " : "; - for (Point pt : polyline.points) { - std::cout << unscale((int)(pt.x * 100) / 100.0) << ":" << unscale((int)(pt.y * 100) / 100.0) << "->"; - } - std::cout << " =W> "; - for (coord_t pt : polyline.get_width()) { - std::cout << unscale(pt) << "-"; - } - std::cout << "\n"; } + // remove too small extrusion at start & end of polylines changes = false; for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline& polyline = pp[i]; @@ -711,14 +567,12 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid // remove bits with too small extrusion size_t idx_point = 0; while (idx_point<polyline.points.size() && polyline.get_width()[idx_point] < min_width && polyline.endpoints.first) { - std::cout << "too thin polyline point :" << polyline.get_width()[idx_point] << " < " << min_width << "\n"; polyline.points.erase(polyline.points.begin() + idx_point); polyline.get_width().erase(polyline.get_width().begin() + idx_point); changes = true; } idx_point = polyline.points.size() - 1; while (idx_point >= 0 && polyline.get_width()[idx_point] < min_width && polyline.endpoints.second) { - std::cout << "too thin polyline point:" << polyline.get_width()[idx_point] << " < " << min_width << "\n"; polyline.points.erase(polyline.points.begin() + idx_point); polyline.get_width().erase(polyline.get_width().begin() + idx_point); idx_point--; @@ -732,22 +586,16 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid } if (changes) concatThickPolylines(pp); - stringstream stri2; - stri2 << id << "-3-medial_axis_fusioned_thincut_" << layer_id << "_" << id << ".svg"; - SVG svg2(stri2.str()); - svg2.draw(*this); - svg2.draw(pp); - svg2.Close(); - /* Loop through all returned polylines in order to extend their endpoints to the - expolygon boundaries */ + // Loop through all returned polylines in order to extend their endpoints to the + // expolygon boundaries for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline& polyline = pp[i]; // extend initial and final segments of each polyline if they're actual endpoints - /* We assign new endpoints to temporary variables because in case of a single-line - polyline, after we extend the start point it will be caught by the intersection() - call, so we keep the inner point until we perform the second intersection() as well */ + // We assign new endpoints to temporary variables because in case of a single-line + // polyline, after we extend the start point it will be caught by the intersection() + // call, so we keep the inner point until we perform the second intersection() as well Point new_front = polyline.points.front(); Point new_back = polyline.points.back(); if (polyline.endpoints.first && !bounds.has_boundary_point(new_front)) { @@ -776,14 +624,6 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid } - stringstream stri3; - stri3 << id << "-4-medial_axis_extended_" << layer_id << "_" << id << ".svg"; - SVG svg3(stri3.str()); - svg3.draw(*this); - svg3.draw(pp); - svg3.Close(); - - /* If we removed any short polylines we now try to connect consecutive polylines in order to allow loop detection. Note that this algorithm is greedier than MedialAxis::process_edge_neighbors() as it will connect random pairs of @@ -840,15 +680,7 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid } if (changes) concatThickPolylines(pp); - - stringstream stri4; - stri4 << id << "-5-medial_axis_loop_" << layer_id << "_" << id << ".svg"; - SVG svg4(stri4.str()); - svg4.draw(*this); - svg4.draw(pp); - svg4.Close(); //remove too thin polylines points (inside a polyline : split it) - changes = false; for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline& polyline = pp[i]; @@ -857,21 +689,20 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid while (idx_point<polyline.points.size()) { if (polyline.width2[idx_point] < min_width) { if (idx_point <= 1) { - std::cout << "too thin remove 2 front points\n"; + //too thin at start polyline.points.erase(polyline.points.begin()); polyline.width2.erase(polyline.width2.begin()); polyline.points.erase(polyline.points.begin()); polyline.width2.erase(polyline.width2.begin()); idx_point = 0; } else if (idx_point >= polyline.points.size() - 2) { - std::cout << "too thin remove 2 back points\n"; + //too thin at end polyline.points.erase(polyline.points.end() - 1); polyline.width2.erase(polyline.width2.end() - 1); polyline.points.erase(polyline.points.end() - 1); polyline.width2.erase(polyline.width2.end() - 1); } else { - std::cout << "too thin :split @" << idx_point << "/" << polyline.points.size()<< "\n"; - //split + //too thin in middle : split pp.emplace_back(); ThickPolyline &newone = pp.back(); newone.points.insert(newone.points.begin(), polyline.points.begin() + idx_point + 1, polyline.points.end()); @@ -887,20 +718,9 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid --i; } } - if (changes) concatThickPolylines(pp); - for (ThickPolyline& polyline : pp) { - std::cout << "poly l:" << unscale(polyline.length()) << " : "; - for (Point pt : polyline.points) { - std::cout << unscale((int)(pt.x * 100) / 100.0) << ":" << unscale((int)(pt.y * 100) / 100.0) << "->"; - } - std::cout << " =W> "; - for (coord_t pt : polyline.get_width()) { - std::cout << unscale(pt) << "-"; - } - std::cout << "\n"; - } + //remove too short polyline changes = true; while (changes) { changes = false; @@ -915,14 +735,6 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid which is variable - extension will be <= max_width/2 on each side) */ if ((polyline.endpoints.first || polyline.endpoints.second) && polyline.length() < max_w * 2) { - std::cout << "remove polyline " << unscale(polyline.length()) << " < " << unscale(max_w * 2) - << " = " << ((polyline.endpoints.first || polyline.endpoints.second) - && polyline.length() < max_w * 2) << "\n"; - //TODO: checkl before if it can't be extended - //pp.erase(pp.begin() + i); - //--i; - //continue; - //changes = true; if (shortest_size > polyline.length()) { shortest_size = polyline.length(); shortest_idx = i; @@ -938,36 +750,25 @@ ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_wid } //TODO last change: reduce the flow at the intersection points ? - //TODO: ensure the volume extruded is correct for what we have been asked. - double surface = 0; - for (ThickPolyline& polyline : pp) { - std::cout << "poly end :" << unscale(polyline.length()) << " : "; - for (Point pt : polyline.points) { - std::cout << unscale((int)(pt.x * 100) / 100.0) << ":" << unscale((int)(pt.y * 100) / 100.0) << "->"; - } - std::cout << " =W> "; - for (coord_t pt : polyline.get_width()) { - std::cout << unscale(pt) << "-"; - } - for (ThickLine l : polyline.thicklines()) { - surface += l.length() * (l.a_width + l.b_width) / 2; - } - std::cout << "\n"; - } - std::cout << "Medial axis : cover " << unscale(unscale(surface)) << " / " << unscale(unscale(this->area())) << " (max = " << unscale(unscale(bounds.area())) << ")\n"; - - - stringstream stri6; - stri6 << id << "-6-" << "medial_axis_end_" << layer_id << "_" << id << ".svg"; - SVG svg6(stri2.str()); - svg6.draw(*this); - svg6.draw(pp); - svg6.Close(); + //TODO: ensure the volume extruded is correct for what we have been asked + //double surface = 0; + //for (ThickPolyline& polyline : pp) { + // std::cout << "poly end :" << unscale(polyline.length()) << " : "; + // for (Point pt : polyline.points) { + // std::cout << unscale((int)(pt.x * 100) / 100.0) << ":" << unscale((int)(pt.y * 100) / 100.0) << "->"; + // } + // std::cout << " =W> "; + // for (coord_t pt : polyline.get_width()) { + // std::cout << unscale(pt) << "-"; + // } + // for (ThickLine l : polyline.thicklines()) { + // surface += l.length() * (l.a_width + l.b_width) / 2; + // } + // std::cout << "\n"; + //} + ////std::cout << "Medial axis : cover " << unscale(unscale(surface)) << " / " << unscale(unscale(this->area())) << " (max = " << unscale(unscale(bounds.area())) << ")\n"; - std::cout << "\n"; - std::cout << "\n"; polylines->insert(polylines->end(), pp.begin(), pp.end()); - id++; } void diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp index 10dbe2fed..6d6509878 100644 --- a/xs/src/libslic3r/Geometry.cpp +++ b/xs/src/libslic3r/Geometry.cpp @@ -13,11 +13,6 @@ #include <utility> #include <stack> #include <vector> -#include "BoundingBox.hpp" -#include "Polygon.hpp" -#include "SVG.hpp" -#include "polypartition.h" -#include "poly2tri/poly2tri.h" #ifdef SLIC3R_DEBUG #include "SVG.hpp" @@ -840,9 +835,6 @@ private: const Lines &lines; }; -int id = 0; -int id1_5 = 0; -int id2 = 0; void MedialAxis::build(ThickPolylines* polylines) { @@ -862,36 +854,12 @@ MedialAxis::build(ThickPolylines* polylines) return; } */ - stringstream stri; - stri << "medial_axis_voro_" << id++ << ".svg"; - SVG svge(stri.str()); - - std::cout << "VORONOI : "; - Line l; - for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) { - if (edge->is_infinite() || edge->is_secondary()) continue; - std::cout << ", " << unscale(edge->vertex0()->x()) << ":" << unscale(edge->vertex0()->y()); - std::cout << "=>" << unscale(edge->vertex1()->x()) << ":" << unscale(edge->vertex1()->y()); - std::cout << " sec:" << edge->is_secondary() << "\n"; - ++edge; - Line li; - li.a.x = edge->vertex0()->x(); - li.a.y = edge->vertex0()->y(); - li.b.x = edge->vertex1()->x(); - li.b.y = edge->vertex1()->y(); - svge.draw(li); - } - /*svg.draw(*this); - svg.draw(pp); - */ - svge.Close(); typedef const VD::vertex_type vert_t; typedef const VD::edge_type edge_t; // collect valid edges (i.e. prune those not belonging to MAT) // note: this keeps twins, so it inserts twice the number of the valid edges - std::set<const VD::edge_type*> cout_edges; this->valid_edges.clear(); { std::set<const VD::edge_type*> seen_edges; @@ -908,26 +876,9 @@ MedialAxis::build(ThickPolylines* polylines) if (!this->validate_edge(&*edge)) continue; this->valid_edges.insert(&*edge); this->valid_edges.insert(edge->twin()); - cout_edges.insert(&*edge); } } this->edges = this->valid_edges; - stringstream stri2; - stri2 << "medial_axis_vorofilter_" << id2++ << ".svg"; - SVG svge2(stri2.str()); - std::cout << "VORONOI filtered : "; - for (auto edge : cout_edges) { - std::cout << ", " << unscale(edge->vertex0()->x()) << ":" << unscale(edge->vertex0()->y()); - std::cout << "=>" << unscale(edge->vertex1()->x()) << ":" << unscale(edge->vertex1()->y()); - std::cout << " sec:" << edge->is_secondary() << "\n"; - Line li; - li.a.x = edge->vertex0()->x(); - li.a.y = edge->vertex0()->y(); - li.b.x = edge->vertex1()->x(); - li.b.y = edge->vertex1()->y(); - svge2.draw(li); - } - svge2.Close(); // iterate through the valid edges to build polylines while (!this->edges.empty()) { @@ -1018,12 +969,6 @@ MedialAxis::process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* pol Point new_point(neighbor->vertex1()->x(), neighbor->vertex1()->y()); polyline->points.push_back(new_point); polyline->get_width().push_back(this->thickness[neighbor].second); - if (abs(this->thickness[neighbor].first - this->thickness[edge].second) > SCALED_EPSILON) { - std::cout << "Error, this point redifined the point thiknesss:" - << this->thickness[edge].first << "->" << this->thickness[edge].second - <<", "<< this->thickness[neighbor].first << "->" << this->thickness[neighbor].second - << "\n"; - } (void)this->edges.erase(neighbor); (void)this->edges.erase(neighbor->twin()); diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index 3f6e5a2c4..ca3078715 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -244,37 +244,13 @@ void PerimeterGenerator::process() true), (float)(-min_width / 2), (float)(min_width / 2)); // compute a bit of overlap to anchor thin walls inside the print. - /*for (int id_anchor = 0; id_anchor < anchor.size(); ++id_anchor) { - stringstream stri; - stri << "anchor" << layer_id << "_" << id_anchor << ".svg"; - SVG svg(stri.str()); - svg.draw(anchor[id_anchor]); - svg.Close(); - }*/ int id_thin = 0; for (ExPolygon &ex : expp) { - ExPolygons ex_off = offset_ex(ex, (float)(ext_perimeter_width / 2), jtSquare); ExPolygons anchor = intersection_ex(offset_ex(ex, (float)(ext_perimeter_width / 2), jtSquare), no_thin_zone, true); ExPolygons bounds = union_ex(ExPolygons() = { ex }, anchor, true); for (ExPolygon &bound : bounds) { if (!intersection_ex(ex, bound).empty()) { - {stringstream stri; - stri << id_thin << "-0-bound" << layer_id << "_" << id_thin << ".svg"; - SVG svg(stri.str()); - svg.draw(bound); - svg.Close(); - } - if (ex_off.size() > 0) { - stringstream stri; - stri << id_thin << "-0.0-ext" << layer_id << "_" << id_thin << ".svg"; - SVG svg(stri.str()); - svg.draw(ex_off[0]); - svg.Close(); - } // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop - //ExPolygons simplified_bounds = bound.simplify(SCALED_EPSILON); - //ex.medial_axis(simplified_bounds.size() == 1 ? simplified_bounds[0] : bound, - //ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls, layer_id); ex.medial_axis(bound, ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls, layer_id); id_thin++; break; @@ -616,7 +592,6 @@ ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylin for (int i = 0; i < (int)lines.size(); ++i) { const ThickLine& line = lines[i]; - std::cout << "line : " << line.a_width << " -> " << line.b_width << "\n"; const coordf_t line_len = line.length(); if (line_len < SCALED_EPSILON) continue; @@ -630,18 +605,15 @@ ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylin { pp.push_back(line.a); width.push_back(line.a_width); - std::cout << line.a_width<<", "; for (size_t j = 1; j < segments; ++j) { pp.push_back(line.point_at(j*seg_len)); coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len; width.push_back(w); width.push_back(w); - std::cout << w << "x2, "; } pp.push_back(line.b); width.push_back(line.b_width); - std::cout << line.b_width<<"\n"; assert(pp.size() == segments + 1); assert(width.size() == segments*2); @@ -661,7 +633,6 @@ ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylin } const double w = fmax(line.a_width, line.b_width); - std::cout << "thin flow " << line.a_width << " , " << line.b_width << "\n"; if (path.polyline.points.empty()) { path.polyline.append(line.a); path.polyline.append(line.b); @@ -699,9 +670,6 @@ ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylin ExtrusionEntityCollection unsortable_coll(paths); unsortable_coll.no_sort = true; coll.append(unsortable_coll); - for (auto path : paths) { - std::cout << "path flow " << path.width << "\n"; - } } } } diff --git a/xs/src/libslic3r/Polyline.cpp b/xs/src/libslic3r/Polyline.cpp index 8e4c29293..945b1272a 100644 --- a/xs/src/libslic3r/Polyline.cpp +++ b/xs/src/libslic3r/Polyline.cpp @@ -258,22 +258,10 @@ bool remove_degenerate(Polylines &polylines) ThickLines ThickPolyline::thicklines() const { - - std::cout << "myThickline(1) "; - for (size_t wi : width2) { - std::cout << " " << wi; - } - std::cout << "\n"; - std::cout << "myThickline(2) "; - for (size_t i = 0; i < width2.size(); ++i) { - std::cout << " " << i << ":" << width2[i]; - } - std::cout << "\n"; ThickLines lines; if (this->points.size() >= 2) { lines.reserve(this->points.size() - 1); for (size_t i = 0; i < this->points.size()-1; ++i) { - std::cout << "create new line " << i << " : " << this->width2[i] << "->" << this->width2[i + 1] << "\n"; ThickLine line(this->points[i], this->points[i+1]); line.a_width = this->width2[i]; line.b_width = this->width2[i + 1]; @@ -310,7 +298,6 @@ void concatThickPolylines(ThickPolylines& pp) { //concat polyline if only 2 polyline at a point for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline *polyline = &pp[i]; - std::cout << "check poly " << i << " \n"; int32_t id_candidate_first_point = -1; int32_t id_candidate_last_point = -1; @@ -339,7 +326,6 @@ void concatThickPolylines(ThickPolylines& pp) { } } if (id_candidate_last_point == id_candidate_first_point && nbCandidate_first_point == 1 && nbCandidate_last_point == 1) { - std::cout << "concat loop! " << id_candidate_last_point << " " << pp.size() << " \n"; //it's a loop! it's a trap! polyline->width2[0] = std::max(polyline->width2.front(), pp[id_candidate_first_point].width2.back()); polyline->points.insert(polyline->points.begin(), pp[id_candidate_first_point].points.begin(), pp[id_candidate_first_point].points.end() - 1); @@ -352,70 +338,33 @@ void concatThickPolylines(ThickPolylines& pp) { if (nbCandidate_first_point == 1) { //concat at front - std::cout << "concat (f) @ " << unscale(polyline->points.front().x) << ":" << unscale(polyline->points.front().y) << " =W> " << polyline->width2.front() << " " << pp[id_candidate_first_point].width2.back() << " \n"; - - std::cout << "before, front " << unscale(pp[id_candidate_first_point].points.front().x) << ":" << unscale(pp[id_candidate_first_point].points.front().y) << " : "; - for (auto wi : pp[id_candidate_first_point].width2) { - std::cout << " " << wi; - } - std::cout << " ," << unscale(pp[id_candidate_first_point].points.back().x) << ":" << unscale(pp[id_candidate_first_point].points.back().y) << "\n"; - std::cout << "before, back " << unscale(polyline->points.front().x) << ":" << unscale(polyline->points.front().y) << " : "; - for (auto wi : polyline->width2) { - std::cout << " " << wi; - } - std::cout << " , " << unscale(polyline->points.back().x) << ":" << unscale(polyline->points.back().y) << "\n"; - polyline->width2[0] = std::max(polyline->width2.front(), pp[id_candidate_first_point].width2.back()); + polyline->width2[0] = std::max(polyline->width2.front(), pp[id_candidate_first_point].width2.back()); polyline->points.insert(polyline->points.begin(), pp[id_candidate_first_point].points.begin(), pp[id_candidate_first_point].points.end() - 1); polyline->width2.insert(polyline->width2.begin(), pp[id_candidate_first_point].width2.begin(), pp[id_candidate_first_point].width2.end() - 1); polyline->endpoints.first = pp[id_candidate_first_point].endpoints.first; pp.erase(pp.begin() + id_candidate_first_point); if (id_candidate_first_point < i) { - std::cout << "move me : " << i << " to " << i - 1; i--; polyline = &pp[i]; } if (id_candidate_last_point > id_candidate_first_point) { - std::cout << "move last : " << id_candidate_last_point << " to " << id_candidate_last_point-1; id_candidate_last_point--; } - std::cout << "after : "; - for (auto wi : polyline->width2) { - std::cout << " " << wi; - } - std::cout << "\n"; } else if (nbCandidate_first_point == 0 && !polyline->endpoints.first && !polyline->first_point().coincides_with(polyline->last_point())) { //update endpoint polyline->endpoints.first = true; } if (nbCandidate_last_point == 1) { //concat at back - std::cout << "concat (l) @ " << unscale(polyline->points.back().x) << ":" << unscale(polyline->points.back().y) << " =W> " << polyline->width2.back() << " " << pp[id_candidate_last_point].width2.front() << " \n"; - - std::cout << "before, front " << unscale(polyline->points.front().x) << ":" << unscale(polyline->points.front().y) << " : "; - for (auto wi : polyline->width2) { - std::cout << " " << wi; - } - std::cout << " , " << unscale(polyline->points.back().x) << ":" << unscale(polyline->points.back().y) << "\n"; - std::cout << "before, back " << unscale(pp[id_candidate_last_point].points.front().x) << ":" << unscale(pp[id_candidate_last_point].points.front().y) << " : "; - for (auto wi : pp[id_candidate_last_point].width2) { - std::cout << " " << wi; - } - std::cout << " ," << unscale(pp[id_candidate_last_point].points.back().x) << ":" << unscale(pp[id_candidate_last_point].points.back().y) << "\n"; polyline->width2[polyline->width2.size() - 1] = std::max(polyline->width2.back(), pp[id_candidate_last_point].width2.front()); polyline->points.insert(polyline->points.end(), pp[id_candidate_last_point].points.begin() + 1, pp[id_candidate_last_point].points.end()); polyline->width2.insert(polyline->width2.end(), pp[id_candidate_last_point].width2.begin() + 1, pp[id_candidate_last_point].width2.end()); polyline->endpoints.second = pp[id_candidate_last_point].endpoints.second; pp.erase(pp.begin() + id_candidate_last_point); if (id_candidate_last_point < i) { - std::cout << "move me : " << i << " to " << i - 1; i--; polyline = &pp[i]; } - std::cout << "after : "; - for (auto wi : polyline->width2) { - std::cout << " " << wi; - } - std::cout << "\n"; } else if (nbCandidate_last_point == 0 && !polyline->endpoints.second && !polyline->first_point().coincides_with(polyline->last_point())) { //update endpoint polyline->endpoints.second = true; @@ -423,7 +372,6 @@ void concatThickPolylines(ThickPolylines& pp) { if (polyline->last_point().coincides_with(polyline->first_point())) { //the concat has created a loop : update endpoints - std::cout << "loop!!(2) \n"; polyline->endpoints.first = false; polyline->endpoints.second = false; } |