Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xs/src/libslic3r/Fill/FillSmooth.cpp415
-rw-r--r--xs/src/libslic3r/GCode.cpp20
-rw-r--r--xs/src/libslic3r/GCode.hpp2
-rw-r--r--xs/src/libslic3r/GCode/ToolOrdering.cpp12
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp1
-rw-r--r--xs/src/libslic3r/PrintConfig.hpp4
6 files changed, 215 insertions, 239 deletions
diff --git a/xs/src/libslic3r/Fill/FillSmooth.cpp b/xs/src/libslic3r/Fill/FillSmooth.cpp
index 345f0fa89..d7572d7a5 100644
--- a/xs/src/libslic3r/Fill/FillSmooth.cpp
+++ b/xs/src/libslic3r/Fill/FillSmooth.cpp
@@ -10,233 +10,210 @@
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) if possible
+ 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) if possible
ExPolygons noOffsetPolys = offset_ex(surfaceNoOverlap.expolygon, -scale_(this->overlap) * (flow.bridge?0:1));
- //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.
- 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;
- for (auto poly = noOffsetPolys.begin(); poly != noOffsetPolys.end(); ++poly){
- surfaceNoOverlap.expolygon = *poly;
- Polylines polylines_layer1 = f1->fill_surface(&surfaceNoOverlap, params1);
- if (!polylines_layer1.empty()){
-
- 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) %s\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()))),
- params.fill_exactly ? "ready" : "only for info"
- );
- 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)
+ //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.
+ 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;
+ for (auto poly = noOffsetPolys.begin(); poly != noOffsetPolys.end(); ++poly){
+ surfaceNoOverlap.expolygon = *poly;
+ Polylines polylines_layer1 = f1->fill_surface(&surfaceNoOverlap, params1);
+ if (!polylines_layer1.empty()){
+
+ 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){
+ 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;
+
+ 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] * (params.fill_exactly? poylineVolume / extrudedVolume : 1),
(float)(flow.width*percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1)), (float)flow.height*0.8);
- }
- else{
- return;
- }
- }
-
- //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)
+ }
+ else{
+ return;
+ }
+ }
+
+ //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){
+ lengthTot += unscale(line->length());
+ nbLines++;
+ }
+ }
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+ if (extrudedVolume == 0) 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] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 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(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)
+ }
+ 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){
+ lengthTot += unscale(line->length());
+ nbLines++;
+ }
+ }
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+
+ // 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] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
(float)(flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2])), (float)flow.height);
- }
- }
+ }
+ }
- if (!eecroot->entities.empty())
- out.entities.push_back(eecroot);
+ if (!eecroot->entities.empty())
+ out.entities.push_back(eecroot);
- }
+ }
} // namespace Slic3r
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index 81b09bbcd..fbf877215 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -1477,13 +1477,9 @@ void GCode::process_layer(
for (ObjectByExtruder::Island &island : object_by_extruder.islands) {
const auto& by_region_specific = const_cast<LayerTools&>(layer_tools).wiping_extrusions().is_anything_overridden() ? island.by_region_per_copy(copy_id, extruder_id, print_wipe_extrusions) : island.by_region;
- if (print.config.infill_first) {
- gcode += this->extrude_infill(print, by_region_specific);
- gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
- } else {
- gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
- gcode += this->extrude_infill(print,by_region_specific);
- }
+ gcode += this->extrude_infill(print, by_region_specific, true);
+ gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
+ gcode += this->extrude_infill(print, by_region_specific, false);
}
if (this->config().gcode_comments) {
gcode += ((std::ostringstream&)(std::ostringstream() << "; stop printing object " << print_object->model_object()->name << " id:" << layer_id << " copy " << copy_id << "\n")).str();
@@ -2133,13 +2129,15 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
}
// Chain the paths hierarchically by a greedy algorithm to minimize a travel distance.
-std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region)
+std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool is_infill_first)
{
std::string gcode;
for (const ObjectByExtruder::Island::Region &region : by_region) {
- m_config.apply(print.regions[&region - &by_region.front()]->config);
- ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
- gcode += extrude_entity(chained, "infill");
+ if (print.regions[&region - &by_region.front()]->config.infill_first == is_infill_first) {
+ m_config.apply(print.regions[&region - &by_region.front()]->config);
+ ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
+ gcode += extrude_entity(chained, "infill");
+ }
}
return gcode;
}
diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp
index d98371000..d1c3c8d56 100644
--- a/xs/src/libslic3r/GCode.hpp
+++ b/xs/src/libslic3r/GCode.hpp
@@ -238,7 +238,7 @@ protected:
std::string extrude_perimeters(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, std::unique_ptr<EdgeGrid::Grid> &lower_layer_edge_grid);
- std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region);
+ std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool is_infill_first);
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
diff --git a/xs/src/libslic3r/GCode/ToolOrdering.cpp b/xs/src/libslic3r/GCode/ToolOrdering.cpp
index 189a94d49..640bb6981 100644
--- a/xs/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/xs/src/libslic3r/GCode/ToolOrdering.cpp
@@ -486,7 +486,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
continue;
- if ((!print.config.infill_first ? perimeters_done : !perimeters_done) || (!object->config.wipe_into_objects && region.config.wipe_into_infill)) {
+ if ((!region.config.infill_first ? perimeters_done : !perimeters_done) || (!object->config.wipe_into_objects && region.config.wipe_into_infill)) {
for (const ExtrusionEntity* ee : this_layer->regions[region_id]->fills.entities) { // iterate through all infill Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
@@ -499,7 +499,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
if (volume_to_wipe<=0)
continue;
- if (!object->config.wipe_into_objects && !print.config.infill_first && region.config.wipe_into_infill)
+ if (!object->config.wipe_into_objects && !region.config.infill_first && region.config.wipe_into_infill)
// In this case we must check that the original extruder is used on this layer before the one we are overridding
// (and the perimeters will be finished before the infill is printed):
if (!lt.is_extruder_order(region.config.perimeter_extruder - 1, new_extruder))
@@ -513,7 +513,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
}
// Now the same for perimeters - see comments above for explanation:
- if (object->config.wipe_into_objects && (print.config.infill_first ? perimeters_done : !perimeters_done))
+ if (object->config.wipe_into_objects && (region.config.infill_first ? perimeters_done : !perimeters_done))
{
for (const ExtrusionEntity* ee : this_layer->regions[region_id]->perimeters.entities) {
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
@@ -574,12 +574,12 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
// printed before its perimeter, or not be printed at all (in case its original extruder has
// not been added to LayerTools
// Either way, we will now force-override it with something suitable:
- if (print.config.infill_first
+ if (region.config.infill_first
|| object->config.wipe_into_objects // in this case the perimeter is overridden, so we can override by the last one safely
|| lt.is_extruder_order(region.config.perimeter_extruder - 1, last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints
|| std::find(lt.extruders.begin(), lt.extruders.end(), region.config.infill_extruder - 1) == lt.extruders.end()) // we have to force override - this could violate infill_first (FIXME)
)
- set_extruder_override(fill, copy, (print.config.infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
+ set_extruder_override(fill, copy, (region.config.infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
else {
// In this case we can (and should) leave it to be printed normally.
// Force overriding would mean it gets printed before its perimeter.
@@ -593,7 +593,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
|| is_entity_overridden(fill, copy) )
continue;
- set_extruder_override(fill, copy, (print.config.infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);
+ set_extruder_override(fill, copy, (region.config.infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);
}
}
}
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index df69fbe38..bb587a74a 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -1011,6 +1011,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("infill_first", coBool);
def->label = L("Infill before perimeters");
+ def->category = L("Infill");
def->tooltip = L("This option will switch the print order of perimeters and infill, making the latter first.");
def->cli = "infill-first!";
def->default_value = new ConfigOptionBool(false);
diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp
index 8d9357664..4c8c21e97 100644
--- a/xs/src/libslic3r/PrintConfig.hpp
+++ b/xs/src/libslic3r/PrintConfig.hpp
@@ -414,6 +414,7 @@ public:
ConfigOptionFloat infill_dense_angle;
ConfigOptionPercent infill_dense_density;
ConfigOptionEnum<InfillPattern> infill_dense_pattern;
+ ConfigOptionBool infill_first;
ConfigOptionBool overhangs;
ConfigOptionBool no_perimeter_unsupported;
ConfigOptionInt min_perimeter_unsupported;
@@ -466,6 +467,7 @@ protected:
OPT_PTR(infill_dense_angle);
OPT_PTR(infill_dense_density);
OPT_PTR(infill_dense_pattern);
+ OPT_PTR(infill_first);
OPT_PTR(overhangs);
OPT_PTR(no_perimeter_unsupported);
OPT_PTR(min_perimeter_unsupported);
@@ -692,7 +694,6 @@ public:
ConfigOptionFloatOrPercent first_layer_speed;
ConfigOptionInts first_layer_temperature;
ConfigOptionFloat infill_acceleration;
- ConfigOptionBool infill_first;
ConfigOptionInts max_fan_speed;
ConfigOptionFloats max_layer_height;
ConfigOptionInts min_fan_speed;
@@ -764,7 +765,6 @@ protected:
OPT_PTR(first_layer_speed);
OPT_PTR(first_layer_temperature);
OPT_PTR(infill_acceleration);
- OPT_PTR(infill_first);
OPT_PTR(max_fan_speed);
OPT_PTR(max_layer_height);
OPT_PTR(min_fan_speed);