Surface / Surface Collection - optimization routines for filtering,

routines for visualization.
This commit is contained in:
bubnikv 2016-09-26 12:42:44 +02:00
parent a506030082
commit 4a13efd081
5 changed files with 204 additions and 4 deletions

View file

@ -1,5 +1,6 @@
#include "BoundingBox.hpp" #include "BoundingBox.hpp"
#include "Surface.hpp" #include "Surface.hpp"
#include "SVG.hpp"
namespace Slic3r { namespace Slic3r {
@ -82,4 +83,65 @@ BoundingBox get_extents(const SurfacesPtr &surfaces)
return bbox; return bbox;
} }
const char* surface_type_to_color_name(const SurfaceType surface_type)
{
switch (surface_type) {
case stTop: return "rgb(255,0,0)"; // "red";
case stBottom: return "rgb(0,255,0)"; // "green";
case stBottomBridge: return "rgb(0,0,255)"; // "blue";
case stInternal: return "rgb(255,255,128)"; // yellow
case stInternalSolid: return "rgb(255,0,255)"; // magenta
case stInternalBridge: return "rgb(0,255,255)";
case stInternalVoid: return "rgb(128,128,128)";
case stPerimeter: return "rgb(128,0,0)"; // maroon
default: return "rgb(64,64,64)";
};
}
Point export_surface_type_legend_to_svg_box_size()
{
return Point(scale_(1.+10.*8.), scale_(3.));
}
void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
{
// 1st row
coord_t pos_x0 = pos.x + scale_(1.);
coord_t pos_x = pos_x0;
coord_t pos_y = pos.y + scale_(1.5);
coord_t step_x = scale_(10.);
svg.draw_legend(Point(pos_x, pos_y), "perimeter" , surface_type_to_color_name(stPerimeter));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "top" , surface_type_to_color_name(stTop));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "bottom" , surface_type_to_color_name(stBottom));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "bottom bridge" , surface_type_to_color_name(stBottomBridge));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "invalid" , surface_type_to_color_name(SurfaceType(-1)));
// 2nd row
pos_x = pos_x0;
pos_y = pos.y+scale_(2.8);
svg.draw_legend(Point(pos_x, pos_y), "internal" , surface_type_to_color_name(stInternal));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal solid" , surface_type_to_color_name(stInternalSolid));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal bridge", surface_type_to_color_name(stInternalBridge));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal void" , surface_type_to_color_name(stInternalVoid));
}
bool export_to_svg(const char *path, const Surfaces &surfaces, const float transparency)
{
BoundingBox bbox;
for (Surfaces::const_iterator surface = surfaces.begin(); surface != surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
SVG svg(path, bbox);
for (Surfaces::const_iterator surface = surfaces.begin(); surface != surfaces.end(); ++surface)
svg.draw(surface->expolygon, surface_type_to_color_name(surface->surface_type), transparency);
svg.Close();
return true;
}
} }

View file

@ -6,7 +6,7 @@
namespace Slic3r { namespace Slic3r {
enum SurfaceType { stTop, stBottom, stBottomBridge, stInternal, stInternalSolid, stInternalBridge, stInternalVoid }; enum SurfaceType { stTop, stBottom, stBottomBridge, stInternal, stInternalSolid, stInternalBridge, stInternalVoid, stPerimeter };
class Surface class Surface
{ {
@ -34,10 +34,43 @@ class Surface
typedef std::vector<Surface> Surfaces; typedef std::vector<Surface> Surfaces;
typedef std::vector<Surface*> SurfacesPtr; typedef std::vector<Surface*> SurfacesPtr;
inline Polygons to_polygons(const SurfacesPtr &src)
{
Polygons polygons;
for (SurfacesPtr::const_iterator it = src.begin(); it != src.end(); ++it) {
polygons.push_back((*it)->expolygon.contour);
for (Polygons::const_iterator ith = (*it)->expolygon.holes.begin(); ith != (*it)->expolygon.holes.end(); ++ith) {
polygons.push_back(*ith);
}
}
return polygons;
}
#if SLIC3R_CPPVER > 11
inline Polygons to_polygons(SurfacesPtr &&src)
{
Polygons polygons;
for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++it) {
polygons.push_back(std::move((*it)->expolygon.contour));
for (Polygons::const_iterator ith = (*it)->expolygon.holes.begin(); ith != (*it)->expolygon.holes.end(); ++ith) {
polygons.push_back(std::move(*ith));
}
}
return polygons;
}
#endif
extern BoundingBox get_extents(const Surface &surface); extern BoundingBox get_extents(const Surface &surface);
extern BoundingBox get_extents(const Surfaces &surfaces); extern BoundingBox get_extents(const Surfaces &surfaces);
extern BoundingBox get_extents(const SurfacesPtr &surfaces); extern BoundingBox get_extents(const SurfacesPtr &surfaces);
class SVG;
extern const char* surface_type_to_color_name(const SurfaceType surface_type);
extern void export_surface_type_legend_to_svg(SVG &svg, const Point &pos);
extern Point export_surface_type_legend_to_svg_box_size();
extern bool export_to_svg(const char *path, const Surfaces &surfaces, const float transparency = 1.f);
} }
#endif #endif

View file

@ -91,7 +91,7 @@ SurfaceCollection::any_bottom_contains(const T &item) const
template bool SurfaceCollection::any_bottom_contains<Polyline>(const Polyline &item) const; template bool SurfaceCollection::any_bottom_contains<Polyline>(const Polyline &item) const;
SurfacesPtr SurfacesPtr
SurfaceCollection::filter_by_type(SurfaceType type) SurfaceCollection::filter_by_type(const SurfaceType type)
{ {
SurfacesPtr ss; SurfacesPtr ss;
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) { for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
@ -100,6 +100,21 @@ SurfaceCollection::filter_by_type(SurfaceType type)
return ss; return ss;
} }
SurfacesPtr
SurfaceCollection::filter_by_types(const SurfaceType *types, int ntypes)
{
SurfacesPtr ss;
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
for (int i = 0; i < ntypes; ++ i) {
if (surface->surface_type == types[i]) {
ss.push_back(&*surface);
break;
}
}
}
return ss;
}
void void
SurfaceCollection::filter_by_type(SurfaceType type, Polygons* polygons) SurfaceCollection::filter_by_type(SurfaceType type, Polygons* polygons)
{ {
@ -111,10 +126,91 @@ SurfaceCollection::filter_by_type(SurfaceType type, Polygons* polygons)
} }
} }
void
SurfaceCollection::keep_type(const SurfaceType type)
{
size_t j = 0;
for (size_t i = 0; i < surfaces.size(); ++ i) {
if (surfaces[i].surface_type == type) {
if (j < i)
std::swap(surfaces[i], surfaces[j]);
++ j;
}
}
if (j < surfaces.size())
surfaces.erase(surfaces.begin() + j, surfaces.end());
}
void
SurfaceCollection::keep_types(const SurfaceType *types, int ntypes)
{
size_t j = 0;
for (size_t i = 0; i < surfaces.size(); ++ i) {
bool keep = false;
for (int k = 0; k < ntypes; ++ k) {
if (surfaces[i].surface_type == types[k]) {
keep = true;
break;
}
}
if (keep) {
if (j < i)
std::swap(surfaces[i], surfaces[j]);
++ j;
}
}
if (j < surfaces.size())
surfaces.erase(surfaces.begin() + j, surfaces.end());
}
void
SurfaceCollection::remove_type(const SurfaceType type)
{
size_t j = 0;
for (size_t i = 0; i < surfaces.size(); ++ i) {
if (surfaces[i].surface_type != type) {
if (j < i)
std::swap(surfaces[i], surfaces[j]);
++ j;
}
}
if (j < surfaces.size())
surfaces.erase(surfaces.begin() + j, surfaces.end());
}
void
SurfaceCollection::remove_types(const SurfaceType *types, int ntypes)
{
size_t j = 0;
for (size_t i = 0; i < surfaces.size(); ++ i) {
bool remove = false;
for (int k = 0; k < ntypes; ++ k) {
if (surfaces[i].surface_type == types[k]) {
remove = true;
break;
}
}
if (! remove) {
if (j < i)
std::swap(surfaces[i], surfaces[j]);
++ j;
}
}
if (j < surfaces.size())
surfaces.erase(surfaces.begin() + j, surfaces.end());
}
void void
SurfaceCollection::append(const SurfaceCollection &coll) SurfaceCollection::append(const SurfaceCollection &coll)
{ {
this->surfaces.insert(this->surfaces.end(), coll.surfaces.begin(), coll.surfaces.end()); this->surfaces.insert(this->surfaces.end(), coll.surfaces.begin(), coll.surfaces.end());
} }
void
SurfaceCollection::append(const SurfaceType surfaceType, const Slic3r::ExPolygons &expoly)
{
for (Slic3r::ExPolygons::const_iterator it = expoly.begin(); it != expoly.end(); ++ it)
this->surfaces.push_back(Slic3r::Surface(surfaceType, *it));
}
} }

View file

@ -21,9 +21,15 @@ class SurfaceCollection
void group(std::vector<SurfacesPtr> *retval); void group(std::vector<SurfacesPtr> *retval);
template <class T> bool any_internal_contains(const T &item) const; template <class T> bool any_internal_contains(const T &item) const;
template <class T> bool any_bottom_contains(const T &item) const; template <class T> bool any_bottom_contains(const T &item) const;
SurfacesPtr filter_by_type(SurfaceType type); SurfacesPtr filter_by_type(const SurfaceType type);
SurfacesPtr filter_by_types(const SurfaceType *types, int ntypes);
void keep_type(const SurfaceType type);
void keep_types(const SurfaceType *types, int ntypes);
void remove_type(const SurfaceType type);
void remove_types(const SurfaceType *types, int ntypes);
void filter_by_type(SurfaceType type, Polygons* polygons); void filter_by_type(SurfaceType type, Polygons* polygons);
void append(const SurfaceCollection &coll); void append(const SurfaceCollection &coll);
void append(const SurfaceType surfaceType, const Slic3r::ExPolygons &expoly);
}; };
} }

View file

@ -5,6 +5,7 @@
#include <ostream> #include <ostream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <stdint.h>
#define SLIC3R_VERSION "1.3.0-dev" #define SLIC3R_VERSION "1.3.0-dev"
@ -26,7 +27,9 @@
// Maximum perimeter length for the loop to apply the small perimeter speed. // Maximum perimeter length for the loop to apply the small perimeter speed.
#define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI #define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI
#define INSET_OVERLAP_TOLERANCE 0.4 #define INSET_OVERLAP_TOLERANCE 0.4
#define EXTERNAL_INFILL_MARGIN 3 // 3mm ring around the top / bottom / bridging areas.
//FIXME This is quite a lot.
#define EXTERNAL_INFILL_MARGIN 3.
#define scale_(val) ((val) / SCALING_FACTOR) #define scale_(val) ((val) / SCALING_FACTOR)
#define unscale(val) ((val) * SCALING_FACTOR) #define unscale(val) ((val) * SCALING_FACTOR)
#define SCALED_EPSILON scale_(EPSILON) #define SCALED_EPSILON scale_(EPSILON)