Skip to content

Commit

Permalink
Apply scarf seam and speed gradient in surface mode
Browse files Browse the repository at this point in the history
CURA-12176

The addSplitWall method is now a template so that it can handle either
ExtrusionLine or Polygon objects. It also takes a function as parameter
because the way we add extrusion lines is not the same for surface mode
and normal mode.
In order to simplify this function, I added a PathAdapter class to work
with different types of paths with more transparency.
  • Loading branch information
wawanbreton committed Oct 28, 2024
1 parent 5339777 commit 893ad91
Show file tree
Hide file tree
Showing 5 changed files with 297 additions and 109 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(engine_SRCS # Except main.cpp.
src/Mold.cpp
src/multiVolumes.cpp
src/path_ordering.cpp
src/PathAdapter.cpp
src/Preheat.cpp
src/PrimeTower/PrimeTower.cpp
src/PrimeTower/PrimeTowerNormal.cpp
Expand Down
88 changes: 70 additions & 18 deletions include/LayerPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class Comb;
class SliceDataStorage;
class LayerPlanBuffer;

template<typename PathType>
class PathAdapter;

/*!
* The LayerPlan class stores multiple moves that are planned.
*
Expand Down Expand Up @@ -398,11 +401,15 @@ class LayerPlan : public NoCopy
const Polygon& polygon,
int startIdx,
const bool reverse,
const Settings& settings,
const GCodePathConfig& config,
coord_t wall_0_wipe_dist = 0,
bool spiralize = false,
const Ratio& flow_ratio = 1.0_r,
bool always_retract = false);
bool always_retract = false,
bool scarf_seam = false,
bool smooth_speed = false,
bool is_candidate_small_feature = false);

/*!
* Add polygons to the gcode with optimized order.
Expand Down Expand Up @@ -435,13 +442,16 @@ class LayerPlan : public NoCopy
void addPolygonsByOptimizer(
const Shape& polygons,
const GCodePathConfig& config,
const Settings& settings,
const ZSeamConfig& z_seam_config = ZSeamConfig(),
coord_t wall_0_wipe_dist = 0,
bool spiralize = false,
const Ratio flow_ratio = 1.0_r,
bool always_retract = false,
bool reverse_order = false,
const std::optional<Point2LL> start_near_location = std::optional<Point2LL>());
const std::optional<Point2LL> start_near_location = std::optional<Point2LL>(),
bool scarf_seam = false,
bool smooth_acceleration = false);

/*!
* Add a single line that is part of a wall to the gcode.
Expand Down Expand Up @@ -836,18 +846,15 @@ class LayerPlan : public NoCopy

/*!
* \brief Add a wall to the gcode with optimized order, but split into pieces in order to facilitate the scarf seam and/or speed gradient.
* \tparam PathType The type of path to be processed, either ExtrusionLine or some subclass of Polyline
* \param wall The full wall to be added
* \param wall_length The pre-calculated full wall length
* \param start_idx The index of the point where to start printing the wall
* \param direction The direction along which to print the wall, which should be 1 or -1
* \param max_index The last index to be used when iterating over the wall segments
* \param settings The settings which should apply to this wall added to the layer plan
* \param default_config The config with which to print the wall lines that are not spanning a bridge or are exposed to air
* \param roofing_config The config with which to print the wall lines that are exposed to air
* \param bridge_config The config with which to print the wall lines that are spanning a bridge
* \param flow_ratio The ratio with which to multiply the extrusion amount
* \param line_width_ratio The line width ratio to be applied
* \param non_bridge_line_volume A pseudo-volume that is derived from the print speed and flow of the non-bridge lines that have preceded this lin
* \param nominal_line_width The nominal line width for the wall
* \param min_bridge_line_len The minimum line width to allow an extrusion move to be processed as a bridge move
* \param always_retract Whether to force a retraction when moving to the start of the polygon (used for outer walls)
* \param is_small_feature Indicates whether the wall is so small that it should be processed differently
Expand All @@ -864,26 +871,26 @@ class LayerPlan : public NoCopy
* \param end_speed_ratio The ratio of the top speed to be applied when finishing a segment
* \param decelerate_length The pre-calculated length of the deceleration phase
* \param is_scarf_closure Indicates whether this function is called to make the scarf closure (overlap over the first scarf pass) or the normal first pass of the wall
* \param compute_distance_to_bridge_start Whether we should compute the distance to start of bridge. This is
* possible only if PathType is ExtrusionLine and will be ignored otherwise.
* \param func_add_segment The function to be called to actually add an extrusion segment with the given parameters
*/
template<class PathType>
void addSplitWall(
const ExtrusionLine& wall,
const PathAdapter<PathType>& wall,
const coord_t wall_length,
size_t start_idx,
const int direction,
const size_t start_idx,
const size_t max_index,
const Settings& settings,
const int direction,
const GCodePathConfig& default_config,
const GCodePathConfig& roofing_config,
const GCodePathConfig& bridge_config,
const double flow_ratio,
const Ratio line_width_ratio,
double& non_bridge_line_volume,
const coord_t min_bridge_line_len,
const bool always_retract,
const bool is_small_feature,
Ratio small_feature_speed_factor,
const coord_t max_area_deviation,
const auto max_resolution,
const double flow_ratio,
const coord_t nominal_line_width,
const coord_t min_bridge_line_len,
const auto scarf_seam_length,
const auto scarf_seam_start_ratio,
const auto scarf_split_distance,
Expand All @@ -893,7 +900,52 @@ class LayerPlan : public NoCopy
const coord_t accelerate_length,
const Ratio end_speed_ratio,
const coord_t decelerate_length,
const bool is_scarf_closure);
const bool is_scarf_closure,
const bool compute_distance_to_bridge_start,
const std::function<void(
const Point3LL& start,
const Point3LL& end,
const Ratio& speed_factor,
const Ratio& flow_ratio,
const Ratio& line_width_ratio,
const coord_t distance_to_bridge_start)>& func_add_segment);

/*!
* \brief Add a wall to the gcode with optimized order, possibly adding a scarf seam / speed gradient according to settings
* \tparam PathType The type of path to be processed, either ExtrusionLine or some subclass of Polyline
* \param wall The full wall to be added
* \param start_idx The index of the point where to start printing the wall
* \param settings The settings which should apply to this wall added to the layer plan
* \param default_config The config with which to print the wall lines that are not spanning a bridge or are exposed to air
* \param flow_ratio The ratio with which to multiply the extrusion amount
* \param always_retract Whether to force a retraction when moving to the start of the polygon (used for outer walls)
* \param is_closed Indicates whether the path is closed (or open)
* \param is_reversed Indicates if the path is to be processed backwards
* \param is_candidate_small_feature Indicates whether the path should be tested for being treated as a smell feature
* \param scarf_seam Indicates whether we may set a scraf seam to the path
* \param smooth_speed Indicates whether we may set a speed gradient to the path
* \param func_add_segment The function to be called to actually add an extrusion segment with the given parameters
*/
template<class PathType>
void addWallWithScarfSeam(
const PathAdapter<PathType>& wall,
size_t start_idx,
const Settings& settings,
const GCodePathConfig& default_config,
const double flow_ratio,
bool always_retract,
const bool is_closed,
const bool is_reversed,
const bool is_candidate_small_feature,
const bool scarf_seam,
const bool smooth_speed,
const std::function<void(
const Point3LL& start,
const Point3LL& end,
const Ratio& speed_factor,
const Ratio& flow_ratio,
const Ratio& line_width_ratio,
const coord_t distance_to_bridge_start)>& func_add_segment);

/*!
* \brief Helper function to calculate the distance from the start of the current wall line to the first bridge segment
Expand Down
46 changes: 35 additions & 11 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
gcode_layer.addPolygonsByOptimizer(
raft_polygons,
gcode_layer.configs_storage_.raft_base_config,
mesh_group_settings,
ZSeamConfig(),
wipe_dist,
spiralize,
Expand Down Expand Up @@ -895,6 +896,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
gcode_layer.addPolygonsByOptimizer(
raft_polygons,
gcode_layer.configs_storage_.raft_interface_config,
mesh_group_settings,
ZSeamConfig(),
wipe_dist,
spiralize,
Expand Down Expand Up @@ -1073,6 +1075,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
gcode_layer.addPolygonsByOptimizer(
raft_polygons,
gcode_layer.configs_storage_.raft_surface_config,
mesh_group_settings,
ZSeamConfig(),
wipe_dist,
spiralize,
Expand Down Expand Up @@ -1477,13 +1480,14 @@ void FffGcodeWriter::processSkirtBrim(const SliceDataStorage& storage, LayerPlan
void FffGcodeWriter::processOozeShield(const SliceDataStorage& storage, LayerPlan& gcode_layer) const
{
LayerIndex layer_nr = std::max(LayerIndex{ 0 }, gcode_layer.getLayerNr());
if (layer_nr == 0 && Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<EPlatformAdhesion>("adhesion_type") == EPlatformAdhesion::BRIM)
const Settings& mesh_group_settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings;
if (layer_nr == 0 && mesh_group_settings.get<EPlatformAdhesion>("adhesion_type") == EPlatformAdhesion::BRIM)
{
return; // ooze shield already generated by brim
}
if (storage.ooze_shield.size() > 0 && layer_nr < storage.ooze_shield.size())
{
gcode_layer.addPolygonsByOptimizer(storage.ooze_shield[layer_nr], gcode_layer.configs_storage_.skirt_brim_config_per_extruder[0]);
gcode_layer.addPolygonsByOptimizer(storage.ooze_shield[layer_nr], gcode_layer.configs_storage_.skirt_brim_config_per_extruder[0], mesh_group_settings);
}
}

Expand Down Expand Up @@ -1516,7 +1520,7 @@ void FffGcodeWriter::processDraftShield(const SliceDataStorage& storage, LayerPl
}
}

gcode_layer.addPolygonsByOptimizer(storage.draft_protection_shield, gcode_layer.configs_storage_.skirt_brim_config_per_extruder[0]);
gcode_layer.addPolygonsByOptimizer(storage.draft_protection_shield, gcode_layer.configs_storage_.skirt_brim_config_per_extruder[0], mesh_group_settings);
}

void FffGcodeWriter::calculateExtruderOrderPerLayer(const SliceDataStorage& storage)
Expand Down Expand Up @@ -1723,7 +1727,26 @@ void FffGcodeWriter::addMeshLayerToGCode_meshSurfaceMode(const SliceMeshStorage&
mesh.settings.get<EZSeamCornerPrefType>("z_seam_corner"),
mesh.settings.get<coord_t>("wall_line_width_0") * 2);
const bool spiralize = Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<bool>("magic_spiralize");
gcode_layer.addPolygonsByOptimizer(polygons, mesh_config.inset0_config, z_seam_config, mesh.settings.get<coord_t>("wall_0_wipe_dist"), spiralize);
constexpr Ratio flow_ratio = 1.0;
constexpr bool always_retract = false;
constexpr bool reverse_order = false;
constexpr std::optional<Point2LL> start_near_location = std::nullopt;
constexpr bool scarf_seam = true;
constexpr bool smooth_speed = true;

gcode_layer.addPolygonsByOptimizer(
polygons,
mesh_config.inset0_config,
mesh.settings,
z_seam_config,
mesh.settings.get<coord_t>("wall_0_wipe_dist"),
spiralize,
flow_ratio,
always_retract,
reverse_order,
start_near_location,
scarf_seam,
smooth_speed);

addMeshOpenPolyLinesToGCode(mesh, mesh_config, gcode_layer);
}
Expand Down Expand Up @@ -1966,7 +1989,7 @@ bool FffGcodeWriter::processMultiLayerInfill(
{
constexpr bool force_comb_retract = false;
gcode_layer.addTravel(infill_polygons[0][0], force_comb_retract);
gcode_layer.addPolygonsByOptimizer(infill_polygons, mesh_config.infill_config[combine_idx]);
gcode_layer.addPolygonsByOptimizer(infill_polygons, mesh_config.infill_config[combine_idx], mesh.settings);
}

if (! infill_lines.empty())
Expand Down Expand Up @@ -2723,7 +2746,7 @@ bool FffGcodeWriter::processSingleLayerInfill(
constexpr bool force_comb_retract = false;
// start the infill polygons at the nearest vertex to the current location
gcode_layer.addTravel(PolygonUtils::findNearestVert(gcode_layer.getLastPlannedPositionOrStartingPosition(), infill_polygons).p(), force_comb_retract);
gcode_layer.addPolygonsByOptimizer(infill_polygons, mesh_config.infill_config[0], ZSeamConfig(), 0, false, 1.0_r, false, false, near_start_location);
gcode_layer.addPolygonsByOptimizer(infill_polygons, mesh_config.infill_config[0], mesh.settings, ZSeamConfig(), 0, false, 1.0_r, false, false, near_start_location);
}
const bool enable_travel_optimization = mesh.settings.get<bool>("infill_enable_travel_optimization");
if (pattern == EFillMethod::GRID || pattern == EFillMethod::LINES || pattern == EFillMethod::TRIANGLES || pattern == EFillMethod::CUBIC
Expand Down Expand Up @@ -2965,7 +2988,7 @@ bool FffGcodeWriter::processInsets(
gcode_layer.addTravel(spiral_inset[spiral_start_vertex]);
}
int wall_0_wipe_dist(0);
gcode_layer.addPolygonsByOptimizer(part.spiral_wall, mesh_config.inset0_config, ZSeamConfig(), wall_0_wipe_dist);
gcode_layer.addPolygonsByOptimizer(part.spiral_wall, mesh_config.inset0_config, mesh.settings, ZSeamConfig(), wall_0_wipe_dist);
}
}
// for non-spiralized layers, determine the shape of the unsupported areas below this part
Expand Down Expand Up @@ -3596,7 +3619,7 @@ void FffGcodeWriter::processSkinPrintFeature(
{
constexpr bool force_comb_retract = false;
gcode_layer.addTravel(skin_polygons[0][0], force_comb_retract);
gcode_layer.addPolygonsByOptimizer(skin_polygons, config);
gcode_layer.addPolygonsByOptimizer(skin_polygons, config, mesh.settings);
}

if (monotonic)
Expand Down Expand Up @@ -4001,6 +4024,7 @@ bool FffGcodeWriter::processSupportInfill(const SliceDataStorage& storage, Layer
gcode_layer.addPolygonsByOptimizer(
support_polygons,
configs[combine_idx],
mesh_group_settings,
z_seam_config,
wall_0_wipe_dist,
spiralize,
Expand Down Expand Up @@ -4167,13 +4191,13 @@ bool FffGcodeWriter::addSupportRoofsToGCode(const SliceDataStorage& storage, con
gcode_layer.setIsInside(false); // going to print stuff outside print object, i.e. support
if (gcode_layer.getLayerNr() == 0)
{
gcode_layer.addPolygonsByOptimizer(wall, current_roof_config);
gcode_layer.addPolygonsByOptimizer(wall, current_roof_config, roof_extruder.settings_);
}
if (! roof_polygons.empty())
{
constexpr bool force_comb_retract = false;
gcode_layer.addTravel(roof_polygons[0][0], force_comb_retract);
gcode_layer.addPolygonsByOptimizer(roof_polygons, current_roof_config);
gcode_layer.addPolygonsByOptimizer(roof_polygons, current_roof_config, roof_extruder.settings_);
}
if (! roof_paths.empty())
{
Expand Down Expand Up @@ -4287,7 +4311,7 @@ bool FffGcodeWriter::addSupportBottomsToGCode(const SliceDataStorage& storage, L
{
constexpr bool force_comb_retract = false;
gcode_layer.addTravel(bottom_polygons[0][0], force_comb_retract);
gcode_layer.addPolygonsByOptimizer(bottom_polygons, gcode_layer.configs_storage_.support_bottom_config);
gcode_layer.addPolygonsByOptimizer(bottom_polygons, gcode_layer.configs_storage_.support_bottom_config, bottom_extruder.settings_);
}
if (! bottom_paths.empty())
{
Expand Down
Loading

0 comments on commit 893ad91

Please sign in to comment.