Skip to content

Commit

Permalink
Add raft settings to make margin and remove inside corners configurab…
Browse files Browse the repository at this point in the history
…lle per raft-type (#2006)
  • Loading branch information
wawanbreton authored Jan 9, 2024
2 parents 90aea70 + 50d0fd0 commit c8bfce0
Show file tree
Hide file tree
Showing 76 changed files with 601 additions and 188 deletions.
3 changes: 2 additions & 1 deletion include/LayerPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "pathPlanning/GCodePath.h"
#include "pathPlanning/NozzleTempInsert.h"
#include "pathPlanning/TimeMaterialEstimates.h"
#include "raft.h"
#include "settings/PathConfigStorage.h"
#include "settings/types/LayerIndex.h"
#include "utils/ExtrusionJunction.h"
Expand Down Expand Up @@ -63,7 +64,7 @@ class LayerPlan : public NoCopy
const SliceDataStorage& storage_; //!< The polygon data obtained from FffPolygonProcessor
const LayerIndex layer_nr_; //!< The layer number of this layer plan
const bool is_initial_layer_; //!< Whether this is the first layer (which might be raft)
const bool is_raft_layer_; //!< Whether this is a layer which is part of the raft
const Raft::LayerType layer_type_; //!< Which part of the raft, airgap or model this layer is.
coord_t layer_thickness_;

std::vector<Point2LL> layer_start_pos_per_extruder_; //!< The starting position of a layer for each extruder
Expand Down
28 changes: 22 additions & 6 deletions include/raft.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//Copyright (c) 2018 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.
// Copyright (c) 2018 Ultimaker B.V.
// CuraEngine is released under the terms of the AGPLv3 or higher.

#ifndef RAFT_H
#define RAFT_H

#include "settings/types/LayerIndex.h"
#include "utils/Coord_t.h"

namespace cura
Expand All @@ -29,7 +30,7 @@ class Raft
/*!
* \brief Get the amount of layers to fill the airgap and initial layer with
* helper parts (support, prime tower, etc.).
*
*
* The initial layer gets a separate filler layer because we don't want to
* apply the layer_0_z_overlap to it.
*/
Expand All @@ -49,13 +50,28 @@ class Raft
/*!
* \brief Get the total amount of extra layers below zero because there is a
* raft.
*
*
* This includes the filler layers which are introduced in the air gap.
*/
static size_t getTotalExtraLayers();

enum LayerType
{
RaftBase,
RaftInterface,
RaftSurface,
Airgap,
Model
};

/*!
* \brief Get the type of layer at the given layer index.
* \param layer_index The layer index to get the type of.
* \return The type of layer at the given layer index.
*/
static LayerType getLayerType(LayerIndex layer_index);
};

}//namespace cura
} // namespace cura

#endif//RAFT_H
#endif // RAFT_H
6 changes: 5 additions & 1 deletion include/sliceDataStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,11 @@ class SliceDataStorage : public NoCopy

std::vector<SkirtBrimLine> skirt_brim[MAX_EXTRUDERS]; //!< Skirt/brim polygons per extruder, ordered from inner to outer polygons.
Polygons support_brim; //!< brim lines for support, going from the edge of the support inward. \note Not ordered by inset.
Polygons raftOutline; // Storage for the outline of the raft. Will be filled with lines when the GCode is generated.

// Storage for the outline of the raft-parts. Will be filled with lines when the GCode is generated.
Polygons raftBaseOutline;
Polygons raftInterfaceOutline;
Polygons raftSurfaceOutline;

int max_print_height_second_to_last_extruder; //!< Used in multi-extrusion: the layer number beyond which all models are printed with the same extruder
std::vector<int> max_print_height_per_extruder; //!< For each extruder the highest layer number at which it is used.
Expand Down
6 changes: 3 additions & 3 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
};

std::vector<ParameterizedRaftPath> raft_outline_paths;
raft_outline_paths.emplace_back(ParameterizedRaftPath{ line_spacing, storage.raftOutline });
raft_outline_paths.emplace_back(ParameterizedRaftPath{ line_spacing, storage.raftBaseOutline });
if (storage.primeTower.enabled_)
{
const Polygons& raft_outline_prime_tower = storage.primeTower.getOuterPoly(layer_nr);
Expand Down Expand Up @@ -761,7 +761,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
Polygons raft_outline_path;
const coord_t small_offset = gcode_layer.configs_storage_.raft_interface_config.getLineWidth()
/ 2; // Do this manually because of micron-movement created in corners when insetting a polygon that was offset with round joint type.
raft_outline_path = storage.raftOutline.offset(-small_offset);
raft_outline_path = storage.raftInterfaceOutline.offset(-small_offset);
raft_outline_path = Simplify(interface_settings).polygon(raft_outline_path); // Remove those micron-movements.
const coord_t infill_outline_width = gcode_layer.configs_storage_.raft_interface_config.getLineWidth();
Polygons raft_lines;
Expand Down Expand Up @@ -903,7 +903,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
Polygons raft_outline_path;
const coord_t small_offset = gcode_layer.configs_storage_.raft_interface_config.getLineWidth()
/ 2; // Do this manually because of micron-movement created in corners when insetting a polygon that was offset with round joint type.
raft_outline_path = storage.raftOutline.offset(-small_offset);
raft_outline_path = storage.raftSurfaceOutline.offset(-small_offset);
raft_outline_path = Simplify(interface_settings).polygon(raft_outline_path); // Remove those micron-movements.
const coord_t infill_outline_width = gcode_layer.configs_storage_.raft_surface_config.getLineWidth();
Polygons raft_lines;
Expand Down
33 changes: 25 additions & 8 deletions src/LayerPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ LayerPlan::LayerPlan(
, storage_(storage)
, layer_nr_(layer_nr)
, is_initial_layer_(layer_nr == 0 - static_cast<LayerIndex>(Raft::getTotalExtraLayers()))
, is_raft_layer_(layer_nr < 0 - static_cast<LayerIndex>(Raft::getFillerLayerCount()))
, layer_type_(Raft::getLayerType(layer_nr))
, layer_thickness_(layer_thickness)
, has_prime_tower_planned_per_extruder_(Application::getInstance().current_slice_->scene.extruders.size(), false)
, current_mesh_(nullptr)
Expand Down Expand Up @@ -124,11 +124,12 @@ LayerPlan::LayerPlan(
layer_start_pos_per_extruder_.emplace_back(extruder.settings_.get<coord_t>("layer_start_x"), extruder.settings_.get<coord_t>("layer_start_y"));
}
extruder_plans_.reserve(Application::getInstance().current_slice_->scene.extruders.size());
const auto is_raft_layer = layer_type_ == Raft::LayerType::RaftBase || layer_type_ == Raft::LayerType::RaftInterface || layer_type_ == Raft::LayerType::RaftSurface;
extruder_plans_.emplace_back(
current_extruder,
layer_nr,
is_initial_layer_,
is_raft_layer_,
is_raft_layer,
layer_thickness,
fan_speed_layer_time_settings_per_extruder[current_extruder],
storage.retraction_wipe_config_per_extruder[current_extruder].retraction_config);
Expand Down Expand Up @@ -156,12 +157,25 @@ Polygons LayerPlan::computeCombBoundary(const CombBoundary boundary_type)
const CombingMode mesh_combing_mode = Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<CombingMode>("retraction_combing");
if (mesh_combing_mode != CombingMode::OFF && (layer_nr_ >= 0 || mesh_combing_mode != CombingMode::NO_SKIN))
{
if (layer_nr_ < 0)
{
comb_boundary = storage_.raftOutline.offset(MM2INT(0.1));
}
else
switch (layer_type_)
{
case Raft::LayerType::RaftBase:
comb_boundary = storage_.raftBaseOutline.offset(MM2INT(0.1));
break;

case Raft::LayerType::RaftInterface:
comb_boundary = storage_.raftInterfaceOutline.offset(MM2INT(0.1));
break;

case Raft::LayerType::RaftSurface:
comb_boundary = storage_.raftSurfaceOutline.offset(MM2INT(0.1));
break;

case Raft::LayerType::Airgap:
// do nothing for airgap
break;

case Raft::LayerType::Model:
for (const std::shared_ptr<SliceMeshStorage>& mesh_ptr : storage_.meshes)
{
const auto& mesh = *mesh_ptr;
Expand Down Expand Up @@ -216,6 +230,7 @@ Polygons LayerPlan::computeCombBoundary(const CombBoundary boundary_type)
}
}
}
break;
}
}
return comb_boundary;
Expand Down Expand Up @@ -255,11 +270,13 @@ bool LayerPlan::setExtruder(const size_t extruder_nr)
{ // first extruder plan in a layer might be empty, cause it is made with the last extruder planned in the previous layer
extruder_plans_.back().extruder_nr_ = extruder_nr;
}

const auto is_raft_layer = layer_type_ == Raft::LayerType::RaftBase || layer_type_ == Raft::LayerType::RaftInterface || layer_type_ == Raft::LayerType::RaftSurface;
extruder_plans_.emplace_back(
extruder_nr,
layer_nr_,
is_initial_layer_,
is_raft_layer_,
is_raft_layer,
layer_thickness_,
fan_speed_layer_time_settings_per_extruder_[extruder_nr],
storage_.retraction_wipe_config_per_extruder[extruder_nr].retraction_config);
Expand Down
81 changes: 66 additions & 15 deletions src/raft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,58 @@ namespace cura

void Raft::generate(SliceDataStorage& storage)
{
assert(storage.raftOutline.size() == 0 && "Raft polygon isn't generated yet, so should be empty!");
assert(
storage.raftBaseOutline.size() == 0 && storage.raftInterfaceOutline.size() == 0 && storage.raftSurfaceOutline.size() == 0
&& "Raft polygon isn't generated yet, so should be empty!");
const Settings& settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<ExtruderTrain&>("raft_base_extruder_nr").settings_;
const coord_t distance = settings.get<coord_t>("raft_margin");
constexpr bool include_support = true;
constexpr bool dont_include_prime_tower = false; // Prime tower raft will be handled separately in 'storage.primeRaftOutline'; see below.
storage.raftOutline = storage.getLayerOutlines(0, include_support, dont_include_prime_tower).offset(distance, ClipperLib::jtRound);
const auto raft_base_margin = settings.get<coord_t>("raft_base_margin");
const auto raft_interface_margin = settings.get<coord_t>("raft_interface_margin");
const auto raft_surface_margin = settings.get<coord_t>("raft_surface_margin");

storage.raftBaseOutline = storage.raftSurfaceOutline = storage.raftInterfaceOutline = storage.getLayerOutlines(0, include_support, dont_include_prime_tower);
storage.raftBaseOutline = storage.raftBaseOutline.offset(raft_base_margin, ClipperLib::jtRound);
storage.raftInterfaceOutline = storage.raftInterfaceOutline.offset(raft_interface_margin, ClipperLib::jtRound);
storage.raftSurfaceOutline = storage.raftSurfaceOutline.offset(raft_surface_margin, ClipperLib::jtRound);

const coord_t shield_line_width_layer0 = settings.get<coord_t>("skirt_brim_line_width");
const coord_t max_raft_distance = std::max(std::max(raft_base_margin, raft_interface_margin), raft_surface_margin);
if (storage.draft_protection_shield.size() > 0)
{
Polygons draft_shield_raft
= storage.draft_protection_shield
.offset(shield_line_width_layer0) // start half a line width outside shield
.difference(storage.draft_protection_shield.offset(-distance - shield_line_width_layer0 / 2, ClipperLib::jtRound)); // end distance inside shield
storage.raftOutline = storage.raftOutline.unionPolygons(draft_shield_raft);
.difference(storage.draft_protection_shield.offset(-max_raft_distance - shield_line_width_layer0 / 2, ClipperLib::jtRound)); // end distance inside shield
storage.raftBaseOutline = storage.raftBaseOutline.unionPolygons(draft_shield_raft);
storage.raftSurfaceOutline = storage.raftSurfaceOutline.unionPolygons(draft_shield_raft);
storage.raftInterfaceOutline = storage.raftInterfaceOutline.unionPolygons(draft_shield_raft);
}
if (storage.oozeShield.size() > 0 && storage.oozeShield[0].size() > 0)
{
const Polygons& ooze_shield = storage.oozeShield[0];
Polygons ooze_shield_raft = ooze_shield
.offset(shield_line_width_layer0) // start half a line width outside shield
.difference(ooze_shield.offset(-distance - shield_line_width_layer0 / 2, ClipperLib::jtRound)); // end distance inside shield
storage.raftOutline = storage.raftOutline.unionPolygons(ooze_shield_raft);
.difference(ooze_shield.offset(-max_raft_distance - shield_line_width_layer0 / 2, ClipperLib::jtRound)); // end distance inside shield
storage.raftBaseOutline = storage.raftBaseOutline.unionPolygons(ooze_shield_raft);
storage.raftSurfaceOutline = storage.raftSurfaceOutline.unionPolygons(ooze_shield_raft);
storage.raftInterfaceOutline = storage.raftInterfaceOutline.unionPolygons(ooze_shield_raft);
}

if (settings.get<bool>("raft_remove_inside_corners"))
{
storage.raftOutline.makeConvex();
}
else
const auto remove_inside_corners = [](Polygons& outline, bool remove_inside_corners, coord_t smoothing)
{
const coord_t smoothing = settings.get<coord_t>("raft_smoothing");
storage.raftOutline = storage.raftOutline.offset(smoothing, ClipperLib::jtRound).offset(-smoothing, ClipperLib::jtRound); // remove small holes and smooth inward corners
}
if (remove_inside_corners)
{
outline.makeConvex();
}
else
{
outline = outline.offset(smoothing, ClipperLib::jtRound).offset(-smoothing, ClipperLib::jtRound);
}
};
remove_inside_corners(storage.raftBaseOutline, settings.get<bool>("raft_base_remove_inside_corners"), settings.get<coord_t>("raft_base_smoothing"));
remove_inside_corners(storage.raftInterfaceOutline, settings.get<bool>("raft_interface_remove_inside_corners"), settings.get<coord_t>("raft_interface_smoothing"));
remove_inside_corners(storage.raftSurfaceOutline, settings.get<bool>("raft_surface_remove_inside_corners"), settings.get<coord_t>("raft_surface_smoothing"));

if (storage.primeTower.enabled_ && ! storage.primeTower.would_have_actual_tower_)
{
Expand Down Expand Up @@ -121,5 +140,37 @@ size_t Raft::getTotalExtraLayers()
return 1 + interface_train.settings_.get<size_t>("raft_interface_layers") + surface_train.settings_.get<size_t>("raft_surface_layers") + getFillerLayerCount();
}

Raft::LayerType Raft::getLayerType(LayerIndex layer_index)
{
const Settings& mesh_group_settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings;
const ExtruderTrain& base_train = mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr");
const ExtruderTrain& interface_train = mesh_group_settings.get<ExtruderTrain&>("raft_interface_extruder_nr");
const ExtruderTrain& surface_train = mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr");
const auto airgap = Raft::getFillerLayerCount();
const auto interface_layers = interface_train.settings_.get<size_t>("raft_interface_layers");
const auto surface_layers = surface_train.settings_.get<size_t>("raft_surface_layers");

if (layer_index < -airgap - surface_layers - interface_layers)
{
return LayerType::RaftBase;
}
if (layer_index < -airgap - surface_layers)
{
return LayerType::RaftInterface;
}
if (layer_index < -airgap)
{
return LayerType::RaftSurface;
}
else if (layer_index < 0)
{
return LayerType::Airgap;
}
else
{
return LayerType::Model;
}
}


} // namespace cura
46 changes: 40 additions & 6 deletions src/sliceDataStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,41 @@ Polygons
const
{
const Settings& mesh_group_settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings;
if (layer_nr < 0 && layer_nr < -static_cast<LayerIndex>(Raft::getFillerLayerCount()))
{ // when processing raft
if (include_support && (extruder_nr == -1 || extruder_nr == int(mesh_group_settings.get<ExtruderTrain&>("adhesion_extruder_nr").extruder_nr_)))

const auto layer_type = Raft::getLayerType(layer_nr);
switch (layer_type)
{
case Raft::LayerType::RaftBase:
case Raft::LayerType::RaftInterface:
case Raft::LayerType::RaftSurface:
{
const Polygons* raftOutline;
bool use_current_extruder_for_raft = extruder_nr == -1;

switch (layer_type)
{
case Raft::LayerType::RaftBase:
raftOutline = &raftBaseOutline;
use_current_extruder_for_raft |= extruder_nr == int(mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr").extruder_nr_);
break;
case Raft::LayerType::RaftInterface:
raftOutline = &raftInterfaceOutline;
use_current_extruder_for_raft |= extruder_nr == int(mesh_group_settings.get<ExtruderTrain&>("raft_interface_extruder_nr").extruder_nr_);
break;
case Raft::LayerType::RaftSurface:
raftOutline = &raftSurfaceOutline;
use_current_extruder_for_raft |= extruder_nr == int(mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr").extruder_nr_);
break;
default:
assert(false && "unreachable due to outer switch statement");
return Polygons();
}

if (include_support && use_current_extruder_for_raft)
{
if (external_polys_only)
{
std::vector<PolygonsPart> parts = raftOutline.splitIntoParts();
std::vector<PolygonsPart> parts = raftOutline->splitIntoParts();
Polygons result;
for (PolygonsPart& part : parts)
{
Expand All @@ -287,15 +315,17 @@ Polygons
}
else
{
return raftOutline;
return *raftOutline;
}
}
else
{
return Polygons();
}
break;
}
else
case Raft::LayerType::Airgap:
case Raft::LayerType::Model:
{
Polygons total;
if (layer_nr >= 0)
Expand Down Expand Up @@ -338,6 +368,10 @@ Polygons
}
return total;
}
default:
assert(false && "unreachable as switch statement is exhaustive");
return Polygons();
}
}

std::vector<bool> SliceDataStorage::getExtrudersUsed() const
Expand Down
6 changes: 3 additions & 3 deletions src/support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,9 @@ Polygons AreaSupport::join(const SliceDataStorage& storage, const Polygons& supp
break;
case EPlatformAdhesion::RAFT:
{
adhesion_size = std::max({ mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr").settings_.get<coord_t>("raft_margin"),
mesh_group_settings.get<ExtruderTrain&>("raft_interface_extruder_nr").settings_.get<coord_t>("raft_margin"),
mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr").settings_.get<coord_t>("raft_margin") });
adhesion_size = std::max({ mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr").settings_.get<coord_t>("raft_base_margin"),
mesh_group_settings.get<ExtruderTrain&>("raft_interface_extruder_nr").settings_.get<coord_t>("raft_interface_margin"),
mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr").settings_.get<coord_t>("raft_surface_margin") });
break;
}
case EPlatformAdhesion::NONE:
Expand Down
Loading

0 comments on commit c8bfce0

Please sign in to comment.