mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 02:09:03 +08:00
Smooth infill (ironing)
- new fill option : smooth (aka ironing) - needed a more powerful function from fill.cpp (implemented in FillBase) - ensure the no_sort mean really no sort (changes in gcode.cpp and ExtrusionEntityCollection)
This commit is contained in:
parent
2749c63b10
commit
0544793128
@ -74,6 +74,8 @@ add_library(libslic3r STATIC
|
|||||||
${LIBDIR}/libslic3r/Fill/FillRectilinear2.hpp
|
${LIBDIR}/libslic3r/Fill/FillRectilinear2.hpp
|
||||||
${LIBDIR}/libslic3r/Fill/FillRectilinear3.cpp
|
${LIBDIR}/libslic3r/Fill/FillRectilinear3.cpp
|
||||||
${LIBDIR}/libslic3r/Fill/FillRectilinear3.hpp
|
${LIBDIR}/libslic3r/Fill/FillRectilinear3.hpp
|
||||||
|
${LIBDIR}/libslic3r/Fill/FillSmooth.cpp
|
||||||
|
${LIBDIR}/libslic3r/Fill/FillSmooth.hpp
|
||||||
${LIBDIR}/libslic3r/Flow.cpp
|
${LIBDIR}/libslic3r/Flow.cpp
|
||||||
${LIBDIR}/libslic3r/Flow.hpp
|
${LIBDIR}/libslic3r/Flow.hpp
|
||||||
${LIBDIR}/libslic3r/Format/3mf.cpp
|
${LIBDIR}/libslic3r/Format/3mf.cpp
|
||||||
|
@ -207,6 +207,45 @@ ExtrusionEntityCollection::flatten() const
|
|||||||
return coll;
|
return coll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns a vector of chained (new) pointers to all non-collection items contained in this one */
|
||||||
|
void
|
||||||
|
ExtrusionEntityCollection::flattenIfSortable(ExtrusionEntityCollection* retval) const
|
||||||
|
{
|
||||||
|
if (no_sort){
|
||||||
|
ExtrusionEntityCollection *unsortable = new ExtrusionEntityCollection(*this);
|
||||||
|
retval->append(*unsortable);
|
||||||
|
unsortable->entities.clear();
|
||||||
|
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||||
|
if ((*it)->is_collection()) {
|
||||||
|
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||||
|
collection->flattenIfSortable(unsortable);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsortable->append(**it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||||
|
if ((*it)->is_collection()) {
|
||||||
|
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||||
|
retval->append(collection->flattenIfSortable().entities);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
retval->append(**it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtrusionEntityCollection
|
||||||
|
ExtrusionEntityCollection::flattenIfSortable() const
|
||||||
|
{
|
||||||
|
ExtrusionEntityCollection coll;
|
||||||
|
this->flattenIfSortable(&coll);
|
||||||
|
return coll;
|
||||||
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
ExtrusionEntityCollection::min_mm3_per_mm() const
|
ExtrusionEntityCollection::min_mm3_per_mm() const
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,9 @@ public:
|
|||||||
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
||||||
size_t items_count() const;
|
size_t items_count() const;
|
||||||
void flatten(ExtrusionEntityCollection* retval) const;
|
void flatten(ExtrusionEntityCollection* retval) const;
|
||||||
ExtrusionEntityCollection flatten() const;
|
ExtrusionEntityCollection flatten() const;
|
||||||
|
void flattenIfSortable(ExtrusionEntityCollection* retval) const;
|
||||||
|
ExtrusionEntityCollection flattenIfSortable() const;
|
||||||
double min_mm3_per_mm() const;
|
double min_mm3_per_mm() const;
|
||||||
|
|
||||||
// Following methods shall never be called on an ExtrusionEntityCollection.
|
// Following methods shall never be called on an ExtrusionEntityCollection.
|
||||||
|
@ -228,9 +228,6 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
|
|||||||
params.density = 0.01 * density;
|
params.density = 0.01 * density;
|
||||||
// params.dont_adjust = true;
|
// params.dont_adjust = true;
|
||||||
params.dont_adjust = false;
|
params.dont_adjust = false;
|
||||||
Polylines polylines = f->fill_surface(&surface, params);
|
|
||||||
if (polylines.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// calculate actual flow from spacing (which might have been adjusted by the infill
|
// calculate actual flow from spacing (which might have been adjusted by the infill
|
||||||
// pattern generator)
|
// pattern generator)
|
||||||
@ -244,22 +241,10 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
|
|||||||
|
|
||||||
float flow_percent = 1;
|
float flow_percent = 1;
|
||||||
if(surface.is_overBridge()){
|
if(surface.is_overBridge()){
|
||||||
flow_percent = layerm.region()->config.over_bridge_flow_ratio;
|
params.flow_mult = layerm.region()->config.over_bridge_flow_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save into layer.
|
f->fill_surface_extrusion(&surface, params, flow, out);
|
||||||
auto *eec = new ExtrusionEntityCollection();
|
|
||||||
out.entities.push_back(eec);
|
|
||||||
// Only concentric fills are not sorted.
|
|
||||||
eec->no_sort = f->no_sort();
|
|
||||||
extrusion_entities_append_paths(
|
|
||||||
eec->entities, STDMOVE(polylines),
|
|
||||||
is_bridge ?
|
|
||||||
erBridgeInfill :
|
|
||||||
(surface.is_solid() ?
|
|
||||||
((surface.surface_type == stTop) ? erTopSolidInfill : erSolidInfill) :
|
|
||||||
erInternalInfill),
|
|
||||||
flow.mm3_per_mm()*flow_percent, flow.width*flow_percent, flow.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add thin fill regions
|
// add thin fill regions
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "../ClipperUtils.hpp"
|
#include "../ClipperUtils.hpp"
|
||||||
#include "../Surface.hpp"
|
#include "../Surface.hpp"
|
||||||
#include "../PrintConfig.hpp"
|
#include "../PrintConfig.hpp"
|
||||||
|
#include "../ExtrusionEntityCollection.hpp"
|
||||||
|
|
||||||
#include "FillBase.hpp"
|
#include "FillBase.hpp"
|
||||||
#include "FillConcentric.hpp"
|
#include "FillConcentric.hpp"
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include "FillRectilinear.hpp"
|
#include "FillRectilinear.hpp"
|
||||||
#include "FillRectilinear2.hpp"
|
#include "FillRectilinear2.hpp"
|
||||||
#include "FillRectilinear3.hpp"
|
#include "FillRectilinear3.hpp"
|
||||||
|
#include "FillSmooth.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -34,6 +36,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
|||||||
case ipArchimedeanChords: return new FillArchimedeanChords();
|
case ipArchimedeanChords: return new FillArchimedeanChords();
|
||||||
case ipHilbertCurve: return new FillHilbertCurve();
|
case ipHilbertCurve: return new FillHilbertCurve();
|
||||||
case ipOctagramSpiral: return new FillOctagramSpiral();
|
case ipOctagramSpiral: return new FillOctagramSpiral();
|
||||||
|
case ipSmooth: return new FillSmooth();
|
||||||
default: CONFESS("unknown type"); return nullptr;
|
default: CONFESS("unknown type"); return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,4 +133,25 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
|
|||||||
return std::pair<float, Point>(out_angle, out_shift);
|
return std::pair<float, Point>(out_angle, out_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out ){
|
||||||
|
Polylines polylines = this->fill_surface(surface, params);
|
||||||
|
if (polylines.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Save into layer.
|
||||||
|
auto *eec = new ExtrusionEntityCollection();
|
||||||
|
out.entities.push_back(eec);
|
||||||
|
// Only concentric fills are not sorted.
|
||||||
|
eec->no_sort = this->no_sort();
|
||||||
|
extrusion_entities_append_paths(
|
||||||
|
eec->entities, STDMOVE(polylines),
|
||||||
|
flow.bridge ?
|
||||||
|
erBridgeInfill :
|
||||||
|
(surface->is_solid() ?
|
||||||
|
((surface->is_top()) ? erTopSolidInfill : erSolidInfill) :
|
||||||
|
erInternalInfill),
|
||||||
|
flow.mm3_per_mm() * params.flow_mult, flow.width * params.flow_mult, flow.height);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "../libslic3r.h"
|
#include "../libslic3r.h"
|
||||||
#include "../BoundingBox.hpp"
|
#include "../BoundingBox.hpp"
|
||||||
#include "../PrintConfig.hpp"
|
#include "../PrintConfig.hpp"
|
||||||
|
#include "../Flow.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -20,12 +21,16 @@ struct FillParams
|
|||||||
memset(this, 0, sizeof(FillParams));
|
memset(this, 0, sizeof(FillParams));
|
||||||
// Adjustment does not work.
|
// Adjustment does not work.
|
||||||
dont_adjust = true;
|
dont_adjust = true;
|
||||||
|
flow_mult = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool full_infill() const { return density > 0.9999f; }
|
bool full_infill() const { return density > 0.9999f; }
|
||||||
|
|
||||||
// Fill density, fraction in <0, 1>
|
// Fill density, fraction in <0, 1>
|
||||||
float density;
|
float density;
|
||||||
|
|
||||||
|
// Fill extruding flow multiplier, fraction in <0, 1>. Used by FillSmooth
|
||||||
|
float flow_mult;
|
||||||
|
|
||||||
// Don't connect the fill lines around the inner perimeter.
|
// Don't connect the fill lines around the inner perimeter.
|
||||||
bool dont_connect;
|
bool dont_connect;
|
||||||
@ -75,6 +80,9 @@ public:
|
|||||||
// Do not sort the fill lines to optimize the print head path?
|
// Do not sort the fill lines to optimize the print head path?
|
||||||
virtual bool no_sort() const { return false; }
|
virtual bool no_sort() const { return false; }
|
||||||
|
|
||||||
|
// This method have to fill the ExtrusionEntityCollection. It call fill_surface by default
|
||||||
|
virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out );
|
||||||
|
|
||||||
// Perform the fill.
|
// Perform the fill.
|
||||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||||
|
|
||||||
|
160
xs/src/libslic3r/Fill/FillSmooth.cpp
Normal file
160
xs/src/libslic3r/Fill/FillSmooth.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#include "../ClipperUtils.hpp"
|
||||||
|
#include "../PolylineCollection.hpp"
|
||||||
|
#include "../ExtrusionEntityCollection.hpp"
|
||||||
|
#include "../Surface.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "FillSmooth.hpp"
|
||||||
|
|
||||||
|
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];
|
||||||
|
// Polylines polylines_layer1;
|
||||||
|
// Polylines polylines_layer2;
|
||||||
|
// Polylines polylines_layer3;
|
||||||
|
|
||||||
|
//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 (! fill_surface_by_lines(&surfaceNoOverlap/* */, params1, anglePass[0], 0.f, polylines_layer1) ||
|
||||||
|
// (nbPass>1 && !fill_surface_by_lines(surface, params2, anglePass[1], 0.f, polylines_layer2)) ||
|
||||||
|
// (nbPass>2 && !fill_surface_by_lines(surface, params3, anglePass[2], 0.f, polylines_layer3))) {
|
||||||
|
// printf("FillSmooth::fill_surface() failed to fill a region.\n");
|
||||||
|
//}
|
||||||
|
/*
|
||||||
|
std::cout<<"polylines_layer1 size ="<<polylines_layer1.size()<<" \n";
|
||||||
|
std::cout<<"polylines_layer2 size ="<<polylines_layer2.size()<<" \n";
|
||||||
|
std::cout<<"polylines_layer3 size ="<<polylines_layer3.size()<<" \n";*/
|
||||||
|
|
||||||
|
//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)
|
||||||
|
}
|
||||||
|
|
||||||
|
//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(&surfaceNoOverlap, params2);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
if (!polylines_layer2.empty()){
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
//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();
|
||||||
|
}
|
||||||
|
if (!polylines_layer3.empty()){
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
58
xs/src/libslic3r/Fill/FillSmooth.hpp
Normal file
58
xs/src/libslic3r/Fill/FillSmooth.hpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef slic3r_FillSmooth_hpp_
|
||||||
|
#define slic3r_FillSmooth_hpp_
|
||||||
|
|
||||||
|
#include "../libslic3r.h"
|
||||||
|
|
||||||
|
#include "FillBase.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class FillSmooth : public Fill
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FillSmooth() {
|
||||||
|
nbPass = 2;
|
||||||
|
anglePass[0] = float(M_PI/4);
|
||||||
|
anglePass[1] = -float(M_PI/4);
|
||||||
|
anglePass[2] = 0;
|
||||||
|
fillPattern[0] = InfillPattern::ipRectilinear;
|
||||||
|
fillPattern[1] = InfillPattern::ipRectilinear;
|
||||||
|
fillPattern[2] = InfillPattern::ipRectilinear;
|
||||||
|
rolePass[0] = erSolidInfill;
|
||||||
|
rolePass[1] = erTopSolidInfill;
|
||||||
|
rolePass[2] = erSolidInfill;
|
||||||
|
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)
|
||||||
|
double extrusionMult = 1.0;
|
||||||
|
percentFlow[0] *= extrusionMult;
|
||||||
|
percentFlow[1] *= extrusionMult;
|
||||||
|
percentFlow[2] *= extrusionMult;
|
||||||
|
}
|
||||||
|
virtual Fill* clone() const { return new FillSmooth(*this); }
|
||||||
|
|
||||||
|
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||||
|
virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int nbPass=2;
|
||||||
|
double percentWidth[3];
|
||||||
|
double percentFlow[3];
|
||||||
|
float anglePass[3];
|
||||||
|
ExtrusionRole rolePass[3];
|
||||||
|
InfillPattern fillPattern[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // slic3r_FillSmooth_hpp_
|
@ -1271,8 +1271,9 @@ void GCode::process_layer(
|
|||||||
point_inside_surface(i, fill->first_point())) {
|
point_inside_surface(i, fill->first_point())) {
|
||||||
if (islands[i].by_region.empty())
|
if (islands[i].by_region.empty())
|
||||||
islands[i].by_region.assign(print.regions.size(), ObjectByExtruder::Island::Region());
|
islands[i].by_region.assign(print.regions.size(), ObjectByExtruder::Island::Region());
|
||||||
islands[i].by_region[region_id].infills.append(fill->entities);
|
//don't do fill->entities because it will discard no_sort
|
||||||
break;
|
islands[i].by_region[region_id].infills.append(fill->flattenIfSortable().entities);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for regions
|
} // for regions
|
||||||
@ -2001,14 +2002,34 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
|
|||||||
for (const ObjectByExtruder::Island::Region ®ion : by_region) {
|
for (const ObjectByExtruder::Island::Region ®ion : by_region) {
|
||||||
m_config.apply(print.regions[®ion - &by_region.front()]->config);
|
m_config.apply(print.regions[®ion - &by_region.front()]->config);
|
||||||
ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
|
ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
|
||||||
for (ExtrusionEntity *fill : chained.entities) {
|
gcode += extrude_infill(print, chained);
|
||||||
auto *eec = dynamic_cast<ExtrusionEntityCollection*>(fill);
|
}
|
||||||
if (eec) {
|
return gcode;
|
||||||
ExtrusionEntityCollection chained2 = eec->chained_path_from(m_last_pos, false);
|
}
|
||||||
for (ExtrusionEntity *ee : chained2.entities)
|
|
||||||
gcode += this->extrude_entity(*ee, "infill");
|
//recursive algorithm to explore the collection tree
|
||||||
} else
|
std::string GCode::extrude_infill(const Print &print, const ExtrusionEntityCollection &collection)
|
||||||
gcode += this->extrude_entity(*fill, "infill");
|
{
|
||||||
|
std::string gcode;
|
||||||
|
|
||||||
|
ExtrusionEntityCollection chained;
|
||||||
|
if (collection.no_sort) chained = collection;
|
||||||
|
else chained = collection.chained_path_from(m_last_pos, false);
|
||||||
|
for (ExtrusionEntity *fill : chained.entities) {
|
||||||
|
auto *eec = dynamic_cast<ExtrusionEntityCollection*>(fill);
|
||||||
|
if (eec) {
|
||||||
|
std::cout << "recursive infill with role: " << fill->role() << " : " << (fill->role() == ExtrusionRole::erBridgeInfill) << "\n";
|
||||||
|
gcode += extrude_infill(print, *eec);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "extrude infill with role: " << fill->role() << " : " << (fill->role() == ExtrusionRole::erBridgeInfill) << "\n";
|
||||||
|
if (/*print.config.disable_fan_top_layers.value && */fill->role() == ExtrusionRole::erTopSolidInfill){ //TODO: add && params.get(disable_fan_top_layers)
|
||||||
|
// gcode += ";_DISABLE_FAN_START\n";
|
||||||
|
}
|
||||||
|
gcode += this->extrude_entity(*fill, "infill");
|
||||||
|
if (/*print.config.disable_fan_top_layers.value && */fill->role() == ExtrusionRole::erTopSolidInfill){ //TODO: add && params.get(disable_fan_top_layers)
|
||||||
|
// gcode += ";_DISABLE_FAN_END\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gcode;
|
return gcode;
|
||||||
|
@ -221,7 +221,8 @@ 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_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);
|
||||||
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
std::string extrude_infill(const Print &print, const ExtrusionEntityCollection &collection); // recursive extrude_infill
|
||||||
|
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
||||||
|
|
||||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
||||||
|
@ -264,11 +264,13 @@ PrintConfigDef::PrintConfigDef()
|
|||||||
def->enum_values.push_back("hilbertcurve");
|
def->enum_values.push_back("hilbertcurve");
|
||||||
def->enum_values.push_back("archimedeanchords");
|
def->enum_values.push_back("archimedeanchords");
|
||||||
def->enum_values.push_back("octagramspiral");
|
def->enum_values.push_back("octagramspiral");
|
||||||
|
def->enum_values.push_back("smooth");
|
||||||
def->enum_labels.push_back("Rectilinear");
|
def->enum_labels.push_back("Rectilinear");
|
||||||
def->enum_labels.push_back("Concentric");
|
def->enum_labels.push_back("Concentric");
|
||||||
def->enum_labels.push_back("Hilbert Curve");
|
def->enum_labels.push_back("Hilbert Curve");
|
||||||
def->enum_labels.push_back("Archimedean Chords");
|
def->enum_labels.push_back("Archimedean Chords");
|
||||||
def->enum_labels.push_back("Octagram Spiral");
|
def->enum_labels.push_back("Octagram Spiral");
|
||||||
|
def->enum_labels.push_back("Ironing");
|
||||||
// solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern.
|
// solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern.
|
||||||
def->aliases.push_back("solid_fill_pattern");
|
def->aliases.push_back("solid_fill_pattern");
|
||||||
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
|
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
|
||||||
|
@ -29,7 +29,7 @@ enum GCodeFlavor {
|
|||||||
|
|
||||||
enum InfillPattern {
|
enum InfillPattern {
|
||||||
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
|
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
|
||||||
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral,
|
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SupportMaterialPattern {
|
enum SupportMaterialPattern {
|
||||||
@ -77,6 +77,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
|
|||||||
keys_map["hilbertcurve"] = ipHilbertCurve;
|
keys_map["hilbertcurve"] = ipHilbertCurve;
|
||||||
keys_map["archimedeanchords"] = ipArchimedeanChords;
|
keys_map["archimedeanchords"] = ipArchimedeanChords;
|
||||||
keys_map["octagramspiral"] = ipOctagramSpiral;
|
keys_map["octagramspiral"] = ipOctagramSpiral;
|
||||||
|
keys_map["smooth"] = ipSmooth;
|
||||||
}
|
}
|
||||||
return keys_map;
|
return keys_map;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user