diff options
author | supermerill <merill@free.fr> | 2018-07-04 19:52:35 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2018-07-04 19:52:35 +0300 |
commit | 4a6706ca5e12213927fb2edfa01a01ad0f244cf4 (patch) | |
tree | a37b9e850bb53f8afd88cd8a9d8521d80af5bb21 | |
parent | e2acfe0d7b488db6fa33372ee27816b2196a0460 (diff) |
many_changestemp4
-rw-r--r-- | lib/Slic3r/GUI/Plater/2DToolpaths.pm | 14 | ||||
-rw-r--r-- | xs/src/libslic3r/ExPolygon.cpp | 268 | ||||
-rw-r--r-- | xs/src/libslic3r/ExPolygon.hpp | 2 | ||||
-rw-r--r-- | xs/src/libslic3r/GCode.cpp | 13 | ||||
-rw-r--r-- | xs/src/libslic3r/Geometry.cpp | 30 | ||||
-rw-r--r-- | xs/src/libslic3r/PerimeterGenerator.cpp | 19 |
6 files changed, 292 insertions, 54 deletions
diff --git a/lib/Slic3r/GUI/Plater/2DToolpaths.pm b/lib/Slic3r/GUI/Plater/2DToolpaths.pm index 10e35f902..c64d50594 100644 --- a/lib/Slic3r/GUI/Plater/2DToolpaths.pm +++ b/lib/Slic3r/GUI/Plater/2DToolpaths.pm @@ -465,13 +465,11 @@ sub Render { foreach my $layerm (@{$layer->regions}) { if ($object->step_done(STEP_PERIMETERS)) { $self->color([0.7, 0, 0]); - print "PERI\n"; $self->_draw($object, $print_z, $_) for map @$_, @{$layerm->perimeters}; } if ($object->step_done(STEP_INFILL)) { $self->color([0, 0, 0.7]); - print "INFILL\n"; $self->_draw($object, $print_z, $_) for map @$_, @{$layerm->fills}; } } @@ -491,12 +489,6 @@ sub Render { sub _draw { my ($self, $object, $print_z, $path) = @_; - if ($path->isa('Slic3r::ExtrusionPath::Collection')){ - print "coll\n";} - if ($path->isa('Slic3r::ExtrusionLoop')){ - print "loop\n";} - if ($path->isa('Slic3r::ExtrusionMultiPath')){ - print "multi\n";} if ($path->isa('Slic3r::ExtrusionPath::Collection')) { $self->_draw($object, $print_z, $_) for @{$path}; @@ -511,12 +503,6 @@ sub _draw { sub _draw_path { my ($self, $object, $print_z, $path) = @_; - if ($path->isa('Slic3r::ExtrusionPath::Collection')){ - print "coll2\n";} - if ($path->isa('Slic3r::ExtrusionLoop')){ - print "loop2\n";} - if ($path->isa('Slic3r::ExtrusionMultiPath')){ - print "multi2\n";} return if $print_z - $path->height > $self->z - epsilon; diff --git a/xs/src/libslic3r/ExPolygon.cpp b/xs/src/libslic3r/ExPolygon.cpp index 02568ffd9..630f598ff 100644 --- a/xs/src/libslic3r/ExPolygon.cpp +++ b/xs/src/libslic3r/ExPolygon.cpp @@ -207,7 +207,7 @@ void ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const } void -ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polylines) const +ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_width, ThickPolylines* polylines) const { // init helper object Slic3r::Geometry::MedialAxis ma(max_width, min_width, this); @@ -218,6 +218,7 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl ma.build(&pp); + for (Lines lines : ma.lines){ cout << "lines " << lines.size() << ": "; for (Line line : lines){ @@ -237,7 +238,188 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl double max_w = 0; for (ThickPolylines::const_iterator it = pp.begin(); it != pp.end(); ++it) max_w = fmaxf(max_w, *std::max_element(it->width.begin(), it->width.end())); - + + /* Aligned fusion: Fusion the bits at the end of lines by "increasing thikness" + * 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; + for (size_t i = 0; i < pp.size(); ++i) { + ThickPolyline& polyline = pp[i]; + if (polyline.endpoints.first && polyline.endpoints.second) continue; // optimization + + ThickPolyline* best_candidate = nullptr; + float best_dot = -1; + int best_idx = 0; + + // find another polyline starting here + for (size_t j = i + 1; j < pp.size(); ++j) { + ThickPolyline& other = pp[j]; + if (polyline.last_point().coincides_with(other.last_point())) { + std::cout << "VOROFUSION av " << unscale(polyline.first_point().x) << ":" << unscale(polyline.first_point().y) << "\n"; + polyline.reverse(); + other.reverse(); + } + else if (polyline.first_point().coincides_with(other.last_point())) { + std::cout << "VOROFUSION ov " << unscale(polyline.last_point().x) << ":" << unscale(polyline.last_point().y) << "\n"; + other.reverse(); + } + else if (polyline.first_point().coincides_with(other.first_point())) { + std::cout << "VOROFUSION ok " << unscale(polyline.last_point().x) << ":" << unscale(polyline.last_point().y) << "\n"; + } + else if (polyline.last_point().coincides_with(other.first_point())) { + std::cout << "VOROFUSION mv " << unscale(polyline.first_point().x) << ":" << unscale(polyline.first_point().y) << "\n"; + polyline.reverse(); + } else { + continue; + } + + //only consider the other if the next point is near us + if (polyline.points.size() < 2 && other.points.size() < 2) continue; + std::cout << "ok to move? : !" << polyline.endpoints.second << " && !" << other.endpoints.second << "\n"; + if (!polyline.endpoints.second || !other.endpoints.second) continue; + if (polyline.points.back().distance_to(other.points.back()) > max_width) { + std::cout << "too far apart : " << polyline.points.back().distance_to(other.points.back())<< " > "<< max_width << "\n"; + continue; + } else { + std::cout << "dist ok : " << polyline.points.back().distance_to(other.points.back()) << " < " << max_width << "\n"; + } + if (polyline.points.size() != other.points.size()) { + std::cout << "not same nbPoints : " << polyline.points.size() << " != " << other.points.size() <<"\n"; + continue; + } + + std::cout << "VOROFUSION (1) ThickPolyline " << polyline.points.size() << ": "; + for (unsigned int i = 0; i < polyline.points.size() && i < 10; i++) { + std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); + } + std::cout << "\n"; + std::cout << "VOROFUSION (2) ThickPolyline " << other.points.size() << ": "; + for (unsigned int i = 0; i < other.points.size() && i < 10; i++) { + std::cout << "->" << unscale(other.points[i].x) << ":" << unscale(other.points[i].y); + } + std::cout << "\n"; + + Pointf v_poly(polyline.lines().front().vector().x, polyline.lines().front().vector().y); + std::cout << "my vect (before norm: " << (v_poly.x) << " : " << (v_poly.y) << "\n"; + std::cout << "my vect (before norm: " << unscale(v_poly.x) << " : " << unscale(v_poly.y) << "\n"; + std::cout << "my vect ( norm: " << std::sqrt(v_poly.x*v_poly.x + v_poly.y*v_poly.y) << "\n"; + v_poly.scale(1 / std::sqrt(v_poly.x*v_poly.x + v_poly.y*v_poly.y)); + std::cout << "my vect: " << v_poly.x << " : " << v_poly.y << "\n"; + Pointf v_other(other.lines().front().vector().x, other.lines().front().vector().y); + std::cout << "his vect (before norm: " << v_other.x << " : " << v_other.y << "\n"; + std::cout << "his vect (before norm: " << unscale(v_other.x) << " : " << unscale(v_other.y) << "\n"; + std::cout << "his vect ( norm: " << std::sqrt(v_other.x*v_other.x + v_other.y*v_other.y) << "\n"; + v_other.scale(1 / std::sqrt(v_other.x*v_other.x + v_other.y*v_other.y)); + std::cout << "his vect: " << v_other.x << " : " << v_other.y << "\n"; + float other_dot = v_poly.x*v_other.x + v_poly.y*v_other.y; + std::cout << "VOROFUSION dot " << other_dot << " >? " << best_dot << "\n"; + if (other_dot > best_dot) { + std::cout << "VOROFUSION WIN: \n"; + best_candidate = &other; + best_idx = j; + best_dot = other_dot; + } + } + std::cout << "VOROFUSION search ended: \n"; + if (best_candidate != nullptr) { + std::cout << "VOROFUSION launched: \n"; + + //TODO: witch if polyline.size > best_candidate->size + //doesn't matter rright now because a if in the selection process prevent this. + + //iterate the points + // as voronoi should create symetric thing, we can iterate synchonously + unsigned int idx_point = 1; + std::cout << "start fusion " << idx_point << " < " << polyline.points.size() << " & " << best_candidate->points.size() << " \n"; + std::cout << "start fusion " << idx_point << " < " << polyline.width.size() << " & " << best_candidate->width.size() << " \n"; + while (idx_point < polyline.points.size() && polyline.points[idx_point].distance_to(best_candidate->points[idx_point]) < max_width) { + std::cout << "fusion " << idx_point << " < " << polyline.points.size() << " & " << best_candidate->points.size()<<" \n"; + //fusion + polyline.points[idx_point].x += best_candidate->points[idx_point].x; + polyline.points[idx_point].x /= 2; + polyline.points[idx_point].y += best_candidate->points[idx_point].y; + polyline.points[idx_point].y /= 2; + polyline.width[idx_point] += best_candidate->width[idx_point]; + ++idx_point; + } + std::cout << "fusion finishing: \n"; + if (idx_point < best_candidate->points.size()) { + if (idx_point + 1 < best_candidate->points.size()) { + std::cout << "fusion create new poly: \n"; + //create a new polyline + pp.emplace_back(); + pp.back().endpoints.first = true; + pp.back().endpoints.second = best_candidate->endpoints.second; + for (int idx_point_new_line = idx_point; idx_point_new_line < best_candidate->points.size(); ++idx_point_new_line) { + pp.back().points.push_back(best_candidate->points[idx_point_new_line]); + pp.back().width.push_back(best_candidate->width[idx_point_new_line]); + } + std::cout << "VOROFUSION (pp) " << pp.back().points.size() << ": "; + for (unsigned int i = 0; i < pp.back().points.size() && i < 10; i++) { + std::cout << "->" << unscale(pp.back().points[i].x) << ":" << unscale(pp.back().points[i].y); + } + } else { + std::cout << "fusion add last point: \n"; + //Add last point + polyline.points.push_back(best_candidate->points[idx_point]); + polyline.width.push_back(best_candidate->width[idx_point]); + //select if an end opccur + polyline.endpoints.second &= best_candidate->endpoints.second; + } + + } else { + //select if an end opccur + polyline.endpoints.second &= best_candidate->endpoints.second; + } + + //remove points that are the same or too close each other, ie simplify + for (unsigned int idx_point = 1; idx_point < polyline.points.size(); ++idx_point) { + //distance of 1 is on the sclaed coordinates, so it correspond to SCALE_FACTOR, so it's very small + if (polyline.points[idx_point - 1].distance_to(polyline.points[idx_point]) < 1) { + std::cout << "fusion erase duplicate@" << idx_point<< " \n"; + if (idx_point < polyline.points.size() -1) { + polyline.points.erase(polyline.points.begin() + idx_point); + } else { + polyline.points.erase(polyline.points.begin() + idx_point -1); + } + --idx_point; + } + } + //remove points that are outside of the geometry + for (unsigned int idx_point = 0; idx_point < polyline.points.size(); ++idx_point) { + //distance of 1 is on the sclaed coordinates, so it correspond to SCALE_FACTOR, so it's very small + if (!bounds.contains_b(polyline.points[idx_point])) { + std::cout << "erase outside point@" << idx_point << " \n"; + polyline.points.erase(polyline.points.begin() + idx_point); + --idx_point; + } + } + if (polyline.points.size() < 2) { + //remove self + pp.erase(pp.begin() + i); + --i; + --best_idx; + } + + + std::cout << "fusion erase second line: \n"; + pp.erase(pp.begin() + best_idx); + + std::cout << "VOROFUSION (res) ThickPolyline " << polyline.points.size() << ": "; + for (int i = 0; i < polyline.points.size() && i < 10; i++) { + std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); + } + std::cout << "\n"; + changes = true; + } + } + } + + /* Loop through all returned polylines in order to extend their endpoints to the expolygon boundaries */ bool removed = false; @@ -255,23 +437,25 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl 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 && !this->has_boundary_point(new_front)) { - std::cout << "ThickPolyline extend(1)?\n"; + std::cout << "ThickPolyline start" << polyline.endpoints.first << " && !"<<bounds.has_boundary_point(new_front) << "?\n"; + if (polyline.endpoints.first && !bounds.has_boundary_point(new_front)) { + std::cout << "ThickPolyline extend(1) " << bounds.contains(new_front) << "?\n"; Line line(polyline.points.front(), polyline.points[1]); // prevent the line from touching on the other side, otherwise intersection() might return that solution if (polyline.points.size() == 2) line.b = line.midpoint(); line.extend_start(max_width); - (void)this->contour.intersection(line, &new_front); + (void)bounds.contour.intersection(line, &new_front); std::cout << "NEW 1 ThickPolyline " << polyline.points.size() << ": "; for (int i = 0; i < polyline.points.size() && i < 10; i++){ std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); } std::cout << "\n"; } - if (polyline.endpoints.second && !this->has_boundary_point(new_back)) { - std::cout << "ThickPolyline extend(1)?\n"; + std::cout << "ThickPolyline end " << polyline.endpoints.second << " && !" << bounds.has_boundary_point(new_back) << "?\n"; + if (polyline.endpoints.second && !bounds.has_boundary_point(new_back)) { + std::cout << "ThickPolyline extend(1)" << bounds.contains(new_back) << "?\n"; Line line( *(polyline.points.end() - 2), polyline.points.back() @@ -281,7 +465,7 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl if (polyline.points.size() == 2) line.a = line.midpoint(); line.extend_end(max_width); - (void)this->contour.intersection(line, &new_back); + (void)bounds.contour.intersection(line, &new_back); std::cout << "NEW 2 ThickPolyline " << polyline.points.size() << ": "; for (int i = 0; i < polyline.points.size() && i < 10; i++){ std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); @@ -293,6 +477,8 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl } + + /* 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 @@ -300,23 +486,29 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl drawbacks since we optimize later using nearest-neighbor which would do the same, but should we use a more sophisticated optimization algorithm we should not connect polylines when more than two meet. */ - //FIXME: try to merge with the segment that is the most "aligned" with me, ie strait lines. if (true || removed) { for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline& polyline = pp[i]; if (polyline.endpoints.first && polyline.endpoints.second) continue; // optimization + ThickPolyline* best_candidate = nullptr; + float best_dot = -1; + int best_idx = 0; + // find another polyline starting here - for (size_t j = i+1; j < pp.size(); ++j) { + for (size_t j = i + 1; j < pp.size(); ++j) { ThickPolyline& other = pp[j]; if (polyline.last_point().coincides_with(other.last_point())) { other.reverse(); - } else if (polyline.first_point().coincides_with(other.last_point())) { + } + else if (polyline.first_point().coincides_with(other.last_point())) { polyline.reverse(); other.reverse(); - } else if (polyline.first_point().coincides_with(other.first_point())) { + } + else if (polyline.first_point().coincides_with(other.first_point())) { polyline.reverse(); - } else if (!polyline.last_point().coincides_with(other.first_point())) { + } + else if (!polyline.last_point().coincides_with(other.first_point())) { continue; } std::cout << "FUSION (1) ThickPolyline " << polyline.points.size() << ": "; @@ -329,19 +521,43 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl std::cout << "->" << unscale(other.points[i].x) << ":" << unscale(other.points[i].y); } std::cout << "\n"; - - polyline.points.insert(polyline.points.end(), other.points.begin() + 1, other.points.end()); - polyline.width.insert(polyline.width.end(), other.width.begin(), other.width.end()); - polyline.endpoints.second = other.endpoints.second; + std::cout << "FUSION (1 again) ThickPolyline " << polyline.points.size() << ": "; + for (int i = 0; i < polyline.points.size() && i < 10; i++) { + std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); + } + std::cout << "\n"; + + Pointf v_poly(polyline.lines().back().vector().x, polyline.lines().back().vector().y); + std::cout << "my vect (before norm: " << (v_poly.x) << " : " << (v_poly.y) << "\n"; + std::cout << "my vect ( norm: " << std::sqrt(v_poly.x*v_poly.x + v_poly.y*v_poly.y) << "\n"; + v_poly.scale(1 / std::sqrt(v_poly.x*v_poly.x + v_poly.y*v_poly.y)); + std::cout << "his vect: " << v_poly.x << " : " << v_poly.y << "\n"; + Pointf v_other(other.lines().front().vector().x, other.lines().front().vector().y); + std::cout << "his vect (before norm: " << v_other.x << " : " << v_other.y << "\n"; + std::cout << "his vect ( norm: " << std::sqrt(v_other.x*v_other.x + v_other.y*v_other.y) << "\n"; + v_other.scale(1 / std::sqrt(v_other.x*v_other.x + v_other.y*v_other.y)); + std::cout << "his vect: " << v_other.x << " : " << v_other.y << "\n"; + float other_dot = v_poly.x*v_other.x + v_poly.y*v_other.y; + std::cout << "FUSION dot " << other_dot << " >? " << best_dot << "\n"; + if (other_dot > best_dot) { + best_candidate = &other; + best_idx = j; + best_dot = other_dot; + } + } + if (best_candidate != nullptr) { + + polyline.points.insert(polyline.points.end(), best_candidate->points.begin() + 1, best_candidate->points.end()); + polyline.width.insert(polyline.width.end(), best_candidate->width.begin(), best_candidate->width.end()); + polyline.endpoints.second = best_candidate->endpoints.second; assert(polyline.width.size() == polyline.points.size()*2 - 2); - pp.erase(pp.begin() + j); + pp.erase(pp.begin () + best_idx); std::cout << "FUSION (res) ThickPolyline " << polyline.points.size() << ": "; - for (int i = 0; i < polyline.points.size() && i < 10; i++){ + for (int i = 0; i < polyline.points.size() && i < 10; i++) { std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); } std::cout << "\n"; - j = i; // restart search from i+1 } } } @@ -349,6 +565,11 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline& polyline = pp[i]; + std::cout << "END ThickPolyline " << polyline.points.size() << ": "; + for (int i = 0; i < polyline.points.size() && i < 10; i++){ + std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); + } + std::cout << "\n"; /* remove too short polylines (we can't do this check before endpoints extension and clipping because we don't @@ -363,11 +584,6 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl std::cout << "ThickPolyline DELETED!!\n"; continue; } - std::cout << "END ThickPolyline " << polyline.points.size() << ": "; - for (int i = 0; i < polyline.points.size() && i < 10; i++){ - std::cout << "->" << unscale(polyline.points[i].x) << ":" << unscale(polyline.points[i].y); - } - std::cout << "\n"; } @@ -379,7 +595,7 @@ void ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines) const { ThickPolylines tp; - this->medial_axis(max_width, min_width, &tp); + this->medial_axis(*this, max_width, min_width, &tp); polylines->insert(polylines->end(), tp.begin(), tp.end()); } diff --git a/xs/src/libslic3r/ExPolygon.hpp b/xs/src/libslic3r/ExPolygon.hpp index f4782ba55..94682c23f 100644 --- a/xs/src/libslic3r/ExPolygon.hpp +++ b/xs/src/libslic3r/ExPolygon.hpp @@ -53,7 +53,7 @@ public: Polygons simplify_p(double tolerance) const; ExPolygons simplify(double tolerance) const; void simplify(double tolerance, ExPolygons* expolygons) const; - void medial_axis(double max_width, double min_width, ThickPolylines* polylines) const; + void medial_axis(const ExPolygon &bounds, double max_width, double min_width, ThickPolylines* polylines) const; void medial_axis(double max_width, double min_width, Polylines* polylines) const; void get_trapezoids(Polygons* polygons) const; void get_trapezoids(Polygons* polygons, double angle) const; diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 0d832e771..6cf79a37e 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1993,11 +1993,11 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string des return this->extrude_multi_path(*multipath, description, speed); else if (const ExtrusionLoop* loop = dynamic_cast<const ExtrusionLoop*>(&entity)) return this->extrude_loop(*loop, description, speed, lower_layer_edge_grid); - else if (const ExtrusionEntityCollection* loop = dynamic_cast<const ExtrusionEntityCollection*>(&entity)){ + else if (const ExtrusionEntityCollection* coll = dynamic_cast<const ExtrusionEntityCollection*>(&entity)){ std::string gcode; ExtrusionEntityCollection chained; - if (loop->no_sort) chained = *loop; - else chained = loop->chained_path_from(m_last_pos, false); + if (coll->no_sort) chained = *coll; + else chained = coll->chained_path_from(m_last_pos, false); for (ExtrusionEntity *next_entity : chained.entities) { gcode += extrude_entity(*next_entity, description, speed, lower_layer_edge_grid); } @@ -2037,7 +2037,7 @@ std::string GCode::extrude_infill(const Print &print, const ObjectByExtruder::Is { std::string gcode; ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false); - gcode += extrude_infill(print, chained); + gcode += extrude_entity(chained, "infill"); return gcode; } @@ -2045,7 +2045,7 @@ std::string GCode::extrude_infill(const Print &print, const ObjectByExtruder::Is std::string GCode::extrude_infill(const Print &print, const ExtrusionEntityCollection &collection) { std::string gcode; - +/* ExtrusionEntityCollection chained; if (collection.no_sort) chained = collection; else chained = collection.chained_path_from(m_last_pos, false); @@ -2056,7 +2056,8 @@ std::string GCode::extrude_infill(const Print &print, const ExtrusionEntityColle } else { gcode += this->extrude_entity(*fill, "infill"); } - } + }*/ + gcode += "CACA"; return gcode; } diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp index 39b626ee3..450742d21 100644 --- a/xs/src/libslic3r/Geometry.cpp +++ b/xs/src/libslic3r/Geometry.cpp @@ -839,7 +839,16 @@ void MedialAxis::build(ThickPolylines* polylines) { construct_voronoi(this->lines.begin(), this->lines.end(), &this->vd); - + + + std::cout << "VORONOI : "; + 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; + } /* // DEBUG: dump all Voronoi edges { @@ -860,6 +869,7 @@ MedialAxis::build(ThickPolylines* polylines) // 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; @@ -876,9 +886,16 @@ 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; + 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"; + } // iterate through the valid edges to build polylines while (!this->edges.empty()) { @@ -890,6 +907,9 @@ MedialAxis::build(ThickPolylines* polylines) polyline.points.push_back(Point( edge->vertex1()->x(), edge->vertex1()->y() )); polyline.width.push_back(this->thickness[edge].first); polyline.width.push_back(this->thickness[edge].second); + + std::cout << "start polyline : " << unscale(edge->vertex0()->x()) << ":" << unscale(edge->vertex0()->y()) + << "=>" << unscale(edge->vertex1()->x()) << ":" << unscale(edge->vertex1()->y()) << "\n"; // remove this edge and its twin from the available edges (void)this->edges.erase(edge); @@ -965,6 +985,9 @@ MedialAxis::process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* pol // break if this is a closed loop if (this->edges.count(neighbor) == 0) return; + + std::cout << "add to polyline : " << unscale(edge->vertex0()->x()) << ":" << unscale(edge->vertex0()->y()) + << "=>" << unscale(edge->vertex1()->x()) << ":" << unscale(edge->vertex1()->y()) << "\n"; Point new_point(neighbor->vertex1()->x(), neighbor->vertex1()->y()); polyline->points.push_back(new_point); @@ -974,9 +997,12 @@ MedialAxis::process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* pol (void)this->edges.erase(neighbor->twin()); edge = neighbor; } else if (neighbors.size() == 0) { + std::cout << "end of polyline \n"; polyline->endpoints.second = true; return; - } else { + } + else { + std::cout << "nothing \n"; // T-shaped or star-shaped joint return; } diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index 2a7f7ce5a..d204e0f56 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -92,10 +92,19 @@ void PerimeterGenerator::process() no_thin_zone, true), -min_width / 2, min_width / 2); - // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop - ExPolygons anchor = intersection_ex(to_polygons(offset_ex(expp, min_width)), no_thin_zone, true); - for (ExPolygon &ex : _clipper_ex(ClipperLib::ctUnion, to_polygons(expp), to_polygons(anchor), true)) - ex.medial_axis(ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls); + std::cout << "LAYER =" << this->layer_id << "\n"; + // compute a bit of overlap to anchor thin walls inside the print. + ExPolygons anchor = intersection_ex(to_polygons(offset_ex(expp, ext_perimeter_width / 2)), no_thin_zone, true); + for (ExPolygon &ex : expp) { + ExPolygons &bounds = _clipper_ex(ClipperLib::ctUnion, to_polygons(ex), to_polygons(anchor), true); + for (ExPolygon &bound : bounds) { + if (!intersection_ex(ex, bound).empty()) { + // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop + ex.medial_axis(bound, ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls); + continue; + } + } + } } } else { //FIXME Is this offset correct if the line width of the inner perimeters differs @@ -238,7 +247,7 @@ void PerimeterGenerator::process() true); ThickPolylines polylines; for (const ExPolygon &ex : gaps_ex) - ex.medial_axis(max, min, &polylines); + ex.medial_axis(ex, max, min, &polylines); if (!polylines.empty()) { ExtrusionEntityCollection gap_fill = this->_variable_width(polylines, erGapFill, this->solid_infill_flow); |