mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-11 20:49:02 +08:00
Modify dense_infill to an automatic parameter
This commit is contained in:
parent
05414e0e56
commit
5dd709bf1e
@ -59,7 +59,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
|
||||
layerm.fill_surfaces.group(&groups);
|
||||
|
||||
//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;
|
||||
const uint32_t nbGroups = groups.size();
|
||||
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 (srf->is_solid()) break;
|
||||
//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) {
|
||||
//remove from the group
|
||||
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) :
|
||||
ipRectilinear;
|
||||
} else {
|
||||
if (layerm.region()->config.infill_dense_layers.getInt() > 0
|
||||
&& surface.maxNbSolidLayersOnTop <= layerm.region()->config.infill_dense_layers.getInt()
|
||||
if (layerm.region()->config.infill_dense.getBool()
|
||||
&& layerm.region()->config.fill_density<40
|
||||
&& surface.maxNbSolidLayersOnTop <= 1
|
||||
&& surface.maxNbSolidLayersOnTop > 0) {
|
||||
density = layerm.region()->config.infill_dense_density.getFloat();
|
||||
density = 42;
|
||||
is_denser = true;
|
||||
fill_pattern = layerm.region()->config.infill_dense_pattern.value;
|
||||
fill_pattern = ipRectiWithPerimeter;
|
||||
}
|
||||
if (density <= 0)
|
||||
continue;
|
||||
@ -253,7 +254,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
|
||||
|
||||
f->layer_id = layerm.layer()->id();
|
||||
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));
|
||||
// Maximum length of the perimeter segment linking two infill lines.
|
||||
f->link_max_length = scale_(link_max_length);
|
||||
|
@ -39,6 +39,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
||||
case ipSmooth: return new FillSmooth();
|
||||
case ipSmoothTriple: return new FillSmoothTriple();
|
||||
case ipSmoothHilbert: return new FillSmoothHilbert();
|
||||
case ipRectiWithPerimeter: return new FillRectilinear2Peri();
|
||||
default: CONFESS("unknown type"); return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -1472,4 +1472,30 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams ¶
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
|
||||
Polylines FillRectilinear2Peri::fill_surface(const Surface *surface, const FillParams ¶ms) {
|
||||
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
|
||||
|
@ -68,6 +68,16 @@ protected:
|
||||
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 ¶ms);
|
||||
|
||||
};
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
|
@ -357,7 +357,7 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "top-layer-anchor=f";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(3);
|
||||
def->default_value = new ConfigOptionFloat(1.5);
|
||||
|
||||
def = this->add("bridged_infill_margin", coFloat);
|
||||
def->label = L("Bridged");
|
||||
@ -366,7 +366,7 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "top-layer-anchor=f";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(3);
|
||||
def->default_value = new ConfigOptionFloat(2);
|
||||
|
||||
def = this->add("external_perimeter_extrusion_width", coFloatOrPercent);
|
||||
def->label = L("External perimeters");
|
||||
@ -870,95 +870,12 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->min = 1;
|
||||
def->default_value = new ConfigOptionInt(1);
|
||||
|
||||
def = this->add("infill_dense_layers", coInt);
|
||||
def->label = L("Number of dense layers");
|
||||
def = this->add("infill_dense", coBool);
|
||||
def->label = L("Suporting dense layer");
|
||||
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->sidetext = L("layers");
|
||||
def->cli = "infill-dense-layers=i";
|
||||
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->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->cli = "infill-dense!";
|
||||
def->default_value = new ConfigOptionBool(1);
|
||||
|
||||
def = this->add("infill_extruder", coInt);
|
||||
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()))
|
||||
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
|
||||
if (fabs(this->fill_density.value - 100.) < EPSILON &&
|
||||
(! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
|
||||
|
@ -30,6 +30,7 @@ enum GCodeFlavor {
|
||||
enum InfillPattern {
|
||||
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
|
||||
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth, ipSmoothHilbert, ipSmoothTriple,
|
||||
ipRectiWithPerimeter,
|
||||
};
|
||||
|
||||
enum SupportMaterialPattern {
|
||||
@ -80,6 +81,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
|
||||
keys_map["smooth"] = ipSmooth;
|
||||
keys_map["smoothtriple"] = ipSmoothTriple;
|
||||
keys_map["smoothhilbert"] = ipSmoothHilbert;
|
||||
keys_map["rectiwithperimeter"] = ipRectiWithPerimeter;
|
||||
}
|
||||
return keys_map;
|
||||
}
|
||||
@ -412,10 +414,7 @@ public:
|
||||
ConfigOptionInt infill_every_layers;
|
||||
ConfigOptionFloatOrPercent infill_overlap;
|
||||
ConfigOptionFloat infill_speed;
|
||||
ConfigOptionInt infill_dense_layers;
|
||||
ConfigOptionFloat infill_dense_angle;
|
||||
ConfigOptionPercent infill_dense_density;
|
||||
ConfigOptionEnum<InfillPattern> infill_dense_pattern;
|
||||
ConfigOptionBool infill_dense;
|
||||
ConfigOptionBool infill_first;
|
||||
ConfigOptionBool overhangs;
|
||||
ConfigOptionBool no_perimeter_unsupported;
|
||||
@ -465,10 +464,7 @@ protected:
|
||||
OPT_PTR(infill_every_layers);
|
||||
OPT_PTR(infill_overlap);
|
||||
OPT_PTR(infill_speed);
|
||||
OPT_PTR(infill_dense_layers);
|
||||
OPT_PTR(infill_dense_angle);
|
||||
OPT_PTR(infill_dense_density);
|
||||
OPT_PTR(infill_dense_pattern);
|
||||
OPT_PTR(infill_dense);
|
||||
OPT_PTR(infill_first);
|
||||
OPT_PTR(overhangs);
|
||||
OPT_PTR(no_perimeter_unsupported);
|
||||
|
@ -170,6 +170,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
|| opt_key == "elefant_foot_compensation"
|
||||
|| opt_key == "support_material_contact_distance"
|
||||
|| opt_key == "xy_size_compensation"
|
||||
|| opt_key == "external_infill_margin"
|
||||
|| opt_key == "bridged_infill_margin"
|
||||
|| opt_key == "hole_size_compensation") {
|
||||
steps.emplace_back(posSlice);
|
||||
} 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_every_layers"
|
||||
|| opt_key == "solid_infill_every_layers"
|
||||
|| opt_key == "infill_dense_layers"
|
||||
|| opt_key == "infill_dense_angle"
|
||||
|| opt_key == "infill_dense_density"
|
||||
|| opt_key == "infill_dense_pattern"
|
||||
|| opt_key == "infill_dense"
|
||||
|| opt_key == "bottom_solid_layers"
|
||||
|| opt_key == "top_solid_layers"
|
||||
|| opt_key == "solid_infill_below_area"
|
||||
|| opt_key == "external_infill_margin"
|
||||
|| opt_key == "bridged_infill_margin"
|
||||
|| opt_key == "infill_extruder"
|
||||
|| opt_key == "solid_infill_extruder"
|
||||
|| opt_key == "infill_extrusion_width"
|
||||
@ -414,13 +411,101 @@ void PrintObject::_prepare_infill()
|
||||
#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) {
|
||||
//count how many surface there are on each one
|
||||
LayerRegion *previousOne = NULL;
|
||||
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) {
|
||||
if (surf.is_solid()) {
|
||||
surf.maxNbSolidLayersOnTop = 0;
|
||||
@ -442,22 +527,34 @@ void PrintObject::count_distance_solid() {
|
||||
// upp.expolygon.overlaps(surf.expolygon) or surf.expolygon.overlaps(upp.expolygon)
|
||||
ExPolygons intersect = intersection_ex(sparse_polys, ExPolygons() = { upp.expolygon }, true);
|
||||
if (!intersect.empty()) {
|
||||
uint16_t dist = (uint16_t)(upp.maxNbSolidLayersOnTop + 1);
|
||||
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;
|
||||
double area_intersect = 0;
|
||||
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.
|
||||
if (surf.area() > area_intersect * 3 &&
|
||||
surf.maxNbSolidLayersOnTop > layerm->region()->config.infill_dense_layers.getInt()) {
|
||||
//like intersect.empty() but more resilient
|
||||
if (area_intersect > layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2){
|
||||
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
|
||||
if (dist == 1) {
|
||||
//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
|
||||
intersect = offset2_ex(intersect,
|
||||
ExPolygons cover_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() + scale_(layerm->region()->config.external_infill_margin));
|
||||
} else {
|
||||
layerm->flow(frInfill).scaled_width());// +scale_(expandby));
|
||||
//layerm->region()->config.external_infill_margin));
|
||||
}
|
||||
else {
|
||||
//just remove too small sections
|
||||
intersect = offset2_ex(intersect,
|
||||
-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_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);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//check if we need to split the surface
|
||||
if (dense_dist != 30000) {
|
||||
uint64_t area_dense = 0;
|
||||
double area_dense = 0;
|
||||
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();
|
||||
if (area_sparse > area_dense * 3) {
|
||||
if (area_sparse > area_dense * COEFF_SPLIT) {
|
||||
//split
|
||||
dense_polys = union_ex(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).
|
||||
// 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.
|
||||
|
@ -596,7 +596,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
||||
break;
|
||||
case coEnum:{
|
||||
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)));
|
||||
else if (opt_key.compare("gcode_flavor") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));
|
||||
|
@ -450,7 +450,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
break;
|
||||
case coEnum:{
|
||||
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);
|
||||
}
|
||||
else if (opt_key.compare("gcode_flavor") == 0 ){
|
||||
|
@ -306,7 +306,7 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"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",
|
||||
"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"
|
||||
};
|
||||
return s_opts;
|
||||
|
@ -833,12 +833,7 @@ void TabPrint::build()
|
||||
optgroup = page->new_optgroup(_(L("Reducing printing time")));
|
||||
optgroup->append_single_option_line("infill_every_layers");
|
||||
optgroup->append_single_option_line("infill_only_where_needed");
|
||||
line = { _(L("Use denser infill below solid layers")), "" };
|
||||
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->append_single_option_line("infill_dense");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Advanced")));
|
||||
optgroup->append_single_option_line("solid_infill_every_layers");
|
||||
|
Loading…
x
Reference in New Issue
Block a user