mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-11 15:39:11 +08:00
update on dense infill: add switch for the algo (good old vs bad new)
This commit is contained in:
parent
a383f89a7d
commit
6a98c06db2
@ -911,12 +911,26 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->default_value = new ConfigOptionInt(1);
|
||||
|
||||
def = this->add("infill_dense", coBool);
|
||||
def->label = L("Suporting dense layer");
|
||||
def->label = ("");
|
||||
def->category = L("Infill");
|
||||
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->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."
|
||||
" The dense infill is layed out with a 50% infill density.");
|
||||
def->cli = "infill-dense!";
|
||||
def->default_value = new ConfigOptionBool(1);
|
||||
|
||||
|
||||
def = this->add("infill_dense_algo", coEnum);
|
||||
def->label = L("Algorithm");
|
||||
def->tooltip = L("Choose the way the dense layer is lay out."
|
||||
" The automatic option let it try to draw the smallest surface with only strait lines inside the sparse infill."
|
||||
" The anchored just enlarge a bit (by bridged anchor) the surfaces that need a better support.");
|
||||
def->cli = "infill-dense-algo=s";
|
||||
def->enum_keys_map = &ConfigOptionEnum<DenseInfillAlgo>::get_enum_values();
|
||||
def->enum_values.push_back("automatic");
|
||||
def->enum_values.push_back("enxtended");
|
||||
def->enum_labels.push_back(L("Automatic"));
|
||||
def->enum_labels.push_back(L("Anchored"));
|
||||
def->default_value = new ConfigOptionEnum<DenseInfillAlgo>(dfaAutomatic);
|
||||
|
||||
def = this->add("infill_extruder", coInt);
|
||||
def->label = L("Infill extruder");
|
||||
def->category = L("Extruders");
|
||||
|
@ -49,6 +49,10 @@ enum FilamentType {
|
||||
ftPLA, ftABS, ftPET, ftHIPS, ftFLEX, ftSCAFF, ftEDGE, ftNGEN, ftPVA
|
||||
};
|
||||
|
||||
enum DenseInfillAlgo {
|
||||
dfaAutomatic, dfaEnlarged,
|
||||
};
|
||||
|
||||
template<> inline t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
|
||||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
@ -136,6 +140,15 @@ template<> inline t_config_enum_values& ConfigOptionEnum<FilamentType>::get_enum
|
||||
return keys_map;
|
||||
}
|
||||
|
||||
template<> inline t_config_enum_values& ConfigOptionEnum<DenseInfillAlgo>::get_enum_values() {
|
||||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
keys_map["automatic"] = dfaAutomatic;
|
||||
keys_map["enlarged"] = dfaEnlarged;
|
||||
}
|
||||
return keys_map;
|
||||
}
|
||||
|
||||
// Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs.
|
||||
// Does not store the actual values, but defines default values.
|
||||
class PrintConfigDef : public ConfigDef
|
||||
@ -429,7 +442,8 @@ public:
|
||||
ConfigOptionInt infill_every_layers;
|
||||
ConfigOptionFloatOrPercent infill_overlap;
|
||||
ConfigOptionFloat infill_speed;
|
||||
ConfigOptionBool infill_dense;
|
||||
ConfigOptionBool infill_dense;
|
||||
ConfigOptionEnum<DenseInfillAlgo> infill_dense_algo;
|
||||
ConfigOptionBool infill_first;
|
||||
ConfigOptionBool overhangs;
|
||||
ConfigOptionBool no_perimeter_unsupported;
|
||||
@ -480,6 +494,7 @@ protected:
|
||||
OPT_PTR(infill_overlap);
|
||||
OPT_PTR(infill_speed);
|
||||
OPT_PTR(infill_dense);
|
||||
OPT_PTR(infill_dense_algo);
|
||||
OPT_PTR(infill_first);
|
||||
OPT_PTR(overhangs);
|
||||
OPT_PTR(no_perimeter_unsupported);
|
||||
|
@ -203,6 +203,7 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
|| opt_key == "infill_every_layers"
|
||||
|| opt_key == "solid_infill_every_layers"
|
||||
|| opt_key == "infill_dense"
|
||||
|| opt_key == "infill_dense_algo"
|
||||
|| opt_key == "bottom_solid_layers"
|
||||
|| opt_key == "top_solid_layers"
|
||||
|| opt_key == "solid_infill_below_area"
|
||||
@ -501,8 +502,8 @@ ExPolygons fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, c
|
||||
|
||||
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;
|
||||
// sparse area = layer's fill area - solid area
|
||||
const float COEFF_SPLIT = 2;
|
||||
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
|
||||
@ -528,39 +529,27 @@ void PrintObject::count_distance_solid() {
|
||||
for (Surface &upp : previousOne->fill_surfaces.surfaces) {
|
||||
// i'm using intersection_ex because the result different than
|
||||
// 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, offset_ex(upp.expolygon, -layerm->flow(frInfill).scaled_width()), true);
|
||||
if (!intersect.empty()) {
|
||||
double area_intersect = 0;
|
||||
for (ExPolygon poly_inter : intersect) area_intersect += poly_inter.area();
|
||||
//like intersect.empty() but more resilient
|
||||
if (area_intersect > layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2){
|
||||
if (layerm->region()->config.infill_dense_algo == dfaEnlarged) {
|
||||
uint16_t dist = (uint16_t)(upp.maxNbSolidLayersOnTop + 1);
|
||||
if (dist <= NB_DENSE_LAYERS) {
|
||||
const int nb_dense_layers = 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.
|
||||
uint64_t 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 * COEFF_SPLIT &&
|
||||
surf.maxNbSolidLayersOnTop > NB_DENSE_LAYERS) {
|
||||
surf.maxNbSolidLayersOnTop > nb_dense_layers) {
|
||||
//split in two
|
||||
if (dist == 1) {
|
||||
//if just under the solid area, we can expand a bit
|
||||
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_(expandby));
|
||||
//layerm->region()->config.external_infill_margin));
|
||||
}
|
||||
else {
|
||||
//remove too small sections and grew a bit to anchor it into the part
|
||||
intersect = offset_ex(intersect,
|
||||
layerm->flow(frInfill).scaled_width() + scale_(layerm->region()->config.bridged_infill_margin));
|
||||
} else {
|
||||
//just remove too small sections
|
||||
intersect = offset2_ex(intersect,
|
||||
-layerm->flow(frInfill).scaled_width(),
|
||||
intersect = offset_ex(intersect,
|
||||
layerm->flow(frInfill).scaled_width());
|
||||
}
|
||||
if (!intersect.empty()) {
|
||||
@ -575,15 +564,63 @@ 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 {
|
||||
surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
|
||||
}
|
||||
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);
|
||||
}
|
||||
} else if (layerm->region()->config.infill_dense_algo == dfaAutomatic) {
|
||||
double area_intersect = 0;
|
||||
for (ExPolygon poly_inter : intersect) area_intersect += poly_inter.area();
|
||||
//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
|
||||
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 = offset_ex(cover_intersect,
|
||||
layerm->flow(frInfill).scaled_width());// +scale_(expandby));
|
||||
//layerm->region()->config.external_infill_margin));
|
||||
} else {
|
||||
//just remove too small sections
|
||||
intersect = offset_ex(intersect,
|
||||
layerm->flow(frInfill).scaled_width());
|
||||
}
|
||||
if (!intersect.empty()) {
|
||||
ExPolygons sparse_surfaces = offset2_ex(
|
||||
diff_ex(sparse_polys, intersect, true),
|
||||
-layerm->flow(frInfill).scaled_width(),
|
||||
layerm->flow(frInfill).scaled_width());
|
||||
ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true);
|
||||
//assign (copy)
|
||||
sparse_polys.clear();
|
||||
sparse_polys.insert(sparse_polys.begin(), sparse_surfaces.begin(), sparse_surfaces.end());
|
||||
dense_polys.insert(dense_polys.end(), dense_surfaces.begin(), dense_surfaces.end());
|
||||
dense_dist = std::min(dense_dist, dist);
|
||||
}
|
||||
} else {
|
||||
if (area_intersect < layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2)
|
||||
surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
|
||||
}
|
||||
} else {
|
||||
surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,9 +590,11 @@ boost::any& Choice::get_value()
|
||||
else if (m_opt_id.compare("support_material_pattern") == 0)
|
||||
m_value = static_cast<SupportMaterialPattern>(ret_enum);
|
||||
else if (m_opt_id.compare("seam_position") == 0)
|
||||
m_value = static_cast<SeamPosition>(ret_enum);
|
||||
else if (m_opt_id.compare("host_type") == 0)
|
||||
m_value = static_cast<PrintHostType>(ret_enum);
|
||||
m_value = static_cast<SeamPosition>(ret_enum);
|
||||
else if (m_opt_id.compare("host_type") == 0)
|
||||
m_value = static_cast<PrintHostType>(ret_enum);
|
||||
else if (m_opt_id.compare("infill_dense_algo") == 0)
|
||||
m_value = static_cast<DenseInfillAlgo>(ret_enum);
|
||||
}
|
||||
|
||||
return m_value;
|
||||
|
@ -605,7 +605,9 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
||||
else if (opt_key.compare("seam_position") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
|
||||
else if (opt_key.compare("host_type") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
|
||||
else if (opt_key.compare("infill_dense_algo") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<DenseInfillAlgo>(boost::any_cast<DenseInfillAlgo>(value)));
|
||||
}
|
||||
break;
|
||||
case coPoints:{
|
||||
|
@ -465,6 +465,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
else if (opt_key.compare("host_type") == 0){
|
||||
ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
|
||||
}
|
||||
else if (opt_key.compare("infill_dense_algo") == 0){
|
||||
ret = static_cast<int>(config.option<ConfigOptionEnum<DenseInfillAlgo>>(opt_key)->value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case coPoints:
|
||||
|
@ -306,7 +306,8 @@ 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", "single_extruder_multi_material_priming", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"infill_dense", "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only", "support_material_solid_first_layer"
|
||||
"infill_dense", "infill_dense_algo", "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only",
|
||||
"support_material_solid_first_layer"
|
||||
};
|
||||
return s_opts;
|
||||
}
|
||||
|
@ -833,7 +833,10 @@ 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");
|
||||
optgroup->append_single_option_line("infill_dense");
|
||||
line = { _(L("Suporting dense layer")), "" };
|
||||
line.append_option(optgroup->get_option("infill_dense"));
|
||||
line.append_option(optgroup->get_option("infill_dense_algo"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Advanced")));
|
||||
optgroup->append_single_option_line("solid_infill_every_layers");
|
||||
@ -1172,12 +1175,20 @@ void TabPrint::update()
|
||||
for (auto el : { "min_perimeter_unsupported", "noperi_bridge_only" })
|
||||
get_field(el)->toggle(have_no_perimeter_unsupported);
|
||||
|
||||
|
||||
bool have_infill = m_config->option<ConfigOptionPercent>("fill_density")->value > 0;
|
||||
// infill_extruder uses the same logic as in Print::extruders()
|
||||
for (auto el : {"fill_pattern", "infill_every_layers", "infill_only_where_needed",
|
||||
"solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
|
||||
get_field(el)->toggle(have_infill);
|
||||
|
||||
bool can_have_infill_dense = m_config->option<ConfigOptionPercent>("fill_density")->value < 50;
|
||||
for (auto el : { "infill_dense" })
|
||||
get_field(el)->toggle(can_have_infill_dense);
|
||||
bool have_infill_dense = m_config->opt_bool("infill_dense") && can_have_infill_dense;
|
||||
for (auto el : { "infill_dense_algo" })
|
||||
get_field(el)->toggle(have_infill_dense);
|
||||
|
||||
bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0;
|
||||
// solid_infill_extruder uses the same logic as in Print::extruders()
|
||||
for (auto el : {"top_fill_pattern", "bottom_fill_pattern", "enforce_full_fill_volume", "external_infill_margin", "infill_first",
|
||||
|
Loading…
x
Reference in New Issue
Block a user