mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-25 09:50:59 +00:00
Divided filament for features (#14042)
* Implement legacy key handling to address possible profile issues following semantic change of per feature filaments * Reimport base * Fix inner wall * Profiles update --------- Co-authored-by: igiannakas <ioannis@my-spot.co.uk>
This commit is contained in:
+4
-13
@@ -1595,7 +1595,7 @@ int CLI::run(int argc, char **argv)
|
||||
record_exit_reson(outfile_dir, CLI_FILE_VERSION_NOT_SUPPORTED, 0, cli_errors[CLI_FILE_VERSION_NOT_SUPPORTED], sliced_info);
|
||||
flush_and_exit(CLI_FILE_VERSION_NOT_SUPPORTED);
|
||||
}
|
||||
Semver old_version(1, 5, 9), old_version2(1, 5, 9), old_version3(2, 0, 0), old_version4(2, 2, 0), old_version5("2.4.0");
|
||||
Semver old_version(1, 5, 9), old_version2(1, 5, 9), old_version3(2, 0, 0), old_version4(2, 2, 0);
|
||||
if ((file_version < old_version) && !config.empty()) {
|
||||
translate_old = true;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old 3mf version %1%, need to translate")%file_version.to_string();
|
||||
@@ -1610,18 +1610,9 @@ int CLI::run(int argc, char **argv)
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old 3mf version %1%, need to set enable_wrapping_detection to false")%file_version.to_string();
|
||||
}
|
||||
|
||||
if ((file_version < old_version5) && !config.empty()) {
|
||||
int converted_count = ConfigMigrations::migrate_legacy_feature_filament_defaults(config);
|
||||
for (ModelObject *model_object : model.objects) {
|
||||
converted_count += ConfigMigrations::migrate_legacy_feature_filament_defaults(model_object->config);
|
||||
for (ModelVolume *model_volume : model_object->volumes)
|
||||
converted_count += ConfigMigrations::migrate_legacy_feature_filament_defaults(model_volume->config);
|
||||
}
|
||||
|
||||
if (converted_count > 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old 3mf version %1%, migrated %2% feature filament selections from 1 to 0 (Default)") % file_version.to_string() % converted_count;
|
||||
}
|
||||
}
|
||||
// ORCA: legacy feature-filament default migration (1 -> 0) is now handled
|
||||
// uniformly in PrintConfigDef::handle_legacy() via the old->new key rename
|
||||
// (wall_filament -> wall_filament_id, etc.), which covers presets too.
|
||||
|
||||
if (normative_check) {
|
||||
ConfigOptionStrings* postprocess_scripts = config.option<ConfigOptionStrings>("post_process");
|
||||
|
||||
@@ -2968,34 +2968,6 @@ private:
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const DynamicConfig::DynamicConfigDifference& diff);
|
||||
|
||||
namespace ConfigMigrations {
|
||||
|
||||
template <typename ConfigLike>
|
||||
inline int migrate_legacy_feature_filament_defaults(ConfigLike &cfg)
|
||||
{
|
||||
static const char *feature_filament_keys[] = {
|
||||
"wall_filament",
|
||||
"sparse_infill_filament",
|
||||
"solid_infill_filament"
|
||||
};
|
||||
|
||||
int converted_count = 0;
|
||||
for (const char *key : feature_filament_keys) {
|
||||
if (!cfg.has(key))
|
||||
continue;
|
||||
|
||||
const ConfigOption *opt = cfg.option(key);
|
||||
if (opt != nullptr && opt->getInt() == 1) {
|
||||
cfg.set_key_value(key, new ConfigOptionInt(0));
|
||||
++converted_count;
|
||||
}
|
||||
}
|
||||
|
||||
return converted_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Configuration store with a static definition of configuration values.
|
||||
// In Slic3r, the static configuration stores are during the slicing / g-code generation for efficiency reasons,
|
||||
// because the configuration values could be accessed directly.
|
||||
|
||||
@@ -916,6 +916,12 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
params.extrusion_role = erSolidInfill;
|
||||
}
|
||||
}
|
||||
if (params.extrusion_role == erTopSolidInfill)
|
||||
params.extruder = region_config.top_surface_filament_id;
|
||||
else if (params.extrusion_role == erBottomSurface)
|
||||
params.extruder = region_config.bottom_surface_filament_id;
|
||||
else if (params.extrusion_role == erSolidInfill)
|
||||
params.extruder = region_config.internal_solid_filament_id;
|
||||
// Orca: apply fill multiline only for sparse infill
|
||||
params.multiline = params.extrusion_role == erInternalInfill ? int(region_config.fill_multiline) : 1;
|
||||
|
||||
@@ -1571,12 +1577,12 @@ void Layer::make_ironing()
|
||||
((config.top_shell_layers > 0 || (this->object()->print()->config().spiral_mode && config.bottom_shell_layers > 1)) &&
|
||||
(config.ironing_type == IroningType::TopSurfaces ||
|
||||
(config.ironing_type == IroningType::TopmostOnly && layerm->layer()->upper_layer == nullptr))))) {
|
||||
if (config.wall_filament == config.solid_infill_filament || config.wall_loops == 0) {
|
||||
if (config.outer_wall_filament_id == config.top_surface_filament_id || config.wall_loops == 0) {
|
||||
// Iron the whole face.
|
||||
ironing_params.extruder = config.solid_infill_filament;
|
||||
ironing_params.extruder = config.top_surface_filament_id;
|
||||
} else {
|
||||
// Iron just the infill.
|
||||
ironing_params.extruder = config.solid_infill_filament;
|
||||
ironing_params.extruder = config.top_surface_filament_id;
|
||||
}
|
||||
}
|
||||
if (ironing_params.extruder != -1) {
|
||||
|
||||
+72
-43
@@ -4775,6 +4775,7 @@ LayerResult GCode::process_layer(
|
||||
|
||||
// Group extrusions by an extruder, then by an object, an island and a region.
|
||||
std::map<unsigned int, std::vector<ObjectByExtruder>> by_extruder;
|
||||
std::vector<std::unique_ptr<ExtrusionEntityCollection>> split_perimeter_storage;
|
||||
bool is_anything_overridden = const_cast<LayerTools&>(layer_tools).wiping_extrusions().is_anything_overridden();
|
||||
for (const LayerToPrint &layer_to_print : layers) {
|
||||
if (layer_to_print.support_layer != nullptr) {
|
||||
@@ -4930,55 +4931,83 @@ LayerResult GCode::process_layer(
|
||||
if (extrusions->entities.empty()) // This shouldn't happen but first_point() would fail.
|
||||
continue;
|
||||
|
||||
// This extrusion is part of certain Region, which tells us which extruder should be used for it:
|
||||
int correct_extruder_id = layer_tools.extruder(*extrusions, region);
|
||||
auto process_extrusions = [&](const ExtrusionEntityCollection *current_extrusions,
|
||||
const ExtrusionEntityCollection *overrides_key,
|
||||
bool use_overrides) {
|
||||
// This extrusion is part of certain Region, which tells us which extruder should be used for it.
|
||||
int correct_extruder_id = layer_tools.extruder(*current_extrusions, region);
|
||||
|
||||
// Let's recover vector of extruder overrides:
|
||||
const WipingExtrusions::ExtruderPerCopy *entity_overrides = nullptr;
|
||||
if (! layer_tools.has_extruder(correct_extruder_id)) {
|
||||
// this entity is not overridden, but its extruder is not in layer_tools - we'll print it
|
||||
// by last extruder on this layer (could happen e.g. when a wiping object is taller than others - dontcare extruders are eradicated from layer_tools)
|
||||
correct_extruder_id = layer_tools.extruders.back();
|
||||
}
|
||||
printing_extruders.clear();
|
||||
if (is_anything_overridden) {
|
||||
entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(extrusions, layer_to_print.original_object, correct_extruder_id, layer_to_print.object()->instances().size());
|
||||
if (entity_overrides == nullptr) {
|
||||
const WipingExtrusions::ExtruderPerCopy *entity_overrides = nullptr;
|
||||
if (! layer_tools.has_extruder(correct_extruder_id)) {
|
||||
// this entity is not overridden, but its extruder is not in layer_tools - we'll print it
|
||||
// by last extruder on this layer (could happen e.g. when a wiping object is taller than others - dontcare extruders are eradicated from layer_tools)
|
||||
correct_extruder_id = layer_tools.extruders.back();
|
||||
}
|
||||
printing_extruders.clear();
|
||||
if (is_anything_overridden && use_overrides) {
|
||||
entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(overrides_key, layer_to_print.original_object, correct_extruder_id, layer_to_print.object()->instances().size());
|
||||
if (entity_overrides == nullptr) {
|
||||
printing_extruders.emplace_back(correct_extruder_id);
|
||||
} else {
|
||||
printing_extruders.reserve(entity_overrides->size());
|
||||
for (int extruder : *entity_overrides)
|
||||
printing_extruders.emplace_back(extruder >= 0 ?
|
||||
// at least one copy is overridden to use this extruder
|
||||
extruder :
|
||||
// at least one copy would normally be printed with this extruder (see get_extruder_overrides function for explanation)
|
||||
static_cast<unsigned int>(- extruder - 1));
|
||||
Slic3r::sort_remove_duplicates(printing_extruders);
|
||||
}
|
||||
} else {
|
||||
printing_extruders.emplace_back(correct_extruder_id);
|
||||
} else {
|
||||
printing_extruders.reserve(entity_overrides->size());
|
||||
for (int extruder : *entity_overrides)
|
||||
printing_extruders.emplace_back(extruder >= 0 ?
|
||||
// at least one copy is overridden to use this extruder
|
||||
extruder :
|
||||
// at least one copy would normally be printed with this extruder (see get_extruder_overrides function for explanation)
|
||||
static_cast<unsigned int>(- extruder - 1));
|
||||
Slic3r::sort_remove_duplicates(printing_extruders);
|
||||
}
|
||||
} else
|
||||
printing_extruders.emplace_back(correct_extruder_id);
|
||||
|
||||
// Now we must add this extrusion into the by_extruder map, once for each extruder that will print it:
|
||||
for (unsigned int extruder : printing_extruders)
|
||||
{
|
||||
std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
|
||||
by_extruder,
|
||||
extruder,
|
||||
&layer_to_print - layers.data(),
|
||||
layers.size(), n_slices+1);
|
||||
for (size_t i = 0; i <= n_slices; ++ i) {
|
||||
bool last = i == n_slices;
|
||||
size_t island_idx = last ? n_slices : slices_test_order[i];
|
||||
if (// extrusions->first_point does not fit inside any slice
|
||||
last ||
|
||||
// extrusions->first_point fits inside ith slice
|
||||
point_inside_surface(island_idx, extrusions->first_point())) {
|
||||
if (islands[island_idx].by_region.empty())
|
||||
islands[island_idx].by_region.assign(print.num_print_regions(), ObjectByExtruder::Island::Region());
|
||||
islands[island_idx].by_region[region.print_region_id()].append(entity_type, extrusions, entity_overrides);
|
||||
break;
|
||||
// Now we must add this extrusion into the by_extruder map, once for each extruder that will print it.
|
||||
for (unsigned int extruder : printing_extruders) {
|
||||
std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
|
||||
by_extruder,
|
||||
extruder,
|
||||
&layer_to_print - layers.data(),
|
||||
layers.size(), n_slices + 1);
|
||||
for (size_t i = 0; i <= n_slices; ++i) {
|
||||
bool last = i == n_slices;
|
||||
size_t island_idx = last ? n_slices : slices_test_order[i];
|
||||
if (last || point_inside_surface(island_idx, current_extrusions->first_point())) {
|
||||
if (islands[island_idx].by_region.empty())
|
||||
islands[island_idx].by_region.assign(print.num_print_regions(), ObjectByExtruder::Island::Region());
|
||||
islands[island_idx].by_region[region.print_region_id()].append(entity_type, current_extrusions, entity_overrides);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool split_mixed_perimeters =
|
||||
entity_type == ObjectByExtruder::Island::Region::PERIMETERS &&
|
||||
region.config().outer_wall_filament_id.value != region.config().inner_wall_filament_id.value &&
|
||||
extrusions->role() == erMixed;
|
||||
|
||||
if (split_mixed_perimeters) {
|
||||
auto outer_perimeters = std::make_unique<ExtrusionEntityCollection>();
|
||||
auto inner_perimeters = std::make_unique<ExtrusionEntityCollection>();
|
||||
for (const ExtrusionEntity *entity : extrusions->entities) {
|
||||
const ExtrusionRole role = entity->role();
|
||||
if (role == erExternalPerimeter || role == erOverhangPerimeter)
|
||||
outer_perimeters->append(*entity);
|
||||
else if (role == erPerimeter)
|
||||
inner_perimeters->append(*entity);
|
||||
}
|
||||
|
||||
if (!outer_perimeters->entities.empty()) {
|
||||
split_perimeter_storage.emplace_back(std::move(outer_perimeters));
|
||||
process_extrusions(split_perimeter_storage.back().get(), nullptr, false);
|
||||
}
|
||||
if (!inner_perimeters->entities.empty()) {
|
||||
split_perimeter_storage.emplace_back(std::move(inner_perimeters));
|
||||
process_extrusions(split_perimeter_storage.back().get(), nullptr, false);
|
||||
}
|
||||
} else {
|
||||
process_extrusions(extrusions, extrusions, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,40 +80,54 @@ bool check_filament_printable_after_group(const std::vector<unsigned int> &used_
|
||||
}
|
||||
|
||||
// Return a zero based extruder from the region, or extruder_override if overriden.
|
||||
unsigned int LayerTools::wall_filament(const PrintRegion ®ion) const
|
||||
unsigned int LayerTools::wall_extruder_id(const PrintRegion ®ion) const
|
||||
{
|
||||
assert(region.config().wall_filament.value > 0);
|
||||
return ((this->extruder_override == 0) ? region.config().wall_filament.value : this->extruder_override) - 1;
|
||||
assert(region.config().outer_wall_filament_id.value > 0);
|
||||
return ((this->extruder_override == 0) ? region.config().outer_wall_filament_id.value : this->extruder_override) - 1;
|
||||
}
|
||||
|
||||
unsigned int LayerTools::sparse_infill_filament(const PrintRegion ®ion) const
|
||||
unsigned int LayerTools::sparse_infill_filament_id(const PrintRegion ®ion) const
|
||||
{
|
||||
assert(region.config().sparse_infill_filament.value > 0);
|
||||
return ((this->extruder_override == 0) ? region.config().sparse_infill_filament.value : this->extruder_override) - 1;
|
||||
assert(region.config().sparse_infill_filament_id.value > 0);
|
||||
return ((this->extruder_override == 0) ? region.config().sparse_infill_filament_id.value : this->extruder_override) - 1;
|
||||
}
|
||||
|
||||
unsigned int LayerTools::solid_infill_filament(const PrintRegion ®ion) const
|
||||
unsigned int LayerTools::internal_solid_filament_id(const PrintRegion ®ion) const
|
||||
{
|
||||
assert(region.config().solid_infill_filament.value > 0);
|
||||
return ((this->extruder_override == 0) ? region.config().solid_infill_filament.value : this->extruder_override) - 1;
|
||||
assert(region.config().internal_solid_filament_id.value > 0);
|
||||
return ((this->extruder_override == 0) ? region.config().internal_solid_filament_id.value : this->extruder_override) - 1;
|
||||
}
|
||||
|
||||
// Returns a zero based extruder this eec should be printed with, according to PrintRegion config or extruder_override if overriden.
|
||||
unsigned int LayerTools::extruder(const ExtrusionEntityCollection &extrusions, const PrintRegion ®ion) const
|
||||
{
|
||||
assert(region.config().wall_filament.value > 0);
|
||||
assert(region.config().sparse_infill_filament.value > 0);
|
||||
assert(region.config().solid_infill_filament.value > 0);
|
||||
assert(region.config().outer_wall_filament_id.value > 0);
|
||||
assert(region.config().sparse_infill_filament_id.value > 0);
|
||||
assert(region.config().internal_solid_filament_id.value > 0);
|
||||
assert(region.config().top_surface_filament_id.value > 0);
|
||||
assert(region.config().bottom_surface_filament_id.value > 0);
|
||||
// 1 based extruder ID.
|
||||
unsigned int extruder = 1;
|
||||
if (this->extruder_override == 0) {
|
||||
if (extrusions.has_infill()) {
|
||||
if (extrusions.has_solid_infill())
|
||||
extruder = region.config().solid_infill_filament;
|
||||
if (extrusions.has_solid_infill()) {
|
||||
ExtrusionRole role = extrusions.role();
|
||||
if (role == erTopSolidInfill || role == erIroning)
|
||||
extruder = region.config().top_surface_filament_id;
|
||||
else if (role == erBottomSurface)
|
||||
extruder = region.config().bottom_surface_filament_id;
|
||||
else
|
||||
extruder = region.config().internal_solid_filament_id;
|
||||
} else {
|
||||
extruder = region.config().sparse_infill_filament_id;
|
||||
}
|
||||
} else {
|
||||
const ExtrusionRole role = extrusions.role();
|
||||
if (role == erPerimeter)
|
||||
extruder = region.config().inner_wall_filament_id.value;
|
||||
else
|
||||
extruder = region.config().sparse_infill_filament;
|
||||
} else
|
||||
extruder = region.config().wall_filament.value;
|
||||
extruder = region.config().outer_wall_filament_id.value;
|
||||
}
|
||||
} else
|
||||
extruder = this->extruder_override;
|
||||
|
||||
@@ -527,7 +541,7 @@ std::vector<unsigned int> ToolOrdering::generate_first_layer_tool_order(const Pr
|
||||
return tool_order;
|
||||
|
||||
for (auto layerm : target_layer->regions()) {
|
||||
int extruder_id = layerm->region().config().option("wall_filament")->getInt();
|
||||
int extruder_id = layerm->region().config().option("outer_wall_filament_id")->getInt();
|
||||
|
||||
for (auto expoly : layerm->raw_slices) {
|
||||
const double nozzle_diameter = print.config().nozzle_diameter.get_at(0);
|
||||
@@ -591,7 +605,7 @@ std::vector<unsigned int> ToolOrdering::generate_first_layer_tool_order(const Pr
|
||||
return tool_order;
|
||||
|
||||
for (auto layerm : target_layer->regions()) {
|
||||
int extruder_id = layerm->region().config().option("wall_filament")->getInt();
|
||||
int extruder_id = layerm->region().config().option("outer_wall_filament_id")->getInt();
|
||||
for (auto expoly : layerm->raw_slices) {
|
||||
const double nozzle_diameter = object.print()->config().nozzle_diameter.get_at(0);
|
||||
const coordf_t line_width = object.config().get_abs_value("line_width", nozzle_diameter);
|
||||
@@ -682,24 +696,32 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
||||
}
|
||||
|
||||
if (something_nonoverriddable){
|
||||
layer_tools.extruders.emplace_back((extruder_override == 0) ? region.config().wall_filament.value : extruder_override);
|
||||
layer_tools.extruders.emplace_back((extruder_override == 0) ? region.config().outer_wall_filament_id.value : extruder_override);
|
||||
if (extruder_override == 0 && region.config().wall_loops.value > 1)
|
||||
layer_tools.extruders.emplace_back(region.config().inner_wall_filament_id.value);
|
||||
if (layerCount == 0) {
|
||||
firstLayerExtruders.emplace_back((extruder_override == 0) ? region.config().wall_filament.value : extruder_override);
|
||||
firstLayerExtruders.emplace_back((extruder_override == 0) ? region.config().outer_wall_filament_id.value : extruder_override);
|
||||
}
|
||||
}
|
||||
|
||||
layer_tools.has_object = true;
|
||||
}
|
||||
|
||||
bool has_infill = false;
|
||||
bool has_solid_infill = false;
|
||||
bool has_infill = false;
|
||||
bool has_internal_solid = false;
|
||||
bool has_top_solid_surface = false;
|
||||
bool has_bottom_surface = false;
|
||||
bool something_nonoverriddable = false;
|
||||
for (const ExtrusionEntity *ee : layerm->fills.entities) {
|
||||
// fill represents infill extrusions of a single island.
|
||||
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
||||
ExtrusionRole role = fill->entities.empty() ? erNone : fill->entities.front()->role();
|
||||
if (is_solid_infill(role))
|
||||
has_solid_infill = true;
|
||||
if (role == erTopSolidInfill || role == erIroning)
|
||||
has_top_solid_surface = true;
|
||||
else if (role == erBottomSurface)
|
||||
has_bottom_surface = true;
|
||||
else if (is_solid_infill(role))
|
||||
has_internal_solid = true;
|
||||
else if (role != erNone)
|
||||
has_infill = true;
|
||||
|
||||
@@ -711,14 +733,18 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
||||
|
||||
if (something_nonoverriddable || !m_print_config_ptr) {
|
||||
if (extruder_override == 0) {
|
||||
if (has_solid_infill)
|
||||
layer_tools.extruders.emplace_back(region.config().solid_infill_filament);
|
||||
if (has_internal_solid)
|
||||
layer_tools.extruders.emplace_back(region.config().internal_solid_filament_id);
|
||||
if (has_top_solid_surface)
|
||||
layer_tools.extruders.emplace_back(region.config().top_surface_filament_id);
|
||||
if (has_bottom_surface)
|
||||
layer_tools.extruders.emplace_back(region.config().bottom_surface_filament_id);
|
||||
if (has_infill)
|
||||
layer_tools.extruders.emplace_back(region.config().sparse_infill_filament);
|
||||
} else if (has_solid_infill || has_infill)
|
||||
layer_tools.extruders.emplace_back(region.config().sparse_infill_filament_id);
|
||||
} else if (has_internal_solid || has_top_solid_surface || has_bottom_surface || has_infill)
|
||||
layer_tools.extruders.emplace_back(extruder_override);
|
||||
}
|
||||
if (has_solid_infill || has_infill)
|
||||
if (has_internal_solid || has_top_solid_surface || has_bottom_surface || has_infill)
|
||||
layer_tools.has_object = true;
|
||||
}
|
||||
layerCount++;
|
||||
@@ -1657,7 +1683,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
|
||||
if (wipe_into_infill_only && ! is_infill_first)
|
||||
// In this case we must check that the original extruder is used on this layer before the one we are overridding
|
||||
// (and the perimeters will be finished before the infill is printed):
|
||||
if (!lt.is_extruder_order(lt.wall_filament(region), new_extruder))
|
||||
if (!lt.is_extruder_order(lt.wall_extruder_id(region), new_extruder))
|
||||
continue;
|
||||
|
||||
if ((!is_entity_overridden(fill, object, copy) && fill->total_volume() > min_infill_volume))
|
||||
@@ -1775,8 +1801,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
|
||||
if (is_infill_first
|
||||
//BBS
|
||||
//|| object->config().flush_into_objects // in this case the perimeter is overridden, so we can override by the last one safely
|
||||
|| lt.is_extruder_order(lt.wall_filament(region), last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints
|
||||
|| ! lt.has_extruder(lt.sparse_infill_filament(region)))) // we have to force override - this could violate infill_first (FIXME)
|
||||
|| lt.is_extruder_order(lt.wall_extruder_id(region), last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints
|
||||
|| ! lt.has_extruder(lt.sparse_infill_filament_id(region)))) // we have to force override - this could violate infill_first (FIXME)
|
||||
set_extruder_override(fill, object, copy, (is_infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
|
||||
else {
|
||||
// In this case we can (and should) leave it to be printed normally.
|
||||
|
||||
@@ -139,9 +139,9 @@ public:
|
||||
bool has_extruder(unsigned int extruder) const { return std::find(this->extruders.begin(), this->extruders.end(), extruder) != this->extruders.end(); }
|
||||
|
||||
// Return a zero based extruder from the region, or extruder_override if overriden.
|
||||
unsigned int wall_filament(const PrintRegion ®ion) const;
|
||||
unsigned int sparse_infill_filament(const PrintRegion ®ion) const;
|
||||
unsigned int solid_infill_filament(const PrintRegion ®ion) const;
|
||||
unsigned int wall_extruder_id(const PrintRegion ®ion) const;
|
||||
unsigned int sparse_infill_filament_id(const PrintRegion ®ion) const;
|
||||
unsigned int internal_solid_filament_id(const PrintRegion ®ion) const;
|
||||
// Returns a zero based extruder this eec should be printed with, according to PrintRegion config or extruder_override if overriden.
|
||||
unsigned int extruder(const ExtrusionEntityCollection &extrusions, const PrintRegion ®ion) const;
|
||||
|
||||
|
||||
@@ -3881,7 +3881,7 @@ void WipeTower::generate_new(std::vector<std::vector<WipeTower::ToolChangeResult
|
||||
for (auto &used : m_used_filament_length) // reset used filament stats
|
||||
used = 0.f;
|
||||
|
||||
int wall_filament = get_wall_filament_for_all_layer();
|
||||
int wall_filament_id = get_wall_filament_for_all_layer();
|
||||
|
||||
std::vector<WipeTower::ToolChangeResult> layer_result;
|
||||
int index = 0;
|
||||
@@ -3909,24 +3909,24 @@ void WipeTower::generate_new(std::vector<std::vector<WipeTower::ToolChangeResult
|
||||
ToolChangeResult finish_layer_tcr;
|
||||
ToolChangeResult timelapse_wall;
|
||||
|
||||
auto get_wall_filament_for_this_layer = [this, &layer, &wall_filament]() -> int {
|
||||
auto get_wall_filament_for_this_layer = [this, &layer, &wall_filament_id]() -> int {
|
||||
if (layer.tool_changes.size() == 0)
|
||||
return -1;
|
||||
|
||||
int candidate_id = -1;
|
||||
for (size_t idx = 0; idx < layer.tool_changes.size(); ++idx) {
|
||||
if (idx == 0) {
|
||||
if (layer.tool_changes[idx].old_tool == wall_filament)
|
||||
return wall_filament;
|
||||
else if (m_filpar[layer.tool_changes[idx].old_tool].category == m_filpar[wall_filament].category) {
|
||||
if (layer.tool_changes[idx].old_tool == wall_filament_id)
|
||||
return wall_filament_id;
|
||||
else if (m_filpar[layer.tool_changes[idx].old_tool].category == m_filpar[wall_filament_id].category) {
|
||||
candidate_id = layer.tool_changes[idx].old_tool;
|
||||
}
|
||||
}
|
||||
if (layer.tool_changes[idx].new_tool == wall_filament) {
|
||||
return wall_filament;
|
||||
if (layer.tool_changes[idx].new_tool == wall_filament_id) {
|
||||
return wall_filament_id;
|
||||
}
|
||||
|
||||
if ((candidate_id == -1) && (m_filpar[layer.tool_changes[idx].new_tool].category == m_filpar[wall_filament].category))
|
||||
if ((candidate_id == -1) && (m_filpar[layer.tool_changes[idx].new_tool].category == m_filpar[wall_filament_id].category))
|
||||
candidate_id = layer.tool_changes[idx].new_tool;
|
||||
}
|
||||
return candidate_id == -1 ? layer.tool_changes[0].new_tool : candidate_id;
|
||||
|
||||
@@ -141,7 +141,8 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
const PrintRegionConfig& config = a.config();
|
||||
const PrintRegionConfig& other_config = b.config();
|
||||
|
||||
return config.wall_filament == other_config.wall_filament
|
||||
return config.outer_wall_filament_id == other_config.outer_wall_filament_id
|
||||
&& config.inner_wall_filament_id == other_config.inner_wall_filament_id
|
||||
&& config.wall_loops == other_config.wall_loops
|
||||
&& config.wall_sequence == other_config.wall_sequence
|
||||
&& config.is_infill_first == other_config.is_infill_first
|
||||
|
||||
@@ -1345,7 +1345,7 @@ static inline std::vector<std::vector<ExPolygons>> segmentation_top_and_bottom_l
|
||||
if (const PrintRegionConfig &config = region->region().config();
|
||||
// color_idx == 0 means "don't know" extruder aka the underlying extruder.
|
||||
// As this region may split existing regions, we collect statistics over all regions for color_idx == 0.
|
||||
color_idx == 0 || config.wall_filament == int(color_idx)) {
|
||||
color_idx == 0 || config.outer_wall_filament_id == int(color_idx)) {
|
||||
//BBS: the extrusion line width is outer wall rather than inner wall
|
||||
const double nozzle_diameter = print_object.print()->config().nozzle_diameter.get_at(0);
|
||||
double outer_wall_line_width = config.get_abs_value("outer_wall_line_width", nozzle_diameter);
|
||||
|
||||
@@ -620,7 +620,7 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP
|
||||
// get the real top surface
|
||||
ExPolygons grown_lower_slices;
|
||||
ExPolygons bridge_checker;
|
||||
auto nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->wall_filament - 1);
|
||||
auto nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->outer_wall_filament_id - 1);
|
||||
// Check whether surface be bridge or not
|
||||
if (this->lower_slices != NULL) {
|
||||
// BBS: get the Polygons below the polygon this layer
|
||||
@@ -1173,7 +1173,7 @@ void PerimeterGenerator::process_classic()
|
||||
// We consider overhang any part where the entire nozzle diameter is not supported by the
|
||||
// lower layer, so we take lower slices and offset them by half the nozzle diameter used
|
||||
// in the current layer
|
||||
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->wall_filament - 1);
|
||||
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->outer_wall_filament_id - 1);
|
||||
m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter / 2)));
|
||||
}
|
||||
|
||||
@@ -2114,7 +2114,7 @@ void PerimeterGenerator::process_arachne()
|
||||
// We consider overhang any part where the entire nozzle diameter is not supported by the
|
||||
// lower layer, so we take lower slices and offset them by half the nozzle diameter used
|
||||
// in the current layer
|
||||
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->wall_filament - 1);
|
||||
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->outer_wall_filament_id - 1);
|
||||
m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter / 2)));
|
||||
}
|
||||
|
||||
@@ -2547,7 +2547,7 @@ bool PerimeterGeneratorLoop::is_internal_contour() const
|
||||
|
||||
std::vector<Polygons> PerimeterGenerator::generate_lower_polygons_series(float width)
|
||||
{
|
||||
float nozzle_diameter = print_config->nozzle_diameter.get_at(config->wall_filament - 1);
|
||||
float nozzle_diameter = print_config->nozzle_diameter.get_at(config->outer_wall_filament_id - 1);
|
||||
float start_offset = -0.5 * width;
|
||||
float end_offset = 0.5 * nozzle_diameter;
|
||||
|
||||
|
||||
@@ -1072,10 +1072,13 @@ static std::vector<std::string> s_Preset_print_options{
|
||||
"print_order",
|
||||
"support_remove_small_overhang",
|
||||
"filename_format",
|
||||
"wall_filament",
|
||||
"outer_wall_filament_id",
|
||||
"inner_wall_filament_id",
|
||||
"support_bottom_z_distance",
|
||||
"sparse_infill_filament",
|
||||
"solid_infill_filament",
|
||||
"sparse_infill_filament_id",
|
||||
"internal_solid_filament_id",
|
||||
"top_surface_filament_id",
|
||||
"bottom_surface_filament_id",
|
||||
"support_filament",
|
||||
"support_interface_filament",
|
||||
"support_interface_not_for_body",
|
||||
|
||||
@@ -4103,7 +4103,10 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio
|
||||
opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_filaments));
|
||||
}
|
||||
|
||||
static const char* keys_with_default[] = {"wall_filament", "sparse_infill_filament", "solid_infill_filament"};
|
||||
static const char* keys_with_default[] = {
|
||||
"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id",
|
||||
"internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id"
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(keys_with_default) / sizeof(keys_with_default[0]); ++ i) {
|
||||
std::string key = std::string(keys_with_default[i]);
|
||||
auto *opt = dynamic_cast<ConfigOptionInt*>(out.option(key, false));
|
||||
|
||||
@@ -2021,7 +2021,7 @@ Flow Print::brim_flow() const
|
||||
frPerimeter,
|
||||
// Flow::new_from_config_width takes care of the percent to value substitution
|
||||
width,
|
||||
(float)m_config.nozzle_diameter.get_at(m_print_regions.front()->config().wall_filament-1),
|
||||
(float)m_config.nozzle_diameter.get_at(m_print_regions.front()->config().outer_wall_filament_id-1),
|
||||
(float)this->skirt_first_layer_height());
|
||||
}
|
||||
|
||||
|
||||
@@ -815,9 +815,12 @@ bool verify_update_print_object_regions(
|
||||
for (const PrintObjectRegions::PaintedRegion ®ion : layer_range.painted_regions) {
|
||||
const PrintObjectRegions::VolumeRegion &parent_region = layer_range.volume_regions[region.parent];
|
||||
PrintRegionConfig cfg = parent_region.region->config();
|
||||
cfg.wall_filament.value = region.extruder_id;
|
||||
cfg.solid_infill_filament.value = region.extruder_id;
|
||||
cfg.sparse_infill_filament.value = region.extruder_id;
|
||||
cfg.outer_wall_filament_id.value = region.extruder_id;
|
||||
cfg.inner_wall_filament_id.value = region.extruder_id;
|
||||
cfg.internal_solid_filament_id.value = region.extruder_id;
|
||||
cfg.top_surface_filament_id.value = region.extruder_id;
|
||||
cfg.bottom_surface_filament_id.value = region.extruder_id;
|
||||
cfg.sparse_infill_filament_id.value = region.extruder_id;
|
||||
if (cfg != region.region->config()) {
|
||||
// Region configuration changed.
|
||||
if (print_region_ref_cnt(*region.region) == 0) {
|
||||
@@ -1060,9 +1063,12 @@ static PrintObjectRegions* generate_print_object_regions(
|
||||
if (const PrintObjectRegions::VolumeRegion &parent_region = layer_range.volume_regions[parent_region_id];
|
||||
parent_region.model_volume->is_model_part() || parent_region.model_volume->is_modifier()) {
|
||||
PrintRegionConfig cfg = parent_region.region->config();
|
||||
cfg.wall_filament.value = painted_extruder_id;
|
||||
cfg.solid_infill_filament.value = painted_extruder_id;
|
||||
cfg.sparse_infill_filament.value = painted_extruder_id;
|
||||
cfg.outer_wall_filament_id.value = painted_extruder_id;
|
||||
cfg.inner_wall_filament_id.value = painted_extruder_id;
|
||||
cfg.internal_solid_filament_id.value = painted_extruder_id;
|
||||
cfg.top_surface_filament_id.value = painted_extruder_id;
|
||||
cfg.bottom_surface_filament_id.value = painted_extruder_id;
|
||||
cfg.sparse_infill_filament_id.value = painted_extruder_id;
|
||||
layer_range.painted_regions.push_back({ painted_extruder_id, parent_region_id, get_create_region(std::move(cfg))});
|
||||
}
|
||||
// Sort the regions by parent region::print_object_region_id() and extruder_id to help the slicing algorithm when applying MM segmentation.
|
||||
|
||||
+120
-29
@@ -4116,7 +4116,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->gui_type = ConfigOptionDef::GUIType::one_string;
|
||||
def->set_default_value(new ConfigOptionPoints());
|
||||
|
||||
def = this->add("sparse_infill_filament", coInt);
|
||||
def = this->add("sparse_infill_filament_id", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Infill");
|
||||
def->category = L("Extruders");
|
||||
@@ -4998,11 +4998,20 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
def = this->add("wall_filament", coInt);
|
||||
def = this->add("outer_wall_filament_id", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Walls");
|
||||
def->label = L("Outer walls");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print walls.\n\"Default\" uses the active object/part filament.");
|
||||
def->tooltip = L("Filament to print outer walls.\n\"Default\" uses the active object/part filament.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
|
||||
def = this->add("inner_wall_filament_id", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Inner walls");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print inner walls.\n\"Default\" uses the active object/part filament.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
@@ -5759,11 +5768,29 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(15));
|
||||
|
||||
def = this->add("solid_infill_filament", coInt);
|
||||
def = this->add("internal_solid_filament_id", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Solid infill");
|
||||
def->label = L("Internal solid infill");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print solid infill.\n\"Default\" uses the active object/part filament.");
|
||||
def->tooltip = L("Filament to print internal solid infill.\n\"Default\" uses the active object/part filament.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
|
||||
def = this->add("top_surface_filament_id", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Top surface");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print top surface.\n\"Default\" uses the active object/part filament.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
|
||||
def = this->add("bottom_surface_filament_id", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Bottom surface");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print bottom surface.\n\"Default\" uses the active object/part filament.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
@@ -7995,12 +8022,34 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
||||
opt_key = "change_filament_gcode";
|
||||
} else if (opt_key == "bridge_fan_speed") {
|
||||
opt_key = "overhang_fan_speed";
|
||||
} else if (opt_key == "infill_extruder") {
|
||||
opt_key = "sparse_infill_filament";
|
||||
}else if (opt_key == "solid_infill_extruder") {
|
||||
opt_key = "solid_infill_filament";
|
||||
}else if (opt_key == "perimeter_extruder") {
|
||||
opt_key = "wall_filament";
|
||||
} else if (opt_key == "infill_extruder" || opt_key == "sparse_infill_filament") {
|
||||
// ORCA: legacy feature-filament selector. Pre-2.4.0-dev these keys were 1-based and the
|
||||
// default value "1" meant "the first/active filament". The current scheme uses a dedicated
|
||||
// key where 0 = "Default" (inherit the object/part filament) and 1..N = explicit filament.
|
||||
// Renaming to the new *_id key here means every config (process presets, 3mf project
|
||||
// settings, imported gcode) is translated uniformly on load - not just the version-gated
|
||||
// 3mf paths the old bespoke migration covered - and a brand-new key can never be misread as
|
||||
// a legacy default. Map the legacy default "1" to "0" (inherit); keep explicit values >1.
|
||||
opt_key = "sparse_infill_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
} else if (opt_key == "solid_infill_extruder" || opt_key == "solid_infill_filament") {
|
||||
opt_key = "internal_solid_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
} else if (opt_key == "top_solid_infill_filament") {
|
||||
opt_key = "top_surface_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
} else if (opt_key == "bottom_solid_infill_filament") {
|
||||
opt_key = "bottom_surface_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
} else if (opt_key == "perimeter_extruder" || opt_key == "wall_filament" || opt_key == "wall_filament_id") {
|
||||
opt_key = "outer_wall_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
} else if (opt_key == "inner_wall_filament") {
|
||||
opt_key = "inner_wall_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
} else if (opt_key == "outer_wall_filament") {
|
||||
opt_key = "outer_wall_filament_id";
|
||||
if (value == "1") value = "0";
|
||||
}else if(opt_key == "wipe_tower_extruder") {
|
||||
opt_key = "wipe_tower_filament";
|
||||
}else if (opt_key == "support_material_extruder") {
|
||||
@@ -8449,10 +8498,18 @@ void DynamicPrintConfig::normalize_fdm(int used_filaments)
|
||||
int extruder = this->option("extruder")->getInt();
|
||||
this->erase("extruder");
|
||||
if (extruder != 0) {
|
||||
if (!this->has("sparse_infill_filament") || this->option("sparse_infill_filament")->getInt() == 0)
|
||||
this->option("sparse_infill_filament", true)->setInt(extruder);
|
||||
if (!this->has("wall_filament") || this->option("wall_filament")->getInt() == 0)
|
||||
this->option("wall_filament", true)->setInt(extruder);
|
||||
if (!this->has("sparse_infill_filament_id") || this->option("sparse_infill_filament_id")->getInt() == 0)
|
||||
this->option("sparse_infill_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("outer_wall_filament_id") || this->option("outer_wall_filament_id")->getInt() == 0)
|
||||
this->option("outer_wall_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("inner_wall_filament_id") || this->option("inner_wall_filament_id")->getInt() == 0)
|
||||
this->option("inner_wall_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("internal_solid_filament_id") || this->option("internal_solid_filament_id")->getInt() == 0)
|
||||
this->option("internal_solid_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("top_surface_filament_id") || this->option("top_surface_filament_id")->getInt() == 0)
|
||||
this->option("top_surface_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("bottom_surface_filament_id") || this->option("bottom_surface_filament_id")->getInt() == 0)
|
||||
this->option("bottom_surface_filament_id", true)->setInt(extruder);
|
||||
// Don't propagate the current extruder to support.
|
||||
// For non-soluble supports, the default "0" extruder means to use the active extruder,
|
||||
// for soluble supports one certainly does not want to set the extruder to non-soluble.
|
||||
@@ -8463,12 +8520,25 @@ void DynamicPrintConfig::normalize_fdm(int used_filaments)
|
||||
}
|
||||
}
|
||||
|
||||
if (this->has("sparse_infill_filament")) {
|
||||
int sparse_infill_filament = this->option("sparse_infill_filament")->getInt();
|
||||
if (sparse_infill_filament > 0 && (!this->has("solid_infill_filament") || this->option("solid_infill_filament")->getInt() == 0))
|
||||
this->option("solid_infill_filament", true)->setInt(sparse_infill_filament);
|
||||
if (this->has("sparse_infill_filament_id")) {
|
||||
int sparse_infill_filament_id = this->option("sparse_infill_filament_id")->getInt();
|
||||
if (sparse_infill_filament_id > 0 && (!this->has("internal_solid_filament_id") || this->option("internal_solid_filament_id")->getInt() == 0))
|
||||
this->option("internal_solid_filament_id", true)->setInt(sparse_infill_filament_id);
|
||||
}
|
||||
|
||||
const int internal_solid = this->has("internal_solid_filament_id") ? this->option("internal_solid_filament_id")->getInt() : 0;
|
||||
const int top_surface = this->has("top_surface_filament_id") ? this->option("top_surface_filament_id")->getInt() : 0;
|
||||
const int bottom_surface = this->has("bottom_surface_filament_id") ? this->option("bottom_surface_filament_id")->getInt() : 0;
|
||||
|
||||
if (internal_solid == 0 && top_surface > 0)
|
||||
this->option("internal_solid_filament_id", true)->setInt(top_surface);
|
||||
if (internal_solid == 0 && bottom_surface > 0)
|
||||
this->option("internal_solid_filament_id", true)->setInt(bottom_surface);
|
||||
if (top_surface == 0 && internal_solid > 0)
|
||||
this->option("top_surface_filament_id", true)->setInt(internal_solid);
|
||||
if (bottom_surface == 0 && internal_solid > 0)
|
||||
this->option("bottom_surface_filament_id", true)->setInt(internal_solid);
|
||||
|
||||
if (this->has("spiral_mode") && this->opt<ConfigOptionBool>("spiral_mode", true)->value) {
|
||||
{
|
||||
// this should be actually done only on the spiral layers instead of all
|
||||
@@ -8525,10 +8595,18 @@ void DynamicPrintConfig::normalize_fdm_1()
|
||||
int extruder = this->option("extruder")->getInt();
|
||||
this->erase("extruder");
|
||||
if (extruder != 0) {
|
||||
if (!this->has("sparse_infill_filament") || this->option("sparse_infill_filament")->getInt() == 0)
|
||||
this->option("sparse_infill_filament", true)->setInt(extruder);
|
||||
if (!this->has("wall_filament") || this->option("wall_filament")->getInt() == 0)
|
||||
this->option("wall_filament", true)->setInt(extruder);
|
||||
if (!this->has("sparse_infill_filament_id") || this->option("sparse_infill_filament_id")->getInt() == 0)
|
||||
this->option("sparse_infill_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("outer_wall_filament_id") || this->option("outer_wall_filament_id")->getInt() == 0)
|
||||
this->option("outer_wall_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("inner_wall_filament_id") || this->option("inner_wall_filament_id")->getInt() == 0)
|
||||
this->option("inner_wall_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("internal_solid_filament_id") || this->option("internal_solid_filament_id")->getInt() == 0)
|
||||
this->option("internal_solid_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("top_surface_filament_id") || this->option("top_surface_filament_id")->getInt() == 0)
|
||||
this->option("top_surface_filament_id", true)->setInt(extruder);
|
||||
if (!this->has("bottom_surface_filament_id") || this->option("bottom_surface_filament_id")->getInt() == 0)
|
||||
this->option("bottom_surface_filament_id", true)->setInt(extruder);
|
||||
// Don't propagate the current extruder to support.
|
||||
// For non-soluble supports, the default "0" extruder means to use the active extruder,
|
||||
// for soluble supports one certainly does not want to set the extruder to non-soluble.
|
||||
@@ -8539,12 +8617,25 @@ void DynamicPrintConfig::normalize_fdm_1()
|
||||
}
|
||||
}
|
||||
|
||||
if (this->has("sparse_infill_filament")) {
|
||||
int sparse_infill_filament = this->option("sparse_infill_filament")->getInt();
|
||||
if (sparse_infill_filament > 0 && (!this->has("solid_infill_filament") || this->option("solid_infill_filament")->getInt() == 0))
|
||||
this->option("solid_infill_filament", true)->setInt(sparse_infill_filament);
|
||||
if (this->has("sparse_infill_filament_id")) {
|
||||
int sparse_infill_filament_id = this->option("sparse_infill_filament_id")->getInt();
|
||||
if (sparse_infill_filament_id > 0 && (!this->has("internal_solid_filament_id") || this->option("internal_solid_filament_id")->getInt() == 0))
|
||||
this->option("internal_solid_filament_id", true)->setInt(sparse_infill_filament_id);
|
||||
}
|
||||
|
||||
const int internal_solid = this->has("internal_solid_filament_id") ? this->option("internal_solid_filament_id")->getInt() : 0;
|
||||
const int top_surface = this->has("top_surface_filament_id") ? this->option("top_surface_filament_id")->getInt() : 0;
|
||||
const int bottom_surface = this->has("bottom_surface_filament_id") ? this->option("bottom_surface_filament_id")->getInt() : 0;
|
||||
|
||||
if (internal_solid == 0 && top_surface > 0)
|
||||
this->option("internal_solid_filament_id", true)->setInt(top_surface);
|
||||
if (internal_solid == 0 && bottom_surface > 0)
|
||||
this->option("internal_solid_filament_id", true)->setInt(bottom_surface);
|
||||
if (top_surface == 0 && internal_solid > 0)
|
||||
this->option("top_surface_filament_id", true)->setInt(internal_solid);
|
||||
if (bottom_surface == 0 && internal_solid > 0)
|
||||
this->option("bottom_surface_filament_id", true)->setInt(internal_solid);
|
||||
|
||||
if (this->has("spiral_mode") && this->opt<ConfigOptionBool>("spiral_mode", true)->value) {
|
||||
{
|
||||
// this should be actually done only on the spiral layers instead of all
|
||||
|
||||
@@ -1123,7 +1123,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionPercent, fuzzy_skin_ripple_offset))
|
||||
((ConfigOptionInt, fuzzy_skin_layers_between_ripple_offset))
|
||||
((ConfigOptionFloat, gap_infill_speed))
|
||||
((ConfigOptionInt, sparse_infill_filament))
|
||||
((ConfigOptionInt, sparse_infill_filament_id))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_line_width))
|
||||
((ConfigOptionPercent, infill_wall_overlap))
|
||||
((ConfigOptionPercent, top_bottom_infill_wall_overlap))
|
||||
@@ -1156,14 +1156,17 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloatsNullable, filament_ironing_speed))
|
||||
// Detect bridging perimeters
|
||||
((ConfigOptionBool, detect_overhang_wall))
|
||||
((ConfigOptionInt, wall_filament))
|
||||
((ConfigOptionInt, outer_wall_filament_id))
|
||||
((ConfigOptionInt, inner_wall_filament_id))
|
||||
((ConfigOptionFloatOrPercent, inner_wall_line_width))
|
||||
((ConfigOptionFloat, inner_wall_speed))
|
||||
// Total number of perimeters.
|
||||
((ConfigOptionInt, wall_loops))
|
||||
((ConfigOptionBool, alternate_extra_wall))
|
||||
((ConfigOptionFloat, minimum_sparse_infill_area))
|
||||
((ConfigOptionInt, solid_infill_filament))
|
||||
((ConfigOptionInt, internal_solid_filament_id))
|
||||
((ConfigOptionInt, top_surface_filament_id))
|
||||
((ConfigOptionInt, bottom_surface_filament_id))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_line_width))
|
||||
((ConfigOptionFloat, internal_solid_infill_speed))
|
||||
// Detect thin walls.
|
||||
|
||||
+130
-61
@@ -232,7 +232,7 @@ void PrintObject::_transform_hole_to_polyholes()
|
||||
bool twist = this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_twisted.value;
|
||||
if (diameter_max - diameter_min < max_variation * 2 && diameter_line_max - diameter_line_min < max_variation * 2) {
|
||||
layerid2center[layer_idx].emplace_back(
|
||||
std::tuple<Point, float, int, coord_t, bool>{center, diameter_max, layer->m_regions[region_idx]->region().config().wall_filament.value, max_variation, twist}, & hole);
|
||||
std::tuple<Point, float, int, coord_t, bool>{center, diameter_max, layer->m_regions[region_idx]->region().config().outer_wall_filament_id.value, max_variation, twist}, & hole);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,18 +316,29 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
continue;
|
||||
for (auto layerm : layer->regions()) {
|
||||
auto region = layerm->region();
|
||||
int wall_filament = region.config().wall_filament;
|
||||
int solid_infill_filament = region.config().solid_infill_filament;
|
||||
int sparse_infill_filament = region.config().sparse_infill_filament;
|
||||
int outer_wall_filament_id = region.config().outer_wall_filament_id;
|
||||
int inner_wall_filament_id = region.config().inner_wall_filament_id;
|
||||
int internal_solid_filament_id = region.config().internal_solid_filament_id;
|
||||
int top_surface_filament_id = region.config().top_surface_filament_id;
|
||||
int bottom_surface_filament_id = region.config().bottom_surface_filament_id;
|
||||
int sparse_infill_filament_id = region.config().sparse_infill_filament_id;
|
||||
|
||||
if (!layerm->fills.entities.empty()) {
|
||||
if (solid_infill_filament > 0)
|
||||
geometric_unprintables[extruder_id].insert(solid_infill_filament - 1);
|
||||
if (sparse_infill_filament > 0)
|
||||
geometric_unprintables[extruder_id].insert(sparse_infill_filament - 1);
|
||||
if (internal_solid_filament_id > 0)
|
||||
geometric_unprintables[extruder_id].insert(internal_solid_filament_id - 1);
|
||||
if (top_surface_filament_id > 0)
|
||||
geometric_unprintables[extruder_id].insert(top_surface_filament_id - 1);
|
||||
if (bottom_surface_filament_id > 0)
|
||||
geometric_unprintables[extruder_id].insert(bottom_surface_filament_id - 1);
|
||||
if (sparse_infill_filament_id > 0)
|
||||
geometric_unprintables[extruder_id].insert(sparse_infill_filament_id - 1);
|
||||
}
|
||||
if (!layerm->perimeters.entities.empty()) {
|
||||
if (outer_wall_filament_id > 0)
|
||||
geometric_unprintables[extruder_id].insert(outer_wall_filament_id - 1);
|
||||
if (inner_wall_filament_id > 0)
|
||||
geometric_unprintables[extruder_id].insert(inner_wall_filament_id - 1);
|
||||
}
|
||||
if (!layerm->perimeters.entities.empty() && wall_filament > 0)
|
||||
geometric_unprintables[extruder_id].insert(wall_filament - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,21 +363,28 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
auto layer = m_layers[j];
|
||||
for (auto layerm : layer->regions()) {
|
||||
const auto& region = layerm->region();
|
||||
int wall_filament = region.config().wall_filament;
|
||||
int solid_infill_filament = region.config().solid_infill_filament;
|
||||
int sparse_infill_filament = region.config().sparse_infill_filament;
|
||||
int outer_wall_filament_id = region.config().outer_wall_filament_id;
|
||||
int inner_wall_filament_id = region.config().inner_wall_filament_id;
|
||||
int internal_solid_filament_id = region.config().internal_solid_filament_id;
|
||||
int top_surface_filament_id = region.config().top_surface_filament_id;
|
||||
int bottom_surface_filament_id = region.config().bottom_surface_filament_id;
|
||||
int sparse_infill_filament_id = region.config().sparse_infill_filament_id;
|
||||
std::optional<ExPolygons> fill_expolys;
|
||||
BoundingBox fill_bbox;
|
||||
std::optional<ExPolygons> wall_expolys;
|
||||
BoundingBox wall_bbox;
|
||||
|
||||
for (size_t idx = 0; idx < unprintable_area_in_obj_coord.size(); ++idx) {
|
||||
bool do_infill_filament_detect = (solid_infill_filament > 0 && tbb_geometric_unprintables[idx].count(solid_infill_filament - 1) == 0) ||
|
||||
(sparse_infill_filament > 0 && tbb_geometric_unprintables[idx].count(sparse_infill_filament-1) == 0);
|
||||
bool do_infill_filament_detect = (internal_solid_filament_id > 0 && tbb_geometric_unprintables[idx].count(internal_solid_filament_id - 1) == 0) ||
|
||||
(top_surface_filament_id > 0 && tbb_geometric_unprintables[idx].count(top_surface_filament_id - 1) == 0) ||
|
||||
(bottom_surface_filament_id > 0 && tbb_geometric_unprintables[idx].count(bottom_surface_filament_id - 1) == 0) ||
|
||||
(sparse_infill_filament_id > 0 && tbb_geometric_unprintables[idx].count(sparse_infill_filament_id-1) == 0);
|
||||
|
||||
bool infill_unprintable = !layerm->fills.entities.empty() &&
|
||||
((solid_infill_filament > 0 && tbb_geometric_unprintables[idx].count(solid_infill_filament - 1) > 0) ||
|
||||
(sparse_infill_filament > 0 && tbb_geometric_unprintables[idx].count(sparse_infill_filament - 1) > 0));
|
||||
((internal_solid_filament_id > 0 && tbb_geometric_unprintables[idx].count(internal_solid_filament_id - 1) > 0) ||
|
||||
(top_surface_filament_id > 0 && tbb_geometric_unprintables[idx].count(top_surface_filament_id - 1) > 0) ||
|
||||
(bottom_surface_filament_id > 0 && tbb_geometric_unprintables[idx].count(bottom_surface_filament_id - 1) > 0) ||
|
||||
(sparse_infill_filament_id > 0 && tbb_geometric_unprintables[idx].count(sparse_infill_filament_id - 1) > 0));
|
||||
|
||||
if (!layerm->fills.entities.empty() && do_infill_filament_detect) {
|
||||
if (!fill_expolys) {
|
||||
@@ -375,19 +393,27 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
}
|
||||
if (fill_bbox.overlap(unprintable_area_bbox[idx]) &&
|
||||
!intersection(*fill_expolys, unprintable_area_in_obj_coord[idx]).empty()) {
|
||||
if (solid_infill_filament > 0)
|
||||
tbb_geometric_unprintables[idx].insert(solid_infill_filament - 1);
|
||||
if (sparse_infill_filament > 0)
|
||||
tbb_geometric_unprintables[idx].insert(sparse_infill_filament - 1);
|
||||
if (internal_solid_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(internal_solid_filament_id - 1);
|
||||
if (top_surface_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(top_surface_filament_id - 1);
|
||||
if (bottom_surface_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(bottom_surface_filament_id - 1);
|
||||
if (sparse_infill_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(sparse_infill_filament_id - 1);
|
||||
infill_unprintable = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool do_wall_filament_detect = wall_filament > 0 && tbb_geometric_unprintables[idx].count(wall_filament - 1) == 0;
|
||||
if (!layerm->perimeters.entities.empty() && do_wall_filament_detect) {
|
||||
bool do_outer_wall_filament_detect = outer_wall_filament_id > 0 && tbb_geometric_unprintables[idx].count(outer_wall_filament_id - 1) == 0;
|
||||
bool do_inner_wall_filament_detect = inner_wall_filament_id > 0 && tbb_geometric_unprintables[idx].count(inner_wall_filament_id - 1) == 0;
|
||||
if (!layerm->perimeters.entities.empty() && (do_outer_wall_filament_detect || do_inner_wall_filament_detect)) {
|
||||
// if infill is unprintable, no need to check wall since wall contour surrounds infill contour
|
||||
if (infill_unprintable) {
|
||||
tbb_geometric_unprintables[idx].insert(wall_filament - 1);
|
||||
if (outer_wall_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(outer_wall_filament_id - 1);
|
||||
if (inner_wall_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(inner_wall_filament_id - 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -402,7 +428,10 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
|
||||
if (wall_bbox.overlap(unprintable_area_bbox[idx]) &&
|
||||
!intersection(*wall_expolys, unprintable_area_in_obj_coord[idx]).empty()) {
|
||||
tbb_geometric_unprintables[idx].insert(wall_filament - 1);
|
||||
if (outer_wall_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(outer_wall_filament_id - 1);
|
||||
if (inner_wall_filament_id > 0)
|
||||
tbb_geometric_unprintables[idx].insert(inner_wall_filament_id - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1263,8 +1292,10 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "bottom_shell_thickness"
|
||||
|| opt_key == "top_shell_thickness"
|
||||
|| opt_key == "minimum_sparse_infill_area"
|
||||
|| opt_key == "sparse_infill_filament"
|
||||
|| opt_key == "solid_infill_filament"
|
||||
|| opt_key == "sparse_infill_filament_id"
|
||||
|| opt_key == "internal_solid_filament_id"
|
||||
|| opt_key == "top_surface_filament_id"
|
||||
|| opt_key == "bottom_surface_filament_id"
|
||||
|| opt_key == "sparse_infill_line_width"
|
||||
|| opt_key == "skin_infill_line_width"
|
||||
|| opt_key == "skeleton_infill_line_width"
|
||||
@@ -1327,7 +1358,8 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
steps.emplace_back(posPrepareInfill);
|
||||
} else if (
|
||||
opt_key == "outer_wall_line_width"
|
||||
|| opt_key == "wall_filament"
|
||||
|| opt_key == "outer_wall_filament_id"
|
||||
|| opt_key == "inner_wall_filament_id"
|
||||
|| opt_key == "fuzzy_skin"
|
||||
|| opt_key == "fuzzy_skin_thickness"
|
||||
|| opt_key == "fuzzy_skin_point_distance"
|
||||
@@ -3548,13 +3580,23 @@ PrintObjectConfig PrintObject::object_config_from_model_object(const PrintObject
|
||||
}
|
||||
|
||||
const std::string key_extruder { "extruder" };
|
||||
static constexpr const std::initializer_list<const std::string_view> keys_extruders { "sparse_infill_filament"sv, "solid_infill_filament"sv, "wall_filament"sv };
|
||||
static constexpr const std::initializer_list<const std::string_view> keys_extruders {
|
||||
"sparse_infill_filament_id"sv,
|
||||
"internal_solid_filament_id"sv,
|
||||
"top_surface_filament_id"sv,
|
||||
"bottom_surface_filament_id"sv,
|
||||
"outer_wall_filament_id"sv,
|
||||
"inner_wall_filament_id"sv
|
||||
};
|
||||
|
||||
struct FeatureFilamentOverrideMask
|
||||
{
|
||||
bool sparse_infill_filament = false;
|
||||
bool solid_infill_filament = false;
|
||||
bool wall_filament = false;
|
||||
bool sparse_infill_filament_id = false;
|
||||
bool internal_solid_filament_id = false;
|
||||
bool top_surface_filament_id = false;
|
||||
bool bottom_surface_filament_id = false;
|
||||
bool outer_wall_filament_id = false;
|
||||
bool inner_wall_filament_id = false;
|
||||
};
|
||||
|
||||
static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPrintConfig &in, FeatureFilamentOverrideMask &feature_overrides)
|
||||
@@ -3572,19 +3614,31 @@ static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPr
|
||||
int extruder = static_cast<const ConfigOptionInt*>(it->second.get())->value;
|
||||
if (extruder > 0) {
|
||||
my_opt->setInt(extruder);
|
||||
if (it->first == "sparse_infill_filament")
|
||||
feature_overrides.sparse_infill_filament = true;
|
||||
else if (it->first == "solid_infill_filament")
|
||||
feature_overrides.solid_infill_filament = true;
|
||||
else if (it->first == "wall_filament")
|
||||
feature_overrides.wall_filament = true;
|
||||
if (it->first == "sparse_infill_filament_id")
|
||||
feature_overrides.sparse_infill_filament_id = true;
|
||||
else if (it->first == "internal_solid_filament_id")
|
||||
feature_overrides.internal_solid_filament_id = true;
|
||||
else if (it->first == "top_surface_filament_id")
|
||||
feature_overrides.top_surface_filament_id = true;
|
||||
else if (it->first == "bottom_surface_filament_id")
|
||||
feature_overrides.bottom_surface_filament_id = true;
|
||||
else if (it->first == "outer_wall_filament_id")
|
||||
feature_overrides.outer_wall_filament_id = true;
|
||||
else if (it->first == "inner_wall_filament_id")
|
||||
feature_overrides.inner_wall_filament_id = true;
|
||||
} else {
|
||||
if (it->first == "sparse_infill_filament")
|
||||
feature_overrides.sparse_infill_filament = false;
|
||||
else if (it->first == "solid_infill_filament")
|
||||
feature_overrides.solid_infill_filament = false;
|
||||
else if (it->first == "wall_filament")
|
||||
feature_overrides.wall_filament = false;
|
||||
if (it->first == "sparse_infill_filament_id")
|
||||
feature_overrides.sparse_infill_filament_id = false;
|
||||
else if (it->first == "internal_solid_filament_id")
|
||||
feature_overrides.internal_solid_filament_id = false;
|
||||
else if (it->first == "top_surface_filament_id")
|
||||
feature_overrides.top_surface_filament_id = false;
|
||||
else if (it->first == "bottom_surface_filament_id")
|
||||
feature_overrides.bottom_surface_filament_id = false;
|
||||
else if (it->first == "outer_wall_filament_id")
|
||||
feature_overrides.outer_wall_filament_id = false;
|
||||
else if (it->first == "inner_wall_filament_id")
|
||||
feature_overrides.inner_wall_filament_id = false;
|
||||
}
|
||||
} else
|
||||
my_opt->set(it->second.get());
|
||||
@@ -3592,12 +3646,18 @@ static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPr
|
||||
|
||||
// 3) Apply base extruder only to features that were not explicitly overridden.
|
||||
if (base_extruder > 0) {
|
||||
if (!feature_overrides.sparse_infill_filament)
|
||||
out.sparse_infill_filament.value = base_extruder;
|
||||
if (!feature_overrides.solid_infill_filament)
|
||||
out.solid_infill_filament.value = base_extruder;
|
||||
if (!feature_overrides.wall_filament)
|
||||
out.wall_filament.value = base_extruder;
|
||||
if (!feature_overrides.sparse_infill_filament_id)
|
||||
out.sparse_infill_filament_id.value = base_extruder;
|
||||
if (!feature_overrides.internal_solid_filament_id)
|
||||
out.internal_solid_filament_id.value = base_extruder;
|
||||
if (!feature_overrides.top_surface_filament_id)
|
||||
out.top_surface_filament_id.value = base_extruder;
|
||||
if (!feature_overrides.bottom_surface_filament_id)
|
||||
out.bottom_surface_filament_id.value = base_extruder;
|
||||
if (!feature_overrides.outer_wall_filament_id)
|
||||
out.outer_wall_filament_id.value = base_extruder;
|
||||
if (!feature_overrides.inner_wall_filament_id)
|
||||
out.inner_wall_filament_id.value = base_extruder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3608,9 +3668,12 @@ PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &defau
|
||||
|
||||
// For model parts, non-zero values coming from the print defaults should stay explicit.
|
||||
if (volume.is_model_part()) {
|
||||
feature_overrides.sparse_infill_filament = (config.sparse_infill_filament.value > 0);
|
||||
feature_overrides.solid_infill_filament = (config.solid_infill_filament.value > 0);
|
||||
feature_overrides.wall_filament = (config.wall_filament.value > 0);
|
||||
feature_overrides.sparse_infill_filament_id = (config.sparse_infill_filament_id.value > 0);
|
||||
feature_overrides.internal_solid_filament_id = (config.internal_solid_filament_id.value > 0);
|
||||
feature_overrides.top_surface_filament_id = (config.top_surface_filament_id.value > 0);
|
||||
feature_overrides.bottom_surface_filament_id = (config.bottom_surface_filament_id.value > 0);
|
||||
feature_overrides.outer_wall_filament_id = (config.outer_wall_filament_id.value > 0);
|
||||
feature_overrides.inner_wall_filament_id = (config.inner_wall_filament_id.value > 0);
|
||||
}
|
||||
|
||||
if (volume.is_model_part()) {
|
||||
@@ -3629,9 +3692,12 @@ PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &defau
|
||||
apply_to_print_region_config(config, *layer_range_config, feature_overrides);
|
||||
}
|
||||
// Resolve feature defaults and clamp invalid extruders to index 1.
|
||||
clamp_feature_filament_to_valid(config.sparse_infill_filament, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.wall_filament, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.solid_infill_filament, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.sparse_infill_filament_id, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.outer_wall_filament_id, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.inner_wall_filament_id, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.internal_solid_filament_id, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.top_surface_filament_id, num_extruders);
|
||||
clamp_feature_filament_to_valid(config.bottom_surface_filament_id, num_extruders);
|
||||
if (config.sparse_infill_density.value < 0.00011f)
|
||||
// Switch of infill for very low infill rates, also avoid division by zero in infill generator for these very low rates.
|
||||
// See GH issue #5910.
|
||||
@@ -3694,9 +3760,12 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full
|
||||
object_config.brim_type != btNoBrim && object_config.brim_width > 0.,
|
||||
object_extruders);
|
||||
for (const std::pair<const t_layer_height_range, ModelConfig> &range_and_config : model_object.layer_config_ranges)
|
||||
if (range_and_config.second.has("wall_filament") ||
|
||||
range_and_config.second.has("sparse_infill_filament") ||
|
||||
range_and_config.second.has("solid_infill_filament"))
|
||||
if (range_and_config.second.has("outer_wall_filament_id") ||
|
||||
range_and_config.second.has("inner_wall_filament_id") ||
|
||||
range_and_config.second.has("sparse_infill_filament_id") ||
|
||||
range_and_config.second.has("internal_solid_filament_id") ||
|
||||
range_and_config.second.has("top_surface_filament_id") ||
|
||||
range_and_config.second.has("bottom_surface_filament_id"))
|
||||
PrintRegion::collect_object_printing_extruders(
|
||||
print_config,
|
||||
region_config_from_model_volume(default_region_config, &range_and_config.second.get(), *model_volume, filament_extruders),
|
||||
@@ -4113,8 +4182,8 @@ void PrintObject::combine_infill()
|
||||
// Limit the number of combined layers to the maximum height allowed by this regions' nozzle.
|
||||
//FIXME limit the layer height to max_layer_height
|
||||
double nozzle_diameter = std::min(
|
||||
this->print()->config().nozzle_diameter.get_at(region.config().sparse_infill_filament.value - 1),
|
||||
this->print()->config().nozzle_diameter.get_at(region.config().solid_infill_filament.value - 1));
|
||||
this->print()->config().nozzle_diameter.get_at(region.config().sparse_infill_filament_id.value - 1),
|
||||
this->print()->config().nozzle_diameter.get_at(region.config().internal_solid_filament_id.value - 1));
|
||||
|
||||
//Orca: Limit combination of infill to up to infill_combination_max_layer_height
|
||||
const double infill_combination_max_layer_height = region.config().infill_combination_max_layer_height.get_abs_value(nozzle_diameter);
|
||||
|
||||
@@ -7,12 +7,16 @@ namespace Slic3r {
|
||||
unsigned int PrintRegion::extruder(FlowRole role) const
|
||||
{
|
||||
size_t extruder = 0;
|
||||
if (role == frPerimeter || role == frExternalPerimeter)
|
||||
extruder = m_config.wall_filament;
|
||||
if (role == frPerimeter)
|
||||
extruder = m_config.inner_wall_filament_id;
|
||||
else if (role == frExternalPerimeter)
|
||||
extruder = m_config.outer_wall_filament_id;
|
||||
else if (role == frInfill)
|
||||
extruder = m_config.sparse_infill_filament;
|
||||
else if (role == frSolidInfill || role == frTopSolidInfill)
|
||||
extruder = m_config.solid_infill_filament;
|
||||
extruder = m_config.sparse_infill_filament_id;
|
||||
else if (role == frSolidInfill)
|
||||
extruder = m_config.internal_solid_filament_id;
|
||||
else if (role == frTopSolidInfill)
|
||||
extruder = m_config.top_surface_filament_id;
|
||||
else
|
||||
throw Slic3r::InvalidArgument("Unknown role");
|
||||
return extruder;
|
||||
@@ -51,9 +55,12 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he
|
||||
|
||||
coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
|
||||
{
|
||||
return (print_config.nozzle_diameter.get_at(m_config.wall_filament.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.sparse_infill_filament.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.solid_infill_filament.value - 1)) / 3.;
|
||||
return (print_config.nozzle_diameter.get_at(m_config.outer_wall_filament_id.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.inner_wall_filament_id.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.sparse_infill_filament_id.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.internal_solid_filament_id.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.top_surface_filament_id.value - 1) +
|
||||
print_config.nozzle_diameter.get_at(m_config.bottom_surface_filament_id.value - 1)) / 6.;
|
||||
}
|
||||
|
||||
coordf_t PrintRegion::bridging_height_avg(const PrintConfig &print_config) const
|
||||
@@ -70,12 +77,19 @@ void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_con
|
||||
int i = std::max(0, extruder_id - 1);
|
||||
object_extruders.emplace_back((i >= num_extruders) ? 0 : i);
|
||||
};
|
||||
if (region_config.wall_loops.value > 0 || has_brim)
|
||||
emplace_extruder(region_config.wall_filament);
|
||||
if (region_config.wall_loops.value > 0 || has_brim) {
|
||||
emplace_extruder(region_config.outer_wall_filament_id);
|
||||
if (region_config.wall_loops.value > 1)
|
||||
emplace_extruder(region_config.inner_wall_filament_id);
|
||||
}
|
||||
if (region_config.sparse_infill_density.value > 0)
|
||||
emplace_extruder(region_config.sparse_infill_filament);
|
||||
if (region_config.top_shell_layers.value > 0 || region_config.bottom_shell_layers.value > 0)
|
||||
emplace_extruder(region_config.solid_infill_filament);
|
||||
emplace_extruder(region_config.sparse_infill_filament_id);
|
||||
if (region_config.sparse_infill_density.value > 0 || region_config.top_shell_layers.value > 0 || region_config.bottom_shell_layers.value > 0)
|
||||
emplace_extruder(region_config.internal_solid_filament_id);
|
||||
if (region_config.top_shell_layers.value > 0)
|
||||
emplace_extruder(region_config.top_surface_filament_id);
|
||||
if (region_config.bottom_shell_layers.value > 0)
|
||||
emplace_extruder(region_config.bottom_surface_filament_id);
|
||||
}
|
||||
|
||||
void PrintRegion::collect_object_printing_extruders(const Print &print, std::vector<unsigned int> &object_extruders) const
|
||||
@@ -85,9 +99,12 @@ void PrintRegion::collect_object_printing_extruders(const Print &print, std::vec
|
||||
#ifndef NDEBUG
|
||||
// BBS
|
||||
auto num_extruders = int(print.config().filament_diameter.size());
|
||||
assert(this->config().wall_filament <= num_extruders);
|
||||
assert(this->config().sparse_infill_filament <= num_extruders);
|
||||
assert(this->config().solid_infill_filament <= num_extruders);
|
||||
assert(this->config().outer_wall_filament_id <= num_extruders);
|
||||
assert(this->config().inner_wall_filament_id <= num_extruders);
|
||||
assert(this->config().sparse_infill_filament_id <= num_extruders);
|
||||
assert(this->config().internal_solid_filament_id <= num_extruders);
|
||||
assert(this->config().top_surface_filament_id <= num_extruders);
|
||||
assert(this->config().bottom_surface_filament_id <= num_extruders);
|
||||
#endif
|
||||
collect_object_printing_extruders(print.config(), this->config(), print.has_brim(), object_extruders);
|
||||
}
|
||||
|
||||
@@ -1226,7 +1226,7 @@ namespace SupportMaterialInternal {
|
||||
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
|
||||
Polygons lower_grown_slices = expand(lower_layer_polygons,
|
||||
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
|
||||
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().wall_filament-1))),
|
||||
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().outer_wall_filament_id-1))),
|
||||
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
// Collect perimeters of this layer.
|
||||
//FIXME split_at_first_point() could split a bridge mid-way
|
||||
|
||||
@@ -998,10 +998,10 @@ float GLVolumeCollection::get_selection_support_normal_z() const
|
||||
} else { // For normal supports, if the angle is set to 0, calculate normal_z from overlap.
|
||||
const double layer_height = full_cfg.opt_float("layer_height");
|
||||
const auto* nozzle_diameter_opt = full_cfg.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
const int wall_filament = full_cfg.opt_int("wall_filament");
|
||||
const int wall_filament_id = full_cfg.opt_int("outer_wall_filament_id");
|
||||
const size_t nozzle_count = nozzle_diameter_opt->values.size();
|
||||
const size_t wall_extruder_idx = (wall_filament > 0 && wall_filament <= static_cast<int>(nozzle_count))
|
||||
? static_cast<size_t>(wall_filament - 1)
|
||||
const size_t wall_extruder_idx = (wall_filament_id > 0 && wall_filament_id <= static_cast<int>(nozzle_count))
|
||||
? static_cast<size_t>(wall_filament_id - 1)
|
||||
: 0; // Invalid extruder index falls back to extruder 1.
|
||||
|
||||
// Use wall extruder's nozzle diameter for better estimation of external perimeter width,
|
||||
|
||||
@@ -592,9 +592,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
toggle_field(el, have_perimeters);
|
||||
|
||||
bool have_infill = config->option<ConfigOptionPercent>("sparse_infill_density")->value > 0;
|
||||
// sparse_infill_filament uses the same logic as in Print::extruders()
|
||||
// sparse_infill_filament_id uses the same logic as in Print::extruders()
|
||||
for (auto el : { "sparse_infill_pattern", "infill_combination", "fill_multiline","infill_direction",
|
||||
"minimum_sparse_infill_area", "sparse_infill_filament", "infill_anchor", "infill_anchor_max","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"})
|
||||
"minimum_sparse_infill_area", "sparse_infill_filament_id", "infill_anchor", "infill_anchor_max","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"})
|
||||
toggle_line(el, have_infill);
|
||||
|
||||
bool have_combined_infill = config->opt_bool("infill_combination") && have_infill;
|
||||
@@ -656,7 +656,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
|
||||
for (auto el : { "infill_direction", "sparse_infill_line_width", "gap_fill_target","filter_out_gap_fill","infill_wall_overlap",
|
||||
"sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle", "internal_bridge_angle", "relative_bridge_angle",
|
||||
"solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "solid_infill_filament",
|
||||
"solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id",
|
||||
})
|
||||
toggle_field(el, have_infill || has_solid_infill);
|
||||
|
||||
@@ -711,8 +711,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
config->opt_enum<BrimType>("brim_type") != btPainted;
|
||||
toggle_field("brim_width", have_brim_width);
|
||||
toggle_field("brim_flow_ratio", have_brim);
|
||||
// wall_filament uses the same logic as in Print::extruders()
|
||||
toggle_field("wall_filament", have_perimeters || have_brim);
|
||||
// Wall filament selectors use the same logic as in Print::extruders().
|
||||
toggle_field("outer_wall_filament_id", have_perimeters || have_brim);
|
||||
toggle_field("inner_wall_filament_id", have_perimeters || have_brim);
|
||||
|
||||
bool have_brim_ear = (config->opt_enum<BrimType>("brim_type") == btEar);
|
||||
const auto brim_width = config->opt_float("brim_width");
|
||||
|
||||
@@ -705,7 +705,7 @@ static void convert_object_to_vertices(const Slic3r::PrintObject& object, const
|
||||
continue;
|
||||
const Slic3r::PrintRegionConfig& cfg = layerm->region().config();
|
||||
if (has_perimeters) {
|
||||
const size_t extruder_id = static_cast<size_t>(std::max(cfg.wall_filament.value - 1, 0));
|
||||
const size_t extruder_id = static_cast<size_t>(std::max(cfg.outer_wall_filament_id.value - 1, 0));
|
||||
convert_to_vertices(layerm->perimeters, layer_z, layer_id, extruder_id,
|
||||
object_helper.color_id(layer_z, extruder_id), EGCodeExtrusionRole::ExternalPerimeter,
|
||||
copy, data.vertices);
|
||||
@@ -715,10 +715,13 @@ static void convert_object_to_vertices(const Slic3r::PrintObject& object, const
|
||||
// fill represents infill extrusions of a single island.
|
||||
const auto& fill = *dynamic_cast<const Slic3r::ExtrusionEntityCollection*>(ee);
|
||||
if (!fill.entities.empty()) {
|
||||
const bool is_solid_infill = Slic3r::is_solid_infill(fill.entities.front()->role());
|
||||
const Slic3r::ExtrusionRole role = fill.entities.front()->role();
|
||||
const bool is_solid_infill = Slic3r::is_solid_infill(role);
|
||||
const size_t extruder_id = is_solid_infill ?
|
||||
static_cast<size_t>(std::max(cfg.solid_infill_filament.value - 1, 0)) :
|
||||
static_cast<size_t>(std::max(cfg.sparse_infill_filament.value - 1, 0));
|
||||
static_cast<size_t>(std::max((role == Slic3r::erTopSolidInfill || role == Slic3r::erIroning ? cfg.top_surface_filament_id.value :
|
||||
role == Slic3r::erBottomSurface ? cfg.bottom_surface_filament_id.value :
|
||||
cfg.internal_solid_filament_id.value) - 1, 0)) :
|
||||
static_cast<size_t>(std::max(cfg.sparse_infill_filament_id.value - 1, 0));
|
||||
convert_to_vertices(fill, layer_z, layer_id, extruder_id,
|
||||
object_helper.color_id(layer_z, extruder_id),
|
||||
is_solid_infill ? EGCodeExtrusionRole::SolidInfill : EGCodeExtrusionRole::InternalInfill,
|
||||
|
||||
+118
-40
@@ -1517,9 +1517,16 @@ std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode) const
|
||||
const DynamicPrintConfig& glb_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
int glb_support_intf_extr = glb_config.opt_int("support_interface_filament");
|
||||
int glb_support_extr = glb_config.opt_int("support_filament");
|
||||
int glb_wall_extr = glb_config.opt_int("wall_filament");
|
||||
int glb_sparse_infill_extr = glb_config.opt_int("sparse_infill_filament");
|
||||
int glb_solid_infill_extr = glb_config.opt_int("solid_infill_filament");
|
||||
int glb_outer_wall_extr = glb_config.opt_int("outer_wall_filament_id");
|
||||
int glb_inner_wall_extr = glb_config.opt_int("inner_wall_filament_id");
|
||||
if (glb_outer_wall_extr == 0) glb_outer_wall_extr = glb_inner_wall_extr;
|
||||
if (glb_inner_wall_extr == 0) glb_inner_wall_extr = glb_outer_wall_extr;
|
||||
int glb_sparse_infill_extr = glb_config.opt_int("sparse_infill_filament_id");
|
||||
int glb_internal_solid_extr = glb_config.opt_int("internal_solid_filament_id");
|
||||
int glb_top_surface_extr = glb_config.opt_int("top_surface_filament_id");
|
||||
int glb_bottom_surface_extr = glb_config.opt_int("bottom_surface_filament_id");
|
||||
if (glb_top_surface_extr == 0) glb_top_surface_extr = glb_internal_solid_extr;
|
||||
if (glb_bottom_surface_extr == 0) glb_bottom_surface_extr = glb_internal_solid_extr;
|
||||
bool glb_support = glb_config.opt_bool("enable_support");
|
||||
glb_support |= glb_config.opt_int("raft_layers") > 0;
|
||||
|
||||
@@ -1573,17 +1580,30 @@ std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode) const
|
||||
plate_extruders.push_back(glb_support_extr);
|
||||
}
|
||||
|
||||
int obj_wall_extr = 0;
|
||||
const ConfigOption* wall_opt = mo->config.option("wall_filament");
|
||||
if (wall_opt != nullptr)
|
||||
obj_wall_extr = wall_opt->getInt();
|
||||
if (obj_wall_extr != 0)
|
||||
plate_extruders.push_back(obj_wall_extr);
|
||||
else if (glb_wall_extr != 0)
|
||||
plate_extruders.push_back(glb_wall_extr);
|
||||
int obj_outer_wall_extr = 0;
|
||||
if (const ConfigOption* wall_opt = mo->config.option("outer_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_outer_wall_extr = wall_opt->getInt();
|
||||
if (obj_outer_wall_extr == 0)
|
||||
if (const ConfigOption* wall_opt = mo->config.option("inner_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_outer_wall_extr = wall_opt->getInt();
|
||||
if (obj_outer_wall_extr != 0)
|
||||
plate_extruders.push_back(obj_outer_wall_extr);
|
||||
else if (glb_outer_wall_extr != 0)
|
||||
plate_extruders.push_back(glb_outer_wall_extr);
|
||||
|
||||
int obj_inner_wall_extr = 0;
|
||||
if (const ConfigOption* wall_opt = mo->config.option("inner_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_inner_wall_extr = wall_opt->getInt();
|
||||
if (obj_inner_wall_extr == 0)
|
||||
if (const ConfigOption* wall_opt = mo->config.option("outer_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_inner_wall_extr = wall_opt->getInt();
|
||||
if (obj_inner_wall_extr != 0)
|
||||
plate_extruders.push_back(obj_inner_wall_extr);
|
||||
else if (glb_inner_wall_extr != 0)
|
||||
plate_extruders.push_back(glb_inner_wall_extr);
|
||||
|
||||
int obj_sparse_infill_extr = 0;
|
||||
const ConfigOption* sparse_infill_opt = mo->config.option("sparse_infill_filament");
|
||||
const ConfigOption* sparse_infill_opt = mo->config.option("sparse_infill_filament_id");
|
||||
if (sparse_infill_opt != nullptr)
|
||||
obj_sparse_infill_extr = sparse_infill_opt->getInt();
|
||||
if (obj_sparse_infill_extr != 0)
|
||||
@@ -1591,14 +1611,33 @@ std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode) const
|
||||
else if (glb_sparse_infill_extr != 0)
|
||||
plate_extruders.push_back(glb_sparse_infill_extr);
|
||||
|
||||
int obj_solid_infill_extr = 0;
|
||||
const ConfigOption* solid_infill_opt = mo->config.option("solid_infill_filament");
|
||||
if (solid_infill_opt != nullptr)
|
||||
obj_solid_infill_extr = solid_infill_opt->getInt();
|
||||
if (obj_solid_infill_extr != 0)
|
||||
plate_extruders.push_back(obj_solid_infill_extr);
|
||||
else if (glb_solid_infill_extr != 0)
|
||||
plate_extruders.push_back(glb_solid_infill_extr);
|
||||
int obj_internal_solid_extr = 0;
|
||||
if (const ConfigOption* solid_opt = mo->config.option("internal_solid_filament_id"); solid_opt != nullptr)
|
||||
obj_internal_solid_extr = solid_opt->getInt();
|
||||
if (obj_internal_solid_extr != 0)
|
||||
plate_extruders.push_back(obj_internal_solid_extr);
|
||||
else if (glb_internal_solid_extr != 0)
|
||||
plate_extruders.push_back(glb_internal_solid_extr);
|
||||
|
||||
int obj_top_surface_extr = 0;
|
||||
if (const ConfigOption* top_opt = mo->config.option("top_surface_filament_id"); top_opt != nullptr)
|
||||
obj_top_surface_extr = top_opt->getInt();
|
||||
if (obj_top_surface_extr == 0)
|
||||
obj_top_surface_extr = obj_internal_solid_extr;
|
||||
if (obj_top_surface_extr != 0)
|
||||
plate_extruders.push_back(obj_top_surface_extr);
|
||||
else if (glb_top_surface_extr != 0)
|
||||
plate_extruders.push_back(glb_top_surface_extr);
|
||||
|
||||
int obj_bottom_surface_extr = 0;
|
||||
if (const ConfigOption* bottom_opt = mo->config.option("bottom_surface_filament_id"); bottom_opt != nullptr)
|
||||
obj_bottom_surface_extr = bottom_opt->getInt();
|
||||
if (obj_bottom_surface_extr == 0)
|
||||
obj_bottom_surface_extr = obj_internal_solid_extr;
|
||||
if (obj_bottom_surface_extr != 0)
|
||||
plate_extruders.push_back(obj_bottom_surface_extr);
|
||||
else if (glb_bottom_surface_extr != 0)
|
||||
plate_extruders.push_back(glb_bottom_surface_extr);
|
||||
|
||||
}
|
||||
|
||||
@@ -1629,9 +1668,16 @@ std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D
|
||||
// if 3mf file
|
||||
int glb_support_intf_extr = full_config.opt_int("support_interface_filament");
|
||||
int glb_support_extr = full_config.opt_int("support_filament");
|
||||
int glb_wall_extr = full_config.opt_int("wall_filament");
|
||||
int glb_sparse_infill_extr = full_config.opt_int("sparse_infill_filament");
|
||||
int glb_solid_infill_extr = full_config.opt_int("solid_infill_filament");
|
||||
int glb_outer_wall_extr = full_config.opt_int("outer_wall_filament_id");
|
||||
int glb_inner_wall_extr = full_config.opt_int("inner_wall_filament_id");
|
||||
if (glb_outer_wall_extr == 0) glb_outer_wall_extr = glb_inner_wall_extr;
|
||||
if (glb_inner_wall_extr == 0) glb_inner_wall_extr = glb_outer_wall_extr;
|
||||
int glb_sparse_infill_extr = full_config.opt_int("sparse_infill_filament_id");
|
||||
int glb_internal_solid_extr = full_config.opt_int("internal_solid_filament_id");
|
||||
int glb_top_surface_extr = full_config.opt_int("top_surface_filament_id");
|
||||
int glb_bottom_surface_extr = full_config.opt_int("bottom_surface_filament_id");
|
||||
if (glb_top_surface_extr == 0) glb_top_surface_extr = glb_internal_solid_extr;
|
||||
if (glb_bottom_surface_extr == 0) glb_bottom_surface_extr = glb_internal_solid_extr;
|
||||
|
||||
bool glb_support = full_config.opt_bool("enable_support");
|
||||
glb_support |= full_config.opt_int("raft_layers") > 0;
|
||||
@@ -1695,17 +1741,30 @@ std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D
|
||||
else if (glb_support_extr != 0)
|
||||
plate_extruders.push_back(glb_support_extr);
|
||||
|
||||
int obj_wall_extr = 0;
|
||||
const ConfigOption* wall_opt = object->config.option("wall_filament");
|
||||
if (wall_opt != nullptr)
|
||||
obj_wall_extr = wall_opt->getInt();
|
||||
if (obj_wall_extr != 0)
|
||||
plate_extruders.push_back(obj_wall_extr);
|
||||
else if (glb_wall_extr != 0)
|
||||
plate_extruders.push_back(glb_wall_extr);
|
||||
int obj_outer_wall_extr = 0;
|
||||
if (const ConfigOption* wall_opt = object->config.option("outer_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_outer_wall_extr = wall_opt->getInt();
|
||||
if (obj_outer_wall_extr == 0)
|
||||
if (const ConfigOption* wall_opt = object->config.option("inner_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_outer_wall_extr = wall_opt->getInt();
|
||||
if (obj_outer_wall_extr != 0)
|
||||
plate_extruders.push_back(obj_outer_wall_extr);
|
||||
else if (glb_outer_wall_extr != 0)
|
||||
plate_extruders.push_back(glb_outer_wall_extr);
|
||||
|
||||
int obj_inner_wall_extr = 0;
|
||||
if (const ConfigOption* wall_opt = object->config.option("inner_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_inner_wall_extr = wall_opt->getInt();
|
||||
if (obj_inner_wall_extr == 0)
|
||||
if (const ConfigOption* wall_opt = object->config.option("outer_wall_filament_id"); wall_opt != nullptr)
|
||||
obj_inner_wall_extr = wall_opt->getInt();
|
||||
if (obj_inner_wall_extr != 0)
|
||||
plate_extruders.push_back(obj_inner_wall_extr);
|
||||
else if (glb_inner_wall_extr != 0)
|
||||
plate_extruders.push_back(glb_inner_wall_extr);
|
||||
|
||||
int obj_sparse_infill_extr = 0;
|
||||
const ConfigOption* sparse_infill_opt = object->config.option("sparse_infill_filament");
|
||||
const ConfigOption* sparse_infill_opt = object->config.option("sparse_infill_filament_id");
|
||||
if (sparse_infill_opt != nullptr)
|
||||
obj_sparse_infill_extr = sparse_infill_opt->getInt();
|
||||
if (obj_sparse_infill_extr != 0)
|
||||
@@ -1713,14 +1772,33 @@ std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D
|
||||
else if (glb_sparse_infill_extr != 0)
|
||||
plate_extruders.push_back(glb_sparse_infill_extr);
|
||||
|
||||
int obj_solid_infill_extr = 0;
|
||||
const ConfigOption* solid_infill_opt = object->config.option("solid_infill_filament");
|
||||
if (solid_infill_opt != nullptr)
|
||||
obj_solid_infill_extr = solid_infill_opt->getInt();
|
||||
if (obj_solid_infill_extr != 0)
|
||||
plate_extruders.push_back(obj_solid_infill_extr);
|
||||
else if (glb_solid_infill_extr != 0)
|
||||
plate_extruders.push_back(glb_solid_infill_extr);
|
||||
int obj_internal_solid_extr = 0;
|
||||
if (const ConfigOption* solid_opt = object->config.option("internal_solid_filament_id"); solid_opt != nullptr)
|
||||
obj_internal_solid_extr = solid_opt->getInt();
|
||||
if (obj_internal_solid_extr != 0)
|
||||
plate_extruders.push_back(obj_internal_solid_extr);
|
||||
else if (glb_internal_solid_extr != 0)
|
||||
plate_extruders.push_back(glb_internal_solid_extr);
|
||||
|
||||
int obj_top_surface_extr = 0;
|
||||
if (const ConfigOption* top_opt = object->config.option("top_surface_filament_id"); top_opt != nullptr)
|
||||
obj_top_surface_extr = top_opt->getInt();
|
||||
if (obj_top_surface_extr == 0)
|
||||
obj_top_surface_extr = obj_internal_solid_extr;
|
||||
if (obj_top_surface_extr != 0)
|
||||
plate_extruders.push_back(obj_top_surface_extr);
|
||||
else if (glb_top_surface_extr != 0)
|
||||
plate_extruders.push_back(glb_top_surface_extr);
|
||||
|
||||
int obj_bottom_surface_extr = 0;
|
||||
if (const ConfigOption* bottom_opt = object->config.option("bottom_surface_filament_id"); bottom_opt != nullptr)
|
||||
obj_bottom_surface_extr = bottom_opt->getInt();
|
||||
if (obj_bottom_surface_extr == 0)
|
||||
obj_bottom_surface_extr = obj_internal_solid_extr;
|
||||
if (obj_bottom_surface_extr != 0)
|
||||
plate_extruders.push_back(obj_bottom_surface_extr);
|
||||
else if (glb_bottom_surface_extr != 0)
|
||||
plate_extruders.push_back(glb_bottom_surface_extr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-22
@@ -1598,9 +1598,12 @@ Sidebar::Sidebar(Plater *parent)
|
||||
{
|
||||
Choice::register_dynamic_list("support_filament", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("support_interface_filament", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("wall_filament", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("sparse_infill_filament", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("solid_infill_filament", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("outer_wall_filament_id", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("inner_wall_filament_id", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("sparse_infill_filament_id", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("internal_solid_filament_id", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("top_surface_filament_id", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("bottom_surface_filament_id", &dynamic_filament_list);
|
||||
Choice::register_dynamic_list("wipe_tower_filament", &dynamic_filament_list);
|
||||
|
||||
p->scrolled = new wxPanel(this);
|
||||
@@ -4871,7 +4874,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
"extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology",
|
||||
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
|
||||
"layer_height", "initial_layer_print_height", "min_layer_height", "max_layer_height",
|
||||
"wall_loops", "wall_filament", "sparse_infill_density", "sparse_infill_filament", "top_shell_layers",
|
||||
"wall_loops", "outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_density", "sparse_infill_filament_id", "top_shell_layers",
|
||||
"enable_support", "support_filament", "support_interface_filament",
|
||||
"support_top_z_distance", "support_bottom_z_distance", "raft_layers",
|
||||
"wipe_tower_rotation_angle", "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extra_flow", "wipe_tower_max_purge_speed",
|
||||
@@ -6153,22 +6156,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
}
|
||||
}
|
||||
|
||||
if (load_config && !config_loaded.empty() &&
|
||||
(en_3mf_file_type == En3mfType::From_BBS || en_3mf_file_type == En3mfType::From_Orca) &&
|
||||
file_version < Semver("2.4.0-dev")) {
|
||||
int converted_count = ConfigMigrations::migrate_legacy_feature_filament_defaults(config_loaded);
|
||||
for (ModelObject *model_object : model.objects) {
|
||||
converted_count += ConfigMigrations::migrate_legacy_feature_filament_defaults(model_object->config);
|
||||
for (ModelVolume *model_volume : model_object->volumes)
|
||||
converted_count += ConfigMigrations::migrate_legacy_feature_filament_defaults(model_volume->config);
|
||||
}
|
||||
|
||||
if (converted_count > 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << " "
|
||||
<< boost::format("old 3mf version %1%, migrated %2% feature filament selections from 1 to 0 (Default)")
|
||||
% file_version.to_string() % converted_count;
|
||||
}
|
||||
}
|
||||
// ORCA: legacy feature-filament default migration (1 -> 0) is now handled
|
||||
// uniformly in PrintConfigDef::handle_legacy() via the old->new key rename
|
||||
// (wall_filament -> wall_filament_id, etc.), which also covers saved presets.
|
||||
|
||||
// plate data
|
||||
if (plate_data.size() > 0) {
|
||||
@@ -16669,8 +16659,10 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
||||
update_scheduled = true;
|
||||
}
|
||||
// Orca: update when *_filament changed
|
||||
else if (opt_key == "support_interface_filament" || opt_key == "support_filament" || opt_key == "wall_filament" ||
|
||||
opt_key == "sparse_infill_filament" || opt_key == "solid_infill_filament") {
|
||||
else if (opt_key == "support_interface_filament" || opt_key == "support_filament" ||
|
||||
opt_key == "outer_wall_filament_id" || opt_key == "inner_wall_filament_id" ||
|
||||
opt_key == "sparse_infill_filament_id" || opt_key == "internal_solid_filament_id" ||
|
||||
opt_key == "top_surface_filament_id" || opt_key == "bottom_surface_filament_id") {
|
||||
update_scheduled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,9 +128,12 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
|
||||
auto feature_extruder_active = [idx_extruder, num_extruders](int i) {
|
||||
return i <= 0 || i > num_extruders || idx_extruder == -1 || idx_extruder == i - 1;
|
||||
};
|
||||
bool perimeter_extruder_active = feature_extruder_active(print_config.opt_int("wall_filament"));
|
||||
bool infill_extruder_active = feature_extruder_active(print_config.opt_int("sparse_infill_filament"));
|
||||
bool solid_infill_extruder_active = feature_extruder_active(print_config.opt_int("solid_infill_filament"));
|
||||
bool perimeter_extruder_active = feature_extruder_active(print_config.opt_int("outer_wall_filament_id"))
|
||||
&& feature_extruder_active(print_config.opt_int("inner_wall_filament_id"));
|
||||
bool infill_extruder_active = feature_extruder_active(print_config.opt_int("sparse_infill_filament_id"));
|
||||
bool solid_infill_extruder_active = feature_extruder_active(print_config.opt_int("internal_solid_filament_id"))
|
||||
&& feature_extruder_active(print_config.opt_int("top_surface_filament_id"))
|
||||
&& feature_extruder_active(print_config.opt_int("bottom_surface_filament_id"));
|
||||
bool support_material_extruder_active = feature_extruder_active(print_config.opt_int("support_filament"));
|
||||
bool support_material_interface_extruder_active = feature_extruder_active(print_config.opt_int("support_interface_filament"));
|
||||
|
||||
|
||||
@@ -2667,9 +2667,12 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("single_extruder_multi_material_priming", "multimaterial_settings_prime_tower");
|
||||
|
||||
optgroup = page->new_optgroup(L("Filament for Features"), L"param_filament_for_features");
|
||||
optgroup->append_single_option_line("wall_filament", "multimaterial_settings_filament_for_features#walls");
|
||||
optgroup->append_single_option_line("sparse_infill_filament", "multimaterial_settings_filament_for_features#infill");
|
||||
optgroup->append_single_option_line("solid_infill_filament", "multimaterial_settings_filament_for_features#solid-infill");
|
||||
optgroup->append_single_option_line("outer_wall_filament_id", "multimaterial_settings_filament_for_features#walls");
|
||||
optgroup->append_single_option_line("inner_wall_filament_id", "multimaterial_settings_filament_for_features#walls");
|
||||
optgroup->append_single_option_line("sparse_infill_filament_id", "multimaterial_settings_filament_for_features#infill");
|
||||
optgroup->append_single_option_line("internal_solid_filament_id", "multimaterial_settings_filament_for_features#solid-infill");
|
||||
optgroup->append_single_option_line("top_surface_filament_id", "multimaterial_settings_filament_for_features#solid-infill");
|
||||
optgroup->append_single_option_line("bottom_surface_filament_id", "multimaterial_settings_filament_for_features#solid-infill");
|
||||
optgroup->append_single_option_line("wipe_tower_filament", "multimaterial_settings_filament_for_features#wipe-tower");
|
||||
|
||||
optgroup = page->new_optgroup(L("Ooze prevention"), L"param_ooze_prevention");
|
||||
|
||||
Reference in New Issue
Block a user