From e9b87b69df85e0693224afb40ebbbd0e24d3d710 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 4 Dec 2013 00:10:31 +0100 Subject: [PATCH] Bugfix: segfault in SurfaceCollection->group(), fixed with a better implementation. #1566 --- xs/src/SurfaceCollection.cpp | 41 +++++++++++++++++------------------- xs/src/SurfaceCollection.hpp | 16 +------------- xs/xsp/SurfaceCollection.xsp | 2 +- 3 files changed, 21 insertions(+), 38 deletions(-) diff --git a/xs/src/SurfaceCollection.cpp b/xs/src/SurfaceCollection.cpp index ce4995ea..fb63d333 100644 --- a/xs/src/SurfaceCollection.cpp +++ b/xs/src/SurfaceCollection.cpp @@ -21,34 +21,31 @@ SurfaceCollection::simplify(double tolerance) /* group surfaces by common properties */ void -SurfaceCollection::group(std::vector &retval, bool merge_solid) +SurfaceCollection::group(std::vector *retval, bool merge_solid) { - typedef std::map t_unique_map; - t_unique_map unique_map; - for (Surfaces::iterator it = this->surfaces.begin(); it != this->surfaces.end(); ++it) { - // build the t_surface_group_key struct with this surface's properties - t_surface_group_key key; - if (merge_solid && it->is_solid()) { - key.surface_type = stTop; - } else { - key.surface_type = it->surface_type; + // find a group with the same properties + SurfacesPtr* group = NULL; + for (std::vector::iterator git = retval->begin(); git != retval->end(); ++git) { + Surface* gkey = git->front(); + if ((gkey->surface_type == it->surface_type || (merge_solid && gkey->is_solid() && it->is_solid())) + && gkey->thickness == it->thickness + && gkey->thickness_layers == it->thickness_layers + && gkey->bridge_angle == it->bridge_angle) { + group = &*git; + break; + } } - key.thickness = it->thickness; - key.thickness_layers = it->thickness_layers; - key.bridge_angle = it->bridge_angle; - // check whether we already have a group for these properties - if (unique_map.find(key) == unique_map.end()) { - // no group exists, add it - unique_map[key] = SurfacesPtr(); + // if no group with these properties exists, add one + if (group == NULL) { + retval->resize(retval->size() + 1); + group = &retval->back(); } - unique_map[key].push_back(&*it); + + // append surface to group + group->push_back(&*it); } - - retval.reserve(unique_map.size()); - for (t_unique_map::const_iterator it = unique_map.begin(); it != unique_map.end(); ++it) - retval.push_back(it->second); } } diff --git a/xs/src/SurfaceCollection.hpp b/xs/src/SurfaceCollection.hpp index 32bd6c04..dc5ebc11 100644 --- a/xs/src/SurfaceCollection.hpp +++ b/xs/src/SurfaceCollection.hpp @@ -6,26 +6,12 @@ namespace Slic3r { -struct t_surface_group_key { - SurfaceType surface_type; - double thickness; - unsigned short thickness_layers; - double bridge_angle; - - bool operator< (const t_surface_group_key &key) const { - return (this->surface_type < key.surface_type) - || (this->thickness < key.thickness) - || (this->thickness_layers < key.thickness_layers) - || (this->bridge_angle < key.bridge_angle); - } -}; - class SurfaceCollection { public: Surfaces surfaces; void simplify(double tolerance); - void group(std::vector &retval, bool merge_solid = false); + void group(std::vector *retval, bool merge_solid = false); }; } diff --git a/xs/xsp/SurfaceCollection.xsp b/xs/xsp/SurfaceCollection.xsp index d880ebcd..4219bbe6 100644 --- a/xs/xsp/SurfaceCollection.xsp +++ b/xs/xsp/SurfaceCollection.xsp @@ -80,7 +80,7 @@ SurfaceCollection::group(merge_solid = false) CODE: // perform grouping std::vector groups; - THIS->group(groups, merge_solid); + THIS->group(&groups, merge_solid); // build return arrayref AV* av = newAV();