No (more) need for a separate FillParams class

This commit is contained in:
Alessandro Ranellucci 2016-11-30 18:43:56 +01:00
parent 3e04877571
commit ea98d97743
18 changed files with 103 additions and 115 deletions

View File

@ -51,8 +51,10 @@ Fill::new_from_type(const std::string &type)
}
Polylines
Fill::fill_surface(const Surface &surface, const FillParams &params)
Fill::fill_surface(const Surface &surface)
{
if (this->density == 0) return Polylines();
// Perform offset.
ExPolygons expp = offset_ex(surface.expolygon, -scale_(this->spacing)/2);
@ -60,7 +62,6 @@ Fill::fill_surface(const Surface &surface, const FillParams &params)
Polylines polylines_out;
for (size_t i = 0; i < expp.size(); ++i)
this->_fill_surface_single(
params,
surface.thickness_layers,
this->_infill_direction(surface),
expp[i],

View File

@ -16,26 +16,7 @@ namespace Slic3r {
class Surface;
struct FillParams
{
public:
FillParams() : density(0), dont_connect(false), dont_adjust(false), complete(false) {};
// Fill density, fraction in <0, 1>
float density;
// Don't connect the fill lines around the inner perimeter.
bool dont_connect;
// Don't adjust spacing to fill the space evenly.
bool dont_adjust;
// For Honeycomb.
// we were requested to complete each loop;
// in this case we don't try to make more continuous paths
bool complete;
};
// Abstract base class for the infill generators.
class Fill
{
public:
@ -60,16 +41,29 @@ public:
coord_t loop_clipping;
// In scaled coordinates. Bounding box of the 2D projection of the object.
// If not defined, the bounding box of each single expolygon is used.
BoundingBox bounding_box;
// Fill density, fraction in <0, 1>
float density;
// Don't connect the fill lines around the inner perimeter.
bool dont_connect;
// Don't adjust spacing to fill the space evenly.
bool dont_adjust;
// For Honeycomb.
// we were requested to complete each loop;
// in this case we don't try to make more continuous paths
bool complete;
public:
virtual ~Fill() {}
static Fill* new_from_type(const InfillPattern type);
static Fill* new_from_type(const std::string &type);
static coord_t adjust_solid_spacing(const coord_t width, const coord_t distance);
void set_bounding_box(const BoundingBox &bb) { this->bounding_box = bb; }
// Implementations can override the following virtual methods:
// Use bridge flow for the fill?
virtual bool use_bridge_flow() const { return false; }
@ -77,10 +71,8 @@ public:
virtual bool no_sort() const { return false; }
// Perform the fill.
virtual Polylines fill_surface(const Surface &surface, const FillParams &params);
static coord_t adjust_solid_spacing(const coord_t width, const coord_t distance);
virtual Polylines fill_surface(const Surface &surface);
protected:
Fill() :
layer_id(size_t(-1)),
@ -88,17 +80,21 @@ protected:
spacing(0.f),
angle(0),
link_max_length(0),
loop_clipping(0)
loop_clipping(0),
density(0),
dont_connect(false),
dont_adjust(false),
complete(false)
{};
// The expolygon may be modified by the method to avoid a copy.
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
Polylines* polylines_out) {};
// Implementations can override the following virtual method:
virtual float _layer_angle(size_t idx) const {
return (idx % 2) == 0 ? (M_PI/2.) : 0;
}

View File

@ -149,7 +149,6 @@ makeGrid(coord_t z, coord_t gridSize, size_t gridWidth, size_t gridHeight, size_
void
Fill3DHoneycomb::_fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
@ -157,7 +156,7 @@ Fill3DHoneycomb::_fill_surface_single(
{
// no rotation is supported for this infill pattern
BoundingBox bb = expolygon.contour.bounding_box();
const coord_t distance = coord_t(scale_(this->spacing) / params.density);
const coord_t distance = coord_t(scale_(this->spacing) / this->density);
// align bounding box to a multiple of our honeycomb grid module
// (a module is 2*$distance since one $distance half-module is
@ -181,7 +180,7 @@ Fill3DHoneycomb::_fill_surface_single(
polylines = intersection_pl(polylines, (Polygons)expolygon);
// connect lines
if (!params.dont_connect && !polylines.empty()) { // prevent calling leftmost_point() on empty collections
if (!this->dont_connect && !polylines.empty()) { // prevent calling leftmost_point() on empty collections
ExPolygon expolygon_off;
{
ExPolygons expolygons_off = offset_ex(expolygon, SCALED_EPSILON);

View File

@ -19,7 +19,6 @@ public:
protected:
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,

View File

@ -8,7 +8,6 @@ namespace Slic3r {
void
FillConcentric::_fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
@ -17,9 +16,9 @@ FillConcentric::_fill_surface_single(
// no rotation is supported for this infill pattern
const coord_t min_spacing = scale_(this->spacing);
coord_t distance = coord_t(min_spacing / params.density);
coord_t distance = coord_t(min_spacing / this->density);
if (params.density > 0.9999f && !params.dont_adjust) {
if (this->density > 0.9999f && !this->dont_adjust) {
BoundingBox bounding_box = expolygon.contour.bounding_box();
distance = this->adjust_solid_spacing(bounding_box.size().x, distance);
this->spacing = unscale(distance);

View File

@ -12,7 +12,6 @@ public:
protected:
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,

View File

@ -8,20 +8,19 @@ namespace Slic3r {
void
FillHoneycomb::_fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
Polylines* polylines_out)
{
// cache hexagons math
CacheID cache_id = std::make_pair(params.density, this->spacing);
CacheID cache_id = std::make_pair(this->density, this->spacing);
Cache::iterator it_m = this->cache.find(cache_id);
if (it_m == this->cache.end()) {
it_m = this->cache.insert(it_m, std::pair<CacheID,CacheData>(cache_id, CacheData()));
CacheData &m = it_m->second;
coord_t min_spacing = scale_(this->spacing);
m.distance = min_spacing / params.density;
m.distance = min_spacing / this->density;
m.hex_side = m.distance / (sqrt(3)/2);
m.hex_width = m.distance * 2; // $m->{hex_width} == $m->{hex_side} * sqrt(3);
coord_t hex_height = m.hex_side * 2;
@ -73,7 +72,7 @@ FillHoneycomb::_fill_surface_single(
}
}
if (true || params.complete) {
if (true || this->complete) {
// we were requested to complete each loop;
// in this case we don't try to make more continuous paths
Polygons polygons_trimmed = intersection((Polygons)expolygon, polygons);

View File

@ -16,7 +16,6 @@ public:
protected:
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,

View File

@ -7,7 +7,6 @@
namespace Slic3r {
void FillPlanePath::_fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
@ -15,11 +14,13 @@ void FillPlanePath::_fill_surface_single(
{
expolygon.rotate(-direction.first);
const coord_t distance_between_lines = scale_(this->spacing) / params.density;
const coord_t distance_between_lines = scale_(this->spacing) / this->density;
// align infill across layers using the object's bounding box
// Rotated bounding box of the whole object.
BoundingBox bounding_box = this->bounding_box.rotated(-direction.first);
// align infill across layers using the object's bounding box (if available)
BoundingBox bounding_box = this->bounding_box.defined
? this->bounding_box
: expolygon.contour.bounding_box();
bounding_box = bounding_box.rotated(-direction.first);
const Point shift = this->_centered()
? bounding_box.center()

View File

@ -20,7 +20,6 @@ public:
protected:
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,

View File

@ -8,25 +8,26 @@
namespace Slic3r {
void FillRectilinear::_fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
Polylines* polylines_out)
{
assert(params.density > 0.0001f && params.density <= 1.f);
assert(this->density > 0.0001f && this->density <= 1.f);
// rotate polygons so that we can work with vertical lines here
expolygon.rotate(-direction.first);
this->_min_spacing = scale_(this->spacing);
this->_line_spacing = coord_t(coordf_t(this->_min_spacing) / params.density);
this->_line_spacing = coord_t(coordf_t(this->_min_spacing) / this->density);
this->_diagonal_distance = this->_line_spacing * 2;
this->_line_oscillation = this->_line_spacing - this->_min_spacing; // only for Line infill
// We ignore this->bounding_box because it doesn't matter; we're doing align_to_grid below.
BoundingBox bounding_box = expolygon.contour.bounding_box();
// define flow spacing according to requested density
if (params.density > 0.9999f && !params.dont_adjust) {
if (this->density > 0.9999f && !this->dont_adjust) {
this->_line_spacing = this->adjust_solid_spacing(bounding_box.size().x, this->_line_spacing);
this->spacing = unscale(this->_line_spacing);
} else {
@ -79,7 +80,7 @@ void FillRectilinear::_fill_surface_single(
size_t n_polylines_out_old = polylines_out->size();
// connect lines
if (!params.dont_connect && !polylines.empty()) { // prevent calling leftmost_point() on empty collections
if (!this->dont_connect && !polylines.empty()) { // prevent calling leftmost_point() on empty collections
// offset the expolygon by max(min_spacing/2, extra)
ExPolygon expolygon_off;
{

View File

@ -14,7 +14,6 @@ public:
protected:
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,

View File

@ -835,7 +835,7 @@ enum DirectionMask
DIR_BACKWARD = 2
};
bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillParams &params, float angleBase, float pattern_shift, Polylines &polylines_out)
bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, float angleBase, float pattern_shift, Polylines &polylines_out)
{
// At the end, only the new polylines will be rotated back.
size_t n_polylines_out_initial = polylines_out.size();
@ -849,8 +849,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
std::pair<float, Point> rotate_vector = this->_infill_direction(*surface);
rotate_vector.first += angleBase;
myassert(params.density > 0.0001f && params.density <= 1.f);
coord_t line_spacing = coord_t(scale_(this->spacing) / params.density);
myassert(this->density > 0.0001f && this->density <= 1.f);
coord_t line_spacing = coord_t(scale_(this->spacing) / this->density);
// On the polygons of poly_with_offset, the infill lines will be connected.
ExPolygonWithOffset poly_with_offset(
@ -867,8 +867,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
BoundingBox bounding_box(poly_with_offset.polygons_src);
// define flow spacing according to requested density
bool full_infill = params.density > 0.9999f;
if (full_infill && !params.dont_adjust) {
bool full_infill = this->density > 0.9999f;
if (full_infill && !this->dont_adjust) {
line_spacing = this->adjust_solid_spacing(bounding_box.size().x, line_spacing);
this->spacing = unscale(line_spacing);
} else {
@ -1391,7 +1391,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
(distNext < distPrev) :
intrsctn_type_next == INTERSECTION_TYPE_OTHER_VLINE_OK;
myassert(intrsctn->is_inner());
bool skip = params.dont_connect || (link_max_length > 0 && (take_next ? distNext : distPrev) > link_max_length);
bool skip = this->dont_connect || (link_max_length > 0 && (take_next ? distNext : distPrev) > link_max_length);
if (skip) {
// Just skip the connecting contour and start a new path.
goto dont_connect;
@ -1453,7 +1453,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
distance_of_segmens(poly, intrsctn->iSegment, iSegNext, false)) :
(vert_seg_dir_valid_mask == DIR_FORWARD);
// Skip this perimeter line?
bool skip = params.dont_connect;
bool skip = this->dont_connect;
if (! skip && link_max_length > 0) {
coordf_t link_length = measure_perimeter_segment_on_vertical_line_length(
poly_with_offset, segs, i_vline, intrsctn->iContour, i_intersection, iNext, dir_forward);
@ -1555,66 +1555,66 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
return true;
}
Polylines FillRectilinear2::fill_surface(const Surface &surface, const FillParams &params)
Polylines FillRectilinear2::fill_surface(const Surface &surface)
{
Polylines polylines_out;
if (! fill_surface_by_lines(&surface, params, 0.f, 0.f, polylines_out)) {
if (! fill_surface_by_lines(&surface, 0.f, 0.f, polylines_out)) {
printf("FillRectilinear2::fill_surface() failed to fill a region.\n");
}
return polylines_out;
}
Polylines FillGrid2::fill_surface(const Surface &surface, const FillParams &params)
Polylines FillGrid2::fill_surface(const Surface &surface)
{
// Each linear fill covers half of the target coverage.
FillParams params2 = params;
params2.density *= 0.5f;
FillGrid2 fill2 = *this;
fill2.density *= 0.5f;
Polylines polylines_out;
if (! fill_surface_by_lines(&surface, params2, 0.f, 0.f, polylines_out) ||
! fill_surface_by_lines(&surface, params2, float(M_PI / 2.), 0.f, polylines_out)) {
if (! fill2.fill_surface_by_lines(&surface, 0.f, 0.f, polylines_out) ||
! fill2.fill_surface_by_lines(&surface, float(M_PI / 2.), 0.f, polylines_out)) {
printf("FillGrid2::fill_surface() failed to fill a region.\n");
}
return polylines_out;
}
Polylines FillTriangles::fill_surface(const Surface &surface, const FillParams &params)
Polylines FillTriangles::fill_surface(const Surface &surface)
{
// Each linear fill covers 1/3 of the target coverage.
FillParams params2 = params;
params2.density *= 0.333333333f;
FillTriangles fill2 = *this;
fill2.density *= 0.333333333f;
Polylines polylines_out;
if (! fill_surface_by_lines(&surface, params2, 0.f, 0., polylines_out) ||
! fill_surface_by_lines(&surface, params2, float(M_PI / 3.), 0., polylines_out) ||
! fill_surface_by_lines(&surface, params2, float(2. * M_PI / 3.), 0.5 * this->spacing / params2.density, polylines_out)) {
if (! fill2.fill_surface_by_lines(&surface, 0.f, 0., polylines_out) ||
! fill2.fill_surface_by_lines(&surface, float(M_PI / 3.), 0., polylines_out) ||
! fill2.fill_surface_by_lines(&surface, float(2. * M_PI / 3.), 0.5 * this->spacing / fill2.density, polylines_out)) {
printf("FillTriangles::fill_surface() failed to fill a region.\n");
}
return polylines_out;
}
Polylines FillStars::fill_surface(const Surface &surface, const FillParams &params)
Polylines FillStars::fill_surface(const Surface &surface)
{
// Each linear fill covers 1/3 of the target coverage.
FillParams params2 = params;
params2.density *= 0.333333333f;
FillStars fill2 = *this;
fill2.density *= 0.333333333f;
Polylines polylines_out;
if (! fill_surface_by_lines(&surface, params2, 0.f, 0., polylines_out) ||
! fill_surface_by_lines(&surface, params2, float(M_PI / 3.), 0., polylines_out) ||
! fill_surface_by_lines(&surface, params2, float(2. * M_PI / 3.), 0., polylines_out)) {
if (! fill2.fill_surface_by_lines(&surface, 0.f, 0., polylines_out) ||
! fill2.fill_surface_by_lines(&surface, float(M_PI / 3.), 0., polylines_out) ||
! fill2.fill_surface_by_lines(&surface, float(2. * M_PI / 3.), 0., polylines_out)) {
printf("FillStars::fill_surface() failed to fill a region.\n");
}
return polylines_out;
}
Polylines FillCubic::fill_surface(const Surface &surface, const FillParams &params)
Polylines FillCubic::fill_surface(const Surface &surface)
{
// Each linear fill covers 1/3 of the target coverage.
FillParams params2 = params;
params2.density *= 0.333333333f;
FillCubic fill2 = *this;
fill2.density *= 0.333333333f;
Polylines polylines_out;
if (! fill_surface_by_lines(&surface, params2, 0.f, z, polylines_out) ||
! fill_surface_by_lines(&surface, params2, float(M_PI / 3.), -z, polylines_out) ||
if (! fill2.fill_surface_by_lines(&surface, 0.f, z, polylines_out) ||
! fill2.fill_surface_by_lines(&surface, float(M_PI / 3.), -z, polylines_out) ||
// Rotated by PI*2/3 + PI to achieve reverse sloping wall.
! fill_surface_by_lines(&surface, params2, float(M_PI * 2. / 3.), z, polylines_out)) {
! fill2.fill_surface_by_lines(&surface, float(M_PI * 2. / 3.), z, polylines_out)) {
printf("FillCubic::fill_surface() failed to fill a region.\n");
}
return polylines_out;

View File

@ -13,17 +13,17 @@ class FillRectilinear2 : public Fill
{
public:
virtual ~FillRectilinear2() {}
virtual Polylines fill_surface(const Surface &surface, const FillParams &params);
virtual Polylines fill_surface(const Surface &surface);
protected:
bool fill_surface_by_lines(const Surface *surface, const FillParams &params, float angleBase, float pattern_shift, Polylines &polylines_out);
bool fill_surface_by_lines(const Surface *surface, float angleBase, float pattern_shift, Polylines &polylines_out);
};
class FillGrid2 : public FillRectilinear2
{
public:
virtual ~FillGrid2() {}
virtual Polylines fill_surface(const Surface &surface, const FillParams &params);
virtual Polylines fill_surface(const Surface &surface);
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
@ -34,7 +34,7 @@ class FillTriangles : public FillRectilinear2
{
public:
virtual ~FillTriangles() {}
virtual Polylines fill_surface(const Surface &surface, const FillParams &params);
virtual Polylines fill_surface(const Surface &surface);
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
@ -45,7 +45,7 @@ class FillStars : public FillRectilinear2
{
public:
virtual ~FillStars() {}
virtual Polylines fill_surface(const Surface &surface, const FillParams &params);
virtual Polylines fill_surface(const Surface &surface);
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
@ -56,7 +56,7 @@ class FillCubic : public FillRectilinear2
{
public:
virtual ~FillCubic() {}
virtual Polylines fill_surface(const Surface &surface, const FillParams &params);
virtual Polylines fill_surface(const Surface &surface);
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.

View File

@ -182,7 +182,7 @@ LayerRegion::make_fill()
#else
std::auto_ptr<Fill> f = std::auto_ptr<Fill>(Fill::new_from_type(fill_pattern));
#endif
f->set_bounding_box(this->layer()->object()->bounding_box());
f->bounding_box = this->layer()->object()->bounding_box();
// calculate the actual flow we'll be using for this infill
coordf_t h = (surface.thickness == -1) ? this->layer()->height : surface.thickness;
@ -229,10 +229,9 @@ LayerRegion::make_fill()
f->loop_clipping = scale_(flow.nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER;
// apply half spacing using this flow's own spacing and generate infill
FillParams params;
params.density = density/100;
params.dont_adjust = false;
Polylines polylines = f->fill_surface(surface, params);
f->density = density/100;
f->dont_adjust = false;
Polylines polylines = f->fill_surface(surface);
if (polylines.empty())
continue;

View File

@ -62,9 +62,8 @@ SLAPrint::slice()
fill->bounding_box.merge(Point::new_scale(bb.max.x, bb.max.y));
fill->spacing = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value);
fill->angle = Geometry::deg2rad(this->config.fill_angle.value);
FillParams fill_params;
fill_params.density = this->config.fill_density.value/100;
fill->density = this->config.fill_density.value/100;
ExtrusionPath templ(erInternalInfill);
templ.width = fill->spacing;
@ -103,7 +102,7 @@ SLAPrint::slice()
const ExPolygons internal_ex = intersection_ex(infill, internal);
for (ExPolygons::const_iterator it = internal_ex.begin(); it != internal_ex.end(); ++it) {
Polylines polylines = fill->fill_surface(Surface(stInternal, *it), fill_params);
Polylines polylines = fill->fill_surface(Surface(stInternal, *it));
layer.infill.append(polylines, templ);
}
}

View File

@ -163,8 +163,7 @@ class Filler
fill = NULL;
}
};
Fill *fill;
FillParams params;
Fill* fill;
};
}

View File

@ -12,7 +12,7 @@
~Filler();
void set_bounding_box(BoundingBox *bbox)
%code{% THIS->fill->set_bounding_box(*bbox); %};
%code{% THIS->fill->bounding_box = *bbox; %};
void set_spacing(coordf_t spacing)
%code{% THIS->fill->spacing = spacing; %};
coordf_t spacing()
@ -34,20 +34,20 @@
%code{% RETVAL = THIS->fill->no_sort(); %};
void set_density(float density)
%code{% THIS->params.density = density; %};
%code{% THIS->fill->density = density; %};
void set_dont_connect(bool dont_connect)
%code{% THIS->params.dont_connect = dont_connect; %};
%code{% THIS->fill->dont_connect = dont_connect; %};
void set_dont_adjust(bool dont_adjust)
%code{% THIS->params.dont_adjust = dont_adjust; %};
%code{% THIS->fill->dont_adjust = dont_adjust; %};
void set_complete(bool complete)
%code{% THIS->params.complete = complete; %};
%code{% THIS->fill->complete = complete; %};
PolylineCollection* _fill_surface(Surface *surface)
%code{%
PolylineCollection *pc = NULL;
if (THIS->fill != NULL) {
pc = new PolylineCollection();
pc->polylines = THIS->fill->fill_surface(*surface, THIS->params);
pc->polylines = THIS->fill->fill_surface(*surface);
}
RETVAL = pc;
%};