Modify dense_infill to an automatic parameter

This commit is contained in:
supermerill 2018-08-03 19:54:19 +02:00 committed by supermerill
parent 05414e0e56
commit 5dd709bf1e
11 changed files with 210 additions and 167 deletions

View File

@ -59,7 +59,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
layerm.fill_surfaces.group(&groups); layerm.fill_surfaces.group(&groups);
//if internal infill can be dense, place it on his own group //if internal infill can be dense, place it on his own group
if (layerm.region()->config.infill_dense_layers.getInt() > 0) { if (layerm.region()->config.infill_dense.getBool() && layerm.region()->config.fill_density<40) {
SurfacesPtr *denseGroup = NULL; SurfacesPtr *denseGroup = NULL;
const uint32_t nbGroups = groups.size(); const uint32_t nbGroups = groups.size();
for (uint32_t num_group = 0; num_group < nbGroups; ++num_group) { for (uint32_t num_group = 0; num_group < nbGroups; ++num_group) {
@ -68,7 +68,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
//if solid, wrong group //if solid, wrong group
if (srf->is_solid()) break; if (srf->is_solid()) break;
//find surface that can be used as dense infill //find surface that can be used as dense infill
if (srf->maxNbSolidLayersOnTop <= layerm.region()->config.infill_dense_layers.getInt() if (srf->maxNbSolidLayersOnTop <= 1
&& srf->maxNbSolidLayersOnTop > 0) { && srf->maxNbSolidLayersOnTop > 0) {
//remove from the group //remove from the group
groups[num_group].erase(groups[num_group].begin() + num_srf); groups[num_group].erase(groups[num_group].begin() + num_srf);
@ -193,12 +193,13 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
(surface.is_top() ? layerm.region()->config.top_fill_pattern.value : layerm.region()->config.bottom_fill_pattern.value) : (surface.is_top() ? layerm.region()->config.top_fill_pattern.value : layerm.region()->config.bottom_fill_pattern.value) :
ipRectilinear; ipRectilinear;
} else { } else {
if (layerm.region()->config.infill_dense_layers.getInt() > 0 if (layerm.region()->config.infill_dense.getBool()
&& surface.maxNbSolidLayersOnTop <= layerm.region()->config.infill_dense_layers.getInt() && layerm.region()->config.fill_density<40
&& surface.maxNbSolidLayersOnTop <= 1
&& surface.maxNbSolidLayersOnTop > 0) { && surface.maxNbSolidLayersOnTop > 0) {
density = layerm.region()->config.infill_dense_density.getFloat(); density = 42;
is_denser = true; is_denser = true;
fill_pattern = layerm.region()->config.infill_dense_pattern.value; fill_pattern = ipRectiWithPerimeter;
} }
if (density <= 0) if (density <= 0)
continue; continue;
@ -253,7 +254,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
f->layer_id = layerm.layer()->id(); f->layer_id = layerm.layer()->id();
f->z = layerm.layer()->print_z; f->z = layerm.layer()->print_z;
if (is_denser)f->angle = float(Geometry::deg2rad(layerm.region()->config.infill_dense_angle.value)); if (is_denser)f->angle = 0;
else f->angle = float(Geometry::deg2rad(layerm.region()->config.fill_angle.value)); else f->angle = float(Geometry::deg2rad(layerm.region()->config.fill_angle.value));
// Maximum length of the perimeter segment linking two infill lines. // Maximum length of the perimeter segment linking two infill lines.
f->link_max_length = scale_(link_max_length); f->link_max_length = scale_(link_max_length);

View File

@ -39,6 +39,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
case ipSmooth: return new FillSmooth(); case ipSmooth: return new FillSmooth();
case ipSmoothTriple: return new FillSmoothTriple(); case ipSmoothTriple: return new FillSmoothTriple();
case ipSmoothHilbert: return new FillSmoothHilbert(); case ipSmoothHilbert: return new FillSmoothHilbert();
case ipRectiWithPerimeter: return new FillRectilinear2Peri();
default: CONFESS("unknown type"); return nullptr; default: CONFESS("unknown type"); return nullptr;
} }
} }

View File

@ -1472,4 +1472,30 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams &para
return polylines_out; return polylines_out;
} }
Polylines FillRectilinear2Peri::fill_surface(const Surface *surface, const FillParams &params) {
Polylines polylines_out;
//generate perimeter:
//TODO: better optimize start/end point?
ExPolygons path_perimeter = offset_ex(surface->expolygon, scale_(-this->spacing/2));
for (ExPolygon &expolygon : path_perimeter) {
expolygon.contour.make_counter_clockwise();
polylines_out.push_back(expolygon.contour.split_at_index(0));
for (Polygon hole : expolygon.holes) {
hole.make_clockwise();
polylines_out.push_back(hole.split_at_index(0));
}
}
//50% overlap with the new perimeter
ExPolygons path_inner = offset2_ex(surface->expolygon, scale_(-this->spacing * 1.5), scale_(this->spacing));
for (ExPolygon &expolygon : path_inner) {
Surface surfInner(*surface, expolygon);
if (!fill_surface_by_lines(&surfInner, params, 0.f, 0.f, polylines_out)) {
printf("FillRectilinear2::fill_surface() failed to fill a region.\n");
}
}
return polylines_out;
}
} // namespace Slic3r } // namespace Slic3r

View File

@ -68,6 +68,16 @@ protected:
virtual float _layer_angle(size_t idx) const { return 0.f; } virtual float _layer_angle(size_t idx) const { return 0.f; }
}; };
class FillRectilinear2Peri : public FillRectilinear2 {
public:
// require bridge flow since it's a pre-bridge over very sparse infill
virtual bool use_bridge_flow() const { return true; }
virtual Fill* clone() const { return new FillRectilinear2Peri(*this); };
virtual ~FillRectilinear2Peri() {}
virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
};
}; // namespace Slic3r }; // namespace Slic3r

View File

@ -357,7 +357,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = L("mm"); def->sidetext = L("mm");
def->cli = "top-layer-anchor=f"; def->cli = "top-layer-anchor=f";
def->min = 0; def->min = 0;
def->default_value = new ConfigOptionFloat(3); def->default_value = new ConfigOptionFloat(1.5);
def = this->add("bridged_infill_margin", coFloat); def = this->add("bridged_infill_margin", coFloat);
def->label = L("Bridged"); def->label = L("Bridged");
@ -366,7 +366,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = L("mm"); def->sidetext = L("mm");
def->cli = "top-layer-anchor=f"; def->cli = "top-layer-anchor=f";
def->min = 0; def->min = 0;
def->default_value = new ConfigOptionFloat(3); def->default_value = new ConfigOptionFloat(2);
def = this->add("external_perimeter_extrusion_width", coFloatOrPercent); def = this->add("external_perimeter_extrusion_width", coFloatOrPercent);
def->label = L("External perimeters"); def->label = L("External perimeters");
@ -870,95 +870,12 @@ PrintConfigDef::PrintConfigDef()
def->min = 1; def->min = 1;
def->default_value = new ConfigOptionInt(1); def->default_value = new ConfigOptionInt(1);
def = this->add("infill_dense_layers", coInt); def = this->add("infill_dense", coBool);
def->label = L("Number of dense layers"); def->label = L("Suporting dense layer");
def->category = L("Infill"); def->category = L("Infill");
def->tooltip = L("Set the number of denser infill layer you want between the normal sparse infill and the top layers. 0 to disable"); def->tooltip = L("Enable the creation of a support layer under the first solid layer. Allow to use lower infill ratio without compromizing the top quality");
def->sidetext = L("layers"); def->cli = "infill-dense!";
def->cli = "infill-dense-layers=i"; def->default_value = new ConfigOptionBool(1);
def->min = 0;
def->default_value = new ConfigOptionInt(0);
def = this->add("infill_dense_angle", coFloat);
def->label = L("angle");
def->category = L("Infill");
def->tooltip = L("Set the Angle of dense infill.");
def->sidetext = L("layers");
def->cli = "infill-dense-angle=i";
def->min = 0;
def->default_value = new ConfigOptionFloat(0);
def = this->add("infill_dense_density", coPercent);
def->gui_type = "f_enum_open";
def->gui_flags = "show_value";
def->label = L("Dense fill density");
def->category = L("Infill");
def->tooltip = L("Density of the dense internal infill, expressed in the range 0% - 100%.");
def->sidetext = L("%");
def->cli = "infill-dense-density=s";
def->min = 0;
def->max = 100;
def->enum_values.push_back("0");
def->enum_values.push_back("4");
def->enum_values.push_back("5.5");
def->enum_values.push_back("7.5");
def->enum_values.push_back("10");
def->enum_values.push_back("13");
def->enum_values.push_back("18");
def->enum_values.push_back("23");
def->enum_values.push_back("31");
def->enum_values.push_back("42");
def->enum_values.push_back("55");
def->enum_values.push_back("75");
def->enum_values.push_back("100");
def->enum_labels.push_back("0");
def->enum_labels.push_back("4");
def->enum_labels.push_back("5.5");
def->enum_labels.push_back("7.5");
def->enum_labels.push_back("10");
def->enum_labels.push_back("13");
def->enum_labels.push_back("18");
def->enum_labels.push_back("23");
def->enum_labels.push_back("31");
def->enum_labels.push_back("42");
def->enum_labels.push_back("55");
def->enum_labels.push_back("75");
def->enum_labels.push_back("100");
def->default_value = new ConfigOptionPercent(42);
def = this->add("infill_dense_pattern", coEnum);
def->label = L("pattern");
def->category = L("Sparse fill pattern");
def->tooltip = L("Fill pattern for denser-density sparse infill.");
def->cli = "dense-fill-pattern=s";
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("grid");
def->enum_values.push_back("triangles");
def->enum_values.push_back("stars");
def->enum_values.push_back("cubic");
def->enum_values.push_back("line");
def->enum_values.push_back("concentric");
def->enum_values.push_back("honeycomb");
def->enum_values.push_back("3dhoneycomb");
def->enum_values.push_back("gyroid");
def->enum_values.push_back("hilbertcurve");
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
def->enum_labels.push_back("Rectilinear");
def->enum_labels.push_back("Grid");
def->enum_labels.push_back("Triangles");
def->enum_labels.push_back("Stars");
def->enum_labels.push_back("Cubic");
def->enum_labels.push_back("Line");
def->enum_labels.push_back("Concentric");
def->enum_labels.push_back("Honeycomb");
def->enum_labels.push_back("3D Honeycomb");
def->enum_labels.push_back("Gyroid");
def->enum_labels.push_back("Hilbert Curve");
def->enum_labels.push_back("Archimedean Chords");
def->enum_labels.push_back("Octagram Spiral");
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
def = this->add("infill_extruder", coInt); def = this->add("infill_extruder", coInt);
def->label = L("Infill extruder"); def->label = L("Infill extruder");
@ -2446,11 +2363,6 @@ std::string FullPrintConfig::validate()
if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->bottom_fill_pattern.serialize())) if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->bottom_fill_pattern.serialize()))
return "Invalid value for --bottom-fill-pattern"; return "Invalid value for --bottom-fill-pattern";
// --infill-dense-pattern
if (! print_config_def.get("infill_dense_pattern")->has_enum_value(this->infill_dense_pattern.serialize()))
return "Invalid value for --infill-dense-pattern";
// --fill-density // --fill-density
if (fabs(this->fill_density.value - 100.) < EPSILON && if (fabs(this->fill_density.value - 100.) < EPSILON &&
(! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize()) (! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())

View File

@ -30,6 +30,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, ipSmooth, ipSmoothHilbert, ipSmoothTriple, ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth, ipSmoothHilbert, ipSmoothTriple,
ipRectiWithPerimeter,
}; };
enum SupportMaterialPattern { enum SupportMaterialPattern {
@ -80,6 +81,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
keys_map["smooth"] = ipSmooth; keys_map["smooth"] = ipSmooth;
keys_map["smoothtriple"] = ipSmoothTriple; keys_map["smoothtriple"] = ipSmoothTriple;
keys_map["smoothhilbert"] = ipSmoothHilbert; keys_map["smoothhilbert"] = ipSmoothHilbert;
keys_map["rectiwithperimeter"] = ipRectiWithPerimeter;
} }
return keys_map; return keys_map;
} }
@ -412,10 +414,7 @@ public:
ConfigOptionInt infill_every_layers; ConfigOptionInt infill_every_layers;
ConfigOptionFloatOrPercent infill_overlap; ConfigOptionFloatOrPercent infill_overlap;
ConfigOptionFloat infill_speed; ConfigOptionFloat infill_speed;
ConfigOptionInt infill_dense_layers; ConfigOptionBool infill_dense;
ConfigOptionFloat infill_dense_angle;
ConfigOptionPercent infill_dense_density;
ConfigOptionEnum<InfillPattern> infill_dense_pattern;
ConfigOptionBool infill_first; ConfigOptionBool infill_first;
ConfigOptionBool overhangs; ConfigOptionBool overhangs;
ConfigOptionBool no_perimeter_unsupported; ConfigOptionBool no_perimeter_unsupported;
@ -465,10 +464,7 @@ protected:
OPT_PTR(infill_every_layers); OPT_PTR(infill_every_layers);
OPT_PTR(infill_overlap); OPT_PTR(infill_overlap);
OPT_PTR(infill_speed); OPT_PTR(infill_speed);
OPT_PTR(infill_dense_layers); OPT_PTR(infill_dense);
OPT_PTR(infill_dense_angle);
OPT_PTR(infill_dense_density);
OPT_PTR(infill_dense_pattern);
OPT_PTR(infill_first); OPT_PTR(infill_first);
OPT_PTR(overhangs); OPT_PTR(overhangs);
OPT_PTR(no_perimeter_unsupported); OPT_PTR(no_perimeter_unsupported);

View File

@ -170,6 +170,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "elefant_foot_compensation" || opt_key == "elefant_foot_compensation"
|| opt_key == "support_material_contact_distance" || opt_key == "support_material_contact_distance"
|| opt_key == "xy_size_compensation" || opt_key == "xy_size_compensation"
|| opt_key == "external_infill_margin"
|| opt_key == "bridged_infill_margin"
|| opt_key == "hole_size_compensation") { || opt_key == "hole_size_compensation") {
steps.emplace_back(posSlice); steps.emplace_back(posSlice);
} else if ( } else if (
@ -197,15 +199,10 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "infill_only_where_needed" || opt_key == "infill_only_where_needed"
|| opt_key == "infill_every_layers" || opt_key == "infill_every_layers"
|| opt_key == "solid_infill_every_layers" || opt_key == "solid_infill_every_layers"
|| opt_key == "infill_dense_layers" || opt_key == "infill_dense"
|| opt_key == "infill_dense_angle"
|| opt_key == "infill_dense_density"
|| opt_key == "infill_dense_pattern"
|| opt_key == "bottom_solid_layers" || opt_key == "bottom_solid_layers"
|| opt_key == "top_solid_layers" || opt_key == "top_solid_layers"
|| opt_key == "solid_infill_below_area" || opt_key == "solid_infill_below_area"
|| opt_key == "external_infill_margin"
|| opt_key == "bridged_infill_margin"
|| opt_key == "infill_extruder" || opt_key == "infill_extruder"
|| opt_key == "solid_infill_extruder" || opt_key == "solid_infill_extruder"
|| opt_key == "infill_extrusion_width" || opt_key == "infill_extrusion_width"
@ -414,13 +411,101 @@ void PrintObject::_prepare_infill()
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
} }
void PrintObject::count_distance_solid() { // Function used by fit_to_size.
// It check if polygon_to_check can be decimated, using only point into allowedPoints and also cover polygon_to_cover
ExPolygon try_fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, const ExPolygons &allowedPoints) {
ExPolygon polygon_reduced = polygon_to_check;
auto point = polygon_reduced.contour.points.begin();
bool has_del = false;
while (point != polygon_reduced.contour.points.end()) {
bool ok = false;
for (ExPolygon poly : allowedPoints) {
if (poly.contains_b(*point)) {
ok = true;
has_del = true;
break;
}
}
if (ok) ++point;
else polygon_reduced.contour.points.erase(point);
}
if (has_del) polygon_reduced.holes.clear();
return polygon_reduced;
}
// find one of the smallest polygon, growing polygon_to_check, only using point into allowedPoints and covering polygon_to_cover.
ExPolygons fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, const ExPolygons &allowedPoints,
const ExPolygon &growing_area, const coord_t offset, float coverage) {
//grow the polygon_to_check enough to cover polygon_to_cover
float current_coverage = current_coverage;
coord_t previous_offset = 0;
coord_t current_offset = offset;
ExPolygon polygon_reduced = try_fit_to_size(polygon_to_cover, polygon_to_check, allowedPoints);
while (!diff_ex(polygon_to_cover, polygon_reduced).empty()){
//not enough, use a bigger offset
float percent_coverage = polygon_reduced.area() / growing_area.area();
float next_coverage = percent_coverage + (percent_coverage - current_coverage) * 4;
previous_offset = current_offset;
current_offset *= 2;
if (next_coverage < 0.1) current_offset *= 2;
//create the bigger polygon and test it
ExPolygons bigger_polygon = offset_ex(polygon_to_check, current_offset);
if (bigger_polygon.size() != 1) {
// Error, growing a single polygon result in many/no other => fallback to full coverage
return ExPolygons({ growing_area });
}
bigger_polygon = intersection_ex(bigger_polygon[0], growing_area);
if (bigger_polygon.size() != 1 || bigger_polygon[0].area() > growing_area.area()) {
// Growing too much => we can as well use the full coverage, in this case
return ExPolygons() = { growing_area };
}
polygon_reduced = try_fit_to_size(polygon_to_cover, bigger_polygon[0], allowedPoints);
}
//ok, we have a good one, now try to optimise (unless there are almost no growth)
if (current_offset > offset * 3){
//try to shrink
uint32_t nb_opti_max = 6;
for (uint32_t i = 0; i < nb_opti_max; ++i){
coord_t new_offset = (previous_offset + current_offset) / 2;
ExPolygons bigger_polygon = offset_ex(polygon_to_check, new_offset);
if (bigger_polygon.size() != 1) {
//Warn, growing a single polygon result in many/no other, use previous good result
break;
}
bigger_polygon = intersection_ex(bigger_polygon[0], growing_area);
if (bigger_polygon.size() != 1 || bigger_polygon[0].area() > growing_area.area()) {
//growing too much, use previous good result (imo, should not be possible to enter this branch)
break;
}
ExPolygon polygon_test = try_fit_to_size(polygon_to_cover, bigger_polygon[0], allowedPoints);
if (!diff_ex(polygon_to_cover, polygon_test).empty()){
//bad, not enough, use a bigger offset
previous_offset = new_offset;
}
else {
//good, we may now try a smaller offset
current_offset = new_offset;
polygon_reduced = polygon_test;
}
}
}
//return the area which cover the growing_area. Intersect it to retreive the holes.
return intersection_ex(polygon_reduced, growing_area);
}
void PrintObject::count_distance_solid() {
//if dense area * COEFF_SPLIT > sparse area then fill all with dense
// sparse area = layer's fill area - dense area
const float COEFF_SPLIT = .1;
const int NB_DENSE_LAYERS = 1;
for (int idx_region = 0; idx_region < this->_print->regions.size(); ++idx_region) { for (int idx_region = 0; idx_region < this->_print->regions.size(); ++idx_region) {
//count how many surface there are on each one //count how many surface there are on each one
LayerRegion *previousOne = NULL; LayerRegion *previousOne = NULL;
if (this->layers.size() > 1) previousOne = this->layers[this->layers.size() - 1]->get_region(idx_region); if (this->layers.size() > 1) previousOne = this->layers[this->layers.size() - 1]->get_region(idx_region);
if (previousOne != NULL && previousOne->region()->config.infill_dense_layers.getInt() > 0) { if (previousOne != NULL && previousOne->region()->config.infill_dense.getBool() && previousOne->region()->config.fill_density<40) {
for (Surface &surf : previousOne->fill_surfaces.surfaces) { for (Surface &surf : previousOne->fill_surfaces.surfaces) {
if (surf.is_solid()) { if (surf.is_solid()) {
surf.maxNbSolidLayersOnTop = 0; surf.maxNbSolidLayersOnTop = 0;
@ -442,22 +527,34 @@ void PrintObject::count_distance_solid() {
// upp.expolygon.overlaps(surf.expolygon) or surf.expolygon.overlaps(upp.expolygon) // upp.expolygon.overlaps(surf.expolygon) or surf.expolygon.overlaps(upp.expolygon)
ExPolygons intersect = intersection_ex(sparse_polys, ExPolygons() = { upp.expolygon }, true); ExPolygons intersect = intersection_ex(sparse_polys, ExPolygons() = { upp.expolygon }, true);
if (!intersect.empty()) { if (!intersect.empty()) {
uint16_t dist = (uint16_t)(upp.maxNbSolidLayersOnTop + 1); double area_intersect = 0;
if (dist <= layerm->region()->config.infill_dense_layers.getInt()) {
// it will be a dense infill, split the surface if needed
uint64_t area_intersect = 0;
for (ExPolygon poly_inter : intersect) area_intersect += poly_inter.area(); for (ExPolygon poly_inter : intersect) area_intersect += poly_inter.area();
//if it's in a dense area and the current surface isn't a dense one yet and the not-dense is too small. //like intersect.empty() but more resilient
if (surf.area() > area_intersect * 3 && if (area_intersect > layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2){
surf.maxNbSolidLayersOnTop > layerm->region()->config.infill_dense_layers.getInt()) { uint16_t dist = (uint16_t)(upp.maxNbSolidLayersOnTop + 1);
if (dist <= NB_DENSE_LAYERS) {
// it will be a dense infill, split the surface if needed
//if the not-dense is too big to do a full dense and the current surface isn't a dense one yet.
if (surf.area() > area_intersect * COEFF_SPLIT &&
surf.maxNbSolidLayersOnTop > NB_DENSE_LAYERS) {
//split in two //split in two
if (dist == 1) { if (dist == 1) {
//if just under the solid area, we can expand a bit //if just under the solid area, we can expand a bit
//remove too small sections and grew a bit to anchor it into the part ExPolygons cover_intersect;
intersect = offset2_ex(intersect, for (ExPolygon &expoly_tocover : intersect) {
ExPolygons temp = (fit_to_size(expoly_tocover, expoly_tocover,
diff_ex(offset_ex(layerm->fill_no_overlap_expolygons, layerm->flow(frInfill).scaled_width()),
offset_ex(layerm->fill_no_overlap_expolygons, -layerm->flow(frInfill).scaled_width())),
surf.expolygon,
4 * layerm->flow(frInfill).scaled_width(), 0.01));
cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end());
}
intersect = offset2_ex(cover_intersect,
-layerm->flow(frInfill).scaled_width(), -layerm->flow(frInfill).scaled_width(),
layerm->flow(frInfill).scaled_width() + scale_(layerm->region()->config.external_infill_margin)); layerm->flow(frInfill).scaled_width());// +scale_(expandby));
} else { //layerm->region()->config.external_infill_margin));
}
else {
//just remove too small sections //just remove too small sections
intersect = offset2_ex(intersect, intersect = offset2_ex(intersect,
-layerm->flow(frInfill).scaled_width(), -layerm->flow(frInfill).scaled_width(),
@ -475,21 +572,25 @@ void PrintObject::count_distance_solid() {
dense_polys.insert(dense_polys.end(), dense_surfaces.begin(), dense_surfaces.end()); dense_polys.insert(dense_polys.end(), dense_surfaces.begin(), dense_surfaces.end());
dense_dist = std::min(dense_dist, dist); dense_dist = std::min(dense_dist, dist);
} }
} else { }
else {
if (area_intersect < layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2)
surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist); surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
} }
} else { }
else {
surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist); surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
} }
} }
} }
}
//check if we need to split the surface //check if we need to split the surface
if (dense_dist != 30000) { if (dense_dist != 30000) {
uint64_t area_dense = 0; double area_dense = 0;
for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area(); for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area();
uint64_t area_sparse = 0; double area_sparse = 0;
for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area(); for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area();
if (area_sparse > area_dense * 3) { if (area_sparse > area_dense * COEFF_SPLIT) {
//split //split
dense_polys = union_ex(dense_polys); dense_polys = union_ex(dense_polys);
for (ExPolygon dense_poly : dense_polys) { for (ExPolygon dense_poly : dense_polys) {
@ -526,6 +627,7 @@ void PrintObject::count_distance_solid() {
} }
} }
// This function analyzes slices of a region (SurfaceCollection slices). // This function analyzes slices of a region (SurfaceCollection slices).
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface. // Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
// Initially all slices are of type stInternal. // Initially all slices are of type stInternal.

View File

@ -596,7 +596,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
break; break;
case coEnum:{ case coEnum:{
if (opt_key.compare("top_fill_pattern") == 0 || opt_key.compare("bottom_fill_pattern") == 0 || if (opt_key.compare("top_fill_pattern") == 0 || opt_key.compare("bottom_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0 || opt_key.compare("infill_dense_pattern") == 0) opt_key.compare("fill_pattern") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value))); config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
else if (opt_key.compare("gcode_flavor") == 0) else if (opt_key.compare("gcode_flavor") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value))); config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));

View File

@ -450,7 +450,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
break; break;
case coEnum:{ case coEnum:{
if (opt_key.compare("top_fill_pattern") == 0 || opt_key.compare("bottom_fill_pattern") == 0 || if (opt_key.compare("top_fill_pattern") == 0 || opt_key.compare("bottom_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0 || opt_key.compare("infill_dense_pattern") == 0 ){ opt_key.compare("fill_pattern") == 0 ){
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value); ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
} }
else if (opt_key.compare("gcode_flavor") == 0 ){ else if (opt_key.compare("gcode_flavor") == 0 ){

View File

@ -306,7 +306,7 @@ const std::vector<std::string>& Preset::print_options()
"elefant_foot_compensation", "xy_size_compensation", "hole_size_compensation", "threads", "resolution", "elefant_foot_compensation", "xy_size_compensation", "hole_size_compensation", "threads", "resolution",
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging",
"only_one_perimeter_top", "compatible_printers", "compatible_printers_condition", "inherits", "only_one_perimeter_top", "compatible_printers", "compatible_printers_condition", "inherits",
"infill_dense_layers", "infill_dense_density", "infill_dense_pattern", "infill_dense_angle", "infill_dense",
"no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only" "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only"
}; };
return s_opts; return s_opts;

View File

@ -833,12 +833,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Reducing printing time"))); optgroup = page->new_optgroup(_(L("Reducing printing time")));
optgroup->append_single_option_line("infill_every_layers"); optgroup->append_single_option_line("infill_every_layers");
optgroup->append_single_option_line("infill_only_where_needed"); optgroup->append_single_option_line("infill_only_where_needed");
line = { _(L("Use denser infill below solid layers")), "" }; optgroup->append_single_option_line("infill_dense");
line.append_option(optgroup->get_option("infill_dense_layers"));
line.append_option(optgroup->get_option("infill_dense_density"));
line.append_option(optgroup->get_option("infill_dense_pattern"));
line.append_option(optgroup->get_option("infill_dense_angle"));
optgroup->append_line(line);
optgroup = page->new_optgroup(_(L("Advanced"))); optgroup = page->new_optgroup(_(L("Advanced")));
optgroup->append_single_option_line("solid_infill_every_layers"); optgroup->append_single_option_line("solid_infill_every_layers");