mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-16 11:51:49 +08:00
Merge remote-tracking branch 'remotes/supermerill/master'
This commit is contained in:
commit
a4572696e7
@ -1775,13 +1775,18 @@ FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const F
|
||||
|
||||
// remove areas for gapfill
|
||||
// factor=0.5 : remove area smaller than a spacing. factor=1 : max spacing for the gapfill (but not the width)
|
||||
float factor = 0.9f;
|
||||
ExPolygons rectilinear_areas = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor, params.flow->scaled_spacing() * factor);
|
||||
//choose between 2 to avoid dotted line effect.
|
||||
float factor1 = 0.99f;
|
||||
float factor2 = 0.7f;
|
||||
ExPolygons rectilinear_areas1 = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor1, params.flow->scaled_spacing() * factor1);
|
||||
ExPolygons rectilinear_areas2 = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor2, params.flow->scaled_spacing() * factor2);
|
||||
std::cout << "FillRectilinear2WGapFill use " << (rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 ? "1" : "2") << "\n";
|
||||
ExPolygons &rectilinear_areas = rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 ? rectilinear_areas1 : rectilinear_areas2;
|
||||
ExPolygons gapfill_areas = diff_ex(ExPolygons{ surface->expolygon }, rectilinear_areas);
|
||||
double rec_area = 0;
|
||||
for (ExPolygon &p : rectilinear_areas)rec_area += p.area();
|
||||
double gf_area = 0;
|
||||
for (ExPolygon &p : gapfill_areas)gf_area += p.area();
|
||||
for (ExPolygon &p : gapfill_areas) gf_area += p.area();
|
||||
//std::cout << unscaled(unscaled(surface->expolygon.area())) << " = " << unscaled(unscaled(rec_area)) << " + " << unscaled(unscaled(gf_area)) << "\n";
|
||||
|
||||
// rectilinear
|
||||
@ -1851,21 +1856,20 @@ FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const F
|
||||
//gapfill
|
||||
if (gapfill_areas.size() > 0) {
|
||||
ThickPolylines polylines_gapfill;
|
||||
double min = 0.2 * params.flow->scaled_width() * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
double min = 0.4 * scale_(params.flow->nozzle_diameter) * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
double max = 2. * params.flow->scaled_width();
|
||||
// collapse
|
||||
double min_offset = 0.1 * params.flow->scaled_width() * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
//be sure we don't gapfill where the perimeters are already touching each other (negative spacing).
|
||||
min = std::max(min, double(Flow::new_from_spacing(EPSILON, params.flow->nozzle_diameter , params.flow->height, false).scaled_width()));
|
||||
double max_offset = 2. * params.flow->scaled_spacing();
|
||||
ExPolygons gapfill_areas_collapsed = diff_ex(
|
||||
offset2_ex(gapfill_areas, double(-min_offset / 2), double(+min_offset / 2)),
|
||||
offset2_ex(gapfill_areas, double(-max_offset / 2), double(+max_offset / 2)),
|
||||
true);
|
||||
//ExPolygons gapfill_areas_collapsed = diff_ex(
|
||||
// offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2)),
|
||||
// offset2_ex(gapfill_areas, double(-max / 2), double(+max / 2)),
|
||||
// true);
|
||||
ExPolygons gapfill_areas_collapsed = offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2));
|
||||
for (const ExPolygon &ex : gapfill_areas_collapsed) {
|
||||
//remove too small gaps that are too hard to fill.
|
||||
//ie one that are smaller than an extrusion with width of min and a length of max.
|
||||
if (ex.area() > min * max) {
|
||||
if (ex.area() > scale_(params.flow->nozzle_diameter)*scale_(params.flow->nozzle_diameter) * 2) {
|
||||
MedialAxis{ ex, params.flow->scaled_width() * 2, params.flow->scaled_width() / 5, coord_t(params.flow->height) }.build(polylines_gapfill);
|
||||
}
|
||||
}
|
||||
|
@ -29,28 +29,30 @@ MedialAxis::polyline_from_voronoi(const Lines& voronoi_edges, ThickPolylines* po
|
||||
this->lines = voronoi_edges;
|
||||
construct_voronoi(lines.begin(), lines.end(), &this->vd);
|
||||
|
||||
/*
|
||||
typedef const VD::edge_type edge_t;
|
||||
|
||||
// DEBUG: dump all Voronoi edges
|
||||
{
|
||||
/*{
|
||||
for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) {
|
||||
if (edge->is_infinite()) continue;
|
||||
|
||||
const edge_t* edgeptr = &*edge;
|
||||
ThickPolyline polyline;
|
||||
polyline.points.push_back(Point( edge->vertex0()->x(), edge->vertex0()->y() ));
|
||||
polyline.points.push_back(Point( edge->vertex1()->x(), edge->vertex1()->y() ));
|
||||
polyline.width.push_back(this->thickness[edgeptr].first);
|
||||
polyline.width.push_back(this->thickness[edgeptr].second);
|
||||
polylines->push_back(polyline);
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}*/
|
||||
|
||||
|
||||
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
|
||||
this->valid_edges.clear();
|
||||
{
|
||||
std::set<const VD::edge_type*> seen_edges;
|
||||
std::set<const edge_t*> seen_edges;
|
||||
for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) {
|
||||
// if we only process segments representing closed loops, none if the
|
||||
// infinite edges (if any) would be part of our MAT anyway
|
||||
@ -71,6 +73,18 @@ MedialAxis::polyline_from_voronoi(const Lines& voronoi_edges, ThickPolylines* po
|
||||
// iterate through the valid edges to build polylines
|
||||
while (!this->edges.empty()) {
|
||||
const edge_t* edge = *this->edges.begin();
|
||||
if (this->thickness[edge].first > this->max_width*1.001) {
|
||||
//std::cerr << "Error, edge.first has a thickness of " << unscaled(this->thickness[edge].first) << " > " << unscaled(this->max_width) << "\n";
|
||||
//(void)this->edges.erase(edge);
|
||||
//(void)this->edges.erase(edge->twin());
|
||||
//continue;
|
||||
}
|
||||
if (this->thickness[edge].second > this->max_width*1.001) {
|
||||
//std::cerr << "Error, edge.second has a thickness of " << unscaled(this->thickness[edge].second) << " > " << unscaled(this->max_width) << "\n";
|
||||
//(void)this->edges.erase(edge);
|
||||
//(void)this->edges.erase(edge->twin());
|
||||
//continue;
|
||||
}
|
||||
|
||||
// start a polyline
|
||||
ThickPolyline polyline;
|
||||
@ -97,7 +111,7 @@ MedialAxis::polyline_from_voronoi(const Lines& voronoi_edges, ThickPolylines* po
|
||||
|
||||
assert(polyline.width.size() == polyline.points.size());
|
||||
|
||||
// prevent loop endpoints from being extended
|
||||
// if loop, set endpoints to false
|
||||
if (polyline.first_point().coincides_with(polyline.last_point())) {
|
||||
polyline.endpoints.first = false;
|
||||
polyline.endpoints.second = false;
|
||||
@ -446,7 +460,7 @@ MedialAxis::fusion_curve(ThickPolylines &pp)
|
||||
for (size_t i = 0; i < pp.size(); ++i) {
|
||||
ThickPolyline& polyline = pp[i];
|
||||
// only consider 2-point polyline with endpoint
|
||||
if (polyline.points.size() != 2) continue;
|
||||
//if (polyline.points.size() != 2) continue; // too restrictive.
|
||||
if (polyline.endpoints.first) polyline.reverse();
|
||||
else if (!polyline.endpoints.second) continue;
|
||||
if (polyline.width.back() > EPSILON) continue;
|
||||
@ -496,6 +510,10 @@ MedialAxis::fusion_curve(ThickPolylines &pp)
|
||||
sum_dot += dot_temp;
|
||||
}
|
||||
}
|
||||
sum_dot = abs(sum_dot);
|
||||
std::cout << " with mindot= " << min_dot << "< 0.5" << " ; with sum_dot= " << sum_dot << "< 0.2" << " ; with crosspoint.size= " << crosspoint.size() << " ; with coeff_contour_angle= " << coeff_contour_angle << " 0.2> " << (1 - (coeff_contour_angle / (PI / 2)))
|
||||
<< " ; length= " << unscaled(polyline.length())<<" >? 1.42*width= "<< polyline.width.front()<<"->"<< polyline.width.back() << "\n";
|
||||
|
||||
//only consider very shallow angle for contour
|
||||
if (mindot > 0.15 &&
|
||||
(1 - (coeff_contour_angle / (PI / 2))) > 0.2) continue;
|
||||
@ -504,6 +522,8 @@ MedialAxis::fusion_curve(ThickPolylines &pp)
|
||||
if (crosspoint.size() != 2) continue;
|
||||
if (sum_dot > 0.2) continue;
|
||||
if (min_dot > 0.5) continue;
|
||||
//don't remove useful bits. TODO: use the mindot to know by how much to multiply (1 when 90°, 1.42 when 45+, 1 when 0°)
|
||||
if (polyline.length() > polyline.width.front()*1.42) continue;
|
||||
|
||||
//don't pull, it distords the line if there are too many points.
|
||||
//// pull it a bit, depends on my size, the dot?, and the coeff at my 0-end (~14% for a square, almost 0 for a gentle curve)
|
||||
@ -534,6 +554,8 @@ MedialAxis::fusion_curve(ThickPolylines &pp)
|
||||
concatThickPolylines(pp);
|
||||
///reorder, in case of change
|
||||
std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { return a.length() < b.length(); });
|
||||
//have to redo it to remove multi-branch bits.
|
||||
fusion_curve(pp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -622,8 +644,14 @@ MedialAxis::extends_line_both_side(ThickPolylines& pp) {
|
||||
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);
|
||||
if (!polyline.points.empty()) {
|
||||
polyline.reverse();
|
||||
this->extends_line(polyline, anchors, this->min_width);
|
||||
}
|
||||
if (polyline.points.empty()) {
|
||||
pp.erase(pp.begin() + i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,9 +770,8 @@ MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, con
|
||||
l2.extend_end(max_width);
|
||||
(void)bounds->contour.first_intersection(l2, &new_bound);
|
||||
}
|
||||
if (new_bound.coincides_with_epsilon(new_back)) {
|
||||
if (new_bound.coincides_with_epsilon(new_back))
|
||||
return;
|
||||
}
|
||||
polyline.points.push_back(new_bound);
|
||||
//polyline.width.push_back(join_width);
|
||||
//it thickens the line a bit too early, imo
|
||||
@ -1303,6 +1330,22 @@ MedialAxis::remove_too_short_polylines(ThickPolylines& pp, const coord_t min_siz
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MedialAxis::check_width(ThickPolylines& pp, double max_width, std::string msg)
|
||||
{
|
||||
//remove empty polyline
|
||||
int nb = 0;
|
||||
for (size_t i = 0; i < pp.size(); ++i) {
|
||||
for (size_t j = 0; j < pp[i].width.size(); ++j) {
|
||||
if (pp[i].width[j] > max_width * 1.01) {
|
||||
std::cout << "Error " << msg << " width " << unscaled(pp[i].width[j]) << "(" << i << ":" << j << ") > " << unscaled(max_width) << "\n";
|
||||
nb++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nb > 0) std::cout << "== nbBig = " << nb << " ==\n";
|
||||
}
|
||||
|
||||
void
|
||||
MedialAxis::ensure_not_overextrude(ThickPolylines& pp)
|
||||
{
|
||||
@ -1494,6 +1537,27 @@ MedialAxis::build(ThickPolylines &polylines_out)
|
||||
// compute the Voronoi diagram and extract medial axis polylines
|
||||
ThickPolylines pp;
|
||||
this->polyline_from_voronoi(this->expolygon.lines(), &pp);
|
||||
|
||||
//sanity check, as the voronoi can return (abeit very rarely) randomly high values.
|
||||
for (ThickPolyline &tp : pp) {
|
||||
for (int i = 0; i < tp.width.size(); i++) {
|
||||
if (tp.width[i] > this->max_width) {
|
||||
tp.width[i] = this->max_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
//std::cout << "polyline_from_voronoi\n";
|
||||
//{
|
||||
// std::stringstream stri;
|
||||
// stri << "medial_axis_1_voronoi_" << id << ".svg";
|
||||
// SVG svg(stri.str());
|
||||
// //svg.draw(bounds);
|
||||
// svg.draw(this->expolygon);
|
||||
// svg.draw(pp);
|
||||
// svg.Close();
|
||||
//}
|
||||
|
||||
//check_width(pp, this->max_width, "polyline_from_voronoi");
|
||||
|
||||
concatThickPolylines(pp);
|
||||
|
||||
@ -1522,6 +1586,7 @@ MedialAxis::build(ThickPolylines &polylines_out)
|
||||
// std::cout << "\n";
|
||||
//}
|
||||
|
||||
// "remove" the little paths that are at the outside of a curve.
|
||||
fusion_curve(pp);
|
||||
//{
|
||||
// std::stringstream stri;
|
||||
|
@ -110,6 +110,8 @@ class MedialAxis {
|
||||
void grow_to_nozzle_diameter(ThickPolylines& pp, const ExPolygons& anchors);
|
||||
/// taper the ends of polylines (don't activate that for gapfill)
|
||||
void taper_ends(ThickPolylines& pp);
|
||||
//cleaning method
|
||||
void check_width(ThickPolylines& pp, double max_width, std::string msg);
|
||||
};
|
||||
|
||||
/// create a ExtrusionEntityCollection from ThickPolylines, discretizing the variable width into little sections (of 4*SCALED_RESOLUTION length) where needed.
|
||||
|
@ -279,7 +279,6 @@ void concatThickPolylines(ThickPolylines& pp) {
|
||||
for (size_t j = 0; j < pp.size(); ++j) {
|
||||
if (j == i) continue;
|
||||
ThickPolyline *other = &pp[j];
|
||||
if (other->first_point().coincides_with(other->last_point())) continue;
|
||||
if (polyline->last_point().coincides_with(other->last_point())) {
|
||||
id_candidate_last_point = j;
|
||||
nbCandidate_last_point++;
|
||||
|
@ -86,30 +86,37 @@ SCENARIO("thin walls: ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO: compare with mainline slic3r
|
||||
GIVEN("semicicumference"){
|
||||
GIVEN("semicicumference") {
|
||||
ExPolygon expolygon;
|
||||
expolygon.contour = Slic3r::Polygon{ Points{
|
||||
Point{ 1185881, 829367 }, Point{ 1421988, 1578184 }, Point{ 1722442, 2303558 }, Point{ 2084981, 2999998 }, Point{ 2506843, 3662186 }, Point{ 2984809, 4285086 }, Point{ 3515250, 4863959 }, Point{ 4094122, 5394400 }, Point{ 4717018, 5872368 }, Point{ 5379210, 6294226 }, Point{ 6075653, 6656769 }, Point{ 6801033, 6957229 }, Point{ 7549842, 7193328 }, Point{ 8316383, 7363266 }, Point{ 9094809, 7465751 }, Point{ 9879211, 7500000 }, Point{ 10663611, 7465750 }, Point{ 11442038, 7363265 }, Point{ 12208580, 7193327 }, Point{ 12957389, 6957228 }, Point{ 13682769, 6656768 }, Point{ 14379209, 6294227 }, Point{ 15041405, 5872366 }, Point{ 15664297, 5394401 }, Point{ 16243171, 4863960 }, Point{ 16758641, 4301424 }, Point{ 17251579, 3662185 }, Point{ 17673439, 3000000 }, Point{ 18035980, 2303556 }, Point{ 18336441, 1578177 }, Point{ 18572539, 829368 }, Point{ 18750748, 0 }, Point{ 19758422, 0 }, Point{ 19727293, 236479 }, Point{ 19538467, 1088188 }, Point{ 19276136, 1920196 }, Point{ 18942292, 2726179 }, Point{ 18539460, 3499999 }, Point{ 18070731, 4235755 }, Point{ 17539650, 4927877 }, Point{ 16950279, 5571067 }, Point{ 16307090, 6160437 }, Point{ 15614974, 6691519 }, Point{ 14879209, 7160248 }, Point{ 14105392, 7563079 }, Point{ 13299407, 7896927 }, Point{ 12467399, 8159255 }, Point{ 11615691, 8348082 }, Point{ 10750769, 8461952 }, Point{ 9879211, 8500000 }, Point{ 9007652, 8461952 }, Point{ 8142729, 8348082 }, Point{ 7291022, 8159255 }, Point{ 6459015, 7896927 }, Point{ 5653029, 7563079 }, Point{ 4879210, 7160247 }, Point{ 4143447, 6691519 }, Point{ 3451331, 6160437 }, Point{ 2808141, 5571066 }, Point{ 2218773, 4927878 }, Point{ 1687689, 4235755 }, Point{ 1218962, 3499999 }, Point{ 827499, 2748020 }, Point{ 482284, 1920196 }, Point{ 219954, 1088186 }, Point{ 31126, 236479 }, Point{ 0, 0 }, Point{ 1005754, 0 }
|
||||
Point{ 1185881, 829367 }, Point{ 1421988, 1578184 }, Point{ 1722442, 2303558 }, Point{ 2084981, 2999998 }, Point{ 2506843, 3662186 }, Point{ 2984809, 4285086 }, Point{ 3515250, 4863959 }, Point{ 4094122, 5394400 }, Point{ 4717018, 5872368 },
|
||||
Point{ 5379210, 6294226 }, Point{ 6075653, 6656769 }, Point{ 6801033, 6957229 }, Point{ 7549842, 7193328 }, Point{ 8316383, 7363266 }, Point{ 9094809, 7465751 }, Point{ 9879211, 7500000 }, Point{ 10663611, 7465750 }, Point{ 11442038, 7363265 },
|
||||
Point{ 12208580, 7193327 }, Point{ 12957389, 6957228 }, Point{ 13682769, 6656768 }, Point{ 14379209, 6294227 }, Point{ 15041405, 5872366 }, Point{ 15664297, 5394401 }, Point{ 16243171, 4863960 }, Point{ 16758641, 4301424 }, Point{ 17251579, 3662185 },
|
||||
Point{ 17673439, 3000000 }, Point{ 18035980, 2303556 }, Point{ 18336441, 1578177 }, Point{ 18572539, 829368 }, Point{ 18750748, 0 }, Point{ 19758422, 0 }, Point{ 19727293, 236479 }, Point{ 19538467, 1088188 }, Point{ 19276136, 1920196 },
|
||||
Point{ 18942292, 2726179 }, Point{ 18539460, 3499999 }, Point{ 18070731, 4235755 }, Point{ 17539650, 4927877 }, Point{ 16950279, 5571067 }, Point{ 16307090, 6160437 }, Point{ 15614974, 6691519 }, Point{ 14879209, 7160248 }, Point{ 14105392, 7563079 },
|
||||
Point{ 13299407, 7896927 }, Point{ 12467399, 8159255 }, Point{ 11615691, 8348082 }, Point{ 10750769, 8461952 }, Point{ 9879211, 8500000 }, Point{ 9007652, 8461952 }, Point{ 8142729, 8348082 }, Point{ 7291022, 8159255 }, Point{ 6459015, 7896927 },
|
||||
Point{ 5653029, 7563079 }, Point{ 4879210, 7160247 }, Point{ 4143447, 6691519 }, Point{ 3451331, 6160437 }, Point{ 2808141, 5571066 }, Point{ 2218773, 4927878 }, Point{ 1687689, 4235755 }, Point{ 1218962, 3499999 }, Point{ 827499, 2748020 },
|
||||
Point{ 482284, 1920196 }, Point{ 219954, 1088186 }, Point{ 31126, 236479 }, Point{ 0, 0 }, Point{ 1005754, 0 }
|
||||
} };
|
||||
|
||||
WHEN("creating the medial axis"){
|
||||
WHEN("creating the medial axis") {
|
||||
Polylines res;
|
||||
expolygon.medial_axis(scale_(1.324888), scale_(0.25), &res);
|
||||
|
||||
THEN("medial axis of a semicircumference is a single line"){
|
||||
THEN("medial axis of a semicircumference is a single line") {
|
||||
REQUIRE(res.size() == 1);
|
||||
}
|
||||
THEN("all medial axis segments of a semicircumference have the same orientation (but the 2 end points)"){
|
||||
THEN("all medial axis segments of a semicircumference have the same orientation (but the 2 end points)") {
|
||||
Lines lines = res[0].lines();
|
||||
double min_angle = 1, max_angle = -1;
|
||||
//std::cout << "first angle=" << lines[0].ccw(lines[1].b) << "\n";
|
||||
for (int idx = 1; idx < lines.size()-1; idx++){
|
||||
for (int idx = 1; idx < lines.size() - 1; idx++) {
|
||||
double angle = lines[idx - 1].ccw(lines[idx].b);
|
||||
if (std::abs(angle) - EPSILON < 0) angle = 0;
|
||||
//if (angle < 0) std::cout << unscale_(lines[idx - 1].a.x()) << ":" << unscale_(lines[idx - 1].a.y()) << " -> " << unscale_(lines[idx - 1].b.x()) << ":" << unscale_(lines[idx - 1].b.y()) << " -> " << unscale_(lines[idx].b.x()) << ":" << unscale_(lines[idx].b.y()) << "\n";
|
||||
std::cout << "angle=" << 180*lines[idx].a.ccw_angle(lines[idx-1].a, lines[idx].b)/PI << "\n";
|
||||
std::cout << "angle=" << 180 * lines[idx].a.ccw_angle(lines[idx - 1].a, lines[idx].b) / PI << "\n";
|
||||
min_angle = std::min(min_angle, angle);
|
||||
max_angle = std::max(max_angle, angle);
|
||||
}
|
||||
@ -122,6 +129,28 @@ SCENARIO("thin walls: ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GIVEN("round with large and very small distance between points"){
|
||||
ExPolygon expolygon;
|
||||
expolygon.contour = Slic3r::Polygon{ Points{
|
||||
Point::new_scale(15.181601,-2.389639), Point::new_scale(15.112616,-1.320034), Point::new_scale(14.024491,-0.644338), Point::new_scale(13.978982,-0.624495), Point::new_scale(9.993299,0.855584), Point::new_scale(9.941970,0.871195), Point::new_scale(5.796743,1.872643),
|
||||
Point::new_scale(5.743826,1.882168), Point::new_scale(1.509170,2.386464), Point::new_scale(1.455460,2.389639), Point::new_scale(-2.809359,2.389639), Point::new_scale(-2.862805,2.386464), Point::new_scale(-7.097726,1.882168), Point::new_scale(-7.150378,1.872643), Point::new_scale(-11.286344,0.873576),
|
||||
Point::new_scale(-11.335028,0.858759), Point::new_scale(-14.348632,-0.237938), Point::new_scale(-14.360538,-0.242436), Point::new_scale(-15.181601,-0.737570), Point::new_scale(-15.171309,-2.388509)
|
||||
} };
|
||||
expolygon.holes.push_back(Slic3r::Polygon{ Points{
|
||||
Point::new_scale( -11.023311,-1.034226 ), Point::new_scale( -6.920984,-0.042941 ), Point::new_scale( -2.768613,0.463207 ), Point::new_scale( 1.414714,0.463207 ), Point::new_scale( 5.567085,-0.042941 ), Point::new_scale( 9.627910,-1.047563 )
|
||||
} });
|
||||
|
||||
WHEN("creating the medial axis"){
|
||||
Polylines res;
|
||||
expolygon.medial_axis(scale_(2.5), scale_(0.5), &res);
|
||||
|
||||
THEN("medial axis of it is two line"){
|
||||
REQUIRE(res.size() == 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("french cross")
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user