add compensation in 100% fill to push the exact amount of plastic needed, todo: add kill switch for that

bugfix smoothFill overlap removal
This commit is contained in:
supermerill 2018-06-26 17:05:37 +02:00
parent f26b0482f3
commit 11a940a1ae
6 changed files with 295 additions and 167 deletions

View File

@ -222,7 +222,20 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f->loop_clipping = scale_(flow.nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER;
// f->layer_height = h;
//give the overlap size, it's not the real value (it can depend of the external_perimeter_extrusion_width)
f->overlap = layerm.region()->config.infill_overlap.get_abs_value(flow.nozzle_diameter);
/*printf("infill_overlap : widdth=%d scaled=%d unscaled=%d, widdth=%d scaled=%d unscaled=%d, infill_overlap=%d, absvalue_scaled=%d, absvalue_UNscaled=%d.\n",
layerm.region()->config.perimeter_extrusion_width.getFloat(),
scale_(layerm.region()->config.perimeter_extrusion_width.getFloat()),
unscale(layerm.region()->config.perimeter_extrusion_width.getFloat()),
layerm.flow(frPerimeter).width,
scale_(layerm.flow(frPerimeter).width),
unscale(layerm.flow(frPerimeter).width),
layerm.region()->config.infill_overlap.getFloat(),
layerm.region()->config.infill_overlap.get_abs_value(layerm.region()->config.perimeter_extrusion_width),
f->overlap);*/
// apply half spacing using this flow's own spacing and generate infill
FillParams params;
params.density = 0.01 * density;

View File

@ -53,7 +53,7 @@ Fill* Fill::new_from_type(const std::string &type)
Polylines Fill::fill_surface(const Surface *surface, const FillParams &params)
{
// Perform offset.
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing)));
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(0 - 0.5 * this->spacing)));
// Create the infills for each of the regions.
Polylines polylines_out;
for (size_t i = 0; i < expp.size(); ++ i)
@ -139,12 +139,51 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
Polylines polylines = this->fill_surface(surface, params);
if (polylines.empty())
return;
// ensure it doesn't over or under-extrude
double multFlow = 1;
if (!params.dont_adjust && params.density == 1 && !flow.bridge){
// compute the path of the nozzle -> extruded volume
double lengthTot = 0;
int nbLines = 0;
for (auto pline = polylines.begin(); pline != polylines.end(); ++pline){
Lines lines = pline->lines();
for (auto line = lines.begin(); line != lines.end(); ++line){
lengthTot += unscale(line->length());
nbLines++;
}
}
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
// compute real volume
double poylineVolume = 0;
/// un-overlap the surface (it's done in perimeterGenerator, it just pass the surface polys a bit bigger to us,
/// so we have to shrink it, it's silly, it should be here we should decide how to use the overlap setting!)
ExPolygons noOffsetPolys = offset2_ex(surface->expolygon, -scale_(this->overlap), 0);
for (auto poly = noOffsetPolys.begin(); poly != noOffsetPolys.end(); ++poly){
poylineVolume += flow.height*unscale(unscale(poly->area()));
// add external "perimeter gap"
double perimeterRoundGap = unscale(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
// add holes "perimeter gaps"
double holesGaps = 0;
for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole){
holesGaps += unscale(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
}
/*printf("process want %f mm3 extruded for a volume of %f (%f + %f + %f) space : we mult by %f \n",
extrudedVolume,
(poylineVolume + perimeterRoundGap + holesGaps),
poylineVolume, perimeterRoundGap, holesGaps,
(poylineVolume + perimeterRoundGap + holesGaps) / extrudedVolume);*/
poylineVolume += perimeterRoundGap + holesGaps;
}
if (extrudedVolume != 0) multFlow = poylineVolume / extrudedVolume;
}
// Save into layer.
auto *eec = new ExtrusionEntityCollection();
out.entities.push_back(eec);
// Only concentric fills are not sorted.
/// pass the no_sort attribute to the extrusion path
eec->no_sort = this->no_sort();
/// add it into the collection
out.entities.push_back(eec);
/// push the path
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines),
flow.bridge ?
@ -152,7 +191,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
(surface->is_solid() ?
((surface->is_top()) ? erTopSolidInfill : erSolidInfill) :
erInternalInfill),
flow.mm3_per_mm() * params.flow_mult, flow.width * params.flow_mult, flow.height);
flow.mm3_per_mm() * params.flow_mult * multFlow, flow.width * params.flow_mult, flow.height);
}

View File

@ -29,7 +29,7 @@ struct FillParams
// Fill density, fraction in <0, 1>
float density;
// Fill extruding flow multiplier, fraction in <0, 1>. Used by FillSmooth
// Fill extruding flow multiplier, fraction in <0, 1>. Used by "over bridge compensation"
float flow_mult;
// Don't connect the fill lines around the inner perimeter.
@ -53,7 +53,7 @@ public:
coordf_t z;
// in unscaled coordinates
coordf_t spacing;
// infill / perimeter overlap, in unscaled coordinates
// infill / perimeter overlap, in unscaled coordinates
coordf_t overlap;
// in radians, ccw, 0 = East
float angle;

View File

@ -779,8 +779,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
ExPolygonWithOffset poly_with_offset(
surface->expolygon,
- rotate_vector.first,
scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
scale_(this->overlap - 0.5 * this->spacing));
scale_(0 - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
scale_(0 - 0.5 * this->spacing));
if (poly_with_offset.n_contours_inner == 0) {
// Not a single infill line fits.
//FIXME maybe one shall trigger the gap fill here?

View File

@ -10,146 +10,229 @@
namespace Slic3r {
Polylines FillSmooth::fill_surface(const Surface *surface, const FillParams &params)
{
//ERROR: you shouldn't call that. Default to the rectilinear one.
printf("FillSmooth::fill_surface() : you call the wrong method (fill_surface instead of fill_surface_extrusion).\n");
Polylines polylines_out;
return polylines_out;
}
void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams &params, const Flow &flow, ExtrusionEntityCollection &out )
{
coordf_t init_spacing = this->spacing;
//printf("FillSmooth::fill_surface() : you call the right method (fill_surface instead of fill_surface_extrusion).\n");
//second pass with half layer width
FillParams params1 = params;
FillParams params2 = params;
FillParams params3 = params;
params1.density *= percentWidth[0];
params2.density *= percentWidth[1];
params3.density *= percentWidth[2];
//a small under-overlap to prevent over-extrudion on thin surfaces (i.e. remove the overlap)
Surface surfaceNoOverlap(*surface);
//remove the overlap (prevent over-extruding)
ExPolygons offsetPloys = offset2_ex(surfaceNoOverlap.expolygon, -scale_(this->overlap)*0.9, 0);
if(offsetPloys.size() == 1) surfaceNoOverlap.expolygon = offsetPloys[0];
//TODO: recursive if multiple polys instead of failing
//if (polylines_layer1.empty() && polylines_layer2.empty() && polylines_layer3.empty())
// return;
//create root node
ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
//you don't want to sort the extrusions: big infill first, small second
eecroot->no_sort = true;
ExtrusionEntityCollection *eec;
// first infill
std::unique_ptr<Fill> f1 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
f1->bounding_box = this->bounding_box;
f1->spacing = init_spacing;
f1->layer_id = this->layer_id;
f1->z = this->z;
f1->angle = anglePass[0];
// Maximum length of the perimeter segment linking two infill lines.
f1->link_max_length = this->link_max_length;
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f1->loop_clipping = this->loop_clipping;
Polylines polylines_layer1 = f1->fill_surface(surface, params1);
if (!polylines_layer1.empty()){
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);
eec->no_sort = false; //can be sorted inside the pass
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines_layer1),
flow.bridge ? erBridgeInfill : rolePass[0],
flow.mm3_per_mm()*percentFlow[0], (float)flow.width*percentFlow[0], (float)flow.height*0.9);
//reduced flow width & height for a better view (it's only a gui thing)
}else{
return;
Polylines FillSmooth::fill_surface(const Surface *surface, const FillParams &params)
{
//ERROR: you shouldn't call that. Default to the rectilinear one.
printf("FillSmooth::fill_surface() : you call the wrong method (fill_surface instead of fill_surface_extrusion).\n");
Polylines polylines_out;
return polylines_out;
}
//second infill
if (nbPass > 1){
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[1]));
f2->bounding_box = this->bounding_box;
f2->spacing = init_spacing;
f2->layer_id = this->layer_id;
f2->z = this->z;
f2->angle = anglePass[1];
void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams &params, const Flow &flow, ExtrusionEntityCollection &out)
{
coordf_t init_spacing = this->spacing;
//printf("FillSmooth::fill_surface() : you call the right method (fill_surface instead of fill_surface_extrusion).\n");
//second pass with half layer width
FillParams params1 = params;
FillParams params2 = params;
FillParams params3 = params;
params1.density *= percentWidth[0];
params2.density *= percentWidth[1];
params3.density *= percentWidth[2];
//a small under-overlap to prevent over-extrudion on thin surfaces (i.e. remove the overlap)
Surface surfaceNoOverlap(*surface);
//remove the overlap (prevent over-extruding) if possible
ExPolygons noOffsetPolys = offset2_ex(surfaceNoOverlap.expolygon, -scale_(this->overlap) * 1, 0);
//printf("FillSmooth::fill_surface() : overlap=%f->%f.\n", overlap, -scale_(this->overlap));
//printf("FillSmooth::polys : 1->%i.\n", noOffsetPolys.size());
//printf("FillSmooth::polys : %f %f->%f.\n", surface->expolygon.area(), surfaceNoOverlap.expolygon.area(), noOffsetPolys[0].area());
//if (offsetPolys.size() == 1) surfaceNoOverlap.expolygon = offsetPolys[0];
//TODO: recursive if multiple polys instead of failing
//if (polylines_layer1.empty() && polylines_layer2.empty() && polylines_layer3.empty())
// return;
//create root node
ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
//you don't want to sort the extrusions: big infill first, small second
eecroot->no_sort = true;
ExtrusionEntityCollection *eec;
double volumeToOccupy = 0;
// first infill
std::unique_ptr<Fill> f1 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
f1->bounding_box = this->bounding_box;
f1->spacing = init_spacing;
f1->layer_id = this->layer_id;
f1->z = this->z;
f1->angle = anglePass[0];
// Maximum length of the perimeter segment linking two infill lines.
f2->link_max_length = this->link_max_length;
f1->link_max_length = this->link_max_length;
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f2->loop_clipping = this->loop_clipping;
Polylines polylines_layer2 = f2->fill_surface(&surfaceNoOverlap, params2);
f1->loop_clipping = this->loop_clipping;
for (auto poly = noOffsetPolys.begin(); poly != noOffsetPolys.end(); ++poly){
surfaceNoOverlap.expolygon = *poly;
Polylines polylines_layer1 = f1->fill_surface(&surfaceNoOverlap, params1);
if (!polylines_layer1.empty()){
if (!polylines_layer2.empty()){
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer2[0].points.size() > 3){
polylines_layer2[0].points.erase(polylines_layer2[0].points.begin());
polylines_layer2[polylines_layer2.size() - 1].points.pop_back();
double lengthTot = 0;
int nbLines = 0;
for (auto pline = polylines_layer1.begin(); pline != polylines_layer1.end(); ++pline){
Lines lines = pline->lines();
for (auto line = lines.begin(); line != lines.end(); ++line){
printf("line length = %f, scaled:%f, unscaled:%f \n", line->length(), scale_(line->length()), unscale(line->length()));
lengthTot += unscale(line->length());
nbLines++;
}
}
// add external "perimeter gap"
double poylineVolume = flow.height*unscale(unscale(poly->area()));
double perimeterRoundGap = unscale(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
// add holes "perimeter gaps"
double holesGaps = 0;
for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole){
holesGaps += unscale(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
}
poylineVolume += perimeterRoundGap + holesGaps;
//extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue)
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
volumeToOccupy += poylineVolume;
printf("FillSmooth: request extruding of %f length, with mm3_per_mm of %f =volume=> %f / %f (%f)\n",
lengthTot,
flow.mm3_per_mm(),
flow.mm3_per_mm() * lengthTot,
flow.height*unscale(unscale(surfaceNoOverlap.area())),
(flow.mm3_per_mm() * lengthTot) / (flow.height*unscale(unscale(surfaceNoOverlap.area())))
);
printf("FillSmooth: extruding flow mult %f vs old: %f\n", percentFlow[0] * poylineVolume / extrudedVolume, percentFlow[0] / percentWidth[0]);
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);
eec->no_sort = false; //can be sorted inside the pass
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines_layer1),
flow.bridge ? erBridgeInfill : rolePass[0],
//reduced flow height for a better view (it's only a gui thing)
params.flow_mult * flow.mm3_per_mm() * percentFlow[0] * poylineVolume / extrudedVolume, (float)flow.width*percentFlow[0] * poylineVolume / extrudedVolume, (float)flow.height*0.8);
}
// Save into layer smoothing path.
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);
eec->no_sort = false;
// print thin
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines_layer2),
rolePass[1],
flow.mm3_per_mm()*percentFlow[1], (float)flow.width*(percentFlow[1] < 0.1 ? 0.1 : percentFlow[1]), (float)flow.height);
}else{
return;
}
}
// third infill
if (nbPass > 2){
std::unique_ptr<Fill> f3 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
f3->bounding_box = this->bounding_box;
f3->spacing = init_spacing;
f3->layer_id = this->layer_id;
f3->z = this->z;
f3->angle = anglePass[2];
// Maximum length of the perimeter segment linking two infill lines.
f3->link_max_length = this->link_max_length;
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f3->loop_clipping = this->loop_clipping;
Polylines polylines_layer3 = f3->fill_surface(&surfaceNoOverlap, params1);
if (!polylines_layer3.empty()){
//remove some points that are not inside the area
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer3[0].points.size() > 3){
polylines_layer3[0].points.erase(polylines_layer3[0].points.begin());
polylines_layer3[polylines_layer3.size() - 1].points.pop_back();
else{
return;
}
// Save into layer smoothing path. layer 3
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);
eec->no_sort = false;
// print thin
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines_layer3),
rolePass[2], //slow (if last)
flow.mm3_per_mm()*percentFlow[2], (float)flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2]), (float)flow.height);
}
}
if (!eecroot->entities.empty())
out.entities.push_back(eecroot);
}
//second infill
if (nbPass > 1){
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[1]));
f2->bounding_box = this->bounding_box;
f2->spacing = init_spacing;
f2->layer_id = this->layer_id;
f2->z = this->z;
f2->angle = anglePass[1];
// Maximum length of the perimeter segment linking two infill lines.
f2->link_max_length = this->link_max_length;
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f2->loop_clipping = this->loop_clipping;
Polylines polylines_layer2 = f2->fill_surface(surface, params2);
if (!polylines_layer2.empty()){
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer2[0].points.size() > 3){
polylines_layer2[0].points.erase(polylines_layer2[0].points.begin());
polylines_layer2[polylines_layer2.size() - 1].points.pop_back();
}
//compute the path of the nozzle
double lengthTot = 0;
int nbLines = 0;
for (auto pline = polylines_layer2.begin(); pline != polylines_layer2.end(); ++pline){
Lines lines = pline->lines();
for (auto line = lines.begin(); line != lines.end(); ++line){
//printf("line length = %f, scaled:%f, unscaled:%f \n", line->length(), scale_(line->length()), unscale(line->length()));
lengthTot += unscale(line->length());
nbLines++;
}
}
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
if (extrudedVolume != 0){
printf("FillSmooth: extruding flow of 2nd layer increased by %f\n", volumeToOccupy / extrudedVolume);
printf("FillSmooth: extruding flow of 2nd layer mult %f vs old: %f\n", percentFlow[1] * volumeToOccupy / extrudedVolume, percentFlow[1] / percentWidth[1]);
}
else{
printf("FillSmooth: extruding flow of 2nd layer increased by INFINITE \n");
extrudedVolume = 1;
}
// Save into layer smoothing path.
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);
eec->no_sort = false;
// print thin
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines_layer2),
rolePass[1],
//reduced flow width for a better view (it's only a gui thing)
params.flow_mult * flow.mm3_per_mm() * percentFlow[1] * volumeToOccupy / extrudedVolume, (float)flow.width*(percentFlow[1] < 0.1 ? 0.1 : percentFlow[1]), (float)flow.height);
}
else{
return;
}
}
// third infill
if (nbPass > 2){
std::unique_ptr<Fill> f3 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
f3->bounding_box = this->bounding_box;
f3->spacing = init_spacing;
f3->layer_id = this->layer_id;
f3->z = this->z;
f3->angle = anglePass[2];
// Maximum length of the perimeter segment linking two infill lines.
f3->link_max_length = this->link_max_length;
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f3->loop_clipping = this->loop_clipping;
Polylines polylines_layer3 = f3->fill_surface(surface, params1);
if (!polylines_layer3.empty()){
//remove some points that are not inside the area
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer3[0].points.size() > 3){
polylines_layer3[0].points.erase(polylines_layer3[0].points.begin());
polylines_layer3[polylines_layer3.size() - 1].points.pop_back();
}
//compute the path of the nozzle
double lengthTot = 0;
int nbLines = 0;
for (auto pline = polylines_layer3.begin(); pline != polylines_layer3.end(); ++pline){
Lines lines = pline->lines();
for (auto line = lines.begin(); line != lines.end(); ++line){
printf("line length3");
//printf("line length = %f, scaled:%f, unscaled:%f \n", line->length(), scale_(line->length()), unscale(line->length()));
lengthTot += unscale(line->length());
nbLines++;
}
}
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
printf("FillSmooth: extruding flow of 3nd layer mult %f vs old: %f\n", percentFlow[2] * volumeToOccupy / extrudedVolume, percentFlow[2] / percentWidth[2]);
// Save into layer smoothing path. layer 3
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);
eec->no_sort = false;
// print thin
extrusion_entities_append_paths(
eec->entities, STDMOVE(polylines_layer3),
rolePass[2], //slow (if last)
//reduced flow width for a better view (it's only a gui thing)
params.flow_mult * flow.mm3_per_mm() * percentFlow[2] * volumeToOccupy / extrudedVolume, (float)flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2]), (float)flow.height);
}
}
if (!eecroot->entities.empty())
out.entities.push_back(eecroot);
}
} // namespace Slic3r

View File

@ -24,16 +24,9 @@ public:
percentWidth[0] = 0.9;
percentWidth[1] = 2;
percentWidth[2] = 1.0;
percentFlow[0] = 0.7/percentWidth[0]; //* 1.25 => 0.9
percentFlow[1] = 0.3/percentWidth[1]; //*1.25 => 0.35
percentFlow[2] = 0.0/percentWidth[2];
// percentWidth[0] = 2.0;
// percentWidth[1] = 0.6;
// percentWidth[2] = 1.0;
// percentFlow[0] = 0.65;
// percentFlow[1] = 0.0;
// percentFlow[2] = 0.0;
// (extrusion mult => 0.9 + 0.15*2 = 1.2)
percentFlow[0] = 0.7;
percentFlow[1] = 0.3;
percentFlow[2] = 0.0;
double extrusionMult = 1.0;
percentFlow[0] *= extrusionMult;
percentFlow[1] *= extrusionMult;
@ -61,19 +54,19 @@ public:
nbPass = 3;
anglePass[0] = float(M_PI / 4);
anglePass[1] = -float(M_PI / 4);
anglePass[2] = 0;
anglePass[2] = float(M_PI / 12); //align with nothing
fillPattern[0] = InfillPattern::ipRectilinear;
fillPattern[1] = InfillPattern::ipRectilinear;
fillPattern[1] = InfillPattern::ipConcentric;
fillPattern[2] = InfillPattern::ipRectilinear;
rolePass[0] = erSolidInfill;
rolePass[1] = erSolidInfill;
rolePass[2] = erTopSolidInfill;
percentWidth[0] = 0.9;
percentWidth[1] = 1.4;
percentWidth[2] = 2.5;
percentFlow[0] = 0.7 / percentWidth[0];
percentFlow[1] = 0.3 / percentWidth[1];
percentFlow[2] = 0.0 / percentWidth[2];
percentWidth[0] = 0.8;
percentWidth[1] = 1.5;
percentWidth[2] = 2.8;
percentFlow[0] = 0.7;
percentFlow[1] = 0.2;
percentFlow[2] = 0.1;
double extrusionMult = 1.0;
percentFlow[0] *= extrusionMult;
percentFlow[1] *= extrusionMult;
@ -87,22 +80,22 @@ class FillSmoothHilbert : public FillSmooth
{
public:
FillSmoothHilbert() {
nbPass = 3;
nbPass = 2;
anglePass[0] = 0;
anglePass[1] = -float(M_PI / 4);
anglePass[2] = float(M_PI / 4);
fillPattern[0] = InfillPattern::ipHilbertCurve;
fillPattern[0] = InfillPattern::ipHilbertCurve; //ipHilbertCurve
fillPattern[1] = InfillPattern::ipRectilinear;
fillPattern[2] = InfillPattern::ipRectilinear;
rolePass[0] = erSolidInfill;
rolePass[1] = erSolidInfill;
rolePass[2] = erTopSolidInfill;
percentWidth[0] = 1;
percentWidth[1] = 1;
percentWidth[2] = 2;
percentFlow[0] = 0.8 / percentWidth[0];
percentFlow[1] = 0.1 / percentWidth[1];
percentFlow[2] = 0.1 / percentWidth[2];
percentWidth[0] = 1.0;
percentWidth[1] = 1.0;
percentWidth[2] = 1.0;
percentFlow[0] = 0.8;
percentFlow[1] = 0.1;
percentFlow[2] = 0.1;
double extrusionMult = 1.0;
percentFlow[0] *= extrusionMult;
percentFlow[1] *= extrusionMult;