diff --git a/lib/Slic3r/Surface.pm b/lib/Slic3r/Surface.pm index e0b6394f1..e1b84ad5a 100644 --- a/lib/Slic3r/Surface.pm +++ b/lib/Slic3r/Surface.pm @@ -7,12 +7,6 @@ our @ISA = qw(Exporter); our @EXPORT_OK = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE S_TYPE_INTERNALVOID); our %EXPORT_TAGS = (types => \@EXPORT_OK); -# delegate handles -sub contains_point { $_[0]->expolygon->contains_point } -sub lines { $_[0]->expolygon->lines } -sub contour { $_[0]->expolygon->contour } -sub holes { $_[0]->expolygon->holes } - # static method to group surfaces having same surface_type, bridge_angle and thickness* sub group { my $class = shift; @@ -43,20 +37,4 @@ sub p { return @{$self->polygons}; } -sub is_solid { - my $self = shift; - my $type = $self->surface_type; - # S_TYPE_INTERNALBRIDGE is not solid because we can't merge it with other solid types - return $type == S_TYPE_TOP - || $type == S_TYPE_BOTTOM - || $type == S_TYPE_INTERNALSOLID; -} - -sub is_bridge { - my $self = shift; - my $type = $self->surface_type; - return $type == S_TYPE_BOTTOM - || $type == S_TYPE_INTERNALBRIDGE; -} - 1; diff --git a/xs/src/Surface.cpp b/xs/src/Surface.cpp index 636467210..fadb47213 100644 --- a/xs/src/Surface.cpp +++ b/xs/src/Surface.cpp @@ -8,6 +8,21 @@ Surface::area() const return this->expolygon.area(); } +bool +Surface::is_solid() const +{ + return this->surface_type == stTop + || this->surface_type == stBottom + || this->surface_type == stInternalSolid; +} + +bool +Surface::is_bridge() const +{ + return this->surface_type == stBottom + || this->surface_type == stInternalBridge; +} + #ifdef SLIC3RXS SV* Surface::to_SV_ref() { diff --git a/xs/src/Surface.hpp b/xs/src/Surface.hpp index f7c72f7fc..5c4d65ef2 100644 --- a/xs/src/Surface.hpp +++ b/xs/src/Surface.hpp @@ -17,6 +17,8 @@ class Surface double bridge_angle; unsigned short extra_perimeters; double area() const; + bool is_solid() const; + bool is_bridge() const; #ifdef SLIC3RXS SV* to_SV_ref(); diff --git a/xs/src/SurfaceCollection.cpp b/xs/src/SurfaceCollection.cpp index b65c80622..898db92e1 100644 --- a/xs/src/SurfaceCollection.cpp +++ b/xs/src/SurfaceCollection.cpp @@ -1,4 +1,5 @@ #include "SurfaceCollection.hpp" +#include namespace Slic3r { @@ -18,4 +19,36 @@ SurfaceCollection::simplify(double tolerance) this->surfaces = ss; } +/* group surfaces by common properties */ +void +SurfaceCollection::group(std::vector &retval, bool merge_solid) const +{ + typedef std::map t_unique_map; + t_unique_map unique_map; + + for (Surfaces::const_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; + } + 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] = Surfaces(); + } + unique_map[key].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 c28894560..e941cee21 100644 --- a/xs/src/SurfaceCollection.hpp +++ b/xs/src/SurfaceCollection.hpp @@ -2,14 +2,30 @@ #define slic3r_SurfaceCollection_hpp_ #include "Surface.hpp" +#include 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) const; }; } diff --git a/xs/xsp/Surface.xsp b/xs/xsp/Surface.xsp index 787db562f..868cc9833 100644 --- a/xs/xsp/Surface.xsp +++ b/xs/xsp/Surface.xsp @@ -14,6 +14,8 @@ unsigned short thickness_layers() %code{% RETVAL = THIS->thickness_layers; %}; double area(); + bool is_solid() const; + bool is_bridge() const; %{ Surface*