ENH: CLI: support multi-extruder slicing

1. add slicing errors for gcode in unprintable area, also for filament mapping
2. use common area for auto arrange
3. support filament_map/filament_map_mode related params
4. add logic to check the filament maps before slicing
5. uptodate support multi-extruder
6. switch new machine/filament support multi-extruder
7. process config params support transfer between mult-extruder and
   single-extruder
8. improve machine-limit logic support multi-extruder
9. flush-volume support multi-extruder
10. add default params to support auto mapping slicing

jira: no-jira
Change-Id: Ice39a365841322ddb586d39c56ff923626822528
(cherry picked from commit f518d6804a9de69deef81c20cd22005a4bbd0cd4)
This commit is contained in:
lane.wei
2024-10-23 16:07:59 +08:00
committed by Noisyfox
parent c99047c6a7
commit db0f3e484a
5 changed files with 524 additions and 51 deletions

View File

@@ -4492,7 +4492,6 @@ void PrintConfigDef::init_fff_params()
def->label = "Extruder ams count";
def->tooltip = "Ams counts of per extruder";
def->set_default_value(new ConfigOptionStrings { });
def->cli = ConfigOptionDef::nocli;
def = this->add("printer_extruder_id", coInts);
def->label = "Printer extruder id";
@@ -7213,12 +7212,12 @@ std::set<std::string> print_options_with_variant = {
"initial_layer_infill_speed",
"outer_wall_speed",
"inner_wall_speed",
"small_perimeter_speed",
"small_perimeter_speed", //coFloatsOrPercents
"small_perimeter_threshold",
"sparse_infill_speed",
"internal_solid_infill_speed",
"top_surface_speed",
"enable_overhang_speed",
"enable_overhang_speed", //coBools
"overhang_1_4_speed",
"overhang_2_4_speed",
"overhang_3_4_speed",
@@ -7233,10 +7232,10 @@ std::set<std::string> print_options_with_variant = {
"initial_layer_acceleration",
"outer_wall_acceleration",
"inner_wall_acceleration",
"sparse_infill_acceleration",
"sparse_infill_acceleration", //coFloatsOrPercents
"top_surface_acceleration",
"print_extruder_id",
"print_extruder_variant"
"print_extruder_id", //coInts
"print_extruder_variant" //coStrings
};
std::set<std::string> filament_options_with_variant = {
@@ -7784,6 +7783,210 @@ int DynamicPrintConfig::get_index_for_extruder(int extruder_or_filament_id, std:
return ret;
}
//only used for cli
//update values in single extruder process config to values in multi-extruder process
//limit the new values
int DynamicPrintConfig::update_values_from_single_to_multi(DynamicPrintConfig& multi_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name)
{
auto print_variant_opt = dynamic_cast<const ConfigOptionStrings*>(multi_config.option(variant_name));
if (!print_variant_opt) {
BOOST_LOG_TRIVIAL(error) << boost::format("%1%:%2%, can not get %3% from config")%__FUNCTION__ %__LINE__ % variant_name;
return -1;
}
int variant_count = print_variant_opt->size();
const ConfigDef *config_def = this->def();
if (!config_def) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define")%__LINE__;
return -1;
}
for (auto& key: key_set)
{
const ConfigOptionDef *optdef = config_def->get(key);
if (!optdef) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%")%__LINE__%key;
continue;
}
switch (optdef->type) {
case coStrings:
{
ConfigOptionStrings * opt = this->option<ConfigOptionStrings>(key);
ConfigOptionStrings * src_opt = multi_config.option<ConfigOptionStrings>(key);
opt->values = src_opt->values;
break;
}
case coInts:
{
ConfigOptionInts * opt = this->option<ConfigOptionInts>(key);
ConfigOptionInts * src_opt = multi_config.option<ConfigOptionInts>(key);
opt->values = src_opt->values;
break;
}
case coFloats:
{
ConfigOptionFloats * opt = this->option<ConfigOptionFloats>(key);
ConfigOptionFloats * src_opt = multi_config.option<ConfigOptionFloats>(key);
assert(variant_count == src_opt->size());
opt->resize(variant_count, opt);
for (int index = 0; index < variant_count; index++)
{
if (opt->values[index] > src_opt->values[index])
opt->values[index] = src_opt->values[index];
}
break;
}
case coFloatsOrPercents:
{
ConfigOptionFloatsOrPercents * opt = this->option<ConfigOptionFloatsOrPercents>(key);
ConfigOptionFloatsOrPercents * src_opt = multi_config.option<ConfigOptionFloatsOrPercents>(key);
assert(variant_count == src_opt->size());
opt->resize(variant_count, opt);
for (int index = 0; index < variant_count; index++)
{
if (opt->values[index].value > src_opt->values[index].value)
opt->values[index] = src_opt->values[index];
}
break;
}
case coBools:
{
ConfigOptionBools * opt = this->option<ConfigOptionBools>(key);
ConfigOptionBools * src_opt = multi_config.option<ConfigOptionBools>(key);
assert(variant_count == src_opt->size());
opt->resize(variant_count, opt);
break;
}
default:
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%")%__LINE__%key;
break;
}
}
return 0;
}
int DynamicPrintConfig::update_values_from_multi_to_single(DynamicPrintConfig& single_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name, std::vector<std::string>& extruder_variants)
{
int extruder_count = extruder_variants.size();
std::vector<int> extruder_index(extruder_count, -1);
auto print_variant_opt = dynamic_cast<const ConfigOptionStrings*>(this->option(variant_name));
if (!print_variant_opt) {
BOOST_LOG_TRIVIAL(error) << boost::format("%1%:%2%, can not get %3% from config")%__FUNCTION__ %__LINE__ % variant_name;
return -1;
}
int variant_count = print_variant_opt->size();
auto print_id_opt = dynamic_cast<const ConfigOptionInts*>(this->option(id_name));
if (!print_id_opt) {
BOOST_LOG_TRIVIAL(error) << boost::format("%1%:%2%, can not get %3% from config")%__FUNCTION__ %__LINE__ % id_name;
return -1;
}
for (int i = 0; i < extruder_count; i++)
{
for (int j = 0; j < variant_count; j++)
{
if ((i+1 == print_id_opt->values[j]) && (extruder_variants[i] == print_variant_opt->values[j])) {
extruder_index[i] = j;
break;
}
}
}
const ConfigDef* config_def = this->def();
if (!config_def) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define") % __LINE__;
return -1;
}
for (auto& key : key_set)
{
const ConfigOptionDef* optdef = config_def->get(key);
if (!optdef) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%") % __LINE__ % key;
continue;
}
switch (optdef->type) {
case coStrings:
{
ConfigOptionStrings* opt = this->option<ConfigOptionStrings>(key);
ConfigOptionStrings* src_opt = single_config.option<ConfigOptionStrings>(key);
assert(variant_count == opt->size());
opt->values = src_opt->values;
break;
}
case coInts:
{
ConfigOptionInts* opt = this->option<ConfigOptionInts>(key);
ConfigOptionInts* src_opt = single_config.option<ConfigOptionInts>(key);
assert(variant_count == opt->size());
opt->values = src_opt->values;
break;
}
case coFloats:
{
ConfigOptionFloats* opt = this->option<ConfigOptionFloats>(key);
ConfigOptionFloats* src_opt = single_config.option<ConfigOptionFloats>(key);
std::vector<double> old_values = opt->values;
assert(variant_count == opt->size());
opt->values = src_opt->values;
for (int i = 0; i < extruder_count; i++)
{
assert(extruder_index[i] != -1);
if (old_values[extruder_index[i]] < opt->values[0])
opt->values[0] = old_values[extruder_index[i]];
}
break;
}
case coFloatsOrPercents:
{
ConfigOptionFloatsOrPercents* opt = this->option<ConfigOptionFloatsOrPercents>(key);
ConfigOptionFloatsOrPercents* src_opt = single_config.option<ConfigOptionFloatsOrPercents>(key);
std::vector<FloatOrPercent> old_values = opt->values;
assert(variant_count == opt->size());
opt->values = src_opt->values;
for (int i = 0; i < extruder_count; i++)
{
assert(extruder_index[i] != -1);
if (old_values[extruder_index[i]].value < opt->values[0].value)
opt->values[0] = old_values[extruder_index[i]];
}
break;
}
case coBools:
{
ConfigOptionBools* opt = this->option<ConfigOptionBools>(key);
ConfigOptionBools* src_opt = single_config.option<ConfigOptionBools>(key);
assert(variant_count == opt->size());
opt->values = src_opt->values;
break;
}
default:
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%") % __LINE__ % key;
break;
}
}
return 0;
}
void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name, unsigned int stride, unsigned int extruder_id)
{
int extruder_count;
@@ -7853,7 +8056,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7867,7 +8070,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7881,7 +8084,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7895,7 +8098,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7909,7 +8112,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7923,7 +8126,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7937,7 +8140,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
new_values.resize(extruder_count * stride);
for (int e_index = 0; e_index < extruder_count; e_index++)
{
for (int i = 0; i < stride; i++)
for (unsigned int i = 0; i < stride; i++)
new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i);
}
opt->values = new_values;
@@ -7953,7 +8156,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name)
{
int extruder_count, filament_count;
int extruder_count;
bool different_extruder = printer_config.support_different_extruders(extruder_count);
if ((extruder_count > 1) || different_extruder)
{
@@ -9291,9 +9494,26 @@ static Points to_points(const std::vector<Vec2d> &dpts)
return pts;
}
Points get_bed_shape(const DynamicPrintConfig &config)
static Polygon get_shared_poly(const std::vector<Pointfs>& extruder_polys)
{
const auto *bed_shape_opt = config.opt<ConfigOptionPoints>("printable_area");
Polygon result;
for (int index = 0; index < extruder_polys.size(); index++)
{
const Pointfs& extruder_area = extruder_polys[index];
if (index == 0)
result.points = to_points(extruder_area);
else {
Polygon extruer_poly;
extruer_poly.points = to_points(extruder_area);
Polygons result_polygon = intersection(extruer_poly, result);
result = result_polygon[0];
}
}
return result;
}
Points get_bed_shape(const DynamicPrintConfig &config, bool use_share)
{
const ConfigOptionPoints *bed_shape_opt = config.opt<ConfigOptionPoints>("printable_area");
if (!bed_shape_opt) {
// Here, it is certain that the bed shape is missing, so an infinite one
@@ -9304,12 +9524,37 @@ Points get_bed_shape(const DynamicPrintConfig &config)
return {};
}
return to_points(make_counter_clockwise(bed_shape_opt->values));
Polygon bed_poly;
if (use_share) {
const ConfigOptionPointsGroups *extruder_area_opt = config.opt<ConfigOptionPointsGroups>("extruder_printable_area");
if (extruder_area_opt && (extruder_area_opt->size() > 0)) {
const std::vector<Pointfs>& extruder_areas = extruder_area_opt->values;
bed_poly = get_shared_poly(extruder_areas);
}
else
bed_poly.points = to_points(make_counter_clockwise(bed_shape_opt->values));
}
else
bed_poly.points = to_points(make_counter_clockwise(bed_shape_opt->values));
return bed_poly.points;
}
Points get_bed_shape(const PrintConfig &cfg)
Points get_bed_shape(const PrintConfig &cfg, bool use_share)
{
return to_points(make_counter_clockwise(cfg.printable_area.values));
Polygon bed_poly;
if (use_share) {
const std::vector<Pointfs>& extruder_areas = cfg.extruder_printable_area.values;
if (extruder_areas.size() > 0) {
bed_poly = get_shared_poly(extruder_areas);
}
else
bed_poly.points = to_points(make_counter_clockwise(cfg.printable_area.values));
}
else
bed_poly.points = to_points(make_counter_clockwise(cfg.printable_area.values));
return bed_poly.points;
}
Points get_bed_shape(const SLAPrinterConfig &cfg) { return to_points(make_counter_clockwise(cfg.printable_area.values)); }
@@ -9329,10 +9574,11 @@ Polygons get_bed_excluded_area(const PrintConfig& cfg)
return {exclude_poly};
}
Polygon get_bed_shape_with_excluded_area(const PrintConfig& cfg)
Polygon get_bed_shape_with_excluded_area(const PrintConfig& cfg, bool use_share)
{
Polygon bed_poly;
bed_poly.points = get_bed_shape(cfg);
bed_poly.points = get_bed_shape(cfg, use_share);
Polygons exclude_polys = get_bed_excluded_area(cfg);
auto tmp = diff({ bed_poly }, exclude_polys);