Updated Arachne with Cura master.

This commit is contained in:
Lukáš Hejl 2022-05-25 16:17:57 +02:00
parent 454e6496ce
commit 3942cf958c
13 changed files with 77 additions and 86 deletions

View file

@ -368,10 +368,12 @@ void SkeletalTrapezoidation::computeSegmentCellRange(vd_t::cell_type& cell, Poin
SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const BeadingStrategy& beading_strategy, SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const BeadingStrategy& beading_strategy,
double transitioning_angle, coord_t discretization_step_size, double transitioning_angle, coord_t discretization_step_size,
coord_t transition_filter_dist, coord_t beading_propagation_transition_dist coord_t transition_filter_dist, coord_t allowed_filter_deviation,
): transitioning_angle(transitioning_angle), coord_t beading_propagation_transition_dist
): transitioning_angle(transitioning_angle),
discretization_step_size(discretization_step_size), discretization_step_size(discretization_step_size),
transition_filter_dist(transition_filter_dist), transition_filter_dist(transition_filter_dist),
allowed_filter_deviation(allowed_filter_deviation),
beading_propagation_transition_dist(beading_propagation_transition_dist), beading_propagation_transition_dist(beading_propagation_transition_dist),
beading_strategy(beading_strategy) beading_strategy(beading_strategy)
{ {
@ -918,7 +920,7 @@ void SkeletalTrapezoidation::generateTransitionMids(ptr_vector_t<std::list<Trans
edge.data.setTransitions(edge_transitions.back()); // initialization edge.data.setTransitions(edge_transitions.back()); // initialization
transitions = edge.data.getTransitions(); transitions = edge.data.getTransitions();
} }
transitions->emplace_back(mid_pos, transition_lower_bead_count); transitions->emplace_back(mid_pos, transition_lower_bead_count, mid_R);
} }
assert((edge.from->data.bead_count == edge.to->data.bead_count) || edge.data.hasTransitions()); assert((edge.from->data.bead_count == edge.to->data.bead_count) || edge.data.hasTransitions());
} }
@ -997,17 +999,13 @@ std::list<SkeletalTrapezoidation::TransitionMidRef> SkeletalTrapezoidation::diss
{ {
std::list<TransitionMidRef> to_be_dissolved; std::list<TransitionMidRef> to_be_dissolved;
if (traveled_dist > max_dist) if (traveled_dist > max_dist)
{
return to_be_dissolved; return to_be_dissolved;
}
bool should_dissolve = true; bool should_dissolve = true;
for (edge_t* edge = edge_to_start->next; edge && edge != edge_to_start->twin; edge = edge->twin->next) for (edge_t* edge = edge_to_start->next; edge && edge != edge_to_start->twin; edge = edge->twin->next){
{
if (!edge->data.isCentral()) if (!edge->data.isCentral())
{
continue; continue;
}
Point a = edge->from->p; Point a = edge->from->p;
Point b = edge->to->p; Point b = edge->to->p;
Point ab = b - a; Point ab = b - a;
@ -1015,19 +1013,22 @@ std::list<SkeletalTrapezoidation::TransitionMidRef> SkeletalTrapezoidation::diss
bool is_aligned = edge->isUpward(); bool is_aligned = edge->isUpward();
edge_t* aligned_edge = is_aligned? edge : edge->twin; edge_t* aligned_edge = is_aligned? edge : edge->twin;
bool seen_transition_on_this_edge = false; bool seen_transition_on_this_edge = false;
if (aligned_edge->data.hasTransitions()) const coord_t origin_radius = origin_transition.feature_radius;
{ const coord_t radius_here = edge->from->data.distance_to_boundary;
const bool dissolve_result_is_odd = bool(origin_transition.lower_bead_count % 2) == going_up;
const coord_t width_deviation = std::abs(origin_radius - radius_here) * 2; // times by two because the deviation happens at both sides of the significant edge
const coord_t line_width_deviation = dissolve_result_is_odd ? width_deviation : width_deviation / 2; // assume the deviation will be split over either 1 or 2 lines, i.e. assume wall_distribution_count = 1
if (line_width_deviation > allowed_filter_deviation)
should_dissolve = false;
if (should_dissolve && aligned_edge->data.hasTransitions()) {
auto& transitions = *aligned_edge->data.getTransitions(); auto& transitions = *aligned_edge->data.getTransitions();
for (auto transition_it = transitions.begin(); transition_it != transitions.end(); ++ transition_it) for (auto transition_it = transitions.begin(); transition_it != transitions.end(); ++ transition_it) { // Note: this is not necessarily iterating in the traveling direction!
{ // Note: this is not necessarily iterating in the traveling direction!
// Check whether we should dissolve // Check whether we should dissolve
coord_t pos = is_aligned? transition_it->pos : ab_size - transition_it->pos; coord_t pos = is_aligned? transition_it->pos : ab_size - transition_it->pos;
if (traveled_dist + pos < max_dist if (traveled_dist + pos < max_dist && transition_it->lower_bead_count == origin_transition.lower_bead_count) { // Only dissolve local optima
&& transition_it->lower_bead_count == origin_transition.lower_bead_count) // Only dissolve local optima if (traveled_dist + pos < beading_strategy.getTransitioningLength(transition_it->lower_bead_count)) {
{
if (traveled_dist + pos < beading_strategy.getTransitioningLength(transition_it->lower_bead_count))
{
// Consecutive transitions both in/decreasing in bead count should never be closer together than the transition distance // Consecutive transitions both in/decreasing in bead count should never be closer together than the transition distance
assert(going_up != is_aligned || transition_it->lower_bead_count == 0); assert(going_up != is_aligned || transition_it->lower_bead_count == 0);
} }
@ -1036,11 +1037,9 @@ std::list<SkeletalTrapezoidation::TransitionMidRef> SkeletalTrapezoidation::diss
} }
} }
} }
if (!seen_transition_on_this_edge) if (should_dissolve && !seen_transition_on_this_edge) {
{
std::list<SkeletalTrapezoidation::TransitionMidRef> to_be_dissolved_here = dissolveNearbyTransitions(edge, origin_transition, traveled_dist + ab_size, max_dist, going_up); std::list<SkeletalTrapezoidation::TransitionMidRef> to_be_dissolved_here = dissolveNearbyTransitions(edge, origin_transition, traveled_dist + ab_size, max_dist, going_up);
if (to_be_dissolved_here.empty()) if (to_be_dissolved_here.empty()) { // The region is too long to be dissolved in this direction, so it cannot be dissolved in any direction.
{ // The region is too long to be dissolved in this direction, so it cannot be dissolved in any direction.
to_be_dissolved.clear(); to_be_dissolved.clear();
return to_be_dissolved; return to_be_dissolved;
} }
@ -1048,12 +1047,10 @@ std::list<SkeletalTrapezoidation::TransitionMidRef> SkeletalTrapezoidation::diss
should_dissolve = should_dissolve && !to_be_dissolved.empty(); should_dissolve = should_dissolve && !to_be_dissolved.empty();
} }
} }
if (!should_dissolve) if (!should_dissolve)
{
to_be_dissolved.clear(); to_be_dissolved.clear();
}
return to_be_dissolved; return to_be_dissolved;
} }
@ -1062,10 +1059,8 @@ void SkeletalTrapezoidation::dissolveBeadCountRegion(edge_t* edge_to_start, coor
{ {
assert(from_bead_count != to_bead_count); assert(from_bead_count != to_bead_count);
if (edge_to_start->to->data.bead_count != from_bead_count) if (edge_to_start->to->data.bead_count != from_bead_count)
{
return; return;
}
edge_to_start->to->data.bead_count = to_bead_count; edge_to_start->to->data.bead_count = to_bead_count;
for (edge_t* edge = edge_to_start->next; edge && edge != edge_to_start->twin; edge = edge->twin->next) for (edge_t* edge = edge_to_start->next; edge && edge != edge_to_start->twin; edge = edge->twin->next)
{ {

View file

@ -59,6 +59,7 @@ class SkeletalTrapezoidation
double transitioning_angle; //!< How pointy a region should be before we apply the method. Equals 180* - limit_bisector_angle double transitioning_angle; //!< How pointy a region should be before we apply the method. Equals 180* - limit_bisector_angle
coord_t discretization_step_size; //!< approximate size of segments when parabolic VD edges get discretized (and vertex-vertex edges) coord_t discretization_step_size; //!< approximate size of segments when parabolic VD edges get discretized (and vertex-vertex edges)
coord_t transition_filter_dist; //!< Filter transition mids (i.e. anchors) closer together than this coord_t transition_filter_dist; //!< Filter transition mids (i.e. anchors) closer together than this
coord_t allowed_filter_deviation; //!< The allowed line width deviation induced by filtering
coord_t beading_propagation_transition_dist; //!< When there are different beadings propagated from below and from above, use this transitioning distance coord_t beading_propagation_transition_dist; //!< When there are different beadings propagated from below and from above, use this transitioning distance
static constexpr coord_t central_filter_dist = scaled<coord_t>(0.02); //!< Filter areas marked as 'central' smaller than this static constexpr coord_t central_filter_dist = scaled<coord_t>(0.02); //!< Filter areas marked as 'central' smaller than this
static constexpr coord_t snap_dist = scaled<coord_t>(0.02); //!< Generic arithmatic inaccuracy. Only used to determine whether a transition really needs to insert an extra edge. static constexpr coord_t snap_dist = scaled<coord_t>(0.02); //!< Generic arithmatic inaccuracy. Only used to determine whether a transition really needs to insert an extra edge.
@ -96,9 +97,10 @@ public:
SkeletalTrapezoidation(const Polygons& polys, SkeletalTrapezoidation(const Polygons& polys,
const BeadingStrategy& beading_strategy, const BeadingStrategy& beading_strategy,
double transitioning_angle double transitioning_angle
, coord_t discretization_step_size = scaled<coord_t>(0.0008) , coord_t discretization_step_size
, coord_t transition_filter_dist = scaled<coord_t>(0.001) , coord_t transition_filter_dist
, coord_t beading_propagation_transition_dist = scaled<coord_t>(0.0004)); , coord_t allowed_filter_deviation
, coord_t beading_propagation_transition_dist);
/*! /*!
* A skeletal graph through the polygons that we need to fill with beads. * A skeletal graph through the polygons that we need to fill with beads.

View file

@ -26,8 +26,10 @@ public:
{ {
coord_t pos; // Position along edge as measure from edge.from.p coord_t pos; // Position along edge as measure from edge.from.p
int lower_bead_count; int lower_bead_count;
TransitionMiddle(coord_t pos, int lower_bead_count) coord_t feature_radius; // The feature radius at which this transition is placed
TransitionMiddle(coord_t pos, int lower_bead_count, coord_t feature_radius)
: pos(pos), lower_bead_count(lower_bead_count) : pos(pos), lower_bead_count(lower_bead_count)
, feature_radius(feature_radius)
{} {}
}; };

View file

@ -38,21 +38,24 @@ WallToolPaths::WallToolPaths(const Polygons& outline, const coord_t bead_width_0
if (const auto &min_bead_width_opt = print_object_config.min_bead_width; min_bead_width_opt.percent) { if (const auto &min_bead_width_opt = print_object_config.min_bead_width; min_bead_width_opt.percent) {
assert(!print_config.nozzle_diameter.empty()); assert(!print_config.nozzle_diameter.empty());
double min_nozzle_diameter = *std::min_element(print_config.nozzle_diameter.values.begin(), print_config.nozzle_diameter.values.end()); double min_nozzle_diameter = *std::min_element(print_config.nozzle_diameter.values.begin(), print_config.nozzle_diameter.values.end());
min_bead_width = scaled<coord_t>(min_bead_width_opt.value * 0.01 * min_nozzle_diameter); this->min_bead_width = scaled<coord_t>(min_bead_width_opt.value * 0.01 * min_nozzle_diameter);
}
if (const auto &wall_transition_filter_deviation_opt = print_object_config.wall_transition_filter_deviation; wall_transition_filter_deviation_opt.percent) {
assert(!print_config.nozzle_diameter.empty());
double min_nozzle_diameter = *std::min_element(print_config.nozzle_diameter.values.begin(), print_config.nozzle_diameter.values.end());
this->wall_transition_filter_deviation = scaled<coord_t>(wall_transition_filter_deviation_opt.value * 0.01 * min_nozzle_diameter);
} }
} }
void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const int64_t allowed_error_distance_squared) void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const int64_t allowed_error_distance_squared)
{ {
if (thiss.size() < 3) if (thiss.size() < 3) {
{
thiss.points.clear(); thiss.points.clear();
return; return;
} }
if (thiss.size() == 3) if (thiss.size() == 3)
{
return; return;
}
Polygon new_path; Polygon new_path;
Point previous = thiss.points.back(); Point previous = thiss.points.back();
@ -76,22 +79,16 @@ void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const
*/ */
int64_t accumulated_area_removed = int64_t(previous.x()) * int64_t(current.y()) - int64_t(previous.y()) * int64_t(current.x()); // Twice the Shoelace formula for area of polygon per line segment. int64_t accumulated_area_removed = int64_t(previous.x()) * int64_t(current.y()) - int64_t(previous.y()) * int64_t(current.x()); // Twice the Shoelace formula for area of polygon per line segment.
for (size_t point_idx = 0; point_idx < thiss.points.size(); point_idx++) for (size_t point_idx = 0; point_idx < thiss.points.size(); point_idx++) {
{
current = thiss.points.at(point_idx % thiss.points.size()); current = thiss.points.at(point_idx % thiss.points.size());
//Check if the accumulated area doesn't exceed the maximum. //Check if the accumulated area doesn't exceed the maximum.
Point next; Point next;
if (point_idx + 1 < thiss.points.size()) if (point_idx + 1 < thiss.points.size()) {
{
next = thiss.points.at(point_idx + 1); next = thiss.points.at(point_idx + 1);
} } else if (point_idx + 1 == thiss.points.size() && new_path.size() > 1) { // don't spill over if the [next] vertex will then be equal to [previous]
else if (point_idx + 1 == thiss.points.size() && new_path.size() > 1)
{ // don't spill over if the [next] vertex will then be equal to [previous]
next = new_path[0]; //Spill over to new polygon for checking removed area. next = new_path[0]; //Spill over to new polygon for checking removed area.
} } else {
else
{
next = thiss.points.at((point_idx + 1) % thiss.points.size()); next = thiss.points.at((point_idx + 1) % thiss.points.size());
} }
const int64_t removed_area_next = int64_t(current.x()) * int64_t(next.y()) - int64_t(current.y()) * int64_t(next.x()); // Twice the Shoelace formula for area of polygon per line segment. const int64_t removed_area_next = int64_t(current.x()) * int64_t(next.y()) - int64_t(current.y()) * int64_t(next.x()); // Twice the Shoelace formula for area of polygon per line segment.
@ -99,8 +96,7 @@ void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const
accumulated_area_removed += removed_area_next; accumulated_area_removed += removed_area_next;
const int64_t length2 = (current - previous).cast<int64_t>().squaredNorm(); const int64_t length2 = (current - previous).cast<int64_t>().squaredNorm();
if (length2 < scaled<int64_t>(25.)) if (length2 < scaled<int64_t>(25.)) {
{
// We're allowed to always delete segments of less than 5 micron. // We're allowed to always delete segments of less than 5 micron.
continue; continue;
} }
@ -109,9 +105,7 @@ void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const
const int64_t base_length_2 = (next - previous).cast<int64_t>().squaredNorm(); const int64_t base_length_2 = (next - previous).cast<int64_t>().squaredNorm();
if (base_length_2 == 0) //Two line segments form a line back and forth with no area. if (base_length_2 == 0) //Two line segments form a line back and forth with no area.
{
continue; //Remove the vertex. continue; //Remove the vertex.
}
//We want to check if the height of the triangle formed by previous, current and next vertices is less than allowed_error_distance_squared. //We want to check if the height of the triangle formed by previous, current and next vertices is less than allowed_error_distance_squared.
//1/2 L = A [actual area is half of the computed shoelace value] // Shoelace formula is .5*(...) , but we simplify the computation and take out the .5 //1/2 L = A [actual area is half of the computed shoelace value] // Shoelace formula is .5*(...) , but we simplify the computation and take out the .5
//A = 1/2 * b * h [triangle area formula] //A = 1/2 * b * h [triangle area formula]
@ -122,16 +116,13 @@ void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const
const int64_t height_2 = double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2); const int64_t height_2 = double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2);
if ((height_2 <= Slic3r::sqr(scaled<coord_t>(0.005)) //Almost exactly colinear (barring rounding errors). if ((height_2 <= Slic3r::sqr(scaled<coord_t>(0.005)) //Almost exactly colinear (barring rounding errors).
&& Line::distance_to_infinite(current, previous, next) <= scaled<double>(0.005))) // make sure that height_2 is not small because of cancellation of positive and negative areas && Line::distance_to_infinite(current, previous, next) <= scaled<double>(0.005))) // make sure that height_2 is not small because of cancellation of positive and negative areas
{
continue; continue;
}
if (length2 < smallest_line_segment_squared if (length2 < smallest_line_segment_squared
&& height_2 <= allowed_error_distance_squared) // removing the vertex doesn't introduce too much error.) && height_2 <= allowed_error_distance_squared) // removing the vertex doesn't introduce too much error.)
{ {
const int64_t next_length2 = (current - next).cast<int64_t>().squaredNorm(); const int64_t next_length2 = (current - next).cast<int64_t>().squaredNorm();
if (next_length2 > smallest_line_segment_squared) if (next_length2 > 4 * smallest_line_segment_squared) {
{
// Special case; The next line is long. If we were to remove this, it could happen that we get quite noticeable artifacts. // Special case; The next line is long. If we were to remove this, it could happen that we get quite noticeable artifacts.
// We should instead move this point to a location where both edges are kept and then remove the previous point that we wanted to keep. // We should instead move this point to a location where both edges are kept and then remove the previous point that we wanted to keep.
// By taking the intersection of these two lines, we get a point that preserves the direction (so it makes the corner a bit more pointy). // By taking the intersection of these two lines, we get a point that preserves the direction (so it makes the corner a bit more pointy).
@ -146,20 +137,16 @@ void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const
// We can't find a better spot for it, but the size of the line is more than 5 micron. // We can't find a better spot for it, but the size of the line is more than 5 micron.
// So the only thing we can do here is leave it in... // So the only thing we can do here is leave it in...
} }
else else {
{
// New point seems like a valid one. // New point seems like a valid one.
current = intersection_point; current = intersection_point;
// If there was a previous point added, remove it. // If there was a previous point added, remove it.
if(!new_path.empty()) if(!new_path.empty()) {
{
new_path.points.pop_back(); new_path.points.pop_back();
previous = previous_previous; previous = previous_previous;
} }
} }
} } else {
else
{
continue; //Remove the vertex. continue; //Remove the vertex.
} }
} }
@ -517,7 +504,8 @@ const std::vector<VariableWidthLines> &WallToolPaths::generate()
wall_0_inset, wall_0_inset,
wall_distribution_count wall_distribution_count
); );
const coord_t transition_filter_dist = scaled<coord_t>(this->print_object_config.wall_transition_filter_distance.value); const coord_t transition_filter_dist = scaled<coord_t>(100.f);
const coord_t allowed_filter_deviation = wall_transition_filter_deviation;
SkeletalTrapezoidation wall_maker SkeletalTrapezoidation wall_maker
( (
prepared_outline, prepared_outline,
@ -525,6 +513,7 @@ const std::vector<VariableWidthLines> &WallToolPaths::generate()
beading_strat->getTransitioningAngle(), beading_strat->getTransitioningAngle(),
discretization_step_size, discretization_step_size,
transition_filter_dist, transition_filter_dist,
allowed_filter_deviation,
wall_transition_length wall_transition_length
); );
wall_maker.generateToolpaths(toolpaths); wall_maker.generateToolpaths(toolpaths);

View file

@ -117,6 +117,7 @@ private:
bool toolpaths_generated; //<! Are the toolpaths generated bool toolpaths_generated; //<! Are the toolpaths generated
std::vector<VariableWidthLines> toolpaths; //<! The generated toolpaths std::vector<VariableWidthLines> toolpaths; //<! The generated toolpaths
Polygons inner_contour; //<! The inner contour of the generated toolpaths Polygons inner_contour; //<! The inner contour of the generated toolpaths
coord_t wall_transition_filter_deviation; //!< The allowed line width deviation induced by filtering
const PrintObjectConfig &print_object_config; const PrintObjectConfig &print_object_config;
}; };

View file

@ -127,7 +127,7 @@ void ExtrusionLine::simplify(const int64_t smallest_line_segment_squared, const
&& height_2 <= allowed_error_distance_squared) // Removing the junction (vertex) doesn't introduce too much error. && height_2 <= allowed_error_distance_squared) // Removing the junction (vertex) doesn't introduce too much error.
{ {
const int64_t next_length2 = (current - next).cast<int64_t>().squaredNorm(); const int64_t next_length2 = (current - next).cast<int64_t>().squaredNorm();
if (next_length2 > smallest_line_segment_squared) if (next_length2 > 4 * smallest_line_segment_squared)
{ {
// Special case; The next line is long. If we were to remove this, it could happen that we get quite noticeable artifacts. // Special case; The next line is long. If we were to remove this, it could happen that we get quite noticeable artifacts.
// We should instead move this point to a location where both edges are kept and then remove the previous point that we wanted to keep. // We should instead move this point to a location where both edges are kept and then remove the previous point that we wanted to keep.

View file

@ -178,7 +178,7 @@ public:
{ {
++start_pos; ++start_pos;
} }
chain.insert(chain.end(), (*closest.polygons)[closest.poly_idx].rbegin(), (*closest.polygons)[closest.poly_idx].rend()); chain.insert(chain.end(), start_pos, (*closest.polygons)[closest.poly_idx].rend());
} }
for(size_t i = old_size; i < chain.size(); ++i) //Update chain length. for(size_t i = old_size; i < chain.size(); ++i) //Update chain length.
{ {

View file

@ -449,7 +449,7 @@ static std::vector<std::string> s_Preset_print_options {
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits", "wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits",
"slicing_engine", "wall_transition_length", "wall_transition_filter_distance", "wall_transition_angle", "slicing_engine", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "wall_split_middle_threshold", "wall_add_middle_threshold", "min_feature_size", "min_bead_width" "wall_distribution_count", "wall_split_middle_threshold", "wall_add_middle_threshold", "min_feature_size", "min_bead_width"
}; };

View file

@ -3067,24 +3067,28 @@ void PrintConfigDef::init_fff_params()
def->min = 0; def->min = 0;
def->set_default_value(new ConfigOptionFloat(0.4)); def->set_default_value(new ConfigOptionFloat(0.4));
def = this->add("wall_transition_filter_distance", coFloat); def = this->add("wall_transition_filter_deviation", coFloatOrPercent);
def->label = L("Wall Transition Distance Filter"); def->label = L("Wall Transitioning Filter Margin");
def->category = L("Advanced"); def->category = L("Advanced");
def->tooltip = L("If it would be transitioning back and forth between different numbers of walls in " def->tooltip = L("Prevent transitioning back and forth between one extra wall and one less. This "
"quick succession, don't transition at all. Remove transitions if they are closer " "margin extends the range of line widths which follow to [Minimum Wall Line "
"together than this distance."); "Width - Margin, 2 * Minimum Wall Line Width + Margin]. Increasing this margin "
"reduces the number of transitions, which reduces the number of extrusion "
"starts/stops and travel time. However, large line width variation can lead to "
"under- or overextrusion problems."
"If expressed as percentage (for example 25%), it will be computed over nozzle diameter.");
def->sidetext = L("mm"); def->sidetext = L("mm");
def->mode = comExpert; def->mode = comExpert;
def->min = 0; def->min = 0;
def->set_default_value(new ConfigOptionFloat(1.4)); def->set_default_value(new ConfigOptionFloatOrPercent(25, true));
def = this->add("wall_transition_angle", coFloat); def = this->add("wall_transition_angle", coFloat);
def->label = L("Wall Transition Angle"); def->label = L("Wall Transitioning Threshold Angle");
def->category = L("Advanced"); def->category = L("Advanced");
def->tooltip = L("When transitioning between different numbers of walls as the part becomes thinner, " def->tooltip = L("When to create transitions between even and odd numbers of walls. A wedge shape with"
"two adjacent walls will join together at this angle. This can make the walls come " " an angle greater than this setting will not have transitions and no walls will be "
"together faster than what the Wall Transition Length indicates, filling the space " "printed in the center to fill the remaining space. Reducing this setting reduces "
"better."); "the number and length of these center walls, but may leave gaps or overextrude.");
def->sidetext = L("°"); def->sidetext = L("°");
def->mode = comExpert; def->mode = comExpert;
def->min = 1.; def->min = 1.;
@ -4089,8 +4093,6 @@ void DynamicPrintConfig::normalize_fdm()
opt_min_bead_width->value = std::max(opt_min_bead_width->value, 0.001); opt_min_bead_width->value = std::max(opt_min_bead_width->value, 0.001);
if (auto *opt_wall_transition_length = this->opt<ConfigOptionFloat>("wall_transition_length", false); opt_wall_transition_length) if (auto *opt_wall_transition_length = this->opt<ConfigOptionFloat>("wall_transition_length", false); opt_wall_transition_length)
opt_wall_transition_length->value = std::max(opt_wall_transition_length->value, 0.001); opt_wall_transition_length->value = std::max(opt_wall_transition_length->value, 0.001);
if (auto *opt_wall_transition_filter_distance = this->opt<ConfigOptionFloat>("wall_transition_filter_distance", false); opt_wall_transition_filter_distance)
opt_wall_transition_filter_distance->value = std::max(opt_wall_transition_filter_distance->value, 0.001);
} }
void handle_legacy_sla(DynamicPrintConfig &config) void handle_legacy_sla(DynamicPrintConfig &config)

View file

@ -489,7 +489,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionEnum<SlicingMode>, slicing_mode)) ((ConfigOptionEnum<SlicingMode>, slicing_mode))
((ConfigOptionEnum<SlicingEngine>, slicing_engine)) ((ConfigOptionEnum<SlicingEngine>, slicing_engine))
((ConfigOptionFloat, wall_transition_length)) ((ConfigOptionFloat, wall_transition_length))
((ConfigOptionFloat, wall_transition_filter_distance)) ((ConfigOptionFloatOrPercent, wall_transition_filter_deviation))
((ConfigOptionFloat, wall_transition_angle)) ((ConfigOptionFloat, wall_transition_angle))
((ConfigOptionInt, wall_distribution_count)) ((ConfigOptionInt, wall_distribution_count))
((ConfigOptionPercent, wall_split_middle_threshold)) ((ConfigOptionPercent, wall_split_middle_threshold))

View file

@ -664,7 +664,7 @@ bool PrintObject::invalidate_state_by_config_options(
} else if ( } else if (
opt_key == "slicing_engine" opt_key == "slicing_engine"
|| opt_key == "wall_transition_length" || opt_key == "wall_transition_length"
|| opt_key == "wall_transition_filter_distance" || opt_key == "wall_transition_filter_deviation"
|| opt_key == "wall_transition_angle" || opt_key == "wall_transition_angle"
|| opt_key == "wall_distribution_count" || opt_key == "wall_distribution_count"
|| opt_key == "wall_split_middle_threshold" || opt_key == "wall_split_middle_threshold"

View file

@ -320,7 +320,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
bool have_arachne = config->opt_enum<SlicingEngine>("slicing_engine") == SlicingEngine::Arachne; bool have_arachne = config->opt_enum<SlicingEngine>("slicing_engine") == SlicingEngine::Arachne;
toggle_field("wall_transition_length", have_arachne); toggle_field("wall_transition_length", have_arachne);
toggle_field("wall_transition_filter_distance", have_arachne); toggle_field("wall_transition_filter_deviation", have_arachne);
toggle_field("wall_transition_angle", have_arachne); toggle_field("wall_transition_angle", have_arachne);
toggle_field("wall_distribution_count", have_arachne); toggle_field("wall_distribution_count", have_arachne);
toggle_field("wall_split_middle_threshold", have_arachne); toggle_field("wall_split_middle_threshold", have_arachne);

View file

@ -1673,7 +1673,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Experimental")); optgroup = page->new_optgroup(L("Experimental"));
optgroup->append_single_option_line("slicing_engine"); optgroup->append_single_option_line("slicing_engine");
optgroup->append_single_option_line("wall_transition_length"); optgroup->append_single_option_line("wall_transition_length");
optgroup->append_single_option_line("wall_transition_filter_distance"); optgroup->append_single_option_line("wall_transition_filter_deviation");
optgroup->append_single_option_line("wall_transition_angle"); optgroup->append_single_option_line("wall_transition_angle");
optgroup->append_single_option_line("wall_distribution_count"); optgroup->append_single_option_line("wall_distribution_count");
optgroup->append_single_option_line("wall_split_middle_threshold"); optgroup->append_single_option_line("wall_split_middle_threshold");