Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--resources/ui_layout/printer_fff.ui1
-rw-r--r--src/libslic3r/GCode.cpp112
-rw-r--r--src/libslic3r/GCode.hpp2
-rw-r--r--src/libslic3r/GCodeWriter.cpp32
-rw-r--r--src/libslic3r/GCodeWriter.hpp11
-rw-r--r--src/libslic3r/Preset.cpp1
-rw-r--r--src/libslic3r/PrintConfig.cpp17
-rw-r--r--src/libslic3r/PrintConfig.hpp2
-rw-r--r--src/slic3r/GUI/DoubleSlider.cpp117
-rw-r--r--src/slic3r/GUI/Tab.cpp2
10 files changed, 187 insertions, 110 deletions
diff --git a/resources/ui_layout/printer_fff.ui b/resources/ui_layout/printer_fff.ui
index f6c51bb18..90acf9b84 100644
--- a/resources/ui_layout/printer_fff.ui
+++ b/resources/ui_layout/printer_fff.ui
@@ -5,6 +5,7 @@ group:Size and coordinates
setting:max_print_height
setting:z_offset
setting:z_step
+ setting:lift_min
group:extruders_count_event:milling_count_event:Capabilities
extruders_count
setting:single_extruder_multi_material
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 7fc592643..2b55f0af5 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -219,16 +219,23 @@ std::string Wipe::wipe(GCode& gcodegen, bool toolchange)
}
//if first layer, ask for a bigger lift for travel to object, to be on the safe side
-static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeWriter & writer, int extruder_id) {
+static inline void set_extra_lift(const float previous_print_z, const int layer_id, const PrintConfig& print_config, GCodeWriter & writer, int extruder_id) {
//if first layer, ask for a bigger lift for travel to object, to be on the safe side
- if (layer.id() == 0 &&
- (print.config().retract_lift.get_at(extruder_id) != 0 || print.config().retract_lift_first_layer.get_at(extruder_id))) {
- //get biggest first layer height and set extra lift for first travel, to be safe.
- double extra_lift_value = 0;
- for (const PrintObject* obj : print.objects())
- extra_lift_value = std::max(extra_lift_value, print.get_object_first_layer_height(*obj));
- writer.set_extra_lift(extra_lift_value * 2);
+ double extra_lift_value = 0;
+ if (print_config.lift_min.value > 0) {
+ double retract_lift = 0;
+ //get the current lift (imo, should be given by the writer... i'm duplicating stuff here)
+ if(//(previous_print_z == 0 && print_config.retract_lift_above.get_at(writer.tool()->id()) == 0) ||
+ print_config.retract_lift_above.get_at(writer.tool()->id()) <= previous_print_z + EPSILON
+ || (layer_id == 0 && print_config.retract_lift_first_layer.get_at(writer.tool()->id())))
+ retract_lift = writer.tool()->retract_lift();
+ // see if it's positive
+ if (previous_print_z + extra_lift_value + retract_lift < print_config.lift_min.value) {
+ extra_lift_value = print_config.lift_min.value - previous_print_z - retract_lift;
+ }
}
+ if(extra_lift_value > 0)
+ writer.set_extra_lift(extra_lift_value);
}
static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const Vec2f &wipe_tower_pt)
@@ -1398,6 +1405,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// Write the custom start G-code
_writeln(file, start_gcode);
+ m_last_pos_defined = false;
+
//flush FanMover buffer to avoid modifying the start gcode if it's manual.
if (this->config().start_gcode_manual && this->m_fan_mover.get() != nullptr) {
std::string to_write = this->m_fan_mover.get()->process_gcode("", true);
@@ -1514,8 +1523,10 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
m_avoid_crossing_perimeters.use_external_mp_once();
+ set_extra_lift(m_last_layer_z, 0, print.config(), m_writer, initial_extruder_id);
_write(file, this->retract());
std::string gcode;
+ //go to origin of the next object (it's 0,0 because we shifted the origin to it)
Polyline polyline = this->travel_to(gcode, Point(0, 0), erNone);
this->write_travel_to(gcode, polyline, "move to origin position for next object");
_write(file, gcode);
@@ -1531,6 +1542,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
this->_print_first_layer_bed_temperature(file, print, between_objects_gcode, initial_extruder_id, false);
this->_print_first_layer_extruder_temperatures(file, print, between_objects_gcode, initial_extruder_id, false);
_writeln(file, between_objects_gcode);
+ } else {
+ set_extra_lift(0, 0, print.config(), m_writer, initial_extruder_id);
}
//reinit the seam placer on the new object
m_seam_placer.init(print);
@@ -1555,6 +1568,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
m_second_layer_things_done = false;
prev_object = &object;
}
+ set_extra_lift(m_last_layer_z, prev_object->layers().back()->id(), print.config(), m_writer, initial_extruder_id /* osef, it's only for the lift_min */);
} else {
// Sort layers by Z.
// All extrusion moves with the same top layer height are extruded uninterrupted.
@@ -2263,7 +2277,22 @@ void GCode::process_layer(
print.config().before_layer_gcode.value, m_writer.tool()->id(), &config)
+ "\n";
}
- gcode += this->change_layer(print_z); // this will increase m_layer_index
+ // print z move to next layer UNLESS
+ // if it's going to the first layer, then we may want to dealy the move in these condition:
+ // there is no "after layer change gcode" and it's the first move from the unknown
+ if (print.config().layer_gcode.value.empty() && !m_last_pos_defined && m_config.start_gcode_manual && (
+ // there is a lift (on the first llyer, so the first move will bring us to the required height
+ (m_writer.tool()->retract_lift() > 0 && (m_config.retract_lift_above.get_at(m_writer.tool()->id()) == 0 || BOOL_EXTRUDER_CONFIG(retract_lift_first_layer)))
+ || // or lift_min is higher than the first layer height.
+ m_config.lift_min.value > layer.print_z
+ ))
+ m_delayed_layer_change = this->change_layer(print_z); //HACK for superslicer#1775
+ else {
+ //extra lift on layer change if multiple objects
+ if(single_object_instance_idx == size_t(-1) && (support_layer != nullptr || layers.size() > 1))
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, first_extruder_id);
+ gcode += this->change_layer(print_z); // this will increase m_layer_index
+ }
m_layer = &layer;
if (! print.config().layer_gcode.value.empty()) {
DynamicConfig config;
@@ -2478,9 +2507,12 @@ void GCode::process_layer(
m_last_processor_extrusion_role = erWipeTower;
//if first layer, ask for a bigger lift for travel to object, to be on the safe side
- set_extra_lift(layer, print, m_writer, extruder_id);
+ if(single_object_instance_idx == size_t(-1) && m_layer_index == 0)
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) {
+ // before going to and from a global skirt, please ensure you are a a safe height
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
const std::pair<size_t, size_t> loops = loops_it->second;
this->set_origin(0., 0.);
m_avoid_crossing_perimeters.use_external_mp();
@@ -2504,27 +2536,30 @@ void GCode::process_layer(
// Allow a straight travel move to the first object point if this is the first layer (but don't in next layers).
if (first_layer && loops.first == 0)
m_avoid_crossing_perimeters.disable_once();
+ // before going to and from a global skirt, please ensure you are a a safe height
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
}
// Extrude brim with the extruder of the 1st region.
if (! m_brim_done) {
- //if first layer, ask for a bigger lift for travel to object, to be on the safe side
- set_extra_lift(layer, print, m_writer, extruder_id);
-
this->set_origin(0., 0.);
m_avoid_crossing_perimeters.use_external_mp();
- gcode += this->extrude_entity(print.brim(), "Brim", m_config.support_material_speed.value);
+ for (const ExtrusionEntity* brim_entity : print.brim().entities) {
+ //if first layer, ask for a bigger lift for travel to each brim, to be on the safe side
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
+ gcode += this->extrude_entity(*brim_entity, "Brim", m_config.support_material_speed.value);
+ }
m_brim_done = true;
m_avoid_crossing_perimeters.use_external_mp(false);
// Allow a straight travel move to the first object point.
m_avoid_crossing_perimeters.disable_once();
+ //to go to the object-only skirt or brim, or to the object (May be overriden here but I don't care)
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
}
//extrude object-only skirt
//TODO: use it also for wiping like the other one (as they are exlusiev)
if (single_object_instance_idx != size_t(-1) && !layers.front().object()->skirt().empty()
&& extruder_id == layer_tools.extruders.front()) {
- //if first layer, ask for a bigger lift for travel to object, to be on the safe side
- set_extra_lift(layer, print, m_writer, extruder_id);
const PrintObject *print_object = layers.front().object();
this->set_origin(unscale(print_object->instances()[single_object_instance_idx].shift));
@@ -2540,8 +2575,6 @@ void GCode::process_layer(
//extrude object-only brim
if (single_object_instance_idx != size_t(-1) && !layers.front().object()->brim().empty()
&& extruder_id == layer_tools.extruders.front()) {
- //if first layer, ask for a bigger lift for travel to object, to be on the safe side
- set_extra_lift(layer, print, m_writer, extruder_id);
const PrintObject *print_object = layers.front().object();
this->set_origin(unscale(print_object->instances()[single_object_instance_idx].shift));
@@ -2566,7 +2599,7 @@ void GCode::process_layer(
for (int print_wipe_extrusions = is_anything_overridden; print_wipe_extrusions>=0; --print_wipe_extrusions) {
if (is_anything_overridden && print_wipe_extrusions == 0)
gcode+="; PURGING FINISHED\n";
-
+ bool first_object = true;
for (InstanceToPrint &instance_to_print : instances_to_print) {
m_config.apply(instance_to_print.print_object.config(), true);
m_layer = layers[instance_to_print.layer_id].layer();
@@ -2592,8 +2625,11 @@ void GCode::process_layer(
m_gcode_label_objects_start += std::string("M486 S") + std::to_string(instance_plater_id) + "\n";
}
}
- //if first layer, ask for a bigger lift for travel to object, to be on the safe side
- set_extra_lift(layer, print, m_writer, extruder_id);
+ // ask for a bigger lift for travel to object when moving to another object
+ if (single_object_instance_idx == size_t(-1) && !first_object)
+ set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
+ else
+ first_object = false;
// When starting a new object, use the external motion planner for the first travel move.
const Point &offset = instance_to_print.print_object.instances()[instance_to_print.instance_id].shift;
std::pair<const PrintObject*, Point> this_object_copy(&instance_to_print.print_object, offset);
@@ -3902,7 +3938,10 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
if (m_config.travel_acceleration.value > 0)
travel_acceleration = m_config.travel_acceleration.get_abs_value(acceleration);
}
-
+ if (m_writer.get_max_acceleration() > 0) {
+ acceleration = std::min((double)m_writer.get_max_acceleration(), acceleration);
+ travel_acceleration = std::min((double)m_writer.get_max_acceleration(), travel_acceleration);
+ }
if (travel_acceleration == acceleration) {
m_writer.set_acceleration((uint32_t)floor(acceleration + 0.5));
// go to first point of extrusion path (stop at midpoint to let us set the decel speed)
@@ -3915,7 +3954,10 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
if (!m_last_pos_defined || m_last_pos != path.first_point()) {
Polyline poly_start = this->travel_to(gcode, path.first_point(), path.role());
coordf_t length = poly_start.length();
- if (length > SCALED_EPSILON) {
+ // if length is enough, it's not the hack for first move, and the travel accel is different than the normal accel
+ // then cut the travel in two to change the accel in-between
+ // TODO: compute the real point where it should be cut, considering an infinite max speed.
+ if (length > std::max(scale_d(EPSILON), scale_d(m_config.min_length)) && m_last_pos_defined && floor(travel_acceleration) != floor(acceleration)) {
Polyline poly_end;
coordf_t min_length = scale_d(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0.5)) * 20;
if (poly_start.size() > 2 && length > min_length * 3) {
@@ -3954,7 +3996,18 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
_add_object_change_labels(gcode);
// compensate retraction
- gcode += this->unretract();
+ if (m_delayed_layer_change.empty()) {
+ gcode += m_writer.unlift();//this->unretract();
+ } else {
+ //check if an unlift happens
+ std::string unlift = m_writer.unlift();
+ if (unlift.empty()) {
+ unlift = m_delayed_layer_change;
+ }
+ m_delayed_layer_change.clear();
+ gcode += unlift;
+ }
+ gcode += m_writer.unretract();
speed = _compute_speed_mm_per_sec(path, speed);
double F = speed * 60; // convert mm/sec to mm/min
@@ -4185,7 +4238,9 @@ std::string GCode::retract(bool toolchange)
methods even if we performed wipe, since this will ensure the entire retraction
length is honored in case wipe path was too short. */
gcode += toolchange ? m_writer.retract_for_toolchange() : m_writer.retract();
- bool need_lift = !m_writer.tool_is_extruder() || toolchange || (BOOL_EXTRUDER_CONFIG(retract_lift_first_layer) && m_config.print_retract_lift.value != 0 && this->m_layer_index == 0);
+ bool need_lift = !m_writer.tool_is_extruder() || toolchange
+ || (BOOL_EXTRUDER_CONFIG(retract_lift_first_layer) && m_config.print_retract_lift.value != 0 && this->m_layer_index == 0)
+ || this->m_writer.get_extra_lift() > 0;
bool last_fill_extusion_role_top_infill = (this->m_last_extrusion_role == ExtrusionRole::erTopSolidInfill || this->m_last_extrusion_role == ExtrusionRole::erIroning);
if(this->m_last_extrusion_role == ExtrusionRole::erGapFill)
last_fill_extusion_role_top_infill = (this->m_last_notgapfill_extrusion_role == ExtrusionRole::erTopSolidInfill || this->m_last_notgapfill_extrusion_role == ExtrusionRole::erIroning);
@@ -4198,12 +4253,7 @@ std::string GCode::retract(bool toolchange)
need_lift = true;
}
if (need_lift)
- if (m_writer.tool()->retract_length() > 0
- || m_config.use_firmware_retraction
- || (!m_writer.tool_is_extruder() && m_writer.tool()->retract_lift() != 0)
- || (BOOL_EXTRUDER_CONFIG(retract_lift_first_layer) && this->m_layer_index == 0)
- )
- gcode += m_writer.lift();
+ gcode += m_writer.lift(this->m_layer_index);
return gcode;
}
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index a5bfb881e..27b016b4e 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -349,6 +349,8 @@ private:
// Markers for the Pressure Equalizer to recognize the extrusion type.
// The Pressure Equalizer removes the markers from the final G-code.
bool m_enable_extrusion_role_markers;
+ // HACK to avoid multiple Z move.
+ std::string m_delayed_layer_change;
// Keeps track of the last extrusion role passed to the processor
ExtrusionRole m_last_processor_extrusion_role;
// How many times will change_layer() be called?
diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp
index 2ed093492..bce90d4a6 100644
--- a/src/libslic3r/GCodeWriter.cpp
+++ b/src/libslic3r/GCodeWriter.cpp
@@ -510,14 +510,14 @@ std::string GCodeWriter::travel_to_z(double z, const std::string &comment)
/* If target Z is lower than current Z but higher than nominal Z
we don't perform the move but we only adjust the nominal Z by
reducing the lift amount that will be used for unlift. */
- if (!this->will_move_z(z)) {
+ // note that if we move but it's lower and we are lifted, we can wait a bit for unlifting, to avoid possible dance on layer change.
+ if (!this->will_move_z(z) || z < m_pos.z() && m_lifted > EPSILON) {
double nominal_z = m_pos.z() - m_lifted;
m_lifted -= (z - nominal_z);
if (std::abs(m_lifted) < EPSILON)
m_lifted = 0.;
return "";
}
-
/* In all the other cases, we perform an actual Z move and cancel
the lift. */
m_lifted = 0;
@@ -548,7 +548,7 @@ bool GCodeWriter::will_move_z(double z) const
we don't perform an actual Z move. */
if (m_lifted > 0) {
double nominal_z = m_pos.z() - m_lifted;
- if (z >= nominal_z && z <= m_pos.z())
+ if (z >= nominal_z + EPSILON && z <= m_pos.z() - EPSILON)
return false;
}
return true;
@@ -698,15 +698,19 @@ std::string GCodeWriter::unretract()
/* If this method is called more than once before calling unlift(),
it will not perform subsequent lifts, even if Z was raised manually
(i.e. with travel_to_z()) and thus _lifted was reduced. */
-std::string GCodeWriter::lift()
+std::string GCodeWriter::lift(int layer_id)
{
// check whether the above/below conditions are met
double target_lift = 0;
if(this->tool_is_extruder()){
- //these two should be in the Tool class methods....
- double above = this->config.retract_lift_above.get_at(m_tool->id());
- double below = this->config.retract_lift_below.get_at(m_tool->id());
- if (m_pos.z() >= above && (below == 0 || m_pos.z() <= below))
+ bool can_lift = this->config.retract_lift_first_layer.get_at(m_tool->id()) && layer_id == 0;
+ if (!can_lift) {
+ //these two should be in the Tool class methods....
+ double above = this->config.retract_lift_above.get_at(m_tool->id());
+ double below = this->config.retract_lift_below.get_at(m_tool->id());
+ can_lift = (m_pos.z() >= above - EPSILON && (below == 0 || m_pos.z() <= below + EPSILON));
+ }
+ if(can_lift)
target_lift = m_tool->retract_lift();
} else {
target_lift = m_tool->retract_lift();
@@ -717,17 +721,19 @@ std::string GCodeWriter::lift()
target_lift = config_region->print_retract_lift.value;
}
- if (this->extra_lift > 0) {
- target_lift += this->extra_lift;
- this->extra_lift = 0;
+ // one-time extra lift (often for dangerous travels)
+ if (this->m_extra_lift > 0) {
+ target_lift += this->m_extra_lift;
+ this->m_extra_lift = 0;
}
// compare against epsilon because travel_to_z() does math on it
// and subtracting layer_height from retract_lift might not give
// exactly zero
- if (std::abs(m_lifted) < EPSILON && target_lift > 0) {
+ if (std::abs(m_lifted) < target_lift - EPSILON && target_lift > 0) {
+ std::string str = this->_travel_to_z(m_pos.z() + target_lift - m_lifted, "lift Z");
m_lifted = target_lift;
- return this->_travel_to_z(m_pos.z() + target_lift, "lift Z");
+ return str;
}
return "";
}
diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp
index 72264aac3..71def452d 100644
--- a/src/libslic3r/GCodeWriter.hpp
+++ b/src/libslic3r/GCodeWriter.hpp
@@ -51,6 +51,7 @@ public:
std::string set_fan(uint8_t speed, bool dont_save = false, uint16_t default_tool = 0);
void set_acceleration(uint32_t acceleration);
uint32_t get_acceleration() const;
+ uint32_t get_max_acceleration() { return this->m_max_acceleration; }
std::string write_acceleration();
std::string reset_e(bool force = false);
std::string update_progress(uint32_t num, uint32_t tot, bool allow_100 = false) const;
@@ -73,11 +74,12 @@ public:
std::string retract(bool before_wipe = false);
std::string retract_for_toolchange(bool before_wipe = false);
std::string unretract();
- std::string lift();
+ void set_extra_lift(double extra_zlift) { this->m_extra_lift = extra_zlift; }
+ double get_extra_lift() { return this->m_extra_lift; }
+ std::string lift(int layer_id);
std::string unlift();
Vec3d get_position() const { return m_pos; }
- void set_extra_lift(double extra_zlift) { this->extra_lift = extra_zlift; }
private:
// Extruders are sorted by their ID, so that binary search is possible.
std::vector<Extruder> m_extruders;
@@ -96,14 +98,15 @@ private:
int16_t m_last_temperature_with_offset;
int16_t m_last_bed_temperature;
bool m_last_bed_temperature_reached;
+ // if positive, it's set, and the next lift wil have this extra lift
+ double m_extra_lift = 0;
+ // current lift, to remove from m_pos to have the current height.
double m_lifted;
Vec3d m_pos = Vec3d::Zero();
std::string _travel_to_z(double z, const std::string &comment);
std::string _retract(double length, double restart_extra, double restart_extra_toolchange, const std::string &comment);
- // if positive, it's set, and the next lift wil have this extra lift
- double extra_lift = 0;
};
} /* namespace Slic3r */
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 888a74d88..a133254fc 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -735,6 +735,7 @@ const std::vector<std::string>& Preset::printer_options()
"gcode_precision_e",
"use_relative_e_distances",
"use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
+ "lift_min",
"min_length",
"max_gcode_per_second",
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 13cc79c72..36cd55d22 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -2590,6 +2590,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloat(0));
+ def = this->add("lift_min", coFloat);
+ def->label = L("Min height for travel");
+ def->category = OptionCategory::extruders;
+ def->tooltip = L("When an extruder travels to an object (from the start position or from an object to another), the nozzle height is guaranteed to be at least at this value."
+ "\nIt's made to ensure the nozzle won't hit clips or things you have on your bed. But be careful to not put a clip in the 'convex shape' of an object."
+ "\nSet to 0 to disable.");
+ def->sidetext = L("mm");
+ def->min = 0;
+ def->mode = comExpert;
+ def->is_vector_extruder = true;
+ def->set_default_value(new ConfigOptionFloat(0));
+
def = this->add("machine_limits_usage", coEnum);
def->label = L("How to apply limits");
def->full_label = L("Purpose of Machine Limits");
@@ -4036,7 +4048,7 @@ void PrintConfigDef::init_fff_params()
"(1+, 0 to use the current extruder to minimize tool changes).");
def->min = 0;
def->mode = comAdvanced;
- def->set_default_value(new ConfigOptionInt(1));
+ def->set_default_value(new ConfigOptionInt(0));
def = this->add("support_material_extrusion_width", coFloatOrPercent);
def->label = L("Support material");
@@ -4068,7 +4080,7 @@ void PrintConfigDef::init_fff_params()
"(1+, 0 to use the current extruder to minimize tool changes). This affects raft too.");
def->min = 0;
def->mode = comAdvanced;
- def->set_default_value(new ConfigOptionInt(1));
+ def->set_default_value(new ConfigOptionInt(0));
def = this->add("support_material_interface_layers", coInt);
def->label = L("Interface layers");
@@ -5915,6 +5927,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
"infill_dense_algo",
"infill_dense",
"infill_extrusion_spacing",
+"lift_min",
"machine_max_acceleration_travel",
"max_speed_reduction",
"milling_after_z",
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index f8b0984b1..0672cdced 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -1338,6 +1338,7 @@ public:
ConfigOptionInts first_layer_temperature;
ConfigOptionInts full_fan_speed_layer;
ConfigOptionFloatOrPercent infill_acceleration;
+ ConfigOptionFloat lift_min;
ConfigOptionInts max_fan_speed;
ConfigOptionFloatsOrPercents max_layer_height;
ConfigOptionFloat max_print_height;
@@ -1442,6 +1443,7 @@ protected:
OPT_PTR(first_layer_temperature);
OPT_PTR(full_fan_speed_layer);
OPT_PTR(infill_acceleration);
+ OPT_PTR(lift_min);
OPT_PTR(max_fan_speed);
OPT_PTR(max_layer_height);
OPT_PTR(max_print_height);
diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp
index 42f24a601..175757b1a 100644
--- a/src/slic3r/GUI/DoubleSlider.cpp
+++ b/src/slic3r/GUI/DoubleSlider.cpp
@@ -986,71 +986,70 @@ void Control::draw_ruler(wxDC& dc)
wxCoord pos = get_position_from_value(tick);
draw_ticks_pair(dc, pos, mid, 5);
draw_tick_text(dc, wxPoint(mid, pos), tick);
- }
- else {
- auto draw_short_ticks = [this, mid](wxDC& dc, double& current_tick, int max_tick) {
- while (current_tick < max_tick) {
- wxCoord pos = get_position_from_value(lround(current_tick));
- draw_ticks_pair(dc, pos, mid, 2);
- current_tick += m_ruler.short_step;
- if (current_tick > m_max_value)
- break;
- }
- };
-
- double short_tick = std::nan("");
- int tick = 0;
- double value = 0.0;
- int sequence = 0;
-
- int prev_y_pos = -1;
- wxCoord label_height = dc.GetMultiLineTextExtent("0").y - 2;
- int values_size = (int)m_values.size();
-
- while (tick <= m_max_value) {
- value += m_ruler.long_step;
- if (value > m_values.back() && sequence < m_ruler.count) {
- value = m_ruler.long_step;
- for (; tick < values_size; tick++)
- if (m_values[tick] < value)
+ } else {
+ auto draw_short_ticks = [this, mid](wxDC& dc, double& current_tick, int max_tick) {
+ while (current_tick < max_tick) {
+ wxCoord pos = get_position_from_value(lround(current_tick));
+ draw_ticks_pair(dc, pos, mid, 2);
+ current_tick += m_ruler.short_step;
+ if (current_tick > m_max_value)
break;
- // short ticks from the last tick to the end of current sequence
- assert(! std::isnan(short_tick));
- draw_short_ticks(dc, short_tick, tick);
- sequence++;
- }
- short_tick = tick;
+ }
+ };
+
+ double short_tick = std::nan("");
+ int tick = 0;
+ double value = 0.0;
+ int sequence = 0;
+
+ int prev_y_pos = -1;
+ wxCoord label_height = dc.GetMultiLineTextExtent("0").y - 2;
+ int values_size = (int)m_values.size();
+
+ while (tick <= m_max_value) {
+ value += m_ruler.long_step;
+ if (value > m_values.back() && sequence < m_ruler.count) {
+ value = m_ruler.long_step;
+ for (; tick < values_size; tick++)
+ if (m_values[tick] < value)
+ break;
+ // short ticks from the last tick to the end of current sequence
+ //assert(!std::isnan(short_tick));
+ draw_short_ticks(dc, short_tick, tick);
+ sequence++;
+ }
+ short_tick = tick;
- for (; tick < values_size; tick++) {
- if (m_values[tick] == value)
- break;
- if (m_values[tick] > value) {
- if (tick > 0)
- tick--;
- break;
- }
- }
- if (tick > m_max_value)
- break;
+ for (; tick < values_size; tick++) {
+ if (m_values[tick] == value)
+ break;
+ if (m_values[tick] > value) {
+ if (tick > 0)
+ tick--;
+ break;
+ }
+ }
+ if (tick > m_max_value)
+ break;
- wxCoord pos = get_position_from_value(tick);
- draw_ticks_pair(dc, pos, mid, 5);
- if (prev_y_pos < 0 || prev_y_pos - pos >= label_height) {
- draw_tick_text(dc, wxPoint(mid, pos), tick);
- prev_y_pos = pos;
- }
+ wxCoord pos = get_position_from_value(tick);
+ draw_ticks_pair(dc, pos, mid, 5);
+ if (prev_y_pos < 0 || prev_y_pos - pos >= label_height) {
+ draw_tick_text(dc, wxPoint(mid, pos), tick);
+ prev_y_pos = pos;
+ }
- draw_short_ticks(dc, short_tick, tick);
+ draw_short_ticks(dc, short_tick, tick);
- if (value == m_values.back() && sequence < m_ruler.count) {
- value = 0.0;
- sequence++;
- tick++;
+ if (value == m_values.back() && sequence < m_ruler.count) {
+ value = 0.0;
+ sequence++;
+ tick++;
+ }
+ }
+ // short ticks from the last tick to the end
+ draw_short_ticks(dc, short_tick, m_max_value);
}
- }
- // short ticks from the last tick to the end
- draw_short_ticks(dc, short_tick, m_max_value);
- }
dc.SetTextForeground(old_clr);
}
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 9db946043..0e3375df3 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -2965,7 +2965,7 @@ void TabPrinter::toggle_options()
// retract lift above / below only applies if using retract lift
vec.resize(0);
- vec = { "retract_lift_above", "retract_lift_below", "retract_lift_top" };
+ vec = { "retract_lift_above", "retract_lift_below", "retract_lift_top", "retract_lift_first_layer" };
for (auto el : vec) {
field = get_field(el, i);
if (field)