mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-09 18:27:00 +00:00
Fix sending print jobs to Bambu H2C printer
This commit is contained in:
@@ -3452,6 +3452,13 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||||||
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
||||||
if (z_offset != nullptr)
|
if (z_offset != nullptr)
|
||||||
m_z_offset = z_offset->value;
|
m_z_offset = z_offset->value;
|
||||||
|
|
||||||
|
// Reprocessing an existing g-code (from-previous reload / imported g-code) reaches apply_config
|
||||||
|
// through this DynamicPrintConfig overload; rebuild the per-filament nozzle grouping onto the
|
||||||
|
// result so the multi-nozzle device GUI can map filaments to physical nozzles. The normal
|
||||||
|
// streaming export uses the PrintConfig overload and hands the live grouping over separately, so
|
||||||
|
// it is intentionally not touched here.
|
||||||
|
ensure_nozzle_group_result(static_cast<int>(m_result.filaments_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
||||||
@@ -6575,6 +6582,75 @@ void GCodeProcessor::init_filament_maps_and_nozzle_type_when_import_only_gcode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Surface a per-filament nozzle grouping onto m_result when reprocessing an already-generated g-code
|
||||||
|
// (from-previous reload / imported g-code) — process_file does not otherwise rebuild it, so the
|
||||||
|
// multi-nozzle device GUI would find nozzle_group_result == NULL and the rack print-dispatch mapping
|
||||||
|
// request fails with code -1. Only invoked from the DynamicPrintConfig apply_config (the reprocess /
|
||||||
|
// import path); the normal streaming export keeps handing the live grouping over separately.
|
||||||
|
void GCodeProcessor::ensure_nozzle_group_result(int min_filament_count)
|
||||||
|
{
|
||||||
|
if (m_nozzle_group_result) {
|
||||||
|
// A grouping was already seeded from the reloaded result (initialize_from_context). Publish it
|
||||||
|
// onto m_result so extract_result() carries it. (The reference relies on the streaming-export
|
||||||
|
// handover for this and returns early here; the reprocess path has no such handover.)
|
||||||
|
m_result.nozzle_group_result = m_nozzle_group_result;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filament_count = std::max(1, min_filament_count);
|
||||||
|
filament_count = std::max(filament_count, static_cast<int>(m_filament_maps.size()));
|
||||||
|
|
||||||
|
std::vector<int> filament_map = m_filament_maps;
|
||||||
|
if (filament_map.empty()) {
|
||||||
|
filament_map.assign(filament_count, 0);
|
||||||
|
} else if (static_cast<int>(filament_map.size()) < filament_count) {
|
||||||
|
filament_map.resize(filament_count, filament_map.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
int min_value = *std::min_element(filament_map.begin(), filament_map.end());
|
||||||
|
if (min_value >= 1) {
|
||||||
|
for (int &value : filament_map) {
|
||||||
|
value -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int &value : filament_map) {
|
||||||
|
value = std::max(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_extruder_id = *std::max_element(filament_map.begin(), filament_map.end());
|
||||||
|
max_extruder_id = std::max(0, max_extruder_id);
|
||||||
|
|
||||||
|
std::string nozzle_diameter = format_diameter_to_str(DEFAULT_TOOLPATH_WIDTH);
|
||||||
|
std::vector<MultiNozzleUtils::NozzleInfo> nozzle_list;
|
||||||
|
nozzle_list.reserve(static_cast<size_t>(max_extruder_id + 1));
|
||||||
|
for (int extruder_id = 0; extruder_id <= max_extruder_id; ++extruder_id) {
|
||||||
|
MultiNozzleUtils::NozzleInfo info;
|
||||||
|
info.diameter = nozzle_diameter;
|
||||||
|
info.volume_type = NozzleVolumeType::nvtStandard;
|
||||||
|
info.extruder_id = extruder_id;
|
||||||
|
info.group_id = extruder_id;
|
||||||
|
nozzle_list.emplace_back(std::move(info));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> filament_nozzle_map(filament_count, 0);
|
||||||
|
for (int i = 0; i < filament_count; ++i) {
|
||||||
|
filament_nozzle_map[i] = filament_map[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned int> used_filaments;
|
||||||
|
used_filaments.reserve(filament_count);
|
||||||
|
for (int i = 0; i < filament_count; ++i) {
|
||||||
|
used_filaments.push_back(static_cast<unsigned int>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = MultiNozzleUtils::LayeredNozzleGroupResult::create(filament_nozzle_map, nozzle_list, used_filaments);
|
||||||
|
if (result) {
|
||||||
|
m_nozzle_group_result = std::make_shared<MultiNozzleUtils::LayeredNozzleGroupResult>(*result);
|
||||||
|
m_result.nozzle_group_result = m_nozzle_group_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GCodeProcessor::use_multi_nozzle_change_time_model() const
|
bool GCodeProcessor::use_multi_nozzle_change_time_model() const
|
||||||
{
|
{
|
||||||
// Multi-nozzle context = a printer that can incur nozzle-change events the single-arg model
|
// Multi-nozzle context = a printer that can incur nozzle-change events the single-arg model
|
||||||
|
|||||||
@@ -1197,6 +1197,11 @@ class Print;
|
|||||||
public:
|
public:
|
||||||
GCodeProcessor();
|
GCodeProcessor();
|
||||||
void init_filament_maps_and_nozzle_type_when_import_only_gcode();
|
void init_filament_maps_and_nozzle_type_when_import_only_gcode();
|
||||||
|
// Reprocessing an already-generated g-code (from-previous / imported g-code) does not rebuild
|
||||||
|
// the per-filament nozzle grouping the multi-nozzle device GUI needs. Surface it onto the
|
||||||
|
// result: keep an already-seeded grouping (from initialize_from_context), otherwise synthesize
|
||||||
|
// a default one from the filament map so the result is never left without it.
|
||||||
|
void ensure_nozzle_group_result(int min_filament_count);
|
||||||
// check whether the gcode path meets the filament_map grouping requirements
|
// check whether the gcode path meets the filament_map grouping requirements
|
||||||
bool check_multi_extruder_gcode_valid(const int extruder_size,
|
bool check_multi_extruder_gcode_valid(const int extruder_size,
|
||||||
const Pointfs plate_printable_area,
|
const Pointfs plate_printable_area,
|
||||||
|
|||||||
@@ -4260,13 +4260,19 @@ void Print::export_gcode_from_previous_file(const std::string& file, GCodeProces
|
|||||||
const Vec3d origin = this->get_plate_origin();
|
const Vec3d origin = this->get_plate_origin();
|
||||||
processor.set_xy_offset(origin(0), origin(1));
|
processor.set_xy_offset(origin(0), origin(1));
|
||||||
// Reloaded sliced projects re-estimate with the same nozzle-grouping slot context as the
|
// Reloaded sliced projects re-estimate with the same nozzle-grouping slot context as the
|
||||||
// original export; harmless when the result carries none (slot 0).
|
// original export; process_file re-derives the device-side nozzle grouping onto the result
|
||||||
|
// (via ensure_nozzle_group_result), so the multi-nozzle send/monitor mapping survives here.
|
||||||
if (result != nullptr && result->nozzle_group_result)
|
if (result != nullptr && result->nozzle_group_result)
|
||||||
processor.initialize_from_context(result->nozzle_group_result);
|
processor.initialize_from_context(result->nozzle_group_result);
|
||||||
//processor.enable_producers(true);
|
//processor.enable_producers(true);
|
||||||
processor.process_file(file);
|
processor.process_file(file);
|
||||||
|
|
||||||
|
// filament seq is loaded from file, processor result will override the value
|
||||||
|
auto filament_seq_loaded = result->filament_change_sequence;
|
||||||
|
auto nozzle_seq_loaded = result->nozzle_change_sequence;
|
||||||
*result = std::move(processor.extract_result());
|
*result = std::move(processor.extract_result());
|
||||||
|
result->filament_change_sequence = filament_seq_loaded;
|
||||||
|
result->nozzle_change_sequence = nozzle_seq_loaded;
|
||||||
} catch (std::exception & /* ex */) {
|
} catch (std::exception & /* ex */) {
|
||||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": found errors when process gcode file %1%") %file.c_str();
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": found errors when process gcode file %1%") %file.c_str();
|
||||||
throw Slic3r::RuntimeError(
|
throw Slic3r::RuntimeError(
|
||||||
|
|||||||
Reference in New Issue
Block a user