mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 15:37:30 -06:00
Merge branch 'main' into enh-port-edit-gcode-dlg
This commit is contained in:
commit
9f44e151ba
32 changed files with 423 additions and 196 deletions
|
@ -4473,7 +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)
|
||||
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
|
||||
|
@ -4518,8 +4518,12 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
// extrude along the path
|
||||
std::string gcode;
|
||||
|
||||
// Orca:
|
||||
// Port of "wipe inside before extruding an external perimeter" feature from super slicer
|
||||
if (m_config.wipe_before_external_loop.value && !paths.empty() && paths.front().size() > 1 && paths.back().size() > 1 && paths.front().role() == erExternalPerimeter) {
|
||||
// If region perimeters size not greater than or equal to 2, then skip the wipe inside move as we will extrude in mid air
|
||||
// as no neighbouring perimeter exists. If an internal perimeter exists, we should find 2 perimeters touching the de-retraction point
|
||||
// 1 - the currently printed external perimeter and 2 - the neighbouring internal perimeter.
|
||||
if (m_config.wipe_before_external_loop.value && !paths.empty() && paths.front().size() > 1 && paths.back().size() > 1 && paths.front().role() == erExternalPerimeter && region_perimeters.size() > 1) {
|
||||
const bool is_full_loop_ccw = loop.polygon().is_counter_clockwise();
|
||||
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0; // loop.make_counter_clockwise();
|
||||
const double nozzle_diam = EXTRUDER_CONFIG(nozzle_diameter);
|
||||
|
@ -4560,11 +4564,28 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
pt.rotate(angle, current_point);
|
||||
pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>();
|
||||
pt.rotate(angle, current_point);
|
||||
|
||||
// use extrude instead of travel_to_xy to trigger the unretract
|
||||
ExtrusionPath fake_path_wipe(Polyline{pt, current_point}, paths.front());
|
||||
fake_path_wipe.mm3_per_mm = 0;
|
||||
gcode += extrude_path(fake_path_wipe, "move inwards before retraction/seam", speed);
|
||||
|
||||
// Search region perimeters for lines that are touching the de-retraction point.
|
||||
// If an internal perimeter exists, we should find 2 perimeters touching the de-retraction point
|
||||
// 1: the currently printed external perimeter and 2: the neighbouring internal perimeter.
|
||||
int discoveredTouchingLines = 0;
|
||||
for (const ExtrusionEntity* ee : region_perimeters){
|
||||
auto potential_touching_line = ee->as_polyline();
|
||||
AABBTreeLines::LinesDistancer<Line> potential_touching_line_distancer{potential_touching_line.lines()};
|
||||
auto touching_line = potential_touching_line_distancer.all_lines_in_radius(pt, scale_(nozzle_diam));
|
||||
if(touching_line.size()){
|
||||
discoveredTouchingLines ++;
|
||||
if(discoveredTouchingLines > 1) break; // found 2 touching lines. End the search early.
|
||||
}
|
||||
}
|
||||
// found 2 perimeters touching the de-retraction point. Its safe to deretract as the point will be
|
||||
// inside the model
|
||||
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.mm3_per_mm = 0;
|
||||
gcode += extrude_path(fake_path_wipe, "move inwards before retraction/seam", speed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4657,14 +4678,14 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string
|
|||
return gcode;
|
||||
}
|
||||
|
||||
std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string description, double speed)
|
||||
std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string description, double speed, const ExtrusionEntitiesPtr& region_perimeters)
|
||||
{
|
||||
if (const ExtrusionPath* path = dynamic_cast<const ExtrusionPath*>(&entity))
|
||||
return this->extrude_path(*path, description, speed);
|
||||
else if (const ExtrusionMultiPath* multipath = dynamic_cast<const ExtrusionMultiPath*>(&entity))
|
||||
return this->extrude_multi_path(*multipath, description, speed);
|
||||
else if (const ExtrusionLoop* loop = dynamic_cast<const ExtrusionLoop*>(&entity))
|
||||
return this->extrude_loop(*loop, description, speed);
|
||||
return this->extrude_loop(*loop, description, speed, region_perimeters);
|
||||
else
|
||||
throw Slic3r::InvalidArgument("Invalid argument supplied to extrude()");
|
||||
return "";
|
||||
|
@ -4691,7 +4712,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
|
|||
m_config.apply(print.get_print_region(®ion - &by_region.front()).config());
|
||||
|
||||
for (const ExtrusionEntity* ee : region.perimeters)
|
||||
gcode += this->extrude_entity(*ee, "perimeter", -1.);
|
||||
gcode += this->extrude_entity(*ee, "perimeter", -1., region.perimeters);
|
||||
}
|
||||
return gcode;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue