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 "Surface.hpp" | ||||
| #include "SVG.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|  | @ -82,4 +83,65 @@ BoundingBox get_extents(const SurfacesPtr &surfaces) | |||
|     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 { | ||||
| 
 | ||||
| enum SurfaceType { stTop, stBottom, stBottomBridge, stInternal, stInternalSolid, stInternalBridge, stInternalVoid }; | ||||
| enum SurfaceType { stTop, stBottom, stBottomBridge, stInternal, stInternalSolid, stInternalBridge, stInternalVoid, stPerimeter }; | ||||
| 
 | ||||
| class Surface | ||||
| { | ||||
|  | @ -34,10 +34,43 @@ class Surface | |||
| typedef std::vector<Surface> Surfaces; | ||||
| 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 Surfaces &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 | ||||
|  |  | |||
|  | @ -91,7 +91,7 @@ SurfaceCollection::any_bottom_contains(const T &item) const | |||
| template bool SurfaceCollection::any_bottom_contains<Polyline>(const Polyline &item) const; | ||||
| 
 | ||||
| SurfacesPtr | ||||
| SurfaceCollection::filter_by_type(SurfaceType type) | ||||
| SurfaceCollection::filter_by_type(const SurfaceType type) | ||||
| { | ||||
|     SurfacesPtr ss; | ||||
|     for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) { | ||||
|  | @ -100,6 +100,21 @@ SurfaceCollection::filter_by_type(SurfaceType type) | |||
|     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 | ||||
| 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 | ||||
| SurfaceCollection::append(const SurfaceCollection &coll) | ||||
| { | ||||
|     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); | ||||
|     template <class T> bool any_internal_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 append(const SurfaceCollection &coll); | ||||
|     void append(const SurfaceType surfaceType, const Slic3r::ExPolygons &expoly); | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <ostream> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #define SLIC3R_VERSION "1.3.0-dev" | ||||
| 
 | ||||
|  | @ -26,7 +27,9 @@ | |||
| // Maximum perimeter length for the loop to apply the small perimeter speed. 
 | ||||
| #define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI | ||||
| #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 unscale(val) ((val) * SCALING_FACTOR) | ||||
| #define SCALED_EPSILON scale_(EPSILON) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv