ironing: bugfix & clean

- remove some debug logs
 - bugfix: 2D toolpath now can draw collection of paths.
 - bugfix: fillsmooth doesn't bug if the area is too small to draw anything.
This commit is contained in:
Merill 2018-04-10 12:48:12 +02:00
parent 0544793128
commit fe657e645d
8 changed files with 106 additions and 62 deletions

View File

@ -491,16 +491,20 @@ sub Render {
sub _draw {
my ($self, $object, $print_z, $path) = @_;
my @paths = ($path->isa('Slic3r::ExtrusionLoop') || $path->isa('Slic3r::ExtrusionMultiPath'))
? @$path
: ($path);
if ($path->isa('Slic3r::ExtrusionPath::Collection')) {
$self->_draw($object, $print_z, $_) for @{$path};
}else{
my @paths = ($path->isa('Slic3r::ExtrusionLoop') || $path->isa('Slic3r::ExtrusionMultiPath'))
? @$path
: ($path);
$self->_draw_path($object, $print_z, $_) for @paths;
$self->_draw_path($object, $print_z, $_) for @paths;
}
}
sub _draw_path {
my ($self, $object, $print_z, $path) = @_;
return if $print_z - $path->height > $self->z - epsilon;
if (abs($print_z - $self->z) < epsilon) {

View File

@ -35,8 +35,10 @@ Fill* Fill::new_from_type(const InfillPattern type)
// case ipGrid: return new FillGrid();
case ipArchimedeanChords: return new FillArchimedeanChords();
case ipHilbertCurve: return new FillHilbertCurve();
case ipOctagramSpiral: return new FillOctagramSpiral();
case ipOctagramSpiral: return new FillOctagramSpiral();
case ipSmooth: return new FillSmooth();
case ipSmoothTriple: return new FillSmoothTriple();
case ipSmoothHilbert: return new FillSmoothHilbert();
default: CONFESS("unknown type"); return nullptr;
}
}

View File

@ -23,7 +23,7 @@ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams
{
coordf_t init_spacing = this->spacing;
printf("FillSmooth::fill_surface() : you call the right method (fill_surface instead of fill_surface_extrusion).\n");
//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;
@ -31,9 +31,6 @@ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams
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);
@ -43,15 +40,6 @@ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams
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;
@ -85,6 +73,8 @@ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams
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;
}
//second infill
@ -102,21 +92,24 @@ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams
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()){
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();
}
// 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;
}
}
@ -134,12 +127,14 @@ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams
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()){
//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();
}
// Save into layer smoothing path. layer 3
eec = new ExtrusionEntityCollection();
eecroot->entities.push_back(eec);

View File

@ -53,6 +53,66 @@ protected:
InfillPattern fillPattern[3];
};
class FillSmoothTriple : public FillSmooth
{
public:
FillSmoothTriple() {
nbPass = 3;
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] = 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];
double extrusionMult = 1.0;
percentFlow[0] *= extrusionMult;
percentFlow[1] *= extrusionMult;
percentFlow[2] *= extrusionMult;
}
virtual Fill* clone() const { return new FillSmoothTriple(*this); }
};
class FillSmoothHilbert : public FillSmooth
{
public:
FillSmoothHilbert() {
nbPass = 3;
anglePass[0] = 0;
anglePass[1] = -float(M_PI / 4);
anglePass[2] = float(M_PI / 4);
fillPattern[0] = InfillPattern::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];
double extrusionMult = 1.0;
percentFlow[0] *= extrusionMult;
percentFlow[1] *= extrusionMult;
percentFlow[2] *= extrusionMult;
}
virtual Fill* clone() const { return new FillSmoothHilbert(*this); }
};
} // namespace Slic3r
#endif // slic3r_FillSmooth_hpp_

View File

@ -2018,18 +2018,9 @@ std::string GCode::extrude_infill(const Print &print, const ExtrusionEntityColle
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";
}
} else {
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;

View File

@ -263,14 +263,18 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("concentric");
def->enum_values.push_back("hilbertcurve");
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
def->enum_values.push_back("smooth");
def->enum_values.push_back("octagramspiral");
def->enum_values.push_back("smooth");
def->enum_values.push_back("smoothtriple");
def->enum_values.push_back("smoothhilbert");
def->enum_labels.push_back("Rectilinear");
def->enum_labels.push_back("Concentric");
def->enum_labels.push_back("Hilbert Curve");
def->enum_labels.push_back("Archimedean Chords");
def->enum_labels.push_back("Octagram Spiral");
def->enum_labels.push_back("Ironing");
def->enum_labels.push_back("Ironing");
def->enum_labels.push_back("Ironing (triple)");
def->enum_labels.push_back("Ironing (hilbert)");
// solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern.
def->aliases.push_back("solid_fill_pattern");
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);

View File

@ -29,7 +29,7 @@ enum GCodeFlavor {
enum InfillPattern {
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth,
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth, ipSmoothHilbert, ipSmoothTriple,
};
enum SupportMaterialPattern {
@ -77,7 +77,9 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
keys_map["hilbertcurve"] = ipHilbertCurve;
keys_map["archimedeanchords"] = ipArchimedeanChords;
keys_map["octagramspiral"] = ipOctagramSpiral;
keys_map["smooth"] = ipSmooth;
keys_map["smooth"] = ipSmooth;
keys_map["smoothtriple"] = ipSmoothTriple;
keys_map["smoothhilbert"] = ipSmoothHilbert;
}
return keys_map;
}

View File

@ -363,11 +363,8 @@ void PrintObject::_prepare_infill()
// the following step needs to be done before combination because it may need
// to remove only half of the combined infill
this->bridge_over_infill();
std::cout<<"INTERNAL BRIDGE ===========================================\n";
this->replaceSurfaceType( stInternalSolid, stInternalOverBridge, stInternalBridge);
std::cout<<"BOTTOM BRIDGE ===========================================\n";
this->replaceSurfaceType( stInternalSolid, stInternalOverBridge, stBottomBridge);
std::cout<<"TOP BRIDGE ===========================================\n";
this->replaceSurfaceType( stTop, stTopOverBridge, stInternalBridge);
this->replaceSurfaceType( stTop, stTopOverBridge, stBottomBridge);
@ -1185,10 +1182,6 @@ void PrintObject::replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_r
layerm->fill_surfaces.filter_by_type(st_under_it, &stIntBridge_init);
double intbridgeareainit=0;
for (ExPolygon &ex : union_ex(stIntBridge_init)) intbridgeareainit+=ex.area();
std::cout<<"init st_replacement="<<totoverareaInit<<", bottombridgearea="<<bottombridgearea
<<", st_to_replace="<<internsolidareainit<<", bottomeareainit="<<bottomeareainit
<<", st_under_it="<<intbridgeareainit<<"\n";
// check whether the lower area is deep enough for absorbing the extra flow
// (for obvious physical reasons but also for preventing the bridge extrudates
@ -1214,16 +1207,12 @@ void PrintObject::replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_r
for (ExPolygon &ex : union_ex(lower_internal_OK)) okarea+=ex.area();
for (ExPolygon &ex : union_ex(lower_internal_Bridge)) bridgearea+=ex.area();
for (ExPolygon &ex : union_ex(lower_internal_Over)) overarea+=ex.area();
std::cout<<"@layer "<<int(layer_it - this->layers.begin())
<<" region under has "<<lower_internal_OK.size()<<" st_replacement : "<<okarea
<<" , has "<<lower_internal_Bridge.size()<<" st_under_it: "<<bridgearea
<<" , has "<<lower_internal_Over.size()<<" st_to_replace: "<<overarea<<"\n";
(*lower_layerm_it)->fill_surfaces.filter_by_type(st_under_it, &lower_internal);
}
double sumarea=0;
for (ExPolygon &ex : union_ex(lower_internal)) sumarea+=ex.area();
std::cout<<"@layer "<<int(layer_it - this->layers.begin())<<" region under has "<<union_ex(lower_internal).size()<<" sum bridge : "<<sumarea<<"\n";
// intersect such lower internal surfaces with the candidate solid surfaces
to_overextrude_pp = intersection(to_overextrude_pp, lower_internal);
}
@ -1241,9 +1230,6 @@ void PrintObject::replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_r
// convert into ExPolygons
to_overextrude = union_ex(to_overextrude_pp);
double finalarea = 0;
for (ExPolygon &ex : to_overextrude) finalarea+=ex.area();
std::cout<<"find an overextruding area of "<<finalarea<<" on layer "<<int(layer_it - this->layers.begin())<<"\n";
}
#ifdef SLIC3R_DEBUG
@ -1268,8 +1254,8 @@ void PrintObject::replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_r
layerm->fill_surfaces.filter_by_type(stInternalOverBridge, &internal_over_tot);
double totoverarea=0;
for (ExPolygon &ex : union_ex(internal_over_tot)) totoverarea+=ex.area();
std::cout<<"final: st_to_replace="<<solidareafinal<<", st_replacement="<<overareafinal<<", totstInternalOverBridge="<<totoverarea<<"\n";
/*
/*
# exclude infill from the layers below if needed
# see discussion at https://github.com/alexrj/Slic3r/issues/240
# Update: do not exclude any infill. Sparse infill is able to absorb the excess material.
@ -1768,7 +1754,7 @@ void PrintObject::_infill()
### $_->fill_surfaces->clear for map @{$_->regions}, @{$object->layers};
*/
this->state.set_done(posInfill);
this->state.set_done(posInfill);
}
// Only active if config->infill_only_where_needed. This step trims the sparse infill,