Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CURA-7979] Lock outer wall in place and width as much as possible #1405

Merged
merged 21 commits into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a5f9acf
Possible to adjust how close to optimal-width/place outer walls are.
rburema Feb 5, 2021
869cc4d
Rethink left-over width w.r.t. redistribution.
rburema Feb 5, 2021
99f7349
Handle the 'initially only outer walls' case.
rburema Feb 5, 2021
aca8aeb
Don't handle 0-width signalling walls.
rburema Feb 5, 2021
4928723
Handle case where inner walls dissapear.
rburema Feb 5, 2021
3f28e22
Expose 'Outer Wall Lock Factor' setting to frontend.
rburema Feb 5, 2021
d13d08b
Add new setting to tests as well.
rburema Feb 7, 2021
21c93de
Rewrote outer wall lock factor usage.
jellespijker Feb 10, 2021
5582c23
Calculate weights only once
jellespijker Feb 10, 2021
2e0af51
Inner beads should also be processed
jellespijker Feb 10, 2021
c1b75ab
Make sure that all beads still adhere to minimum width
jellespijker Feb 10, 2021
8c60b9a
Take into account filtered out beads
jellespijker Feb 12, 2021
3bd13c9
Removed indention
jellespijker Feb 12, 2021
667ef4a
Reimplemented old distribution calculation.
jellespijker Feb 12, 2021
a12e989
Force symmetry from and early start.
jellespijker Feb 12, 2021
2d63dab
Made outer wall lock default behaviour.
jellespijker Feb 15, 2021
219a48c
Updated and added documentation
jellespijker Feb 15, 2021
5b7e466
Renamed parameter to minimum_width_inner for consistency
jellespijker Feb 15, 2021
82eb2b5
Merge remote-tracking branch 'origin/libArachne_rebased' into CURA-79…
jellespijker Feb 16, 2021
4404c7e
Remove dead code. Correct English spelling.
rburema Feb 16, 2021
88e793e
Merge branch 'CURA-7979_fix_outer_wall_artifacts' of https://github.c…
rburema Feb 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/BeadingStrategy/BeadingStrategyFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,21 @@ coord_t getWeightedAverage(const coord_t preferred_bead_width_outer, const coord
return preferred_bead_width_outer;
}

BeadingStrategy* BeadingStrategyFactory::makeStrategy(const StrategyType type, const coord_t preferred_bead_width_outer, const coord_t preferred_bead_width_inner, const coord_t preferred_transition_length, const float transitioning_angle, const bool print_thin_walls, const coord_t min_bead_width, const coord_t min_feature_size, const Ratio wall_transition_threshold, const coord_t max_bead_count, const coord_t outer_wall_offset)
BeadingStrategy* BeadingStrategyFactory::makeStrategy
(
const StrategyType type,
const coord_t preferred_bead_width_outer,
const coord_t preferred_bead_width_inner,
const coord_t preferred_transition_length,
const float transitioning_angle,
const bool print_thin_walls,
const coord_t min_bead_width,
const coord_t min_feature_size,
const Ratio wall_transition_threshold,
const coord_t max_bead_count,
const coord_t outer_wall_offset,
const Ratio outer_wall_lock_factor
)
{
const coord_t bar_preferred_wall_width = getWeightedAverage(preferred_bead_width_outer, preferred_bead_width_inner, max_bead_count);
BeadingStrategy* ret = nullptr;
Expand All @@ -77,7 +91,7 @@ BeadingStrategy* BeadingStrategyFactory::makeStrategy(const StrategyType type, c
if (max_bead_count > 0)
{
logDebug("Applying the Redistribute meta-strategy with outer-wall width = %d, inner-wall width = %d", preferred_bead_width_outer, preferred_bead_width_inner);
ret = new RedistributeBeadingStrategy(preferred_bead_width_outer, preferred_bead_width_inner, ret);
ret = new RedistributeBeadingStrategy(preferred_bead_width_outer, preferred_bead_width_inner, outer_wall_lock_factor, ret);
//Apply the LimitedBeadingStrategy last, since that adds a 0-width marker wall which other beading strategies shouldn't touch.
logDebug("Applying the Limited Beading meta-strategy with maximum bead count = %d.", max_bead_count);
ret = new LimitedBeadingStrategy(max_bead_count, ret);
Expand Down
8 changes: 6 additions & 2 deletions src/BeadingStrategy/BeadingStrategyFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ std::string to_string(StrategyType type);
class BeadingStrategyFactory
{
public:
static BeadingStrategy* makeStrategy(const StrategyType type,
static BeadingStrategy* makeStrategy
(
const StrategyType type,
const coord_t preferred_bead_width_outer = MM2INT(0.5),
const coord_t preferred_bead_width_inner = MM2INT(0.5),
const coord_t preferred_transition_length = MM2INT(0.4),
Expand All @@ -42,7 +44,9 @@ class BeadingStrategyFactory
const coord_t min_feature_size = 0,
const Ratio wall_transition_thresold = 0.5_r,
const coord_t max_bead_count = 0,
const coord_t outer_wall_offset = 0);
const coord_t outer_wall_offset = 0,
const Ratio outer_wall_lock_factor = 0.0_r
);
};

} // namespace cura
Expand Down
47 changes: 40 additions & 7 deletions src/BeadingStrategy/RedistributeBeadingStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,32 @@ namespace cura
{
Beading ret = parent->compute(thickness, bead_count);

// Actual count and thickness as represented by extant walls. Don't count any potential zero-width 'signalling' walls.
bead_count = std::count_if(ret.bead_widths.begin(), ret.bead_widths.end(), [](const coord_t width) { return width > 0; });
thickness -= ret.left_over;

// Early out when the only walls are outer, the parent can have been trusted to handle it.
if (bead_count < 3)
{
if (bead_count == 2 && optimal_width_outer < (thickness / 2))
{
const coord_t back_pos = bead_count - 1;

// Compensate for the outer wall lock factor:
ret.bead_widths[0] = static_cast<coord_t>(outer_wall_lock_factor * optimal_width_outer + outer_wall_lock_inverse * ret.bead_widths[0]);
ret.bead_widths[back_pos] = static_cast<coord_t>(outer_wall_lock_factor * optimal_width_outer + outer_wall_lock_inverse * ret.bead_widths[back_pos]);
ret.toolpath_locations[0] = ret.bead_widths[0] / 2;
ret.toolpath_locations[back_pos] = thickness - ret.bead_widths[back_pos] / 2;

// Check if a third wall needs to be created, if so, do it, otherwise put the rest-width in leftovers:
coord_t left_over = std::max(static_cast<coord_t>(0), thickness - (ret.bead_widths.front() + ret.bead_widths.back()));
if (left_over >= this->getTransitionThickness(0))
{
ret.bead_widths.insert(std::next(ret.bead_widths.begin()), left_over);
ret.toolpath_locations.insert(std::next(ret.toolpath_locations.begin()), thickness / 2);
ret.left_over = 0;
}
else
{
ret.left_over = left_over;
}
}
return ret;
}

Expand All @@ -27,10 +46,14 @@ namespace cura
const coord_t optimal_total_outer_walls_width = optimal_width_outer * 2;
const coord_t optimal_total_inner_walls_width = optimal_width_inner * (bead_count - 2);

// ... do some compensation for the 'outer wall lock factor' in between the calculations:
// NOTE: The weights are inverted here, since these widhts end up in the denominator.
const coord_t optimal_total_thickness = static_cast<coord_t>(outer_wall_lock_factor * thickness + outer_wall_lock_inverse * (optimal_total_outer_walls_width + optimal_total_inner_walls_width));

const coord_t outer_factor_numerator = optimal_total_outer_walls_width * thickness;
const coord_t outer_factor_denominator = current_total_outer_walls_width * (optimal_total_outer_walls_width + optimal_total_inner_walls_width);
const coord_t outer_factor_denominator = current_total_outer_walls_width * optimal_total_thickness;
const coord_t inner_factor_numerator = optimal_total_inner_walls_width * thickness;
const coord_t inner_factor_denominator = current_total_inner_walls_width * (optimal_total_outer_walls_width + optimal_total_inner_walls_width);
const coord_t inner_factor_denominator = current_total_inner_walls_width * optimal_total_thickness;

// Multiply the bead-widths with the right factors:
ret.bead_widths[0] = (ret.bead_widths[0] * outer_factor_numerator) / outer_factor_denominator;
Expand All @@ -40,6 +63,11 @@ namespace cura
}
ret.bead_widths[bead_count - 1] = (ret.bead_widths[bead_count - 1] * outer_factor_numerator) / outer_factor_denominator;

// Filter out any non-positive width walls:
ret.bead_widths.erase(std::remove_if(ret.bead_widths.begin(), ret.bead_widths.end(), [](const coord_t width){ return width <= 0; }), ret.bead_widths.end());
bead_count = ret.bead_widths.size();
ret.toolpath_locations.resize(bead_count);

// Update the first half of the toolpath-locations with the updated bead-widths (starting from 0, up to half):
coord_t last_coord = 0;
coord_t last_width = 0;
Expand All @@ -50,7 +78,11 @@ namespace cura
last_width = ret.bead_widths[i_location];
}

// NOTE: Don't have to alter the middle toolpath if there's any, it'll already be at half thickness.
// Handle the position of any middle wall (note that the width will already have been set correctly):
if (bead_count % 2 == 1)
{
ret.toolpath_locations[bead_count / 2] = thickness / 2;
}

// Update the last half of the toolpath-locations with the updated bead-widths (starting from thickness, down to half):
last_coord = thickness;
Expand All @@ -62,6 +94,7 @@ namespace cura
last_width = ret.bead_widths[i_location];
}

ret.left_over = std::max(static_cast<coord_t>(0), thickness - (ret.toolpath_locations.back() + ret.bead_widths.back() / 2));
return ret;
}

Expand Down
13 changes: 11 additions & 2 deletions src/BeadingStrategy/RedistributeBeadingStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "BeadingStrategy.h"

#include "../settings/types/Ratio.h"

namespace cura
{
/*!
Expand All @@ -29,12 +31,16 @@ namespace cura
* strategies' optimum bead width is a weighted average of the outer and inner walls at that bead count.
* /param optimal_width_outer Inner wall width, guaranteed to be the actual (save rounding errors) at a bead count if the parent
* strategies' optimum bead width is a weighted average of the outer and inner walls at that bead count.
* /param outer_wall_lock_factor How much the outer walls should be forced to their optimal width.
* From '1.0': always, unless impossible, to '0.0': ignore the lock factor, redistribute as normal.
*/
RedistributeBeadingStrategy(coord_t optimal_width_outer, coord_t optimal_width_inner, BeadingStrategy* parent) :
RedistributeBeadingStrategy(const coord_t optimal_width_outer, const coord_t optimal_width_inner, const Ratio outer_wall_lock_factor, BeadingStrategy* parent) :
BeadingStrategy(parent->optimal_width, parent->default_transition_length, parent->transitioning_angle),
parent(parent),
optimal_width_outer(optimal_width_outer),
optimal_width_inner(optimal_width_inner)
optimal_width_inner(optimal_width_inner),
outer_wall_lock_factor(outer_wall_lock_factor),
outer_wall_lock_inverse(1.0_r - outer_wall_lock_factor)
{
name = "RedistributeBeadingStrategy";
}
Expand All @@ -55,6 +61,9 @@ namespace cura
BeadingStrategy* parent;
coord_t optimal_width_outer;
coord_t optimal_width_inner;

Ratio outer_wall_lock_factor;
Ratio outer_wall_lock_inverse;
};

} // namespace cura
Expand Down
3 changes: 2 additions & 1 deletion src/WallToolPaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ const VariableWidthPaths& WallToolPaths::generate()
{
const coord_t wall_transition_length = settings.get<coord_t>("wall_transition_length");
const Ratio wall_transition_threshold = settings.get<Ratio>("wall_transition_threshold");
const Ratio outer_wall_lock_factor = settings.get<Ratio>("wall_0_lock_factor");
const size_t max_bead_count = 2 * inset_count;
const auto beading_strat = std::unique_ptr<BeadingStrategy>(BeadingStrategyFactory::makeStrategy(
strategy_type, bead_width_0, bead_width_x, wall_transition_length, transitioning_angle, print_thin_walls, min_bead_width,
min_feature_size, wall_transition_threshold, max_bead_count, wall_0_inset));
min_feature_size, wall_transition_threshold, max_bead_count, wall_0_inset, outer_wall_lock_factor));
const coord_t transition_filter_dist = settings.get<coord_t>("wall_transition_filter_distance");
SkeletalTrapezoidation wall_maker(prepared_outline, *beading_strat, beading_strat->transitioning_angle, discretization_step_size, transition_filter_dist, wall_transition_length);
wall_maker.generateToolpaths(toolpaths);
Expand Down
1 change: 1 addition & 0 deletions tests/WallsComputationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class WallsComputationTest : public testing::Test
settings.add("wall_transition_length", "1");
settings.add("wall_transition_threshold", "50");
settings.add("wall_x_extruder_nr", "0");
settings.add("wall_0_lock_factor", "0.5");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused setting completely.

}

};
Expand Down