Skip to content

Commit

Permalink
Merge branch 'main' into CURA-8076_seam_avoid_overhangs
Browse files Browse the repository at this point in the history
  • Loading branch information
HellAholic authored Jun 13, 2024
2 parents 89db265 + 5004896 commit d999c08
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 172 deletions.
9 changes: 8 additions & 1 deletion include/FffGcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ class FffGcodeWriter : public NoCopy
*/
void processRaft(const SliceDataStorage& storage);

void startRaftLayer(const SliceDataStorage& storage, LayerPlan& gcode_layer, const LayerIndex layer_nr, size_t layer_extruder, size_t& current_extruder);

void endRaftLayer(const SliceDataStorage& storage, LayerPlan& gcode_layer, const LayerIndex layer_nr, size_t& current_extruder, const bool append_to_prime_tower = true);

/*!
* Convert the polygon data of a layer into a layer plan on the FffGcodeWriter::layer_plan_buffer
*
Expand Down Expand Up @@ -660,8 +664,11 @@ class FffGcodeWriter : public NoCopy
* \param[in] storage where the slice data is stored.
* \param gcode_layer The initial planning of the gcode of the layer.
* \param extruder_nr The extruder to switch to.
* \param append_to_prime_tower Indicates whether we should actually prime the extruder on the prime tower (normal
* case before actually using the extruder) or just do the basic priming (i.e. on first
* layer before starting the print
*/
void setExtruder_addPrime(const SliceDataStorage& storage, LayerPlan& gcode_layer, const size_t extruder_nr) const;
void setExtruder_addPrime(const SliceDataStorage& storage, LayerPlan& gcode_layer, const size_t extruder_nr, const bool append_to_prime_tower = true) const;

/*!
* Add the prime tower gcode for the current layer.
Expand Down
2 changes: 0 additions & 2 deletions include/PrimeTower.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class PrimeTower

public:
bool enabled_; //!< Whether the prime tower is enabled.
bool would_have_actual_tower_; //!< Whether there is an actual tower.
bool multiple_extruders_on_first_layer_; //!< Whether multiple extruders are allowed on the first layer of the prime tower (e.g. when a raft is there)

/*
* In which order, from outside to inside, will we be printing the prime
Expand Down
9 changes: 8 additions & 1 deletion include/gcodeExport.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,14 @@ class GCodeExport : public NoCopy

void writeFanCommand(double speed);

void writeTemperatureCommand(const size_t extruder, const Temperature& temperature, const bool wait = false);
/*!
* \brief Write a GCode temperature command
* \param extruder The extruder number
* \param temperature The temperature to bo set
* \param wait Indicates whether we should just set the temperature and keep going, or wait for the temperature to be reach before going further
* \param force_write_on_equal When true, we should write the temperature command even if the actual set temperature is the same
*/
void writeTemperatureCommand(const size_t extruder, const Temperature& temperature, const bool wait = false, const bool force_write_on_equal = false);
void writeBedTemperatureCommand(const Temperature& temperature, const bool wait = false);
void writeBuildVolumeTemperatureCommand(const Temperature& temperature, const bool wait = false);

Expand Down
21 changes: 21 additions & 0 deletions include/raft.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ class Raft
*/
static size_t getTotalExtraLayers();

/*!
* \brief Get the amount of layers for the raft base.
* \note This is currently hard-coded to 1 because we have yet no setting for the base
*/
static size_t getBaseLayers();

/*! \brief Get the amount of layers for the raft interface. */
static size_t getInterfaceLayers();

/*! \brief Get the amount of layers for the raft top. */
static size_t getSurfaceLayers();

enum LayerType
{
RaftBase,
Expand All @@ -70,6 +82,15 @@ class Raft
* \return The type of layer at the given layer index.
*/
static LayerType getLayerType(LayerIndex layer_index);

private:
/*!
* \brief Get the amount of layers to be printed for the given raft section
* \param extruder_nr_setting_name The name of the setting to be fetched to get the proper extruder number
* \param target_raft_section The name of the setting to be fetched to get the number of layers
* \return The number of layers for the given raft section, or 0 if raft is disabled
*/
static size_t getLayersAmount(const std::string& extruder_nr_setting_name, const std::string& target_raft_section);
};

} // namespace cura
Expand Down
147 changes: 84 additions & 63 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ void FffGcodeWriter::writeGCode(SliceDataStorage& storage, TimeKeeper& time_keep
gcode.writeTravel(p, extruder_settings.get<Velocity>("speed_travel"));
}


calculateExtruderOrderPerLayer(storage);
calculatePrimeLayerPerExtruder(storage);

Expand Down Expand Up @@ -572,7 +571,6 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
const size_t base_extruder_nr = mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr").extruder_nr_;
const size_t interface_extruder_nr = mesh_group_settings.get<ExtruderTrain&>("raft_interface_extruder_nr").extruder_nr_;
const size_t surface_extruder_nr = mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr").extruder_nr_;
const size_t prime_tower_extruder_nr = storage.primeTower.extruder_order_.front();

coord_t z = 0;
const LayerIndex initial_raft_layer_nr = -Raft::getTotalExtraLayers();
Expand All @@ -592,7 +590,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
Shape raft_polygons;
std::optional<Point2LL> last_planned_position = std::optional<Point2LL>();

unsigned int current_extruder_nr = base_extruder_nr;
size_t current_extruder_nr = base_extruder_nr;

{ // raft base layer
const Settings& base_settings = mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr").settings_;
Expand Down Expand Up @@ -746,6 +744,8 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
last_planned_position = gcode_layer.getLastPlannedPositionOrStartingPosition();
}

endRaftLayer(storage, gcode_layer, layer_nr, current_extruder_nr, false);

layer_plan_buffer.handle(gcode_layer, gcode);
}

Expand All @@ -759,7 +759,6 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)

for (LayerIndex raft_interface_layer = 1; static_cast<size_t>(raft_interface_layer) <= num_interface_layers; ++raft_interface_layer)
{ // raft interface layer
bool prime_tower_added_on_this_layer = ! storage.primeTower.enabled_;
const LayerIndex layer_nr = initial_raft_layer_nr + raft_interface_layer;
z += interface_layer_height;

Expand All @@ -784,18 +783,9 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
interface_line_width,
interface_avoid_distance);

if (! prime_tower_added_on_this_layer && current_extruder_nr == prime_tower_extruder_nr)
{
addPrimeTower(storage, gcode_layer, current_extruder_nr);
prime_tower_added_on_this_layer = true;
}

gcode_layer.setIsInside(true);
if (interface_extruder_nr != current_extruder_nr)
{
setExtruder_addPrime(storage, gcode_layer, interface_extruder_nr);
current_extruder_nr = interface_extruder_nr;
}

startRaftLayer(storage, gcode_layer, layer_nr, interface_extruder_nr, current_extruder_nr);

Application::getInstance().communication_->sendLayerComplete(layer_nr, z, interface_layer_height);

Expand Down Expand Up @@ -908,11 +898,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
raft_polygons.clear();
raft_lines.clear();

if (! prime_tower_added_on_this_layer)
{
setExtruder_addPrime(storage, gcode_layer, prime_tower_extruder_nr);
current_extruder_nr = prime_tower_extruder_nr;
}
endRaftLayer(storage, gcode_layer, layer_nr, current_extruder_nr);

layer_plan_buffer.handle(gcode_layer, gcode);
last_planned_position = gcode_layer.getLastPlannedPositionOrStartingPosition();
Expand All @@ -929,7 +915,6 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)

for (LayerIndex raft_surface_layer = 1; static_cast<size_t>(raft_surface_layer) <= num_surface_layers; raft_surface_layer++)
{ // raft surface layers
bool prime_tower_added_on_this_layer = ! storage.primeTower.enabled_;
const LayerIndex layer_nr = initial_raft_layer_nr + 1 + num_interface_layers + raft_surface_layer - 1; // +1: 1 base layer
z += surface_layer_height;

Expand All @@ -954,20 +939,11 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
surface_line_width,
surface_avoid_distance);

if (! prime_tower_added_on_this_layer && current_extruder_nr == prime_tower_extruder_nr)
{
addPrimeTower(storage, gcode_layer, current_extruder_nr);
prime_tower_added_on_this_layer = true;
}

gcode_layer.setIsInside(true);

// make sure that we are using the correct extruder to print raft
if (current_extruder_nr != surface_extruder_nr)
{
setExtruder_addPrime(storage, gcode_layer, surface_extruder_nr);
current_extruder_nr = surface_extruder_nr;
}
startRaftLayer(storage, gcode_layer, layer_nr, surface_extruder_nr, current_extruder_nr);

Application::getInstance().communication_->sendLayerComplete(layer_nr, z, surface_layer_height);

Shape raft_outline_path;
Expand Down Expand Up @@ -1098,16 +1074,41 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
raft_lines.clear();
}

if (! prime_tower_added_on_this_layer)
{
setExtruder_addPrime(storage, gcode_layer, prime_tower_extruder_nr);
current_extruder_nr = prime_tower_extruder_nr;
}
endRaftLayer(storage, gcode_layer, layer_nr, current_extruder_nr);

layer_plan_buffer.handle(gcode_layer, gcode);
}
}

void FffGcodeWriter::startRaftLayer(const SliceDataStorage& storage, LayerPlan& gcode_layer, const LayerIndex layer_nr, size_t layer_extruder, size_t& current_extruder)
{
// If required, fill prime tower with previous extruder
setExtruder_addPrime(storage, gcode_layer, current_extruder);

if (current_extruder != layer_extruder)
{
// Switch to new extruder and prime
setExtruder_addPrime(storage, gcode_layer, layer_extruder);
current_extruder = layer_extruder;
}
}

void FffGcodeWriter::endRaftLayer(const SliceDataStorage& storage, LayerPlan& gcode_layer, const LayerIndex layer_nr, size_t& current_extruder, const bool append_to_prime_tower)
{
// If required, fill prime tower with current extruder
setExtruder_addPrime(storage, gcode_layer, current_extruder, append_to_prime_tower);

// If required, fill prime tower for other extruders
for (const ExtruderUse& extruder_use : getExtruderUse(layer_nr))
{
if (! append_to_prime_tower || (! gcode_layer.getPrimeTowerIsPlanned(extruder_use.extruder_nr) && extruder_use.prime != ExtruderPrime::None))
{
setExtruder_addPrime(storage, gcode_layer, extruder_use.extruder_nr, append_to_prime_tower);
current_extruder = extruder_use.extruder_nr;
}
}
}

FffGcodeWriter::ProcessLayerResult FffGcodeWriter::processLayer(const SliceDataStorage& storage, LayerIndex layer_nr, const size_t total_layers) const
{
spdlog::debug("GcodeWriter processing layer {} of {}", layer_nr, total_layers);
Expand Down Expand Up @@ -1227,19 +1228,11 @@ FffGcodeWriter::ProcessLayerResult FffGcodeWriter::processLayer(const SliceDataS
for (const ExtruderUse& extruder_use : extruder_order)
{
size_t extruder_nr = extruder_use.extruder_nr;
// Everytime you start with a new extruder you want to add a prime tower, unless:
// - prime tower is disabled (setExtruder_addPrime takes care of this)
// - this is the first (and not the only!) extruder in this layer. Since the previous
// layer always ends with this extruder. If the first extruder is the only extruder,
// the prime tower needs to be added anyways, in order to support the prime tower if
// later in the print a prime tower is needed.
// - prime tower is already printed this layer (only applicable for more than 2 extruders).
// The setExtruder_addPrime takes care of this.
if (extruder_nr != extruder_order.front().extruder_nr || (extruder_order.size() == 1 && layer_nr >= 0) || extruder_nr == 0)
{
setExtruder_addPrime(storage, gcode_layer, extruder_nr);
time_keeper.registerTime("Prime tower pre");
}

// Set extruder (if needed) and prime (if needed)
setExtruder_addPrime(storage, gcode_layer, extruder_nr);
time_keeper.registerTime("Prime tower");

if (include_helper_parts && (extruder_nr == support_infill_extruder_nr || extruder_nr == support_roof_extruder_nr || extruder_nr == support_bottom_extruder_nr))
{
addSupportToGCode(storage, gcode_layer, extruder_nr);
Expand All @@ -1266,14 +1259,6 @@ FffGcodeWriter::ProcessLayerResult FffGcodeWriter::processLayer(const SliceDataS
time_keeper.registerTime(fmt::format("Mesh {}", mesh_idx));
}
}
// Always print a prime tower before switching extruder. Unless:
// - The prime tower is already printed this layer (setExtruder_addPrime takes care of this).
// - this is the last extruder of the layer, since the next layer will start with the same extruder.
if (extruder_nr != extruder_order.back().extruder_nr && layer_nr >= 0)
{
setExtruder_addPrime(storage, gcode_layer, extruder_nr);
time_keeper.registerTime("Prime tower post");
}
}

gcode_layer.applyModifyPlugin();
Expand Down Expand Up @@ -1555,7 +1540,17 @@ void FffGcodeWriter::calculateExtruderOrderPerLayer(const SliceDataStorage& stor

void FffGcodeWriter::calculatePrimeLayerPerExtruder(const SliceDataStorage& storage)
{
for (LayerIndex layer_nr = -Raft::getTotalExtraLayers(); layer_nr < static_cast<LayerIndex>(storage.print_layer_count); ++layer_nr)
LayerIndex first_print_layer = -Raft::getTotalExtraLayers();
for (size_t extruder_nr = 0; extruder_nr < MAX_EXTRUDERS; ++extruder_nr)
{
if (getExtruderNeedPrimeBlobDuringFirstLayer(storage, extruder_nr))
{
// Extruders requiring a prime blob have to be primed at first layer
extruder_prime_layer_nr[extruder_nr] = std::min(extruder_prime_layer_nr[extruder_nr], first_print_layer);
}
}

for (LayerIndex layer_nr = first_print_layer; layer_nr < static_cast<LayerIndex>(storage.print_layer_count); ++layer_nr)
{
const std::vector<bool> used_extruders = storage.getExtrudersUsed(layer_nr);
for (size_t extruder_nr = 0; extruder_nr < used_extruders.size(); ++extruder_nr)
Expand All @@ -1581,9 +1576,32 @@ std::vector<ExtruderUse> FffGcodeWriter::getUsedExtrudersOnLayer(
std::vector<bool> extruder_is_used_on_this_layer = storage.getExtrudersUsed(layer_nr);
const auto method = mesh_group_settings.get<PrimeTowerMethod>("prime_tower_mode");
const auto prime_tower_enable = mesh_group_settings.get<bool>("prime_tower_enable");
const LayerIndex raft_base_layer_nr = -Raft::getTotalExtraLayers();
Raft::LayerType layer_type = Raft::getLayerType(layer_nr);

if (layer_type == Raft::RaftBase)
{
// Raft base layers area treated apart because they don't have a proper prime tower
const size_t raft_base_extruder_nr = mesh_group_settings.get<ExtruderTrain&>("raft_base_extruder_nr").extruder_nr_;
ret.push_back(ExtruderUse{ raft_base_extruder_nr, ExtruderPrime::None });

// check if we need prime blob on the first layer
if (layer_nr == raft_base_layer_nr)
{
for (size_t extruder_nr = 0; extruder_nr < extruder_is_used_on_this_layer.size(); extruder_nr++)
{
if (extruder_nr != raft_base_extruder_nr && getExtruderNeedPrimeBlobDuringFirstLayer(storage, extruder_nr))
{
ret.push_back(ExtruderUse{ extruder_nr, ExtruderPrime::None });
}
}
}

return ret;
}

// check if we are on the first layer
if (layer_nr == -static_cast<LayerIndex>(Raft::getTotalExtraLayers()))
if (layer_nr == raft_base_layer_nr)
{
// check if we need prime blob on the first layer
for (size_t used_idx = 0; used_idx < extruder_is_used_on_this_layer.size(); used_idx++)
Expand All @@ -1606,7 +1624,7 @@ std::vector<ExtruderUse> FffGcodeWriter::getUsedExtrudersOnLayer(
}
}

// Now check whether extuders should really used, and how
// Now check whether extruders should really be used, and how
size_t last_extruder = start_extruder;
for (size_t extruder_nr : ordered_extruders)
{
Expand Down Expand Up @@ -3917,7 +3935,7 @@ bool FffGcodeWriter::addSupportBottomsToGCode(const SliceDataStorage& storage, L
return true;
}

void FffGcodeWriter::setExtruder_addPrime(const SliceDataStorage& storage, LayerPlan& gcode_layer, const size_t extruder_nr) const
void FffGcodeWriter::setExtruder_addPrime(const SliceDataStorage& storage, LayerPlan& gcode_layer, const size_t extruder_nr, const bool append_to_prime_tower) const
{
const size_t previous_extruder = gcode_layer.getExtruder();
const bool extruder_changed = gcode_layer.setExtruder(extruder_nr);
Expand Down Expand Up @@ -3950,7 +3968,10 @@ void FffGcodeWriter::setExtruder_addPrime(const SliceDataStorage& storage, Layer
}
}

addPrimeTower(storage, gcode_layer, previous_extruder);
if (append_to_prime_tower)
{
addPrimeTower(storage, gcode_layer, previous_extruder);
}
}

void FffGcodeWriter::addPrimeTower(const SliceDataStorage& storage, LayerPlan& gcode_layer, const size_t prev_extruder) const
Expand Down
Loading

0 comments on commit d999c08

Please sign in to comment.