mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
Merge branch 'main' into feature/support-fliament-cutter-explore-proper-flush-lenght
This commit is contained in:
commit
4b2a09bd07
210 changed files with 2325 additions and 1604 deletions
|
@ -116,7 +116,6 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||
if (excluse_area.size() != 4)
|
||||
return out_points;
|
||||
|
||||
double cutter_area_x = excluse_area[2].x() + 2;
|
||||
double cutter_area_y = excluse_area[2].y() + 2;
|
||||
|
||||
double start_x_position = start_point.x();
|
||||
|
@ -666,6 +665,9 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||
// SoftFever: set new PA for new filament
|
||||
if (gcodegen.config().enable_pressure_advance.get_at(new_extruder_id)) {
|
||||
gcode += gcodegen.writer().set_pressure_advance(gcodegen.config().pressure_advance.get_at(new_extruder_id));
|
||||
// Orca: Adaptive PA
|
||||
// Reset Adaptive PA processor last PA value
|
||||
gcodegen.m_pa_processor->resetPreviousPA(gcodegen.config().pressure_advance.get_at(new_extruder_id));
|
||||
}
|
||||
|
||||
// A phony move to the end position at the wipe tower.
|
||||
|
@ -789,6 +791,9 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||
// SoftFever: set new PA for new filament
|
||||
if (new_extruder_id != -1 && gcodegen.config().enable_pressure_advance.get_at(new_extruder_id)) {
|
||||
gcode += gcodegen.writer().set_pressure_advance(gcodegen.config().pressure_advance.get_at(new_extruder_id));
|
||||
// Orca: Adaptive PA
|
||||
// Reset Adaptive PA processor last PA value
|
||||
gcodegen.m_pa_processor->resetPreviousPA(gcodegen.config().pressure_advance.get_at(new_extruder_id));
|
||||
}
|
||||
|
||||
// A phony move to the end position at the wipe tower.
|
||||
|
@ -1886,6 +1891,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||
|
||||
if (!print.config().small_area_infill_flow_compensation_model.empty())
|
||||
m_small_area_infill_flow_compensator = make_unique<SmallAreaInfillFlowCompensator>(print.config());
|
||||
|
||||
|
||||
file.write_format("; HEADER_BLOCK_START\n");
|
||||
// Write information on the generator.
|
||||
|
@ -2131,6 +2137,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||
|
||||
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
||||
|
||||
// Orca: Initialise AdaptivePA processor filter
|
||||
m_pa_processor = std::make_unique<AdaptivePAProcessor>(*this, tool_ordering.all_extruders());
|
||||
|
||||
// Emit machine envelope limits for the Marlin firmware.
|
||||
this->print_machine_envelope(file, print);
|
||||
|
@ -2482,7 +2491,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||
m_avoid_crossing_perimeters.use_external_mp_once();
|
||||
// BBS. change tool before moving to origin point.
|
||||
if (m_writer.need_toolchange(initial_extruder_id)) {
|
||||
const PrintObjectConfig& object_config = object.config();
|
||||
coordf_t initial_layer_print_height = print.config().initial_layer_print_height.value;
|
||||
file.write(this->set_extruder(initial_extruder_id, initial_layer_print_height, true));
|
||||
prime_extruder = true;
|
||||
|
@ -2773,6 +2781,12 @@ void GCode::process_layers(
|
|||
return in.gcode;
|
||||
return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush);
|
||||
});
|
||||
const auto pa_processor_filter = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&pa_processor = *this->m_pa_processor](std::string in) -> std::string {
|
||||
return pa_processor.process_layer(std::move(in));
|
||||
}
|
||||
);
|
||||
|
||||
const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&output_stream](std::string s) { output_stream.write(s); }
|
||||
);
|
||||
|
@ -2803,9 +2817,9 @@ void GCode::process_layers(
|
|||
else if (m_spiral_vase)
|
||||
tbb::parallel_pipeline(12, generator & spiral_mode & cooling & fan_mover & output);
|
||||
else if (m_pressure_equalizer)
|
||||
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & fan_mover & output);
|
||||
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
|
||||
else
|
||||
tbb::parallel_pipeline(12, generator & cooling & fan_mover & output);
|
||||
tbb::parallel_pipeline(12, generator & cooling & fan_mover & pa_processor_filter & output);
|
||||
}
|
||||
|
||||
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:
|
||||
|
@ -3261,14 +3275,17 @@ namespace ProcessLayer
|
|||
const PrintConfig &config)
|
||||
{
|
||||
std::string gcode;
|
||||
// BBS
|
||||
bool single_filament_print = config.filament_diameter.size() == 1;
|
||||
|
||||
if (custom_gcode != nullptr) {
|
||||
// Extruder switches are processed by LayerTools, they should be filtered out.
|
||||
assert(custom_gcode->type != CustomGCode::ToolChange);
|
||||
|
||||
CustomGCode::Type gcode_type = custom_gcode->type;
|
||||
|
||||
//BBS: inserting color gcode is removed
|
||||
#if 0
|
||||
// BBS
|
||||
bool single_filament_print = config.filament_diameter.size() == 1;
|
||||
bool color_change = gcode_type == CustomGCode::ColorChange;
|
||||
bool tool_change = gcode_type == CustomGCode::ToolChange;
|
||||
// Tool Change is applied as Color Change for a single extruder printer only.
|
||||
|
@ -3280,8 +3297,7 @@ namespace ProcessLayer
|
|||
m600_extruder_before_layer = custom_gcode->extruder - 1;
|
||||
else if (gcode_type == CustomGCode::PausePrint)
|
||||
pause_print_msg = custom_gcode->extra;
|
||||
//BBS: inserting color gcode is removed
|
||||
#if 0
|
||||
|
||||
// we should add or not colorprint_change in respect to nozzle_diameter count instead of really used extruders count
|
||||
if (color_change || tool_change)
|
||||
{
|
||||
|
@ -3344,8 +3360,8 @@ namespace Skirt {
|
|||
{
|
||||
// Prime all extruders printing over the 1st layer over the skirt lines.
|
||||
size_t n_loops = print.skirt().entities.size();
|
||||
size_t n_tools = layer_tools.extruders.size();
|
||||
size_t lines_per_extruder = (n_loops + n_tools - 1) / n_tools;
|
||||
// size_t n_tools = layer_tools.extruders.size();
|
||||
// size_t lines_per_extruder = (n_loops + n_tools - 1) / n_tools;
|
||||
|
||||
// BBS. Extrude skirt with first extruder if min_skirt_length is zero
|
||||
//ORCA: Always extrude skirt with first extruder, independantly of if the minimum skirt length is zero or not. The code below
|
||||
|
@ -3701,7 +3717,8 @@ LayerResult GCode::process_layer(
|
|||
Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done);
|
||||
|
||||
// BBS: get next extruder according to flush and soluble
|
||||
auto get_next_extruder = [&](int current_extruder,const std::vector<unsigned int>&extruders) {
|
||||
// Orca: Left unused due to removed code below
|
||||
/* auto get_next_extruder = [&](int current_extruder,const std::vector<unsigned int>&extruders) {
|
||||
std::vector<float> flush_matrix(cast<float>(m_config.flush_volumes_matrix.values));
|
||||
const unsigned int number_of_extruders = (unsigned int)(sqrt(flush_matrix.size()) + EPSILON);
|
||||
// Extract purging volumes for each extruder pair:
|
||||
|
@ -3719,7 +3736,7 @@ LayerResult GCode::process_layer(
|
|||
}
|
||||
}
|
||||
return next_extruder;
|
||||
};
|
||||
}; */
|
||||
|
||||
if (m_config.enable_overhang_speed && !m_config.overhang_speed_classic) {
|
||||
for (const auto &layer_to_print : layers) {
|
||||
|
@ -3972,7 +3989,7 @@ LayerResult GCode::process_layer(
|
|||
m_avoid_crossing_perimeters.use_external_mp();
|
||||
Flow layer_skirt_flow = print.skirt_flow().with_height(float(m_skirt_done.back() - (m_skirt_done.size() == 1 ? 0. : m_skirt_done[m_skirt_done.size() - 2])));
|
||||
double mm3_per_mm = layer_skirt_flow.mm3_per_mm();
|
||||
for (size_t i = loops.first; i < loops.second; ++i) {
|
||||
for (size_t i = (layer.id() == 0) ? loops.first : loops.second - 1; i < loops.second; ++i) {
|
||||
// Adjust flow according to this layer's layer height.
|
||||
ExtrusionLoop loop = *dynamic_cast<const ExtrusionLoop*>(print.skirt().entities[i]);
|
||||
for (ExtrusionPath &path : loop.paths) {
|
||||
|
@ -4456,6 +4473,7 @@ static std::unique_ptr<EdgeGrid::Grid> calculate_layer_edge_grid(const Layer& la
|
|||
|
||||
std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed, const ExtrusionEntitiesPtr& region_perimeters)
|
||||
{
|
||||
|
||||
// get a copy; don't modify the orientation of the original loop object otherwise
|
||||
// next copies (if any) would not detect the correct orientation
|
||||
|
||||
|
@ -4465,6 +4483,8 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
// if spiral vase, we have to ensure that all contour are in the same orientation.
|
||||
loop.make_counter_clockwise();
|
||||
}
|
||||
if (loop.loop_role() == elrSkirt && (this->m_layer->id() % 2 == 1))
|
||||
loop.reverse();
|
||||
|
||||
// find the point of the loop that is closest to the current extruder position
|
||||
// or randomize if requested
|
||||
|
@ -4581,7 +4601,9 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
if(discoveredTouchingLines > 1){
|
||||
// use extrude instead of travel_to_xy to trigger the unretract
|
||||
ExtrusionPath fake_path_wipe(Polyline{pt, current_point}, paths.front());
|
||||
fake_path_wipe.set_force_no_extrusion(true);
|
||||
fake_path_wipe.mm3_per_mm = 0;
|
||||
//fake_path_wipe.set_extrusion_role(erExternalPerimeter);
|
||||
gcode += extrude_path(fake_path_wipe, "move inwards before retraction/seam", speed);
|
||||
}
|
||||
}
|
||||
|
@ -4593,9 +4615,32 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
return is_small_peri ? small_peri_speed : speed;
|
||||
};
|
||||
|
||||
|
||||
//Orca: Adaptive PA: calculate average mm3_per_mm value over the length of the loop.
|
||||
//This is used for adaptive PA
|
||||
m_multi_flow_segment_path_pa_set = false; // always emit PA on the first path of the loop
|
||||
m_multi_flow_segment_path_average_mm3_per_mm = 0;
|
||||
double weighted_sum_mm3_per_mm = 0.0;
|
||||
double total_multipath_length = 0.0;
|
||||
for (const ExtrusionPath& path : paths) {
|
||||
if(!path.is_force_no_extrusion()){
|
||||
double path_length = unscale<double>(path.length()); //path length in mm
|
||||
weighted_sum_mm3_per_mm += path.mm3_per_mm * path_length;
|
||||
total_multipath_length += path_length;
|
||||
}
|
||||
}
|
||||
if (total_multipath_length > 0.0)
|
||||
m_multi_flow_segment_path_average_mm3_per_mm = weighted_sum_mm3_per_mm / total_multipath_length;
|
||||
// Orca: end of multipath average mm3_per_mm value calculation
|
||||
|
||||
if (!enable_seam_slope) {
|
||||
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
|
||||
gcode += this->_extrude(*path, description, speed_for_path(*path));
|
||||
// Orca: Adaptive PA - dont adapt PA after the first pultipath extrusion is completed
|
||||
// as we have already set the PA value to the average flow over the totality of the path
|
||||
// in the first extrude move
|
||||
// TODO: testing is needed with slope seams and adaptive PA.
|
||||
m_multi_flow_segment_path_pa_set = true;
|
||||
}
|
||||
} else {
|
||||
// Create seam slope
|
||||
|
@ -4627,6 +4672,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
// Then extrude it
|
||||
for (const auto& p : new_loop.get_all_paths()) {
|
||||
gcode += this->_extrude(*p, description, speed_for_path(*p));
|
||||
// Orca: Adaptive PA - dont adapt PA after the first pultipath extrusion is completed
|
||||
// as we have already set the PA value to the average flow over the totality of the path
|
||||
// in the first extrude move
|
||||
m_multi_flow_segment_path_pa_set = true;
|
||||
}
|
||||
|
||||
// Fix path for wipe
|
||||
|
@ -4698,8 +4747,31 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string
|
|||
{
|
||||
// extrude along the path
|
||||
std::string gcode;
|
||||
for (ExtrusionPath path : multipath.paths)
|
||||
|
||||
//Orca: calculate multipath average mm3_per_mm value over the length of the path.
|
||||
//This is used for adaptive PA
|
||||
m_multi_flow_segment_path_pa_set = false; // always emit PA on the first path of the multi-path
|
||||
m_multi_flow_segment_path_average_mm3_per_mm = 0;
|
||||
double weighted_sum_mm3_per_mm = 0.0;
|
||||
double total_multipath_length = 0.0;
|
||||
for (const ExtrusionPath& path : multipath.paths) {
|
||||
if(!path.is_force_no_extrusion()){
|
||||
double path_length = unscale<double>(path.length()); //path length in mm
|
||||
weighted_sum_mm3_per_mm += path.mm3_per_mm * path_length;
|
||||
total_multipath_length += path_length;
|
||||
}
|
||||
}
|
||||
if (total_multipath_length > 0.0)
|
||||
m_multi_flow_segment_path_average_mm3_per_mm = weighted_sum_mm3_per_mm / total_multipath_length;
|
||||
// Orca: end of multipath average mm3_per_mm value calculation
|
||||
|
||||
for (ExtrusionPath path : multipath.paths){
|
||||
gcode += this->_extrude(path, description, speed);
|
||||
// Orca: Adaptive PA - dont adapt PA after the first pultipath extrusion is completed
|
||||
// as we have already set the PA value to the average flow over the totality of the path
|
||||
// in the first extrude move.
|
||||
m_multi_flow_segment_path_pa_set = true;
|
||||
}
|
||||
|
||||
// BBS
|
||||
if (m_wipe.enable) {
|
||||
|
@ -4733,7 +4805,10 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string des
|
|||
|
||||
std::string GCode::extrude_path(ExtrusionPath path, std::string description, double speed)
|
||||
{
|
||||
// description += ExtrusionEntity::role_to_string(path.role());
|
||||
// Orca: Reset average multipath flow as this is a single line, single extrude volumetric speed path
|
||||
m_multi_flow_segment_path_pa_set = false;
|
||||
m_multi_flow_segment_path_average_mm3_per_mm = 0;
|
||||
// description += ExtrusionEntity::role_to_string(path.role());
|
||||
std::string gcode = this->_extrude(path, description, speed);
|
||||
if (m_wipe.enable) {
|
||||
m_wipe.path = std::move(path.polyline);
|
||||
|
@ -4794,8 +4869,8 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
|||
|
||||
std::string gcode;
|
||||
if (! support_fills.entities.empty()) {
|
||||
const double support_speed = m_config.support_speed.value;
|
||||
const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
// const double support_speed = m_config.support_speed.value;
|
||||
// const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
for (const ExtrusionEntity *ee : support_fills.entities) {
|
||||
ExtrusionRole role = ee->role();
|
||||
assert(role == erSupportMaterial || role == erSupportMaterialInterface || role == erSupportTransition);
|
||||
|
@ -5199,7 +5274,28 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
}
|
||||
|
||||
double F = speed * 60; // convert mm/sec to mm/min
|
||||
|
||||
|
||||
// Orca: Dynamic PA
|
||||
// If adaptive PA is enabled, by default evaluate PA on all extrusion moves
|
||||
bool evaluate_adaptive_pa = false;
|
||||
bool role_change = (m_last_extrusion_role != path.role());
|
||||
if(EXTRUDER_CONFIG(adaptive_pressure_advance) && EXTRUDER_CONFIG(enable_pressure_advance)){
|
||||
evaluate_adaptive_pa = true;
|
||||
// If we have already emmited a PA change because the m_multi_flow_segment_path_pa_set is set
|
||||
// skip re-issuing the PA change tag.
|
||||
if (m_multi_flow_segment_path_pa_set && evaluate_adaptive_pa)
|
||||
evaluate_adaptive_pa = false;
|
||||
// TODO: Explore forcing evaluation of PA if a role change is happening mid extrusion.
|
||||
// TODO: This would enable adapting PA for overhang perimeters as they are part of the current loop
|
||||
// TODO: The issue with simply enabling PA evaluation on a role change is that the speed change
|
||||
// TODO: is issued before the overhang perimeter role change is triggered
|
||||
// TODO: because for some reason (maybe path segmentation upstream?) there is a short path extruded
|
||||
// TODO: with the overhang speed and flow before the role change is flagged in the path.role() function.
|
||||
if(role_change)
|
||||
evaluate_adaptive_pa = true;
|
||||
}
|
||||
// Orca: End of dynamic PA trigger flag segment
|
||||
|
||||
//Orca: process custom gcode for extrusion role change
|
||||
if (path.role() != m_last_extrusion_role && !m_config.change_extrusion_role_gcode.value.empty()) {
|
||||
DynamicConfig config;
|
||||
|
@ -5255,6 +5351,45 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_last_height);
|
||||
gcode += buf;
|
||||
}
|
||||
|
||||
// Orca: Dynamic PA
|
||||
// Post processor flag generation code segment when option to emit only at role changes is enabled
|
||||
// Variables published to the post processor:
|
||||
// 1) Tag to trigger a PA evaluation (because a role change was identified and the user has requested dynamic PA adjustments)
|
||||
// 2) Current extruder ID (to identify the PA model for the currently used extruder)
|
||||
// 3) mm3_per_mm value (to then multiply by the final model print speed after slowdown for cooling is applied)
|
||||
// 4) the current acceleration (to pass to the model for evaluation)
|
||||
// 5) whether this is an external perimeter (for future use)
|
||||
// 6) whether this segment is triggered because of a role change (to aid in calculation of average speed for the role)
|
||||
// This tag simplifies the creation of the gcode post processor while also keeping the feature decoupled from other tags.
|
||||
if (evaluate_adaptive_pa) {
|
||||
bool isOverhangPerimeter = (path.role() == erOverhangPerimeter);
|
||||
if (m_multi_flow_segment_path_average_mm3_per_mm > 0) {
|
||||
sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n",
|
||||
GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(),
|
||||
m_writer.extruder()->id(),
|
||||
m_multi_flow_segment_path_average_mm3_per_mm,
|
||||
acceleration_i,
|
||||
((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)),
|
||||
role_change,
|
||||
isOverhangPerimeter);
|
||||
gcode += buf;
|
||||
} else if(_mm3_per_mm >0 ){ // Triggered when extruding a single segment path (like a line).
|
||||
// Check if mm3_mm value is greater than zero as the wipe before external perimeter
|
||||
// is a zero mm3_mm path to force de-retraction to happen and we dont want
|
||||
// to issue a zero flow PA change command for this
|
||||
sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n",
|
||||
GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(),
|
||||
m_writer.extruder()->id(),
|
||||
_mm3_per_mm,
|
||||
acceleration_i,
|
||||
((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)),
|
||||
role_change,
|
||||
isOverhangPerimeter);
|
||||
gcode += buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto overhang_fan_threshold = EXTRUDER_CONFIG(overhang_fan_threshold);
|
||||
auto enable_overhang_bridge_fan = EXTRUDER_CONFIG(enable_overhang_bridge_fan);
|
||||
|
@ -5305,6 +5440,54 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
|
||||
if (!variable_speed) {
|
||||
// F is mm per minute.
|
||||
if( (std::abs(writer().get_current_speed() - F) > EPSILON) || (std::abs(_mm3_per_mm - m_last_mm3_mm) > EPSILON) ){
|
||||
// ORCA: Adaptive PA code segment when adjusting PA within the same feature
|
||||
// There is a speed change coming out of an overhang region
|
||||
// or a flow change, so emit the flag to evaluate PA for the upcomming extrusion
|
||||
// Emit tag before new speed is set so the post processor reads the next speed immediately and uses it.
|
||||
// Dont emit tag if it has just already been emitted from a role change above
|
||||
if(_mm3_per_mm >0 &&
|
||||
EXTRUDER_CONFIG(adaptive_pressure_advance) &&
|
||||
EXTRUDER_CONFIG(enable_pressure_advance) &&
|
||||
EXTRUDER_CONFIG(adaptive_pressure_advance_overhangs) &&
|
||||
!evaluate_adaptive_pa){
|
||||
if(writer().get_current_speed() > F){ // Ramping down speed - use overhang logic where the minimum speed is used between current and upcoming extrusion
|
||||
if(m_config.gcode_comments){
|
||||
sprintf(buf, "; Ramp down-non-variable\n");
|
||||
gcode += buf;
|
||||
}
|
||||
sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n",
|
||||
GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(),
|
||||
m_writer.extruder()->id(),
|
||||
_mm3_per_mm,
|
||||
acceleration_i,
|
||||
((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)),
|
||||
1, // Force a dummy "role change" & "overhang perimeter" for the post processor, as, while technically it is not a role change,
|
||||
// the properties of the extrusion in the overhang are different so it behaves similarly to a role
|
||||
// change for the Adaptive PA post processor.
|
||||
1);
|
||||
}else{ // Ramping up speed - use baseline logic where max speed is used between current and upcoming extrusion
|
||||
if(m_config.gcode_comments){
|
||||
sprintf(buf, "; Ramp up-non-variable\n");
|
||||
gcode += buf;
|
||||
}
|
||||
sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n",
|
||||
GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(),
|
||||
m_writer.extruder()->id(),
|
||||
_mm3_per_mm,
|
||||
acceleration_i,
|
||||
((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)),
|
||||
1, // Force a dummy "role change" & "overhang perimeter" for the post processor, as, while technically it is not a role change,
|
||||
// the properties of the extrusion in the overhang are different so it is technically similar to a role
|
||||
// change for the Adaptive PA post processor.
|
||||
0);
|
||||
}
|
||||
gcode += buf;
|
||||
m_last_mm3_mm = _mm3_per_mm;
|
||||
}
|
||||
// ORCA: End of adaptive PA code segment
|
||||
}
|
||||
|
||||
gcode += m_writer.set_speed(F, "", comment);
|
||||
{
|
||||
if (m_enable_cooling_markers) {
|
||||
|
@ -5499,6 +5682,52 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
continue;
|
||||
path_length += line_length;
|
||||
double new_speed = pre_processed_point.speed * 60.0;
|
||||
|
||||
if ((std::abs(last_set_speed - new_speed) > EPSILON) || (std::abs(_mm3_per_mm - m_last_mm3_mm) > EPSILON)) {
|
||||
// ORCA: Adaptive PA code segment when adjusting PA within the same feature
|
||||
// There is a speed change or flow change so emit the flag to evaluate PA for the upcomming extrusion
|
||||
// Emit tag before new speed is set so the post processor reads the next speed immediately and uses it.
|
||||
if(_mm3_per_mm >0 &&
|
||||
EXTRUDER_CONFIG(adaptive_pressure_advance) &&
|
||||
EXTRUDER_CONFIG(enable_pressure_advance) &&
|
||||
EXTRUDER_CONFIG(adaptive_pressure_advance_overhangs) ){
|
||||
if(last_set_speed > new_speed){ // Ramping down speed - use overhang logic where the minimum speed is used between current and upcoming extrusion
|
||||
if(m_config.gcode_comments) {
|
||||
sprintf(buf, "; Ramp up-variable\n");
|
||||
gcode += buf;
|
||||
}
|
||||
sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n",
|
||||
GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(),
|
||||
m_writer.extruder()->id(),
|
||||
_mm3_per_mm,
|
||||
acceleration_i,
|
||||
((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)),
|
||||
1, // Force a dummy "role change" & "overhang perimeter" for the post processor, as, while technically it is not a role change,
|
||||
// the properties of the extrusion in the overhang are different so it is technically similar to a role
|
||||
// change for the Adaptive PA post processor.
|
||||
1);
|
||||
}else{ // Ramping up speed - use baseline logic where max speed is used between current and upcoming extrusion
|
||||
if(m_config.gcode_comments) {
|
||||
sprintf(buf, "; Ramp down-variable\n");
|
||||
gcode += buf;
|
||||
}
|
||||
sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n",
|
||||
GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(),
|
||||
m_writer.extruder()->id(),
|
||||
_mm3_per_mm,
|
||||
acceleration_i,
|
||||
((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)),
|
||||
1, // Force a dummy "role change" & "overhang perimeter" for the post processor, as, while technically it is not a role change,
|
||||
// the properties of the extrusion in the overhang are different so it is technically similar to a role
|
||||
// change for the Adaptive PA post processor.
|
||||
0);
|
||||
}
|
||||
gcode += buf;
|
||||
m_last_mm3_mm = _mm3_per_mm;
|
||||
}
|
||||
}// ORCA: End of adaptive PA code segment
|
||||
|
||||
|
||||
if (last_set_speed != new_speed) {
|
||||
gcode += m_writer.set_speed(new_speed, "", comment);
|
||||
last_set_speed = new_speed;
|
||||
|
@ -5807,7 +6036,6 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
|
|||
for (int i = 0; i < m_config.z_hop.size(); i++)
|
||||
max_z_hop = std::max(max_z_hop, (float)m_config.z_hop.get_at(i));
|
||||
float travel_len_thresh = scale_(max_z_hop / tan(this->writer().extruder()->travel_slope()));
|
||||
float accum_len = 0.f;
|
||||
Polyline clipped_travel;
|
||||
|
||||
clipped_travel.append(Polyline(travel.points[0], travel.points[1]));
|
||||
|
@ -5909,7 +6137,6 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
|
|||
}
|
||||
|
||||
if (needs_lift && can_lift) {
|
||||
size_t extruder_id = m_writer.extruder()->id();
|
||||
gcode += m_writer.lift(!m_spiral_vase ? lift_type : LiftType::NormalLift);
|
||||
}
|
||||
|
||||
|
@ -5944,6 +6171,9 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z, bool b
|
|||
}
|
||||
if (m_config.enable_pressure_advance.get_at(extruder_id)) {
|
||||
gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(extruder_id));
|
||||
// Orca: Adaptive PA
|
||||
// Reset Adaptive PA processor last PA value
|
||||
m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(extruder_id));
|
||||
}
|
||||
|
||||
gcode += m_writer.toolchange(extruder_id);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue