#include #include "../ClipperUtils.hpp" #include "../Surface.hpp" #include "../PrintConfig.hpp" #include "FillBase.hpp" #include "FillConcentric.hpp" #include "FillHoneycomb.hpp" #include "Fill3DHoneycomb.hpp" #include "FillGyroid.hpp" #include "FillPlanePath.hpp" #include "FillRectilinear.hpp" #include "FillRectilinear2.hpp" #include "FillRectilinear3.hpp" namespace Slic3r { Fill* Fill::new_from_type(const InfillPattern type) { switch (type) { case ipConcentric: return new FillConcentric(); case ipHoneycomb: return new FillHoneycomb(); case ip3DHoneycomb: return new Fill3DHoneycomb(); case ipGyroid: return new FillGyroid(); case ipRectilinear: return new FillRectilinear2(); // case ipRectilinear: return new FillRectilinear(); case ipLine: return new FillLine(); case ipGrid: return new FillGrid2(); case ipTriangles: return new FillTriangles(); case ipStars: return new FillStars(); case ipCubic: return new FillCubic(); // case ipGrid: return new FillGrid(); case ipArchimedeanChords: return new FillArchimedeanChords(); case ipHilbertCurve: return new FillHilbertCurve(); case ipOctagramSpiral: return new FillOctagramSpiral(); default: CONFESS("unknown type"); return nullptr; } } Fill* Fill::new_from_type(const std::string &type) { const t_config_enum_values &enum_keys_map = ConfigOptionEnum::get_enum_values(); t_config_enum_values::const_iterator it = enum_keys_map.find(type); return (it == enum_keys_map.end()) ? nullptr : new_from_type(InfillPattern(it->second)); } Polylines Fill::fill_surface(const Surface *surface, const FillParams ¶ms) { // Perform offset. Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing))); // Create the infills for each of the regions. Polylines polylines_out; for (size_t i = 0; i < expp.size(); ++ i) _fill_surface_single( params, surface->thickness_layers, _infill_direction(surface), expp[i], polylines_out); return polylines_out; } // Calculate a new spacing to fill width with possibly integer number of lines, // the first and last line being centered at the interval ends. // This function possibly increases the spacing, never decreases, // and for a narrow width the increase in spacing may become severe, // therefore the adjustment is limited to 20% increase. coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance) { assert(width >= 0); assert(distance > 0); // floor(width / distance) coord_t number_of_intervals = (width - EPSILON) / distance; coord_t distance_new = (number_of_intervals == 0) ? distance : ((width - EPSILON) / number_of_intervals); const coordf_t factor = coordf_t(distance_new) / coordf_t(distance); assert(factor > 1. - 1e-5); // How much could the extrusion width be increased? By 20%. const coordf_t factor_max = 1.2; if (factor > factor_max) distance_new = coord_t(floor((coordf_t(distance) * factor_max + 0.5))); return distance_new; } // Returns orientation of the infill and the reference point of the infill pattern. // For a normal print, the reference point is the center of a bounding box of the STL. std::pair Fill::_infill_direction(const Surface *surface) const { // set infill angle float out_angle = this->angle; if (out_angle == FLT_MAX) { //FIXME Vojtech: Add a warning? printf("Using undefined infill angle\n"); out_angle = 0.f; } // Bounding box is the bounding box of a perl object Slic3r::Print::Object (c++ object Slic3r::PrintObject) // The bounding box is only undefined in unit tests. Point out_shift = empty(this->bounding_box) ? surface->expolygon.contour.bounding_box().center() : this->bounding_box.center(); #if 0 if (empty(this->bounding_box)) { printf("Fill::_infill_direction: empty bounding box!"); } else { printf("Fill::_infill_direction: reference point %d, %d\n", out_shift.x, out_shift.y); } #endif if (surface->bridge_angle >= 0) { // use bridge angle //FIXME Vojtech: Add a debugf? // Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle); #ifdef SLIC3R_DEBUG printf("Filling bridge with angle %f\n", surface->bridge_angle); #endif /* SLIC3R_DEBUG */ out_angle = surface->bridge_angle; } else if (this->layer_id != size_t(-1)) { // alternate fill direction out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers); } else { // printf("Layer_ID undefined!\n"); } out_angle += float(M_PI/2.); return std::pair(out_angle, out_shift); } } // namespace Slic3r