Skip to content

Commit

Permalink
merge 5.7
Browse files Browse the repository at this point in the history
  • Loading branch information
saumyaj3 committed Apr 26, 2024
2 parents 8b1757e + fe02797 commit fb484b8
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 64 deletions.
4 changes: 3 additions & 1 deletion include/FffGcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,11 @@ class FffGcodeWriter : public NoCopy
*
* \param[in] storage where the slice data is stored.
* \param current_extruder The current extruder with which we last printed
* \param global_extruders_used The extruders that are at some point used for the print job
* \return The order of extruders for a layer beginning with \p current_extruder
*/
std::vector<ExtruderUse> getUsedExtrudersOnLayer(const SliceDataStorage& storage, const size_t start_extruder, const LayerIndex& layer_nr) const;
std::vector<ExtruderUse>
getUsedExtrudersOnLayer(const SliceDataStorage& storage, const size_t start_extruder, const LayerIndex& layer_nr, const std::vector<bool>& global_extruders_used) const;

/*!
* Calculate in which order to plan the meshes of a specific extruder
Expand Down
8 changes: 5 additions & 3 deletions include/PrimeTower.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class LayerPlan;
class PrimeTower
{
private:
using MovesByExtruder = std::vector<Polygons>;
using MovesByLayer = std::vector<MovesByExtruder>;
using MovesByExtruder = std::map<size_t, Polygons>;
using MovesByLayer = std::map<size_t, std::vector<Polygons>>;

size_t extruder_count_; //!< Number of extruders

Expand Down Expand Up @@ -79,10 +79,12 @@ class PrimeTower
*/
PrimeTower();

void initializeExtruders(const std::vector<bool>& used_extruders);

/*!
* Check whether we actually use the prime tower.
*/
void checkUsed(const SliceDataStorage& storage);
void checkUsed();

/*!
* Generate the prime tower area to be used on each layer
Expand Down
2 changes: 1 addition & 1 deletion include/infill/NoZigZagConnectorProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class NoZigZagConnectorProcessor : public ZigzagConnectorProcessor
}

void registerVertex(const Point2LL& vertex);
void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index);
void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index, coord_t min_distance_to_scanline);
void registerPolyFinished();
};

Expand Down
15 changes: 3 additions & 12 deletions include/infill/ZigzagConnectorProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class ZigzagConnectorProcessor
* \param intersection The intersection
* \param scanline_index Index of the current scanline
*/
virtual void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index);
virtual void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index, coord_t min_distance_to_scanline);

/*!
* Handle the end of a polygon and prepare for the next.
Expand Down Expand Up @@ -166,17 +166,6 @@ class ZigzagConnectorProcessor
*/
bool shouldAddCurrentConnector(int start_scanline_idx, int end_scanline_idx) const;

/*!
* Checks whether two points are separated at least by "threshold" microns.
* If they are far away from each other enough, the line represented by the two points
* will be added; In case they are close, the second point will be set to be the same
* as the first and this line won't be added.
*
* \param first_point The first of the points
* \param second_point The second of the points
*/
void checkAndAddZagConnectorLine(Point2LL* first_point, Point2LL* second_point);

/*!
* Adds a Zag connector represented by the given points. The last line of the connector will not be
* added if the given connector is an end piece and "connected_endpieces" is not enabled.
Expand All @@ -186,6 +175,8 @@ class ZigzagConnectorProcessor
*/
void addZagConnector(std::vector<Point2LL>& points, bool is_endpiece);

bool handleConnectorTooCloseToSegment(const coord_t scanline_x, const coord_t min_distance_to_scanline);

protected:
const PointMatrix& rotation_matrix_; //!< The rotation matrix used to enforce the infill angle
Polygons& result_; //!< The result of the computation
Expand Down
13 changes: 9 additions & 4 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1551,12 +1551,13 @@ void FffGcodeWriter::calculateExtruderOrderPerLayer(const SliceDataStorage& stor
}

size_t extruder_count = Application::getInstance().current_slice_->scene.extruders.size();
const std::vector<bool> extruders_used = storage.getExtrudersUsed();
const Settings& mesh_group_settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings;
PrimeTowerMethod prime_tower_mode = mesh_group_settings.get<PrimeTowerMethod>("prime_tower_mode");
for (LayerIndex layer_nr = -Raft::getTotalExtraLayers(); layer_nr < static_cast<LayerIndex>(storage.print_layer_count); layer_nr++)
{
std::vector<std::vector<ExtruderUse>>& extruder_order_per_layer_here = (layer_nr < 0) ? extruder_order_per_layer_negative_layers : extruder_order_per_layer;
std::vector<ExtruderUse> extruder_order = getUsedExtrudersOnLayer(storage, last_extruder, layer_nr);
std::vector<ExtruderUse> extruder_order = getUsedExtrudersOnLayer(storage, last_extruder, layer_nr, extruders_used);
extruder_order_per_layer_here.push_back(extruder_order);

if (! extruder_order.empty())
Expand All @@ -1581,10 +1582,14 @@ void FffGcodeWriter::calculatePrimeLayerPerExtruder(const SliceDataStorage& stor
}
}

std::vector<ExtruderUse> FffGcodeWriter::getUsedExtrudersOnLayer(const SliceDataStorage& storage, const size_t start_extruder, const LayerIndex& layer_nr) const
std::vector<ExtruderUse> FffGcodeWriter::getUsedExtrudersOnLayer(
const SliceDataStorage& storage,
const size_t start_extruder,
const LayerIndex& layer_nr,
const std::vector<bool>& global_extruders_used) const
{
const Settings& mesh_group_settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings;
size_t extruder_count = Application::getInstance().current_slice_->scene.extruders.size();
size_t extruder_count = global_extruders_used.size();
assert(static_cast<int>(extruder_count) > 0);
std::vector<ExtruderUse> ret;
std::vector<bool> extruder_is_used_on_this_layer = storage.getExtrudersUsed(layer_nr);
Expand All @@ -1609,7 +1614,7 @@ std::vector<ExtruderUse> FffGcodeWriter::getUsedExtrudersOnLayer(const SliceData
ordered_extruders.push_back(start_extruder);
for (size_t extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
{
if (extruder_nr != start_extruder)
if (extruder_nr != start_extruder && global_extruders_used[extruder_nr])
{
ordered_extruders.push_back(extruder_nr);
}
Expand Down
2 changes: 2 additions & 0 deletions src/FffPolygonGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper&

Progress::messageProgressStage(Progress::Stage::SUPPORT, &time_keeper);

storage.primeTower.initializeExtruders(storage.getExtrudersUsed());

AreaSupport::generateOverhangAreas(storage);
AreaSupport::generateSupportAreas(storage);
TreeSupport tree_support_generator(storage);
Expand Down
58 changes: 31 additions & 27 deletions src/PrimeTower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,37 @@ PrimeTower::PrimeTower()
&& scene.current_mesh_group->settings.get<coord_t>("prime_tower_size") > 10;

would_have_actual_tower_ = enabled_; // Assume so for now.
}

extruder_count_ = scene.extruders.size();
extruder_order_.resize(extruder_count_);
for (unsigned int extruder_nr = 0; extruder_nr < extruder_count_; extruder_nr++)
void PrimeTower::initializeExtruders(const std::vector<bool>& used_extruders)
{
// Add used extruders in default order, then sort.
for (unsigned int extruder_nr = 0; extruder_nr < used_extruders.size(); extruder_nr++)
{
extruder_order_[extruder_nr] = extruder_nr; // Start with default order, then sort.
if (used_extruders[extruder_nr])
{
extruder_order_.push_back(extruder_nr);
}
}

extruder_count_ = extruder_order_.size();

// Sort from high adhesion to low adhesion.
const Scene* scene_pointer = &scene; // Communicate to lambda via pointer to prevent copy.
const Scene& scene = Application::getInstance().current_slice_->scene;
std::stable_sort(
extruder_order_.begin(),
extruder_order_.end(),
[scene_pointer](const unsigned int& extruder_nr_a, const unsigned int& extruder_nr_b) -> bool
[&scene](const unsigned int& extruder_nr_a, const unsigned int& extruder_nr_b) -> bool
{
const Ratio adhesion_a = scene_pointer->extruders[extruder_nr_a].settings_.get<Ratio>("material_adhesion_tendency");
const Ratio adhesion_b = scene_pointer->extruders[extruder_nr_b].settings_.get<Ratio>("material_adhesion_tendency");
const Ratio adhesion_a = scene.extruders[extruder_nr_a].settings_.get<Ratio>("material_adhesion_tendency");
const Ratio adhesion_b = scene.extruders[extruder_nr_b].settings_.get<Ratio>("material_adhesion_tendency");
return adhesion_a < adhesion_b;
});
}

void PrimeTower::checkUsed(const SliceDataStorage& storage)
void PrimeTower::checkUsed()
{
std::vector<bool> extruder_is_used = storage.getExtrudersUsed();
size_t used_extruder_count = 0;
for (bool is_used : extruder_is_used)
{
used_extruder_count += is_used;
}
if (used_extruder_count <= 1)
if (extruder_count_ <= 1)
{
enabled_ = false;
}
Expand Down Expand Up @@ -108,7 +110,7 @@ void PrimeTower::generateGroundpoly()

void PrimeTower::generatePaths(const SliceDataStorage& storage)
{
checkUsed(storage);
checkUsed();

const int raft_total_extra_layers = Raft::getTotalExtraLayers();
would_have_actual_tower_ = storage.max_print_height_second_to_last_extruder
Expand Down Expand Up @@ -138,9 +140,13 @@ void PrimeTower::generatePaths_denseInfill(std::vector<coord_t>& cumulative_inse
const coord_t base_height = std::max(scene.settings.get<coord_t>("prime_tower_base_height"), has_raft ? layer_height : 0);
const double base_curve_magnitude = mesh_group_settings.get<double>("prime_tower_base_curve_magnitude");

prime_moves_.resize(extruder_count_);
base_extra_moves_.resize(extruder_count_);
inset_extra_moves_.resize(extruder_count_);
for (size_t extruder_nr : extruder_order_)
{
// By default, add empty moves for every extruder
prime_moves_[extruder_nr];
base_extra_moves_[extruder_nr];
inset_extra_moves_[extruder_nr];
}

coord_t cumulative_inset = 0; // Each tower shape is going to be printed inside the other. This is the inset we're doing for each extruder.
for (size_t extruder_nr : extruder_order_)
Expand Down Expand Up @@ -226,8 +232,6 @@ void PrimeTower::generatePaths_sparseInfill(const std::vector<coord_t>& cumulati

if (method == PrimeTowerMethod::INTERLEAVED || method == PrimeTowerMethod::NORMAL)
{
const size_t nb_extruders = scene.extruders.size();

// Pre-compute radiuses of each extruder ring
std::vector<coord_t> rings_radii;
const coord_t tower_size = mesh_group_settings.get<coord_t>("prime_tower_size");
Expand All @@ -242,9 +246,9 @@ void PrimeTower::generatePaths_sparseInfill(const std::vector<coord_t>& cumulati
// Generate all possible extruders combinations, e.g. if there are 4 extruders, we have combinations
// 0 / 0-1 / 0-1-2 / 0-1-2-3 / 1 / 1-2 / 1-2-3 / 2 / 2-3 / 3
// A combination is represented by a bitmask
for (size_t first_extruder_idx = 0; first_extruder_idx < nb_extruders; ++first_extruder_idx)
for (size_t first_extruder_idx = 0; first_extruder_idx < extruder_count_; ++first_extruder_idx)
{
size_t nb_extruders_sparse = method == PrimeTowerMethod::NORMAL ? first_extruder_idx + 1 : nb_extruders;
size_t nb_extruders_sparse = method == PrimeTowerMethod::NORMAL ? first_extruder_idx + 1 : extruder_count_;

for (size_t last_extruder_idx = first_extruder_idx; last_extruder_idx < nb_extruders_sparse; ++last_extruder_idx)
{
Expand Down Expand Up @@ -444,7 +448,7 @@ void PrimeTower::addToGcode_denseInfill(LayerPlan& gcode_layer, const size_t ext
{
// Actual prime pattern
const GCodePathConfig& config = gcode_layer.configs_storage_.prime_tower_config_per_extruder[extruder_nr];
const Polygons& pattern = prime_moves_[extruder_nr];
const Polygons& pattern = prime_moves_.at(extruder_nr);
gcode_layer.addPolygonsByOptimizer(pattern, config);
}
}
Expand All @@ -454,7 +458,7 @@ bool PrimeTower::addToGcode_base(LayerPlan& gcode_layer, const size_t extruder_n
const size_t raft_total_extra_layers = Raft::getTotalExtraLayers();
LayerIndex absolute_layer_number = gcode_layer.getLayerNr() + raft_total_extra_layers;

const std::vector<Polygons>& pattern_extra_brim = base_extra_moves_[extruder_nr];
const std::vector<Polygons>& pattern_extra_brim = base_extra_moves_.at(extruder_nr);
if (absolute_layer_number < pattern_extra_brim.size())
{
// Extra rings for stronger base
Expand All @@ -477,7 +481,7 @@ bool PrimeTower::addToGcode_inset(LayerPlan& gcode_layer, const size_t extruder_

if (absolute_layer_number == 0) // Extra-adhesion on very first layer only
{
const Polygons& pattern_extra_inset = inset_extra_moves_[extruder_nr];
const Polygons& pattern_extra_inset = inset_extra_moves_.at(extruder_nr);
if (! pattern_extra_inset.empty())
{
const GCodePathConfig& config = gcode_layer.configs_storage_.prime_tower_config_per_extruder[extruder_nr];
Expand Down
6 changes: 3 additions & 3 deletions src/infill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,12 @@ void Infill::generateLinearBasedInfill(

for (int scanline_idx = scanline_idx0; scanline_idx != scanline_idx1 + direction; scanline_idx += direction)
{
int x = scanline_idx * line_distance + shift;
int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
const int x = scanline_idx * line_distance + shift;
const int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
assert(scanline_idx - scanline_min_idx >= 0 && scanline_idx - scanline_min_idx < int(cut_list.size()) && "reading infill cutlist index out of bounds!");
cut_list[scanline_idx - scanline_min_idx].push_back(y);
Point2LL scanline_linesegment_intersection(x, y);
zigzag_connector_processor.registerScanlineSegmentIntersection(scanline_linesegment_intersection, scanline_idx);
zigzag_connector_processor.registerScanlineSegmentIntersection(scanline_linesegment_intersection, scanline_idx, line_distance / 4);
crossings_per_scanline[scanline_idx - min_scanline_index].emplace_back(scanline_linesegment_intersection, poly_idx, point_idx);
}
zigzag_connector_processor.registerVertex(p1);
Expand Down
2 changes: 1 addition & 1 deletion src/infill/NoZigZagConnectorProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void NoZigZagConnectorProcessor::registerVertex(const Point2LL&)
// No need to add anything.
}

void NoZigZagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL&, int)
void NoZigZagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL&, int, coord_t)
{
// No need to add anything.
}
Expand Down
22 changes: 20 additions & 2 deletions src/infill/ZigzagConnectorProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,26 @@ bool ZigzagConnectorProcessor::shouldAddCurrentConnector(int start_scanline_idx,
return should_add;
}

bool ZigzagConnectorProcessor::handleConnectorTooCloseToSegment(const coord_t scanline_x, const coord_t min_distance_to_scanline)
{
if (current_connector_.empty())
{
return false;
}
else
{
return std::find_if(
current_connector_.begin(),
current_connector_.end(),
[scanline_x, min_distance_to_scanline](const Point2LL& point)
{
return std::abs(point.X - scanline_x) >= min_distance_to_scanline;
})
== current_connector_.end();
}
}

void ZigzagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index)
void ZigzagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index, coord_t min_distance_to_scanline)
{
if (is_first_connector_)
{
Expand All @@ -97,7 +115,7 @@ void ZigzagConnectorProcessor::registerScanlineSegmentIntersection(const Point2L
else
{
// add the current connector if needed
if (shouldAddCurrentConnector(last_connector_index_, scanline_index))
if (shouldAddCurrentConnector(last_connector_index_, scanline_index) && ! handleConnectorTooCloseToSegment(intersection.X, min_distance_to_scanline))
{
const bool is_this_endpiece = scanline_index == last_connector_index_;
current_connector_.push_back(intersection);
Expand Down
14 changes: 12 additions & 2 deletions src/skin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "settings/types/Angle.h" //For the infill support angle.
#include "settings/types/Ratio.h"
#include "sliceDataStorage.h"
#include "utils/Simplify.h"
#include "utils/math.h"
#include "utils/polygonUtils.h"

Expand Down Expand Up @@ -465,9 +466,12 @@ void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh)
const LayerIndex mesh_min_layer = mesh.settings.get<size_t>("initial_bottom_layers");
const LayerIndex mesh_max_layer = mesh.layers.size() - 1 - mesh.settings.get<size_t>("top_layers");

const Simplify simplifier(mesh.settings.get<ExtruderTrain&>("infill_extruder_nr").settings_);

const auto infill_wall_count = mesh.settings.get<size_t>("infill_wall_line_count");
const auto infill_wall_width = mesh.settings.get<coord_t>("infill_line_width");
const auto infill_overlap = mesh.settings.get<coord_t>("infill_overlap_mm");
const auto is_connected = mesh.settings.get<bool>("zig_zaggify_infill") || mesh.settings.get<EFillMethod>("infill_pattern") == EFillMethod::ZIG_ZAG;
for (LayerIndex layer_idx = 0; layer_idx < static_cast<LayerIndex>(mesh.layers.size()); layer_idx++)
{ // loop also over layers which don't contain infill cause of bottom_ and top_layer to initialize their infill_area_per_combine_per_density
SliceLayer& layer = mesh.layers[layer_idx];
Expand All @@ -494,6 +498,7 @@ void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh)
continue;
}
Polygons less_dense_infill = infill_area; // one step less dense with each infill_step
Polygons sum_more_dense; // NOTE: Only used for zig-zag or connected fills.
for (size_t infill_step = 0; infill_step < max_infill_steps; infill_step++)
{
LayerIndex min_layer = layer_idx + infill_step * gradual_infill_step_layer_count + static_cast<size_t>(layer_skip_count);
Expand Down Expand Up @@ -526,11 +531,16 @@ void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh)
part.infill_area_per_combine_per_density.emplace_back();
std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
const Polygons more_dense_infill = infill_area.difference(less_dense_infill);
infill_area_per_combine_current_density.push_back(more_dense_infill);
infill_area_per_combine_current_density.push_back(
simplifier.polygon(more_dense_infill.difference(sum_more_dense).offset(-infill_wall_width).offset(infill_wall_width)));
if (is_connected)
{
sum_more_dense = sum_more_dense.unionPolygons(more_dense_infill);
}
}
part.infill_area_per_combine_per_density.emplace_back();
std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
infill_area_per_combine_current_density.push_back(infill_area);
infill_area_per_combine_current_density.push_back(simplifier.polygon(infill_area.difference(sum_more_dense).offset(-infill_wall_width).offset(infill_wall_width)));
part.infill_area_own = std::nullopt; // clear infill_area_own, it's not needed any more.
assert(! part.infill_area_per_combine_per_density.empty() && "infill_area_per_combine_per_density is now initialized");
}
Expand Down
Loading

0 comments on commit fb484b8

Please sign in to comment.