mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-15 13:07:33 +00:00
Compare commits
4 Commits
feat/print
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac3997c0d1 | ||
|
|
bd1304443c | ||
|
|
bb3a260acb | ||
|
|
2b6eb425e4 |
@@ -3555,7 +3555,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
|
|
||||||
auto used_filaments = print.get_slice_used_filaments(false);
|
auto used_filaments = print.get_slice_used_filaments(false);
|
||||||
this->placeholder_parser().set("is_all_bbl_filament", std::all_of(used_filaments.begin(), used_filaments.end(), [&](auto idx) {
|
this->placeholder_parser().set("is_all_bbl_filament", std::all_of(used_filaments.begin(), used_filaments.end(), [&](auto idx) {
|
||||||
return m_config.filament_vendor.values[idx] == "Bambu Lab";
|
return m_config.filament_vendor.get_at(idx) == "Bambu Lab";
|
||||||
}));
|
}));
|
||||||
|
|
||||||
//add during_print_exhaust_fan_speed
|
//add during_print_exhaust_fan_speed
|
||||||
@@ -3572,7 +3572,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
this->placeholder_parser().set("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed));
|
this->placeholder_parser().set("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed));
|
||||||
|
|
||||||
auto first_layer_filaments = print.get_slice_used_filaments(true);
|
auto first_layer_filaments = print.get_slice_used_filaments(true);
|
||||||
bool has_tpu_in_first_layer = std::any_of(first_layer_filaments.begin(), first_layer_filaments.end(), [&](unsigned int idx) { return m_config.filament_type.values[idx] == "TPU"; });
|
bool has_tpu_in_first_layer = std::any_of(first_layer_filaments.begin(), first_layer_filaments.end(), [&](unsigned int idx) { return m_config.filament_type.get_at(idx) == "TPU"; });
|
||||||
this->placeholder_parser().set("has_tpu_in_first_layer", new ConfigOptionBool(has_tpu_in_first_layer));
|
this->placeholder_parser().set("has_tpu_in_first_layer", new ConfigOptionBool(has_tpu_in_first_layer));
|
||||||
|
|
||||||
if (print.calib_params().mode == CalibMode::Calib_PA_Line) {
|
if (print.calib_params().mode == CalibMode::Calib_PA_Line) {
|
||||||
@@ -9474,12 +9474,14 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
|
|||||||
if (old_filament_id_in_new_extruder == -1)
|
if (old_filament_id_in_new_extruder == -1)
|
||||||
wipe_volume = 0;
|
wipe_volume = 0;
|
||||||
else {
|
else {
|
||||||
wipe_volume = flush_matrix[old_filament_id_in_new_extruder * number_of_extruders + new_filament_id];
|
size_t flush_idx = size_t(old_filament_id_in_new_extruder) * number_of_extruders + new_filament_id;
|
||||||
|
wipe_volume = flush_idx < flush_matrix.size() ? flush_matrix[flush_idx] : 0.f;
|
||||||
wipe_volume *= m_config.flush_multiplier.get_at(new_extruder_id);
|
wipe_volume *= m_config.flush_multiplier.get_at(new_extruder_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wipe_volume = flush_matrix[old_filament_id * number_of_extruders + new_filament_id];
|
size_t flush_idx = size_t(old_filament_id) * number_of_extruders + new_filament_id;
|
||||||
|
wipe_volume = flush_idx < flush_matrix.size() ? flush_matrix[flush_idx] : 0.f;
|
||||||
wipe_volume *= m_config.flush_multiplier.get_at(new_extruder_id); // if is multi_extruder only use the fist extruder matrix
|
wipe_volume *= m_config.flush_multiplier.get_at(new_extruder_id); // if is multi_extruder only use the fist extruder matrix
|
||||||
}
|
}
|
||||||
wipe_volume = std::max(0.f, wipe_volume-grab_purge_volume);
|
wipe_volume = std::max(0.f, wipe_volume-grab_purge_volume);
|
||||||
|
|||||||
@@ -7596,8 +7596,8 @@ void GCodeProcessor::update_slice_warnings()
|
|||||||
if (used_filaments[idx] < m_result.required_nozzle_HRC.size())
|
if (used_filaments[idx] < m_result.required_nozzle_HRC.size())
|
||||||
filament_hrc = m_result.required_nozzle_HRC[used_filaments[idx]];
|
filament_hrc = m_result.required_nozzle_HRC[used_filaments[idx]];
|
||||||
|
|
||||||
int filament_extruder_id = m_filament_maps[used_filaments[idx]];
|
int filament_extruder_id = used_filaments[idx] < m_filament_maps.size() ? m_filament_maps[used_filaments[idx]] : -1;
|
||||||
int extruder_hrc = nozzle_hrc_lists[filament_extruder_id];
|
int extruder_hrc = (filament_extruder_id >= 0 && (size_t) filament_extruder_id < nozzle_hrc_lists.size()) ? nozzle_hrc_lists[filament_extruder_id] : 0;
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": Check HRC: filament:%1%, hrc=%2%, extruder:%3%, hrc:%4%") % used_filaments[idx] % filament_hrc % filament_extruder_id % extruder_hrc;
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": Check HRC: filament:%1%, hrc=%2%, extruder:%3%, hrc:%4%") % used_filaments[idx] % filament_hrc % filament_extruder_id % extruder_hrc;
|
||||||
|
|
||||||
|
|||||||
@@ -1488,10 +1488,10 @@ static FilamentGroupContext build_filament_group_context(
|
|||||||
|
|
||||||
auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info(), extruder_ams_counts, ignore_ext_filament);
|
auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info(), extruder_ams_counts, ignore_ext_filament);
|
||||||
|
|
||||||
std::vector<std::string> filament_types = print_config.filament_type.values;
|
// The grouping code walks filament_ids and indexes filament_info by the same position.
|
||||||
std::vector<std::string> filament_colours = print_config.filament_colour.values;
|
std::vector<std::string> filament_ids = print_config.filament_ids.values;
|
||||||
std::vector<unsigned char> filament_is_support = print_config.filament_is_support.values;
|
if (filament_ids.size() > filament_nums)
|
||||||
std::vector<std::string> filament_ids = print_config.filament_ids.values;
|
filament_ids.resize(filament_nums);
|
||||||
|
|
||||||
FGMode fg_mode = mode == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode : FGMode::FlushMode;
|
FGMode fg_mode = mode == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode : FGMode::FlushMode;
|
||||||
context.model_info.flush_matrix = std::move(nozzle_flush_mtx);
|
context.model_info.flush_matrix = std::move(nozzle_flush_mtx);
|
||||||
@@ -1500,11 +1500,14 @@ static FilamentGroupContext build_filament_group_context(
|
|||||||
context.model_info.filament_ids = filament_ids;
|
context.model_info.filament_ids = filament_ids;
|
||||||
context.model_info.unprintable_volumes = unprintable_volumes;
|
context.model_info.unprintable_volumes = unprintable_volumes;
|
||||||
|
|
||||||
for (size_t idx = 0; idx < filament_types.size(); ++idx) {
|
// Consumers index filament_info by filament id, so it must span the filament count: a partial
|
||||||
|
// or legacy config can leave any of these arrays short, and get_at clamps.
|
||||||
|
context.model_info.filament_info.reserve(filament_nums);
|
||||||
|
for (size_t idx = 0; idx < filament_nums; ++idx) {
|
||||||
FilamentGroupUtils::FilamentInfo info;
|
FilamentGroupUtils::FilamentInfo info;
|
||||||
info.color = filament_colours[idx];
|
info.color = print_config.filament_colour.get_at(idx);
|
||||||
info.type = filament_types[idx];
|
info.type = print_config.filament_type.get_at(idx);
|
||||||
info.is_support = filament_is_support[idx];
|
info.is_support = print_config.filament_is_support.get_at(idx);
|
||||||
context.model_info.filament_info.emplace_back(std::move(info));
|
context.model_info.filament_info.emplace_back(std::move(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1349,7 +1349,7 @@ public:
|
|||||||
// flavor it reaches understands, not the zero dwell the other flavors flush with.
|
// flavor it reaches understands, not the zero dwell the other flavors flush with.
|
||||||
buffer += "M400\n";
|
buffer += "M400\n";
|
||||||
buffer += "M104";
|
buffer += "M104";
|
||||||
if (target_extruder != -1)
|
if (target_extruder != -1 && target_extruder < int(m_physical_extruder_map.size()))
|
||||||
buffer += (" T" + std::to_string(m_physical_extruder_map[target_extruder]));
|
buffer += (" T" + std::to_string(m_physical_extruder_map[target_extruder]));
|
||||||
buffer += " S" + std::to_string(target_temp) + " N0"; // N0 means the gcode is generated by slicer
|
buffer += " S" + std::to_string(target_temp) + " N0"; // N0 means the gcode is generated by slicer
|
||||||
if (!comment.empty()) buffer += " ;" + comment;
|
if (!comment.empty()) buffer += " ;" + comment;
|
||||||
@@ -1361,7 +1361,7 @@ public:
|
|||||||
WipeTowerWriter &format_line_M109(int target_temp, int target_extruder, const std::string &comment = std::string())
|
WipeTowerWriter &format_line_M109(int target_temp, int target_extruder, const std::string &comment = std::string())
|
||||||
{
|
{
|
||||||
std::string buffer = "M109";
|
std::string buffer = "M109";
|
||||||
if (target_extruder != -1)
|
if (target_extruder != -1 && target_extruder < int(m_physical_extruder_map.size()))
|
||||||
buffer += (" T" + std::to_string(m_physical_extruder_map[target_extruder]));
|
buffer += (" T" + std::to_string(m_physical_extruder_map[target_extruder]));
|
||||||
buffer += " S" + std::to_string(target_temp) + " N0"; // N0 means the gcode is generated by slicer
|
buffer += " S" + std::to_string(target_temp) + " N0"; // N0 means the gcode is generated by slicer
|
||||||
if (!comment.empty()) buffer += " ;" + comment;
|
if (!comment.empty()) buffer += " ;" + comment;
|
||||||
@@ -3309,7 +3309,7 @@ void WipeTower::get_wall_skip_points(const WipeTowerInfo &layer, int layer_id)
|
|||||||
if (!cur_block_depth.count(m_filpar[new_filament].category)) cur_block_depth[m_filpar[new_filament].category] = block->start_depth;
|
if (!cur_block_depth.count(m_filpar[new_filament].category)) cur_block_depth[m_filpar[new_filament].category] = block->start_depth;
|
||||||
process_depth = cur_block_depth[m_filpar[new_filament].category];
|
process_depth = cur_block_depth[m_filpar[new_filament].category];
|
||||||
if (is_need_ramming(new_filament, old_filament, layer_id)) {
|
if (is_need_ramming(new_filament, old_filament, layer_id)) {
|
||||||
if (m_filament_categories[new_filament] == m_filament_categories[old_filament])
|
if (get_filament_category(new_filament) == get_filament_category(old_filament))
|
||||||
process_depth += nozzle_change_depth;
|
process_depth += nozzle_change_depth;
|
||||||
else {
|
else {
|
||||||
if (!cur_block_depth.count(m_filpar[old_filament].category)) {
|
if (!cur_block_depth.count(m_filpar[old_filament].category)) {
|
||||||
@@ -4783,7 +4783,7 @@ int WipeTower::get_wall_filament_for_all_layer()
|
|||||||
int filament_id = -1;
|
int filament_id = -1;
|
||||||
int filament_count = 0;
|
int filament_count = 0;
|
||||||
for (auto iter = filament_counts.begin(); iter != filament_counts.end(); ++iter) {
|
for (auto iter = filament_counts.begin(); iter != filament_counts.end(); ++iter) {
|
||||||
if (m_filament_categories[iter->first] == selected_category && iter->second > filament_count) {
|
if (get_filament_category(iter->first) == selected_category && iter->second > filament_count) {
|
||||||
filament_id = iter->first;
|
filament_id = iter->first;
|
||||||
filament_count = iter->second;
|
filament_count = iter->second;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -665,7 +665,7 @@ PublishSettingsDialog::PublishSettingsDialog(wxWindow* parent,
|
|||||||
};
|
};
|
||||||
wxBoxSizer* links_sizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* links_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
links_sizer->Add(make_link(_L("Publish 3MF Wiki"), "https://www.orcaslicer.com/wiki/publishing_3mf/publish_3mf.html"), 0, wxALIGN_LEFT);
|
links_sizer->Add(make_link(_L("Publish 3MF Wiki"), "https://www.orcaslicer.com/wiki/publishing_3mf/publish_3mf.html"), 0, wxALIGN_LEFT);
|
||||||
links_sizer->Add(make_link(_L("Publish 3MF Video Guide"), "https://www.youtube.com/@OfficialOrcaSlicer/videos"), 0,
|
links_sizer->Add(make_link(_L("Publish 3MF Video Guide"), "https://www.youtube.com/watch?v=-xt1N29UIOg"), 0,
|
||||||
wxTOP | wxALIGN_LEFT, FromDIP(4));
|
wxTOP | wxALIGN_LEFT, FromDIP(4));
|
||||||
|
|
||||||
wxBoxSizer* footer = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* footer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|||||||
@@ -163,6 +163,50 @@ TEST_CASE("H2C multi-nozzle: filaments get distinct nozzles on the 6-nozzle extr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Grouping context spans the filament count with mis-sized config arrays", "[ToolOrdering][H2C]")
|
||||||
|
{
|
||||||
|
// FilamentGroup indexes the grouping context's filament_info by filament id, so a short
|
||||||
|
// per-filament array must not shorten it: the reads run off the end.
|
||||||
|
DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
|
||||||
|
// Single 6-nozzle extruder: opens the grouping engine without needing a BBL multi-extruder.
|
||||||
|
config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4};
|
||||||
|
config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count", true)->values = {6};
|
||||||
|
config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#6"};
|
||||||
|
|
||||||
|
// Four filaments, with filament_type / filament_is_support left short on purpose.
|
||||||
|
config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF", "#FFFF00"};
|
||||||
|
config.option<ConfigOptionStrings>("filament_type", true)->values = {"PLA"};
|
||||||
|
config.option<ConfigOptionBools>("filament_is_support", true)->values = {0};
|
||||||
|
config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75, 1.75, 1.75};
|
||||||
|
config.option<ConfigOptionInts>("filament_map", true)->values = {1, 1, 1, 1};
|
||||||
|
config.option<ConfigOptionFloats>("flush_volumes_matrix", true)->values = std::vector<double>(16, 140.);
|
||||||
|
config.option<ConfigOptionFloats>("flush_multiplier", true)->values = {1.};
|
||||||
|
|
||||||
|
Model model;
|
||||||
|
model.add_object("cube", "", make_cube(20, 20, 20))->add_instance();
|
||||||
|
|
||||||
|
Print print;
|
||||||
|
print.apply(model, config);
|
||||||
|
// apply() does not pad the per-filament arrays, so the mis-sizing survives into the engine.
|
||||||
|
REQUIRE(print.config().filament_type.values.size() < print.config().filament_colour.values.size());
|
||||||
|
|
||||||
|
std::vector<std::vector<unsigned int>> layer_filaments = {{0, 1}, {1, 2}, {2, 3}};
|
||||||
|
|
||||||
|
SECTION("short per-filament arrays still yield one entry per filament") {
|
||||||
|
auto result = ToolOrdering::get_recommended_filament_maps(layer_filaments, &print, FilamentMapMode::fmmAutoForFlush, {}, {});
|
||||||
|
REQUIRE(result.get_extruder_map(false).size() == 4);
|
||||||
|
for (int f = 0; f < 4; ++f)
|
||||||
|
REQUIRE(result.get_extruder_id(f) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("filament_ids longer than the filament count is truncated, not paired past the end") {
|
||||||
|
config.option<ConfigOptionStrings>("filament_ids", true)->values = {"a", "b", "c", "d", "e", "f"};
|
||||||
|
print.apply(model, config);
|
||||||
|
auto result = ToolOrdering::get_recommended_filament_maps(layer_filaments, &print, FilamentMapMode::fmmAutoForFlush, {}, {});
|
||||||
|
REQUIRE(result.get_extruder_map(false).size() == 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("H2C dynamic selector: per-layer nozzle ids reach the g-code surface", "[ToolOrdering][H2C][Dynamic]")
|
TEST_CASE("H2C dynamic selector: per-layer nozzle ids reach the g-code surface", "[ToolOrdering][H2C][Dynamic]")
|
||||||
{
|
{
|
||||||
// The per-layer regroup engine
|
// The per-layer regroup engine
|
||||||
|
|||||||
Reference in New Issue
Block a user