mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-17 03:37:54 -06:00
Surface / Surface Collection - optimization routines for filtering,
routines for visualization.
This commit is contained in:
parent
a506030082
commit
4a13efd081
5 changed files with 204 additions and 4 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue