From e167f89086902ab2f053a897c2b298aa80f9e48a Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 19 Apr 2024 16:57:03 +0200 Subject: [PATCH] Add extra travel move to outer wall start position CURA-11830 --- include/LayerPlan.h | 12 ++++++++--- src/InsetOrderOptimizer.cpp | 3 ++- src/LayerPlan.cpp | 42 ++++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/include/LayerPlan.h b/include/LayerPlan.h index 205779c088..1b4e59a73c 100644 --- a/include/LayerPlan.h +++ b/include/LayerPlan.h @@ -311,10 +311,13 @@ class LayerPlan : public NoCopy * The first travel move in a layer will result in a bogus travel move with * no combing and no retraction. This travel move needs to be fixed * afterwards. - * \param p The point to travel to. + * \param pos The point to travel to. * \param force_retract Whether to force a retraction to occur. + * \param next Optionally, the next point of the segment we are moving to. When given, we will + * add (when possible) an intermediate point where to go in order to start printing the segment + * with proper nozzle speed and unretraction. */ - GCodePath& addTravel(const Point2LL& p, const bool force_retract = false, const coord_t z_offset = 0); + GCodePath& addTravel(const Point2LL& pos, const bool force_retract = false, const coord_t z_offset = 0, const Point2LL* next = nullptr); /*! * Add a travel path to a certain point and retract if needed. @@ -500,6 +503,8 @@ class LayerPlan : public NoCopy * polyline). * \param is_reversed Whether to print this wall in reverse direction. * \param is_linked_path Whether the path is a continuation off the previous path + * \param smooth_approach Whether we should make a smoothed approach to the first point, + * or just move straight to it */ void addWall( const ExtrusionLine& wall, @@ -513,7 +518,8 @@ class LayerPlan : public NoCopy bool always_retract, const bool is_closed, const bool is_reversed, - const bool is_linked_path); + const bool is_linked_path, + const bool smooth_approach = false); /*! * Add an infill wall to the g-code diff --git a/src/InsetOrderOptimizer.cpp b/src/InsetOrderOptimizer.cpp index 9ef4c14e15..f437706ef4 100644 --- a/src/InsetOrderOptimizer.cpp +++ b/src/InsetOrderOptimizer.cpp @@ -149,7 +149,8 @@ bool InsetOrderOptimizer::addToLayer() retract_before, path.is_closed_, backwards, - linked_path); + linked_path, + is_outer_wall); added_something = true; } return added_something; diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 29f50d71cb..4ce0bc0ade 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -368,8 +368,16 @@ std::optional> LayerPlan::getFirstTravelDestinationSta return ret; } -GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, const coord_t z_offset) +GCodePath& LayerPlan::addTravel(const Point2LL& pos, const bool force_retract, const coord_t z_offset, const Point2LL* next) { + if (next) + { + // First travel to intermediate position + Point2LL direction = *next - pos; + direction = (direction * 1000) / vSize(direction); + addTravel(pos - direction * 15); + } + const GCodePathConfig& travel_config = configs_storage_.travel_config_per_extruder[getExtruder()]; const RetractionConfig& retraction_config @@ -392,7 +400,7 @@ GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, con if (is_first_travel_of_layer) { bypass_combing = true; // first travel move is bogus; it is added after this and the previous layer have been planned in LayerPlanBuffer::addConnectingTravelMove - first_travel_destination_ = p; + first_travel_destination_ = pos; first_travel_destination_is_inside_ = is_inside_; if (layer_nr_ == 0 && retraction_enable && mesh_or_extruder_settings.get("retraction_hop_enabled")) { @@ -401,7 +409,7 @@ GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, con } forceNewPathStart(); // force a new travel path after this first bogus move } - else if (force_retract && last_planned_position_ && ! shorterThen(*last_planned_position_ - p, retraction_config.retraction_min_travel_distance)) + else if (force_retract && last_planned_position_ && ! shorterThen(*last_planned_position_ - pos, retraction_config.retraction_min_travel_distance)) { // path is not shorter than min travel distance, force a retraction path->retract = true; @@ -427,7 +435,7 @@ GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, con perform_z_hops_only_when_collides, *extruder, *last_planned_position_, - p, + pos, combPaths, was_inside_, is_inside_, @@ -473,7 +481,7 @@ GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, con last_point = comb_point; } } - distance += vSize(last_point - p); + distance += vSize(last_point - pos); const coord_t retract_threshold = mesh_or_extruder_settings.get("retraction_combing_max_distance"); path->retract = retract || (retract_threshold > 0 && distance > retract_threshold && retraction_enable); // don't perform a z-hop @@ -489,14 +497,14 @@ GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, con // CURA-6675: // Retraction Minimal Travel Distance should work for all travel moves. If the travel move is shorter than the // Retraction Minimal Travel Distance, retraction should be disabled. - if (! is_first_travel_of_layer && last_planned_position_ && shorterThen(*last_planned_position_ - p, retraction_config.retraction_min_travel_distance)) + if (! is_first_travel_of_layer && last_planned_position_ && shorterThen(*last_planned_position_ - pos, retraction_config.retraction_min_travel_distance)) { path->retract = false; path->perform_z_hop = false; } // no combing? retract only when path is not shorter than minimum travel distance - if (! combed && ! is_first_travel_of_layer && last_planned_position_ && ! shorterThen(*last_planned_position_ - p, retraction_config.retraction_min_travel_distance)) + if (! combed && ! is_first_travel_of_layer && last_planned_position_ && ! shorterThen(*last_planned_position_ - pos, retraction_config.retraction_min_travel_distance)) { if (was_inside_) // when the previous location was from printing something which is considered inside (not support or prime tower etc) { // then move inside the printed part, so that we don't ooze on the outer wall while retraction, but on the inside of the print. @@ -516,7 +524,7 @@ GCodePath& LayerPlan::addTravel(const Point2LL& p, const bool force_retract, con // must start new travel path as retraction can be enabled or not depending on path length, etc. forceNewPathStart(); - GCodePath& ret = addTravel_simple(p, path); + GCodePath& ret = addTravel_simple(pos, path); was_inside_ = is_inside_; return ret; } @@ -1007,9 +1015,10 @@ void LayerPlan::addWall( bool always_retract, const bool is_closed, const bool is_reversed, - const bool is_linked_path) + const bool is_linked_path, + const bool smooth_approach) { - if (wall.empty()) + if (wall.size() < 2) { return; } @@ -1110,7 +1119,6 @@ void LayerPlan::addWall( } }; - bool first_line = true; const coord_t small_feature_max_length = settings.get("small_feature_max_length"); const bool is_small_feature = (small_feature_max_length > 0) && (layer_nr_ == 0 || wall.inset_idx_ == 0) && wall.shorterThan(small_feature_max_length); Ratio small_feature_speed_factor = settings.get((layer_nr_ == 0) ? "small_feature_speed_factor_0" : "small_feature_speed_factor"); @@ -1119,10 +1127,12 @@ void LayerPlan::addWall( const coord_t max_area_deviation = std::max(settings.get("meshfix_maximum_extrusion_area_deviation"), 1); // Square micrometres! const coord_t max_resolution = std::max(settings.get("meshfix_maximum_resolution"), coord_t(1)); - ExtrusionJunction p0 = wall[start_idx]; - const int direction = is_reversed ? -1 : 1; const size_t max_index = is_closed ? wall.size() + 1 : wall.size(); + + ExtrusionJunction p0 = wall[start_idx]; + addTravel(p0.p_, always_retract, 0, smooth_approach ? &(wall[(wall.size() + start_idx + direction) % wall.size()].p_) : nullptr); + for (size_t point_idx = 1; point_idx < max_index; point_idx++) { const ExtrusionJunction& p1 = wall[(wall.size() + start_idx + point_idx * direction) % wall.size()]; @@ -1132,12 +1142,6 @@ void LayerPlan::addWall( computeDistanceToBridgeStart((wall.size() + start_idx + point_idx * direction - 1) % wall.size()); } - if (first_line) - { - addTravel(p0.p_, always_retract); - first_line = false; - } - /* If the line has variable width, break it up into pieces with the following constraints: