mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-09-16 14:13:16 +08:00
parent
d2c6929192
commit
fee585a0ae
@ -2917,7 +2917,7 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
|
|||||||
speed = -1;
|
speed = -1;
|
||||||
// get a copy; don't modify the orientation of the original loop object otherwise
|
// get a copy; don't modify the orientation of the original loop object otherwise
|
||||||
// next copies (if any) would not detect the correct orientation
|
// next copies (if any) would not detect the correct orientation
|
||||||
ExtrusionLoop loop = original_loop;
|
ExtrusionLoop loop_to_seam = original_loop;
|
||||||
|
|
||||||
if (m_layer->lower_layer != nullptr && lower_layer_edge_grid != nullptr) {
|
if (m_layer->lower_layer != nullptr && lower_layer_edge_grid != nullptr) {
|
||||||
if (!*lower_layer_edge_grid) {
|
if (!*lower_layer_edge_grid) {
|
||||||
@ -2942,21 +2942,19 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
|
|||||||
|
|
||||||
// extrude all loops ccw
|
// extrude all loops ccw
|
||||||
//no! this was decided in perimeter_generator
|
//no! this was decided in perimeter_generator
|
||||||
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0;// loop.make_counter_clockwise();
|
bool is_hole_loop = (loop_to_seam.loop_role() & ExtrusionLoopRole::elrHole) != 0;// loop.make_counter_clockwise();
|
||||||
bool reverse_turn = loop.polygon().is_clockwise() ^ is_hole_loop;
|
bool reverse_turn = loop_to_seam.polygon().is_clockwise() ^ is_hole_loop;
|
||||||
|
|
||||||
split_at_seam_pos(loop, lower_layer_edge_grid, reverse_turn);
|
split_at_seam_pos(loop_to_seam, lower_layer_edge_grid, reverse_turn);
|
||||||
|
const coordf_t full_loop_dist = loop_to_seam.length();
|
||||||
|
|
||||||
// clip the path to avoid the extruder to get exactly on the first point of the loop;
|
// don't clip the path ?
|
||||||
// if polyline was shorter than the clipping distance we'd get a null polyline, so
|
ExtrusionPaths &paths = loop_to_seam.paths;
|
||||||
// we discard it in that case
|
if (false && m_enable_loop_clipping && m_writer.tool_is_extruder()) {
|
||||||
coordf_t clip_length = 0;
|
coordf_t clip_length = scale_(m_config.seam_gap.get_abs_value(m_writer.tool()->id(), EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
||||||
coordf_t min_clip_length = scale_(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)) * 0.15;
|
coordf_t min_clip_length = scale_(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)) * 0.15;
|
||||||
if (m_enable_loop_clipping && m_writer.tool_is_extruder())
|
|
||||||
clip_length = scale_(m_config.seam_gap.get_abs_value(m_writer.tool()->id(), EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
|
||||||
|
|
||||||
// get paths
|
// get paths
|
||||||
ExtrusionPaths paths = loop.paths;
|
|
||||||
ExtrusionPaths clipped;
|
ExtrusionPaths clipped;
|
||||||
if (clip_length > min_clip_length) {
|
if (clip_length > min_clip_length) {
|
||||||
clipped = clip_end(paths, clip_length);
|
clipped = clip_end(paths, clip_length);
|
||||||
@ -2967,6 +2965,8 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
|
|||||||
} else {
|
} else {
|
||||||
clip_end(paths, clip_length);
|
clip_end(paths, clip_length);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (paths.empty()) return "";
|
if (paths.empty()) return "";
|
||||||
|
|
||||||
// apply the small/external? perimeter speed
|
// apply the small/external? perimeter speed
|
||||||
@ -2974,12 +2974,12 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
|
|||||||
coordf_t min_length = scale_d(this->m_config.small_perimeter_min_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
coordf_t min_length = scale_d(this->m_config.small_perimeter_min_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
||||||
coordf_t max_length = scale_d(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
coordf_t max_length = scale_d(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
||||||
max_length = std::max(min_length, max_length);
|
max_length = std::max(min_length, max_length);
|
||||||
if (loop.length() < max_length) {
|
if (full_loop_dist < max_length) {
|
||||||
if (loop.length() <= min_length) {
|
if (full_loop_dist <= min_length) {
|
||||||
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
||||||
} else if (max_length > min_length) {
|
} else if (max_length > min_length) {
|
||||||
//use a negative speed: it will be use as a ratio when computing the real speed
|
//use a negative speed: it will be use as a ratio when computing the real speed
|
||||||
speed = -(loop.length() - min_length) / (max_length - min_length);
|
speed = -(full_loop_dist - min_length) / (max_length - min_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3245,7 +3245,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
|
|||||||
|
|
||||||
// get a copy; don't modify the orientation of the original loop object otherwise
|
// get a copy; don't modify the orientation of the original loop object otherwise
|
||||||
// next copies (if any) would not detect the correct orientation
|
// next copies (if any) would not detect the correct orientation
|
||||||
ExtrusionLoop loop = original_loop;
|
ExtrusionLoop loop_to_seam = original_loop;
|
||||||
|
|
||||||
if (m_layer->lower_layer != nullptr && lower_layer_edge_grid != nullptr) {
|
if (m_layer->lower_layer != nullptr && lower_layer_edge_grid != nullptr) {
|
||||||
if (! *lower_layer_edge_grid) {
|
if (! *lower_layer_edge_grid) {
|
||||||
@ -3271,48 +3271,55 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
|
|||||||
// extrude all loops ccw
|
// extrude all loops ccw
|
||||||
//no! this was decided in perimeter_generator
|
//no! this was decided in perimeter_generator
|
||||||
//but we need to know where is "inside", so we will use is_hole_loop. if is_hole_loop, then we need toconsider that the right direction is clockwise, else counter clockwise.
|
//but we need to know where is "inside", so we will use is_hole_loop. if is_hole_loop, then we need toconsider that the right direction is clockwise, else counter clockwise.
|
||||||
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0;// loop.make_counter_clockwise();
|
bool is_hole_loop = (loop_to_seam.loop_role() & ExtrusionLoopRole::elrHole) != 0;// loop.make_counter_clockwise();
|
||||||
|
|
||||||
//if spiral vase, we have to ensure that all loops are in the same orientation.
|
//if spiral vase, we have to ensure that all loops are in the same orientation.
|
||||||
if (this->m_config.spiral_vase) {
|
if (this->m_config.spiral_vase) {
|
||||||
loop.make_counter_clockwise();
|
loop_to_seam.make_counter_clockwise();
|
||||||
is_hole_loop = false;
|
is_hole_loop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
split_at_seam_pos(loop, lower_layer_edge_grid, is_hole_loop);
|
split_at_seam_pos(loop_to_seam, lower_layer_edge_grid, is_hole_loop);
|
||||||
|
const coordf_t full_loop_length = loop_to_seam.length();
|
||||||
|
const bool is_full_loop_ccw = loop_to_seam.polygon().is_counter_clockwise();
|
||||||
|
//after that point, loop_to_seam can be modified by 'paths', so don't use it anymore
|
||||||
|
|
||||||
// clip the path to avoid the extruder to get exactly on the first point of the loop;
|
// clip the path to avoid the extruder to get exactly on the first point of the loop;
|
||||||
// if polyline was shorter than the clipping distance we'd get a null polyline, so
|
// if polyline was shorter than the clipping distance we'd get a null polyline, so
|
||||||
// we discard it in that case
|
// we discard it in that case
|
||||||
coordf_t clip_length = 0;
|
ExtrusionPaths& paths = loop_to_seam.paths;
|
||||||
|
if (m_enable_loop_clipping && m_writer.tool_is_extruder()) {
|
||||||
|
coordf_t clip_length = scale_(m_config.seam_gap.get_abs_value(m_writer.tool()->id(), EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
||||||
coordf_t min_clip_length = scale_(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)) * 0.15;
|
coordf_t min_clip_length = scale_(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)) * 0.15;
|
||||||
if (m_enable_loop_clipping && m_writer.tool_is_extruder())
|
|
||||||
clip_length = scale_(m_config.seam_gap.get_abs_value(m_writer.tool()->id(), EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
|
||||||
|
|
||||||
// get paths
|
// get paths
|
||||||
ExtrusionPaths paths = loop.paths;
|
|
||||||
ExtrusionPaths clipped;
|
ExtrusionPaths clipped;
|
||||||
if (clip_length > min_clip_length) {
|
if (clip_length > min_clip_length) {
|
||||||
|
// remove clip_length, like normally, but keep the removed part
|
||||||
clipped = clip_end(paths, clip_length);
|
clipped = clip_end(paths, clip_length);
|
||||||
|
// remove min_clip_length from the removed paths
|
||||||
clip_end(clipped, min_clip_length);
|
clip_end(clipped, min_clip_length);
|
||||||
|
// ensure that the removed paths are travels
|
||||||
for (ExtrusionPath& ep : clipped)
|
for (ExtrusionPath& ep : clipped)
|
||||||
ep.mm3_per_mm = 0;
|
ep.mm3_per_mm = 0;
|
||||||
|
// re-add removed paths as travels.
|
||||||
append(paths, clipped);
|
append(paths, clipped);
|
||||||
} else {
|
} else {
|
||||||
clip_end(paths, clip_length);
|
clip_end(paths, clip_length);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (paths.empty()) return "";
|
if (paths.empty()) return "";
|
||||||
|
|
||||||
// apply the small perimeter speed
|
// apply the small perimeter speed
|
||||||
if (speed == -1 && is_perimeter(paths.front().role()) && loop.length() <=
|
if (speed == -1 && is_perimeter(paths.front().role()) && full_loop_length <=
|
||||||
scale_(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)))) {
|
scale_(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)))) {
|
||||||
double min_length = scale_d(this->m_config.small_perimeter_min_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
double min_length = scale_d(this->m_config.small_perimeter_min_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
||||||
double max_length = scale_d(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
double max_length = scale_d(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
|
||||||
if (loop.length() <= min_length) {
|
if (full_loop_length <= min_length) {
|
||||||
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
||||||
} else {
|
} else {
|
||||||
//set speed between -1 and 0 you have to multiply the real peed by the opposite of that, and add the other part as small_perimeter_speed
|
//set speed between -1 and 0 you have to multiply the real peed by the opposite of that, and add the other part as small_perimeter_speed
|
||||||
speed = (min_length - loop.length()) / (max_length - min_length);
|
speed = (min_length - full_loop_length) / (max_length - min_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3331,8 +3338,9 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
|
|||||||
if (m_wipe.enable)
|
if (m_wipe.enable)
|
||||||
m_wipe.path = paths.front().polyline; // TODO: don't limit wipe to last path
|
m_wipe.path = paths.front().polyline; // TODO: don't limit wipe to last path
|
||||||
|
|
||||||
//wipe for External Perimeter
|
//wipe for External Perimeter (and not vase)
|
||||||
if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 0 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 2) {
|
if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 0 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 2
|
||||||
|
&& (m_enable_loop_clipping && m_writer.tool_is_extruder()) ) {
|
||||||
//get points for wipe
|
//get points for wipe
|
||||||
Point prev_point = *(paths.back().polyline.points.end() - 2); // second to last point
|
Point prev_point = *(paths.back().polyline.points.end() - 2); // second to last point
|
||||||
// *(paths.back().polyline.points.end() - 2) this is the same as (or should be) as paths.front().first_point();
|
// *(paths.back().polyline.points.end() - 2) this is the same as (or should be) as paths.front().first_point();
|
||||||
@ -3395,14 +3403,14 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
|
|||||||
//FIXME improve the algorithm in case the loop is split into segments with a low number of points (see the Point b query).
|
//FIXME improve the algorithm in case the loop is split into segments with a low number of points (see the Point b query).
|
||||||
Point a = next_point; // second point
|
Point a = next_point; // second point
|
||||||
Point b = prev_point; // second to last point
|
Point b = prev_point; // second to last point
|
||||||
if (is_hole_loop ? loop.polygon().is_counter_clockwise() : loop.polygon().is_clockwise()) {
|
if (is_hole_loop ? is_full_loop_ccw : (!is_full_loop_ccw)) {
|
||||||
// swap points
|
// swap points
|
||||||
Point c = a; a = b; b = c;
|
Point c = a; a = b; b = c;
|
||||||
}
|
}
|
||||||
double angle = current_point.ccw_angle(a, b) / 3;
|
double angle = current_point.ccw_angle(a, b) / 3;
|
||||||
|
|
||||||
// turn left if contour, turn right if hole
|
// turn left if contour, turn right if hole
|
||||||
if (is_hole_loop ? loop.polygon().is_counter_clockwise() : loop.polygon().is_clockwise()) angle *= -1;
|
if (is_hole_loop ? is_full_loop_ccw : (!is_full_loop_ccw)) angle *= -1;
|
||||||
|
|
||||||
// create the destination point along the first segment and rotate it
|
// create the destination point along the first segment and rotate it
|
||||||
// we make sure we don't exceed the segment length because we don't know
|
// we make sure we don't exceed the segment length because we don't know
|
||||||
|
Loading…
x
Reference in New Issue
Block a user