mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -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
	
	 bubnikv
						bubnikv