diff options
-rw-r--r-- | xs/src/libslic3r/Fill/FillSmooth.cpp | 415 | ||||
-rw-r--r-- | xs/src/libslic3r/GCode.cpp | 20 | ||||
-rw-r--r-- | xs/src/libslic3r/GCode.hpp | 2 | ||||
-rw-r--r-- | xs/src/libslic3r/GCode/ToolOrdering.cpp | 12 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintConfig.cpp | 1 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintConfig.hpp | 4 |
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 ¶ms) - { - //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 ¶ms, 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 ¶ms) + { + //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 ¶ms, 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 ®ion : by_region) { - m_config.apply(print.regions[®ion - &by_region.front()]->config); - ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false); - gcode += extrude_entity(chained, "infill"); + if (print.regions[®ion - &by_region.front()]->config.infill_first == is_infill_first) { + m_config.apply(print.regions[®ion - &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); |