From 52de292a48c0595afb9b10052520ea2ab7d4c82e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 15 Mar 2014 02:16:04 +0100 Subject: [PATCH] Fixed wrong refactoring of perimeter tree traversal. #1832 --- lib/Slic3r/Layer/Region.pm | 2 +- xs/src/ExtrusionEntityCollection.cpp | 19 +++++++++++++------ xs/src/ExtrusionEntityCollection.hpp | 6 +++--- xs/xsp/ExtrusionEntityCollection.xsp | 13 ++++++++++++- xs/xsp/my.map | 1 + xs/xsp/typemap.xspt | 1 + 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 3e3854400..34da08e21 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -233,7 +233,7 @@ sub make_perimeters { # use a nearest neighbor search to order these children # TODO: supply second argument to chained_path() too? - my $sorted_collection = $collection->chained_path(0); + my $sorted_collection = $collection->chained_path_indices(0); my @orig_indices = @{$sorted_collection->orig_indices}; my @loops = (); diff --git a/xs/src/ExtrusionEntityCollection.cpp b/xs/src/ExtrusionEntityCollection.cpp index 9e5fb83a7..f4d78b404 100644 --- a/xs/src/ExtrusionEntityCollection.cpp +++ b/xs/src/ExtrusionEntityCollection.cpp @@ -1,4 +1,5 @@ #include "ExtrusionEntityCollection.hpp" +#include namespace Slic3r { @@ -34,25 +35,30 @@ ExtrusionEntityCollection::last_point() const } ExtrusionEntityCollection* -ExtrusionEntityCollection::chained_path(bool no_reverse) const +ExtrusionEntityCollection::chained_path(bool no_reverse, std::vector* orig_indices) const { if (this->entities.empty()) { return new ExtrusionEntityCollection (); } - return this->chained_path_from(this->entities.front()->first_point(), no_reverse); + return this->chained_path_from(this->entities.front()->first_point(), no_reverse, orig_indices); } ExtrusionEntityCollection* -ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse) const +ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse, std::vector* orig_indices) const { if (this->no_sort) return this->clone(); ExtrusionEntityCollection* retval = new ExtrusionEntityCollection; retval->entities.reserve(this->entities.size()); retval->orig_indices.reserve(this->entities.size()); + // if we're asked to return the original indices, build a map + std::map indices_map; + ExtrusionEntitiesPtr my_paths; for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) { - my_paths.push_back((*it)->clone()); + ExtrusionEntity* entity = (*it)->clone(); + my_paths.push_back(entity); + if (orig_indices != NULL) indices_map[entity] = it - this->entities.begin(); } Points endpoints; @@ -69,11 +75,12 @@ ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse) // find nearest point int start_index = start_near->nearest_point_index(endpoints); int path_index = start_index/2; + ExtrusionEntity* entity = my_paths.at(path_index); if (start_index % 2 && !no_reverse) { - my_paths.at(path_index)->reverse(); + entity->reverse(); } retval->entities.push_back(my_paths.at(path_index)); - retval->orig_indices.push_back(path_index); + if (orig_indices != NULL) orig_indices->push_back(indices_map[entity]); my_paths.erase(my_paths.begin() + path_index); endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2); start_near = retval->entities.back()->last_point(); diff --git a/xs/src/ExtrusionEntityCollection.hpp b/xs/src/ExtrusionEntityCollection.hpp index f4505183c..591546b36 100644 --- a/xs/src/ExtrusionEntityCollection.hpp +++ b/xs/src/ExtrusionEntityCollection.hpp @@ -11,11 +11,11 @@ class ExtrusionEntityCollection : public ExtrusionEntity public: ExtrusionEntityCollection* clone() const; ExtrusionEntitiesPtr entities; - std::vector orig_indices; + std::vector orig_indices; // handy for XS bool no_sort; ExtrusionEntityCollection(): no_sort(false) {}; - ExtrusionEntityCollection* chained_path(bool no_reverse) const; - ExtrusionEntityCollection* chained_path_from(Point* start_near, bool no_reverse) const; + ExtrusionEntityCollection* chained_path(bool no_reverse, std::vector* orig_indices = NULL) const; + ExtrusionEntityCollection* chained_path_from(Point* start_near, bool no_reverse, std::vector* orig_indices = NULL) const; void reverse(); Point* first_point() const; Point* last_point() const; diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index 11c0d6168..f2196c760 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -20,7 +20,7 @@ %code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; int count() %code{% RETVAL = THIS->entities.size(); %}; - std::vector orig_indices() + std::vector orig_indices() %code{% RETVAL = THIS->orig_indices; %}; %{ @@ -79,5 +79,16 @@ ExtrusionEntityCollection::no_sort(...) OUTPUT: RETVAL +ExtrusionEntityCollection* +ExtrusionEntityCollection::chained_path_indices(bool no_reverse) + PREINIT: + const char* CLASS = "Slic3r::ExtrusionPath::Collection"; + CODE: + std::vector indices; + RETVAL = THIS->chained_path(no_reverse, &indices); + RETVAL->orig_indices = indices; + OUTPUT: + RETVAL + %} }; diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 0b4645656..9fbe0b907 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -1,4 +1,5 @@ std::vector T_STD_VECTOR_INT +std::vector T_STD_VECTOR_INT t_config_option_key T_STD_STRING BoundingBox* O_OBJECT diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index fdb66492e..176b49878 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -2,6 +2,7 @@ %typemap{std::string}; %typemap{t_config_option_key}; %typemap{std::vector}; +%typemap{std::vector}; %typemap{std::vector*}; %typemap{std::vector}; %typemap{std::vector*};