mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-16 18:12:10 +00:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user