mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 14:51:06 +00:00
Merge upstream/hanif/belt-printer-fixes into belt/final-round
Brings in upstream/belt-printer (the Sept 14 main merge) plus Hanif Koh's 21 review-fix commits from PR #15685, on top of the MachineKinematics refactor and the purge-prism / tree-support / first-layer-speed fixes. Conflict resolution: - BeltGCodeWriter is gone (kinematics refactor), so Hanif's plate-offset fix for it is ported into GCodeWriter: the first-layer-plane checks in travel_to_xy / travel_to_xyz / _travel_to_z now evaluate the plate-local point, and BeltGCode::init_belt_writer hands the stored plate origin to the writer it installs. - init_belt_writer(Print&) takes Hanif's signature; the BBL flag is set on the surviving writer by GCode::_do_export. - The shared emit_belt_brim_bands() loop keeps the BeltFloorObjectGuard the local branch added, so apron bands classify first-layer height against their own object. - eager_lift keeps effective_type: it now carries set_force_normal_lift(). - GCodeWriter's initializer list follows Hanif's member order with m_kinematics in its declared position. - TreeSupport::detect_overhangs uses Hanif's clamped build_plate_tilt_slope() for the non-belt path and the belt shear for the belt path.
This commit is contained in:
+31
-46
@@ -2962,10 +2962,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
m_fan_mover.release();
|
||||
m_ordering_cache.clear();
|
||||
|
||||
m_writer->set_is_bbl_machine(is_bbl_printers);
|
||||
|
||||
// Belt printer: initialize belt-specific writer via virtual hook.
|
||||
this->init_belt_writer(print, is_bbl_printers);
|
||||
this->init_belt_writer(print);
|
||||
m_writer->set_is_bbl_machine(is_bbl_printers);
|
||||
|
||||
// Standalone axis remap (works with or without belt mode).
|
||||
// Sync the writer's remap state to the current export UNCONDITIONALLY — even at
|
||||
@@ -5350,8 +5349,7 @@ LayerResult GCode::process_belt_brim_layer(
|
||||
// skip these layers entirely.
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change).c_str(), print_z);
|
||||
gcode += buf;
|
||||
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change) + "\n";
|
||||
sprintf(buf, ";Z:%g\n", print_z);
|
||||
gcode += buf;
|
||||
const float band_height = float(height);
|
||||
@@ -5382,7 +5380,12 @@ LayerResult GCode::process_belt_brim_layer(
|
||||
print.config().layer_change_gcode.value, m_writer->filament()->id(), &config) + "\n";
|
||||
}
|
||||
|
||||
gcode += this->emit_belt_brim_bands(print, layers, single_object_instance_idx);
|
||||
// Objects sharing this apron Z may use different brim filaments; print each in its own tool.
|
||||
for (const unsigned int brim_extruder : layer_tools.extruders) {
|
||||
if (m_writer->filament() == nullptr || m_writer->filament()->id() != brim_extruder)
|
||||
gcode += this->set_extruder(brim_extruder, print_z);
|
||||
gcode += this->emit_belt_brim_bands(print, layers, single_object_instance_idx, brim_extruder);
|
||||
}
|
||||
|
||||
result.gcode = std::move(gcode);
|
||||
return result;
|
||||
@@ -5396,7 +5399,8 @@ LayerResult GCode::process_belt_brim_layer(
|
||||
// object layer, takes the ordinary path, and the band would be silently dropped.
|
||||
std::string GCode::emit_belt_brim_bands(const Print &print,
|
||||
const std::vector<LayerToPrint> &layers,
|
||||
const size_t single_object_instance_idx)
|
||||
const size_t single_object_instance_idx,
|
||||
const unsigned int extruder_id)
|
||||
{
|
||||
std::string gcode;
|
||||
for (const LayerToPrint <p : layers) {
|
||||
@@ -5404,9 +5408,15 @@ std::string GCode::emit_belt_brim_bands(const Print &print,
|
||||
if (band == nullptr || band->fills.empty() || ltp.original_object == nullptr)
|
||||
continue;
|
||||
const PrintObject &object = *ltp.original_object;
|
||||
// belt_brim_filament() is 1-based.
|
||||
if (! object.has_belt_brim() || static_cast<unsigned int>(object.belt_brim_filament() - 1) != extruder_id)
|
||||
continue;
|
||||
// Speeds, flow and retraction all read m_config.
|
||||
m_config.apply(print.default_region_config());
|
||||
m_config.apply(object.config(), true);
|
||||
// Apron bands have no Layer at all (m_layer is null here), so the belt
|
||||
// floor owner has to be named the same way the object brim names it.
|
||||
BeltFloorObjectGuard floor_owner{ m_belt_floor_object, &object };
|
||||
const size_t i_begin = single_object_instance_idx == size_t(-1) ? 0 : single_object_instance_idx;
|
||||
const size_t i_end = single_object_instance_idx == size_t(-1) ? object.instances().size()
|
||||
: single_object_instance_idx + 1;
|
||||
@@ -6631,42 +6641,11 @@ LayerResult GCode::process_layer(
|
||||
std::set<std::pair<size_t, size_t>> belt_brim_emitted;
|
||||
|
||||
// Emit every ORDINARY-layer apron band (belt_brim_prologue band coinciding with an
|
||||
// object/support layer) whose brim filament is this pass's extruder. Mirrors
|
||||
// emit_belt_brim_bands() per band, but filtered to one brim filament so each band
|
||||
// object/support layer) whose brim filament is this pass's extruder, so each band
|
||||
// prints in the correct tool's pass (Finding B). extruder_id is 0-based (the
|
||||
// reindexed tool domain); belt_brim_filament() is 1-based, so subtract one.
|
||||
// reindexed tool domain).
|
||||
auto emit_belt_brim_for_extruder = [this, &print, &layers, single_object_instance_idx](unsigned int extruder_id) -> std::string {
|
||||
std::string gc;
|
||||
for (const LayerToPrint <p : layers) {
|
||||
const BeltBrimBand *band = ltp.belt_brim_band;
|
||||
if (band == nullptr || band->fills.empty() || ltp.original_object == nullptr)
|
||||
continue;
|
||||
const PrintObject &object = *ltp.original_object;
|
||||
if (! object.has_belt_brim() || (unsigned int)(object.belt_brim_filament() - 1) != extruder_id)
|
||||
continue;
|
||||
// Speeds, flow and retraction all read m_config.
|
||||
m_config.apply(print.default_region_config());
|
||||
m_config.apply(object.config(), true);
|
||||
// Apron bands have no Layer at all (m_layer is null here), so the belt
|
||||
// floor owner has to be named the same way the object brim names it.
|
||||
BeltFloorObjectGuard floor_owner{ m_belt_floor_object, &object };
|
||||
const size_t i_begin = single_object_instance_idx == size_t(-1) ? 0 : single_object_instance_idx;
|
||||
const size_t i_end = single_object_instance_idx == size_t(-1) ? object.instances().size()
|
||||
: single_object_instance_idx + 1;
|
||||
for (size_t i = i_begin; i < i_end && i < object.instances().size(); ++ i) {
|
||||
// Band geometry is object-local, like the object's own extrusions.
|
||||
const Point &offset = object.instances()[i].shift;
|
||||
this->set_origin(unscale(offset));
|
||||
this->on_set_origin(&object, offset);
|
||||
m_avoid_crossing_perimeters.use_external_mp();
|
||||
for (const ExtrusionEntity *ee : band->fills.entities)
|
||||
if (ee != nullptr)
|
||||
gc += this->extrude_entity(*ee, "brim", NOZZLE_CONFIG(support_speed));
|
||||
m_avoid_crossing_perimeters.use_external_mp(false);
|
||||
m_avoid_crossing_perimeters.disable_once();
|
||||
}
|
||||
}
|
||||
return gc;
|
||||
return this->emit_belt_brim_bands(print, layers, single_object_instance_idx, extruder_id);
|
||||
};
|
||||
|
||||
for (unsigned int extruder_id : layer_tools.extruders)
|
||||
@@ -6699,8 +6678,13 @@ LayerResult GCode::process_layer(
|
||||
all_label_ids.insert(inst.label_object_id);
|
||||
break;
|
||||
}
|
||||
std::vector<size_t> filament_instances_id(all_label_ids.begin(), all_label_ids.end());
|
||||
m_filament_instances_code = _encode_label_ids_to_base64(filament_instances_id);
|
||||
// Orca: A scheduled extruder may have no object instances on this layer.
|
||||
// Clear any pending mask so it cannot be emitted for the wrong toolchange.
|
||||
m_filament_instances_code.clear();
|
||||
if (!all_label_ids.empty()) {
|
||||
std::vector<size_t> filament_instances_id(all_label_ids.begin(), all_label_ids.end());
|
||||
m_filament_instances_code = _encode_label_ids_to_base64(filament_instances_id);
|
||||
}
|
||||
}
|
||||
|
||||
// The inline _extrude hook may already have taken the snapshot mid-extrusion on a
|
||||
@@ -8675,9 +8659,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
}
|
||||
variable_speed = std::any_of(new_points.begin(), new_points.end(),
|
||||
[speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec)
|
||||
if (!NOZZLE_CONFIG(enable_overhang_speed) && FILAMENT_CONFIG(enable_overhang_bridge_fan) && m_enable_cooling_markers) {
|
||||
for (ProcessedPoint &point : new_points)
|
||||
point.speed = speed;
|
||||
if (FILAMENT_CONFIG(enable_overhang_bridge_fan) && m_enable_cooling_markers) {
|
||||
if (!NOZZLE_CONFIG(enable_overhang_speed))
|
||||
for (ProcessedPoint &point : new_points)
|
||||
point.speed = speed;
|
||||
variable_speed = new_points.size() > 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user