mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-14 21:12:02 +08:00
Merge branch 'master' into dev
This commit is contained in:
commit
2022e3fbd6
@ -21,7 +21,6 @@ group:Filament properties
|
|||||||
setting:filament_soluble
|
setting:filament_soluble
|
||||||
setting:filament_shrink
|
setting:filament_shrink
|
||||||
group:Print speed override
|
group:Print speed override
|
||||||
setting:filament_max_wipe_tower_speed
|
|
||||||
setting:filament_max_volumetric_speed
|
setting:filament_max_volumetric_speed
|
||||||
volumetric_speed_description
|
volumetric_speed_description
|
||||||
|
|
||||||
@ -59,6 +58,7 @@ group:Multimaterial toolchange string reduction
|
|||||||
setting:filament_dip_extraction_speed
|
setting:filament_dip_extraction_speed
|
||||||
group:Wipe tower parameters
|
group:Wipe tower parameters
|
||||||
setting:filament_minimal_purge_on_wipe_tower
|
setting:filament_minimal_purge_on_wipe_tower
|
||||||
|
setting:filament_max_wipe_tower_speed
|
||||||
group:Toolchange parameters with single extruder MM printers
|
group:Toolchange parameters with single extruder MM printers
|
||||||
setting:filament_loading_speed_start
|
setting:filament_loading_speed_start
|
||||||
setting:filament_loading_speed
|
setting:filament_loading_speed
|
||||||
|
@ -417,6 +417,7 @@ int CLI::run(int argc, char **argv)
|
|||||||
PrintBase *print = (printer_technology == ptFFF) ? static_cast<PrintBase*>(&fff_print) : static_cast<PrintBase*>(&sla_print);
|
PrintBase *print = (printer_technology == ptFFF) ? static_cast<PrintBase*>(&fff_print) : static_cast<PrintBase*>(&sla_print);
|
||||||
if (! m_config.opt_bool("dont_arrange")) {
|
if (! m_config.opt_bool("dont_arrange")) {
|
||||||
//FIXME make the min_object_distance configurable.
|
//FIXME make the min_object_distance configurable.
|
||||||
|
print->apply(model, m_print_config); // arrange_objects needs that the print has the config
|
||||||
model.arrange_objects(print);
|
model.arrange_objects(print);
|
||||||
model.center_instances_around_point((! user_center_specified && m_print_config.has("bed_shape")) ?
|
model.center_instances_around_point((! user_center_specified && m_print_config.has("bed_shape")) ?
|
||||||
BoundingBoxf(m_print_config.opt<ConfigOptionPoints>("bed_shape")->values).center() :
|
BoundingBoxf(m_print_config.opt<ConfigOptionPoints>("bed_shape")->values).center() :
|
||||||
|
@ -420,6 +420,10 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
gcode += tcr_gcode;
|
gcode += tcr_gcode;
|
||||||
check_add_eol(toolchange_gcode_str);
|
check_add_eol(toolchange_gcode_str);
|
||||||
|
|
||||||
|
if (gcodegen.writer().tool() && gcodegen.m_config.filament_enable_toolchange_part_fan.values[gcodegen.writer().tool()->id()]) {
|
||||||
|
//if the fan may ahve been changed silently by the wipetower, recover it.
|
||||||
|
gcode += gcodegen.m_writer.set_fan(gcodegen.m_writer.get_fan(), true);
|
||||||
|
}
|
||||||
|
|
||||||
// A phony move to the end position at the wipe tower.
|
// A phony move to the end position at the wipe tower.
|
||||||
gcodegen.writer().travel_to_xy(end_pos.cast<double>());
|
gcodegen.writer().travel_to_xy(end_pos.cast<double>());
|
||||||
@ -428,9 +432,7 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
gcode += gcodegen.writer().retract();
|
gcode += gcodegen.writer().retract();
|
||||||
gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer.");
|
gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer.");
|
||||||
gcode += gcodegen.writer().unretract();
|
gcode += gcodegen.writer().unretract();
|
||||||
}
|
} else {
|
||||||
|
|
||||||
else {
|
|
||||||
// Prepare a future wipe.
|
// Prepare a future wipe.
|
||||||
gcodegen.m_wipe.path.points.clear();
|
gcodegen.m_wipe.path.points.clear();
|
||||||
if (new_extruder_id >= 0) {
|
if (new_extruder_id >= 0) {
|
||||||
@ -845,7 +847,8 @@ namespace DoExport {
|
|||||||
// If the following block is enabled for other firmwares than the Marlin, then the function
|
// If the following block is enabled for other firmwares than the Marlin, then the function
|
||||||
// this->print_machine_envelope(file, print);
|
// this->print_machine_envelope(file, print);
|
||||||
// shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor.
|
// shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor.
|
||||||
if (config.gcode_flavor.value == gcfMarlin || config.gcode_flavor.value == gcfLerdge) {
|
// supermerill: done
|
||||||
|
if (true) {
|
||||||
normal_time_estimator.set_max_acceleration((float)config.machine_max_acceleration_extruding.values[0]);
|
normal_time_estimator.set_max_acceleration((float)config.machine_max_acceleration_extruding.values[0]);
|
||||||
normal_time_estimator.set_retract_acceleration((float)config.machine_max_acceleration_retracting.values[0]);
|
normal_time_estimator.set_retract_acceleration((float)config.machine_max_acceleration_retracting.values[0]);
|
||||||
normal_time_estimator.set_max_travel_acceleration((float)config.machine_max_acceleration_travel.values[0]);
|
normal_time_estimator.set_max_travel_acceleration((float)config.machine_max_acceleration_travel.values[0]);
|
||||||
@ -1073,9 +1076,9 @@ namespace DoExport {
|
|||||||
print_statistics.clear();
|
print_statistics.clear();
|
||||||
print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/();
|
print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/();
|
||||||
print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A";
|
print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A";
|
||||||
print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times_dhm(true);
|
print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times();
|
||||||
if (silent_time_estimator_enabled)
|
if (silent_time_estimator_enabled)
|
||||||
print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times_dhm(true);
|
print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times();
|
||||||
print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges);
|
print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges);
|
||||||
if (! extruders.empty()) {
|
if (! extruders.empty()) {
|
||||||
std::pair<std::string, unsigned int> out_filament_used_mm ("; filament used [mm] = ", 0);
|
std::pair<std::string, unsigned int> out_filament_used_mm ("; filament used [mm] = ", 0);
|
||||||
@ -1205,34 +1208,6 @@ static void init_multiextruders(FILE *file, Print &print, GCodeWriter & writer,
|
|||||||
int(print.config().temperature.get_at(tool_id)));
|
int(print.config().temperature.get_at(tool_id)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//activate first extruder is multi-extruder and not in start-gcode
|
|
||||||
if (writer.multiple_extruders) {
|
|
||||||
if (std::set<uint8_t>{gcfRepRap}.count(print.config().gcode_flavor.value) > 0) {
|
|
||||||
//if not in gcode
|
|
||||||
bool find = false;
|
|
||||||
if (!custom_gcode.empty()) {
|
|
||||||
const char *ptr = custom_gcode.data();
|
|
||||||
while (*ptr != 0) {
|
|
||||||
// Skip whitespaces.
|
|
||||||
for (; *ptr == ' ' || *ptr == '\t'; ++ptr);
|
|
||||||
if (*ptr == 'T') {
|
|
||||||
find = true;
|
|
||||||
break;
|
|
||||||
} else if (*ptr == 'A') {
|
|
||||||
//TODO: ACTIVATE_EXTRUDER for klipper (if used)
|
|
||||||
}
|
|
||||||
// Skip the rest of the line.
|
|
||||||
for (; *ptr != 0 && *ptr != '\r' && *ptr != '\n'; ++ptr);
|
|
||||||
// Skip the end of line indicators.
|
|
||||||
for (; *ptr == '\r' || *ptr == '\n'; ++ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!find) {
|
|
||||||
fprintf(file, writer.toolchange(tool_ordering.first_extruder()).c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.toolchange(tool_ordering.first_extruder());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1462,7 +1437,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||||||
this->print_machine_envelope(file, print);
|
this->print_machine_envelope(file, print);
|
||||||
|
|
||||||
// Disable fan.
|
// Disable fan.
|
||||||
if ( (! print.config().cooling.get_at(initial_extruder_id) || print.config().disable_fan_first_layers.get_at(initial_extruder_id))
|
if ( print.config().disable_fan_first_layers.get_at(initial_extruder_id)
|
||||||
&& config().gcode_flavor != gcfKlipper)
|
&& config().gcode_flavor != gcfKlipper)
|
||||||
_write(file, m_writer.set_fan(0, true));
|
_write(file, m_writer.set_fan(0, true));
|
||||||
|
|
||||||
@ -1522,9 +1497,46 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||||||
DoExport::init_ooze_prevention(print, m_ooze_prevention);
|
DoExport::init_ooze_prevention(print, m_ooze_prevention);
|
||||||
print.throw_if_canceled();
|
print.throw_if_canceled();
|
||||||
|
|
||||||
if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming)) {
|
//activate first extruder is multi-extruder and not in start-gcode
|
||||||
|
if (m_writer.multiple_extruders) {
|
||||||
|
//if not in gcode
|
||||||
|
bool find = false;
|
||||||
|
if (!start_gcode.empty()) {
|
||||||
|
const char *ptr = start_gcode.data();
|
||||||
|
while (*ptr != 0) {
|
||||||
|
// Skip whitespaces.
|
||||||
|
for (; *ptr == ' ' || *ptr == '\t'; ++ptr);
|
||||||
|
if (*ptr == 'T') {
|
||||||
|
// TX for most of the firmwares
|
||||||
|
find = true;
|
||||||
|
break;
|
||||||
|
} else if (*ptr == 'A' && print.config().gcode_flavor.value == gcfKlipper) {
|
||||||
|
// ACTIVATE_EXTRUDER for klipper (if used)
|
||||||
|
if (std::string::npos != start_gcode.find("ACTIVATE_EXTRUDER", size_t(ptr - start_gcode.data()))) {
|
||||||
|
find = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Skip the rest of the line.
|
||||||
|
for (; *ptr != 0 && *ptr != '\r' && *ptr != '\n'; ++ptr);
|
||||||
|
// Skip the end of line indicators.
|
||||||
|
for (; *ptr == '\r' || *ptr == '\n'; ++ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!find) {
|
||||||
// Set initial extruder only after custom start G-code.
|
// Set initial extruder only after custom start G-code.
|
||||||
// Ugly hack: Do not set the initial extruder if the extruder is primed using the MMU priming towers at the edge of the print bed.
|
// Ugly hack: Do not set the initial extruder if the extruder is primed using the MMU priming towers at the edge of the print bed.
|
||||||
|
if (!(has_wipe_tower && print.config().single_extruder_multi_material_priming)) {
|
||||||
|
_write(file, this->set_extruder(initial_extruder_id, 0.));
|
||||||
|
} else {
|
||||||
|
m_writer.toolchange(initial_extruder_id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// set writer to the tool as should be set in the start_gcode.
|
||||||
|
_write(file, this->set_extruder(initial_extruder_id, 0., true));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if we are running a single-extruder setup, just set the extruder and "return nothing"
|
||||||
_write(file, this->set_extruder(initial_extruder_id, 0.));
|
_write(file, this->set_extruder(initial_extruder_id, 0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1693,6 +1705,18 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||||||
if (m_silent_time_estimator_enabled)
|
if (m_silent_time_estimator_enabled)
|
||||||
m_silent_time_estimator.scale_time(config().time_estimation_compensation.get_abs_value(1));
|
m_silent_time_estimator.scale_time(config().time_estimation_compensation.get_abs_value(1));
|
||||||
}
|
}
|
||||||
|
//try to compensate fora random bug #364
|
||||||
|
if (m_normal_time_estimator.get_time() < 0) {
|
||||||
|
std::cerr << "error, negative time estimation : " << m_normal_time_estimator.get_time() << ", retry.\n";
|
||||||
|
m_normal_time_estimator.calculate_time(true);
|
||||||
|
if (m_silent_time_estimator_enabled)
|
||||||
|
m_silent_time_estimator.calculate_time(true);
|
||||||
|
if (config().time_estimation_compensation.get_abs_value(1) != 1) {
|
||||||
|
m_normal_time_estimator.scale_time(config().time_estimation_compensation.get_abs_value(1));
|
||||||
|
if (m_silent_time_estimator_enabled)
|
||||||
|
m_silent_time_estimator.scale_time(config().time_estimation_compensation.get_abs_value(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get filament stats.
|
// Get filament stats.
|
||||||
_write(file, DoExport::update_print_stats_and_format_filament_stats(
|
_write(file, DoExport::update_print_stats_and_format_filament_stats(
|
||||||
@ -1915,7 +1939,7 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c
|
|||||||
if (temp_by_gcode >= 0 && temp_by_gcode < 1000)
|
if (temp_by_gcode >= 0 && temp_by_gcode < 1000)
|
||||||
temp = temp_by_gcode;
|
temp = temp_by_gcode;
|
||||||
m_writer.set_temperature(temp, wait, first_printing_extruder_id);
|
m_writer.set_temperature(temp, wait, first_printing_extruder_id);
|
||||||
} else if(this->config().gcode_flavor != gcfKlipper){
|
} else if(this->config().gcode_flavor != gcfKlipper || print.config().start_gcode.value.empty()){
|
||||||
// Custom G-code does not set the extruder temperature. Do it now.
|
// Custom G-code does not set the extruder temperature. Do it now.
|
||||||
if (print.config().single_extruder_multi_material.value) {
|
if (print.config().single_extruder_multi_material.value) {
|
||||||
// Set temperature of the first printing extruder only.
|
// Set temperature of the first printing extruder only.
|
||||||
@ -4339,7 +4363,7 @@ std::string GCode::retract(bool toolchange)
|
|||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
|
std::string GCode::set_extruder(unsigned int extruder_id, double print_z, bool no_toolchange /*=false*/)
|
||||||
{
|
{
|
||||||
if (!m_writer.need_toolchange(extruder_id))
|
if (!m_writer.need_toolchange(extruder_id))
|
||||||
return "";
|
return "";
|
||||||
@ -4410,7 +4434,7 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
|
|||||||
|
|
||||||
// We inform the writer about what is happening, but we may not use the resulting gcode.
|
// We inform the writer about what is happening, but we may not use the resulting gcode.
|
||||||
std::string toolchange_command = m_writer.toolchange(extruder_id);
|
std::string toolchange_command = m_writer.toolchange(extruder_id);
|
||||||
if (! custom_gcode_changes_tool(toolchange_gcode_parsed, m_writer.toolchange_prefix(), extruder_id))
|
if (! custom_gcode_changes_tool(toolchange_gcode_parsed, m_writer.toolchange_prefix(), extruder_id) && !no_toolchange)
|
||||||
gcode += toolchange_command;
|
gcode += toolchange_command;
|
||||||
else {
|
else {
|
||||||
// user provided his own toolchange gcode, no need to do anything
|
// user provided his own toolchange gcode, no need to do anything
|
||||||
|
@ -334,7 +334,7 @@ private:
|
|||||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
||||||
std::string retract(bool toolchange = false);
|
std::string retract(bool toolchange = false);
|
||||||
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
||||||
std::string set_extruder(unsigned int extruder_id, double print_z);
|
std::string set_extruder(unsigned int extruder_id, double print_z, bool no_toolchange = false);
|
||||||
|
|
||||||
/* Origin of print coordinates expressed in unscaled G-code coordinates.
|
/* Origin of print coordinates expressed in unscaled G-code coordinates.
|
||||||
This affects the input arguments supplied to the extrude*() and travel_to()
|
This affects the input arguments supplied to the extrude*() and travel_to()
|
||||||
|
@ -312,7 +312,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
|||||||
PerExtruderAdjustments &adj = per_extruder_adjustments[i];
|
PerExtruderAdjustments &adj = per_extruder_adjustments[i];
|
||||||
uint16_t extruder_id = extruders[i].id();
|
uint16_t extruder_id = extruders[i].id();
|
||||||
adj.extruder_id = extruder_id;
|
adj.extruder_id = extruder_id;
|
||||||
adj.cooling_slow_down_enabled = config.cooling.get_at(extruder_id);
|
adj.cooling_slow_down_enabled = config.slowdown_below_layer_time.get_at(extruder_id) > 0;
|
||||||
adj.slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(extruder_id));
|
adj.slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(extruder_id));
|
||||||
adj.min_print_speed = float(config.min_print_speed.get_at(extruder_id));
|
adj.min_print_speed = float(config.min_print_speed.get_at(extruder_id));
|
||||||
adj.max_speed_reduction = float(config.max_speed_reduction.get_at(extruder_id) / 100);
|
adj.max_speed_reduction = float(config.max_speed_reduction.get_at(extruder_id) / 100);
|
||||||
|
@ -440,6 +440,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_gcode_flavor == gcfMarlin)
|
if (m_gcode_flavor == gcfMarlin)
|
||||||
m_gcode += "M220 R\n";
|
m_gcode += "M220 R\n";
|
||||||
|
else
|
||||||
|
m_gcode += "M220 S100\n";
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,7 +717,8 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
|||||||
|
|
||||||
uint16_t tool = tools[idx_tool];
|
uint16_t tool = tools[idx_tool];
|
||||||
m_left_to_right = true;
|
m_left_to_right = true;
|
||||||
toolchange_Change(writer, tool, m_filpar[tool].material); // Select the tool, set a speed override for soluble and flex materials.
|
toolchange_Change(writer, tool); // Select the tool, set a speed override for soluble and flex materials.
|
||||||
|
writer.speed_override(int(100 * get_speed_reduction()));
|
||||||
toolchange_Load(writer, cleaning_box); // Prime the tool.
|
toolchange_Load(writer, cleaning_box); // Prime the tool.
|
||||||
if (idx_tool + 1 == tools.size()) {
|
if (idx_tool + 1 == tools.size()) {
|
||||||
// Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
|
// Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
|
||||||
@ -726,7 +729,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
|||||||
toolchange_Wipe(writer, cleaning_box , 20.f);
|
toolchange_Wipe(writer, cleaning_box , 20.f);
|
||||||
box_coordinates box = cleaning_box;
|
box_coordinates box = cleaning_box;
|
||||||
box.translate(0.f, writer.y() - cleaning_box.ld.y() + m_perimeter_width);
|
box.translate(0.f, writer.y() - cleaning_box.ld.y() + m_perimeter_width);
|
||||||
toolchange_Unload(writer, box , m_filpar[m_current_tool].material, m_filpar[tools[idx_tool + 1]].first_layer_temperature, idx_tool + 1);
|
toolchange_Unload(writer, box , m_filpar[tools[idx_tool + 1]].first_layer_temperature, idx_tool + 1);
|
||||||
cleaning_box.translate(prime_section_width, 0.f);
|
cleaning_box.translate(prime_section_width, 0.f);
|
||||||
writer.travel(cleaning_box.ld, 7200);
|
writer.travel(cleaning_box.ld, 7200);
|
||||||
}
|
}
|
||||||
@ -833,15 +836,17 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay
|
|||||||
|
|
||||||
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
||||||
if (tool != (unsigned int)-1){ // This is not the last change.
|
if (tool != (unsigned int)-1){ // This is not the last change.
|
||||||
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material,
|
toolchange_Unload(writer, cleaning_box,
|
||||||
m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature, tool);
|
m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature, tool);
|
||||||
toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.
|
toolchange_Change(writer, tool); // Change the tool, set a speed override for soluble and flex materials.
|
||||||
|
writer.speed_override(int(100 * get_speed_reduction()));
|
||||||
toolchange_Load(writer, cleaning_box);
|
toolchange_Load(writer, cleaning_box);
|
||||||
writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
|
writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
|
||||||
|
writer.speed_override(int(100 * get_speed_reduction()));
|
||||||
toolchange_Wipe(writer, cleaning_box, wipe_volume); // Wipe the newly loaded filament until the end of the assigned wipe area.
|
toolchange_Wipe(writer, cleaning_box, wipe_volume); // Wipe the newly loaded filament until the end of the assigned wipe area.
|
||||||
++ m_num_tool_changes;
|
++ m_num_tool_changes;
|
||||||
} else
|
} else
|
||||||
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material, m_filpar[m_current_tool].temperature, m_current_tool);
|
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].temperature, m_current_tool);
|
||||||
|
|
||||||
m_depth_traversed += wipe_area;
|
m_depth_traversed += wipe_area;
|
||||||
|
|
||||||
@ -952,7 +957,6 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
|
|||||||
void WipeTower::toolchange_Unload(
|
void WipeTower::toolchange_Unload(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
const box_coordinates &cleaning_box,
|
const box_coordinates &cleaning_box,
|
||||||
const std::string& current_material,
|
|
||||||
const int new_temperature,
|
const int new_temperature,
|
||||||
const size_t next_tool)
|
const size_t next_tool)
|
||||||
{
|
{
|
||||||
@ -1184,8 +1188,7 @@ void WipeTower::toolchange_Unload(
|
|||||||
// Change the tool, set a speed override for soluble and flex materials.
|
// Change the tool, set a speed override for soluble and flex materials.
|
||||||
void WipeTower::toolchange_Change(
|
void WipeTower::toolchange_Change(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
const size_t new_tool,
|
const size_t new_tool)
|
||||||
const std::string& new_material)
|
|
||||||
{
|
{
|
||||||
// Ask the writer about how much of the old filament we consumed:
|
// Ask the writer about how much of the old filament we consumed:
|
||||||
if (m_current_tool < m_used_filament_length.size())
|
if (m_current_tool < m_used_filament_length.size())
|
||||||
@ -1244,6 +1247,19 @@ void WipeTower::toolchange_Load(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float WipeTower::get_speed_reduction() const
|
||||||
|
{
|
||||||
|
float speed_override = m_config->filament_max_wipe_tower_speed.get_at(m_current_tool) / 100.f;
|
||||||
|
if (speed_override <= 0) {
|
||||||
|
speed_override = 1;
|
||||||
|
std::string material_upp = boost::algorithm::to_upper_copy(m_filpar[m_current_tool].material);
|
||||||
|
if (material_upp == "PVA") speed_override = (m_z_pos < 0.80f) ? 0.60 : 0.80;
|
||||||
|
if (material_upp == "SCAFF") speed_override = 0.35;
|
||||||
|
if (material_upp == "FLEX") speed_override = 0.35;
|
||||||
|
}
|
||||||
|
return speed_override;
|
||||||
|
}
|
||||||
|
|
||||||
// Wipe the newly loaded filament until the end of the assigned wipe area.
|
// Wipe the newly loaded filament until the end of the assigned wipe area.
|
||||||
void WipeTower::toolchange_Wipe(
|
void WipeTower::toolchange_Wipe(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
@ -1257,6 +1273,9 @@ void WipeTower::toolchange_Wipe(
|
|||||||
const float& xl = cleaning_box.ld.x();
|
const float& xl = cleaning_box.ld.x();
|
||||||
const float& xr = cleaning_box.rd.x();
|
const float& xr = cleaning_box.rd.x();
|
||||||
|
|
||||||
|
// Speed override for the material. Go slow for flex and soluble materials.
|
||||||
|
wipe_coeff *= get_speed_reduction();
|
||||||
|
|
||||||
// Variables x_to_wipe and traversed_x are here to be able to make sure it always wipes at least
|
// Variables x_to_wipe and traversed_x are here to be able to make sure it always wipes at least
|
||||||
// the ordered volume, even if it means violating the box. This can later be removed and simply
|
// the ordered volume, even if it means violating the box. This can later be removed and simply
|
||||||
// wipe until the end of the assigned area.
|
// wipe until the end of the assigned area.
|
||||||
@ -1332,6 +1351,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
|
|||||||
|
|
||||||
// Slow down on the 1st layer.
|
// Slow down on the 1st layer.
|
||||||
float speed_factor = m_is_first_layer ? 0.5f : 1.f;
|
float speed_factor = m_is_first_layer ? 0.5f : 1.f;
|
||||||
|
speed_factor *= get_speed_reduction();
|
||||||
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
||||||
box_coordinates fill_box(Vec2f(m_perimeter_width, m_depth_traversed + m_perimeter_width),
|
box_coordinates fill_box(Vec2f(m_perimeter_width, m_depth_traversed + m_perimeter_width),
|
||||||
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
||||||
|
@ -140,6 +140,8 @@ public:
|
|||||||
float width() const { return m_wipe_tower_width; }
|
float width() const { return m_wipe_tower_width; }
|
||||||
// The wipe tower is finished, there should be no more tool changes or wipe tower prints.
|
// The wipe tower is finished, there should be no more tool changes or wipe tower prints.
|
||||||
bool finished() const { return m_max_color_changes == 0; }
|
bool finished() const { return m_max_color_changes == 0; }
|
||||||
|
// get the speed reduction from the current filament material
|
||||||
|
float get_speed_reduction() const;
|
||||||
|
|
||||||
// Returns gcode to prime the nozzles at the front edge of the print bed.
|
// Returns gcode to prime the nozzles at the front edge of the print bed.
|
||||||
std::vector<ToolChangeResult> prime(
|
std::vector<ToolChangeResult> prime(
|
||||||
@ -366,14 +368,12 @@ private:
|
|||||||
void toolchange_Unload(
|
void toolchange_Unload(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
const box_coordinates &cleaning_box,
|
const box_coordinates &cleaning_box,
|
||||||
const std::string& current_material,
|
|
||||||
const int new_temperature,
|
const int new_temperature,
|
||||||
const size_t temp_tool);
|
const size_t temp_tool);
|
||||||
|
|
||||||
void toolchange_Change(
|
void toolchange_Change(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
const size_t new_tool,
|
const size_t new_tool);
|
||||||
const std::string& new_material);
|
|
||||||
|
|
||||||
void toolchange_Load(
|
void toolchange_Load(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
|
@ -794,27 +794,6 @@ namespace Slic3r {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<CustomGcodeType, std::string>> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const
|
|
||||||
{
|
|
||||||
std::vector<std::pair<CustomGcodeType, std::string>> ret;
|
|
||||||
|
|
||||||
float total_time = 0.0f;
|
|
||||||
for (const std::pair<CustomGcodeType, float> &t : m_custom_gcode_times)
|
|
||||||
{
|
|
||||||
std::string time = _get_time_dhm(t.second);
|
|
||||||
if (include_remaining)
|
|
||||||
{
|
|
||||||
time += " (";
|
|
||||||
time += _get_time_dhm(m_time - total_time);
|
|
||||||
time += ")";
|
|
||||||
}
|
|
||||||
total_time += t.second;
|
|
||||||
ret.push_back({t.first, time});
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return an estimate of the memory consumed by the time estimator.
|
// Return an estimate of the memory consumed by the time estimator.
|
||||||
size_t GCodeTimeEstimator::memory_used() const
|
size_t GCodeTimeEstimator::memory_used() const
|
||||||
{
|
{
|
||||||
|
@ -417,10 +417,6 @@ namespace Slic3r {
|
|||||||
// If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)"
|
// If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)"
|
||||||
std::vector<std::string> get_color_times_minutes(bool include_remaining) const;
|
std::vector<std::string> get_color_times_minutes(bool include_remaining) const;
|
||||||
|
|
||||||
// Returns the estimated time, in format DDd HHh MMm, for each custom_gcode
|
|
||||||
// If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)"
|
|
||||||
std::vector<std::pair<CustomGcodeType, std::string>> get_custom_gcode_times_dhm(bool include_remaining) const;
|
|
||||||
|
|
||||||
// Return an estimate of the memory consumed by the time estimator.
|
// Return an estimate of the memory consumed by the time estimator.
|
||||||
size_t memory_used() const;
|
size_t memory_used() const;
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ public:
|
|||||||
std::string postamble() const;
|
std::string postamble() const;
|
||||||
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1);
|
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1);
|
||||||
std::string set_bed_temperature(unsigned int temperature, bool wait = false);
|
std::string set_bed_temperature(unsigned int temperature, bool wait = false);
|
||||||
|
unsigned int get_fan() { return m_last_fan_speed; }
|
||||||
std::string set_fan(unsigned int speed, bool dont_save = false);
|
std::string set_fan(unsigned int speed, bool dont_save = false);
|
||||||
void set_acceleration(unsigned int acceleration);
|
void set_acceleration(unsigned int acceleration);
|
||||||
std::string write_acceleration();
|
std::string write_acceleration();
|
||||||
|
@ -525,19 +525,19 @@ void PerimeterGenerator::process()
|
|||||||
+(float)(min_spacing / 2 - 1));
|
+(float)(min_spacing / 2 - 1));
|
||||||
|
|
||||||
ExPolygons no_thin_onion = offset_ex(last, double(-good_spacing));
|
ExPolygons no_thin_onion = offset_ex(last, double(-good_spacing));
|
||||||
float div = 2;
|
std::vector<float> divs { 1.8, 1.6 }; //don't over-extrude, so don't use divider >2
|
||||||
while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && no_thin_onion.size() + next_onion.size() > 3) {
|
size_t idx_div = 0;
|
||||||
div -= 0.3;
|
while (next_onion.size() > no_thin_onion.size() && idx_div < divs.size()) {
|
||||||
if (div == 2) div -= 0.3;
|
float div = divs[idx_div];
|
||||||
//use a sightly bigger spacing to try to drastically improve the split, that can lead to very thick gapfill
|
//use a sightly bigger spacing to try to drastically improve the split, that can lead to very thick gapfill
|
||||||
ExPolygons next_onion_secondTry = offset2_ex(
|
ExPolygons next_onion_secondTry = offset2_ex(
|
||||||
last,
|
last,
|
||||||
-(float)(good_spacing + min_spacing / div - 1),
|
-(float)(good_spacing + (min_spacing / div) - 1),
|
||||||
+(float)(min_spacing / div - 1));
|
+(float)((min_spacing / div) - 1));
|
||||||
if (next_onion.size() > next_onion_secondTry.size() * 1.1) {
|
if (next_onion.size() > next_onion_secondTry.size() * 1.2 && next_onion.size() > next_onion_secondTry.size() + 2) {
|
||||||
next_onion = next_onion_secondTry;
|
next_onion = next_onion_secondTry;
|
||||||
}
|
}
|
||||||
if (div > 3 || div < 1.2) break;
|
idx_div++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -752,7 +752,11 @@ void PerimeterGenerator::process()
|
|||||||
coll2.entities.push_back(loop);
|
coll2.entities.push_back(loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entities = coll2;
|
//note: this hacky thing is possible because coll2.entities contains in fact entities's entities
|
||||||
|
//if you does entities = coll2, you'll delete entities's entities and then you have nothing.
|
||||||
|
entities.entities = coll2.entities;
|
||||||
|
//and you have to empty coll2 or it will delete his content, hence crashing our hack
|
||||||
|
coll2.entities.clear();
|
||||||
}
|
}
|
||||||
} else if (this->config->external_perimeters_hole.value) {
|
} else if (this->config->external_perimeters_hole.value) {
|
||||||
//reverse the hole, and put them in first place.
|
//reverse the hole, and put them in first place.
|
||||||
@ -768,13 +772,19 @@ void PerimeterGenerator::process()
|
|||||||
coll2.entities.push_back(loop);
|
coll2.entities.push_back(loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entities = coll2;
|
//note: this hacky thing is possible because coll2.entities contains in fact entities's entities
|
||||||
|
//if you does entities = coll2, you'll delete entities's entities and then you have nothing.
|
||||||
|
entities.entities = coll2.entities;
|
||||||
|
//and you have to empty coll2 or it will delete his content, hence crashing our hack
|
||||||
|
coll2.entities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// append perimeters for this slice as a collection
|
// append perimeters for this slice as a collection
|
||||||
if (!entities.empty())
|
if (!entities.empty()) {
|
||||||
this->loops->append(entities);
|
//move it, to avoid to clone evrything and then delete it
|
||||||
|
this->loops->entities.emplace_back( new ExtrusionEntityCollection(std::move(entities)));
|
||||||
|
}
|
||||||
} // for each loop of an island
|
} // for each loop of an island
|
||||||
|
|
||||||
// fill gaps
|
// fill gaps
|
||||||
|
@ -319,8 +319,8 @@ struct PrintStatistics
|
|||||||
PrintStatistics() { clear(); }
|
PrintStatistics() { clear(); }
|
||||||
std::string estimated_normal_print_time;
|
std::string estimated_normal_print_time;
|
||||||
std::string estimated_silent_print_time;
|
std::string estimated_silent_print_time;
|
||||||
std::vector<std::pair<CustomGcodeType, std::string>> estimated_normal_custom_gcode_print_times;
|
std::vector<std::pair<CustomGcodeType, float>> estimated_normal_custom_gcode_print_times;
|
||||||
std::vector<std::pair<CustomGcodeType, std::string>> estimated_silent_custom_gcode_print_times;
|
std::vector<std::pair<CustomGcodeType, float>> estimated_silent_custom_gcode_print_times;
|
||||||
double total_used_filament;
|
double total_used_filament;
|
||||||
std::vector<std::pair<size_t, double>> color_extruderid_to_used_filament;
|
std::vector<std::pair<size_t, double>> color_extruderid_to_used_filament;
|
||||||
double total_extruded_volume;
|
double total_extruded_volume;
|
||||||
|
@ -1095,8 +1095,16 @@ void PrintConfigDef::init_fff_params()
|
|||||||
|
|
||||||
def = this->add("filament_max_wipe_tower_speed", coFloats);
|
def = this->add("filament_max_wipe_tower_speed", coFloats);
|
||||||
def->label = L("Max speed on the wipe tower");
|
def->label = L("Max speed on the wipe tower");
|
||||||
def->tooltip = L("This setting is used to set the maximum speed when extruding inside the wipe tower (use M220). In %, set 0 to disable and use the Filament type instead.");
|
def->tooltip = L("This setting is used to set the maximum speed when extruding inside the wipe tower (use M220)."
|
||||||
def->sidetext = L("% of mm/s");
|
" In %, set 0 to disable and use the Filament type instead."
|
||||||
|
"\nIf disabled, these filament types will have a defaut value of:"
|
||||||
|
"\n - PVA: 80% to 60%"
|
||||||
|
"\n - SCAFF: 35%"
|
||||||
|
"\n - FLEX: 35%"
|
||||||
|
"\n - OTHERS: 100%"
|
||||||
|
"\nNote that the wipe tower reset the speed at 100% for the unretract in any case."
|
||||||
|
"\nIf using marlin, M220 B/R is used to save the speed override before the wipe tower print.");
|
||||||
|
def->sidetext = L("%");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->max = 200;
|
def->max = 200;
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
@ -1304,7 +1312,7 @@ void PrintConfigDef::init_fff_params()
|
|||||||
" Only the filament used for the perimeter is taken into account."
|
" Only the filament used for the perimeter is taken into account."
|
||||||
"\nBe sure to let enough space between objects, as this compensation is done after the checks.");
|
"\nBe sure to let enough space between objects, as this compensation is done after the checks.");
|
||||||
def->sidetext = L("%");
|
def->sidetext = L("%");
|
||||||
def->min = 0;
|
def->min = 10;
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionPercents{ 100 });
|
def->set_default_value(new ConfigOptionPercents{ 100 });
|
||||||
|
|
||||||
|
@ -337,6 +337,30 @@ inline std::string get_time_dhms(float time_in_secs)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the given time is seconds in format DDd HHh MMm
|
||||||
|
inline std::string get_time_dhm(float time_in_secs)
|
||||||
|
{
|
||||||
|
char buffer[64];
|
||||||
|
|
||||||
|
int minutes = std::round(time_in_secs / 60.);
|
||||||
|
if (minutes <= 0) {
|
||||||
|
::sprintf(buffer, "%ds", (int)time_in_secs);
|
||||||
|
} else {
|
||||||
|
int days = minutes / 1440;
|
||||||
|
minutes -= days * 1440;
|
||||||
|
int hours = minutes / 60;
|
||||||
|
minutes -= hours * 60;
|
||||||
|
if (days > 0)
|
||||||
|
::sprintf(buffer, "%dd %dh %dm", days, hours, minutes);
|
||||||
|
else if (hours > 0)
|
||||||
|
::sprintf(buffer, "%dh %dm", hours, minutes);
|
||||||
|
else
|
||||||
|
::sprintf(buffer, "%dm", minutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
|
@ -95,7 +95,30 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
DynamicPrintConfig new_conf = *config;
|
DynamicPrintConfig new_conf = *config;
|
||||||
auto answer = dialog.ShowModal();
|
auto answer = dialog.ShowModal();
|
||||||
if (!is_global_config || answer == wxID_YES) {
|
|
||||||
|
if (!is_global_config) {
|
||||||
|
if (this->local_config->optptr("spiral_vase"))
|
||||||
|
new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("perimeters"))
|
||||||
|
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
|
||||||
|
else if (this->local_config->optptr("top_solid_layers"))
|
||||||
|
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
|
||||||
|
else if (this->local_config->optptr("fill_density"))
|
||||||
|
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
|
||||||
|
else if (this->local_config->optptr("support_material"))
|
||||||
|
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("support_material_enforce_layers"))
|
||||||
|
new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
|
||||||
|
else if (this->local_config->optptr("exact_last_layer_height"))
|
||||||
|
new_conf.set_key_value("exact_last_layer_height", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("ensure_vertical_shell_thickness"))
|
||||||
|
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("infill_dense"))
|
||||||
|
new_conf.set_key_value("infill_dense", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("extra_perimeters"))
|
||||||
|
new_conf.set_key_value("extra_perimeters", new ConfigOptionBool(false));
|
||||||
|
this->local_config->apply_only(new_conf, this->local_config->keys(), true);
|
||||||
|
} else if (answer == wxID_YES) {
|
||||||
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
|
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
|
||||||
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
|
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
|
||||||
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
|
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
|
||||||
@ -127,7 +150,19 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
DynamicPrintConfig new_conf = *config;
|
DynamicPrintConfig new_conf = *config;
|
||||||
auto answer = dialog.ShowModal();
|
auto answer = dialog.ShowModal();
|
||||||
if (!is_global_config || answer == wxID_YES) {
|
if (!is_global_config) {
|
||||||
|
if (this->local_config->optptr("wipe_tower"))
|
||||||
|
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("support_material_extruder"))
|
||||||
|
new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
|
||||||
|
else if (this->local_config->optptr("support_material_interface_extruder"))
|
||||||
|
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
||||||
|
else if (this->local_config->optptr("support_material_contact_distance_type"))
|
||||||
|
new_conf.set_key_value("support_material_contact_distance_type", new ConfigOptionEnum<SupportZDistanceType>(zdNone));
|
||||||
|
else if (this->local_config->optptr("support_material"))
|
||||||
|
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||||
|
this->local_config->apply_only(new_conf, this->local_config->keys(), true);
|
||||||
|
} else if (answer == wxID_YES) {
|
||||||
new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
|
new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
|
||||||
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
||||||
}
|
}
|
||||||
@ -137,7 +172,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
||||||
((ConfigOptionEnumGeneric*)config->option("support_material_contact_distance_type"))->value != zdNone &&
|
((ConfigOptionEnumGeneric*)config->option("support_material_contact_distance_type"))->value == zdNone &&
|
||||||
!config->opt_bool("support_material_synchronize_layers")) {
|
!config->opt_bool("support_material_synchronize_layers")) {
|
||||||
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
|
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
"need to be synchronized with the object layers."));
|
"need to be synchronized with the object layers."));
|
||||||
@ -147,11 +182,21 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
DynamicPrintConfig new_conf = *config;
|
DynamicPrintConfig new_conf = *config;
|
||||||
auto answer = dialog.ShowModal();
|
auto answer = dialog.ShowModal();
|
||||||
if (!is_global_config || answer == wxID_YES) {
|
if (!is_global_config) {
|
||||||
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
if (this->local_config->optptr("wipe_tower"))
|
||||||
}
|
|
||||||
else
|
|
||||||
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||||
|
else if (this->local_config->optptr("support_material_synchronize_layers"))
|
||||||
|
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
||||||
|
else if (this->local_config->optptr("support_material_contact_distance_type"))
|
||||||
|
new_conf.set_key_value("support_material_contact_distance_type", new ConfigOptionEnum<SupportZDistanceType>(zdFilament));
|
||||||
|
else if (this->local_config->optptr("support_material"))
|
||||||
|
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||||
|
this->local_config->apply_only(new_conf, this->local_config->keys(), true);
|
||||||
|
} else if (answer == wxID_YES) {
|
||||||
|
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
||||||
|
} else {
|
||||||
|
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||||
|
}
|
||||||
apply(config, &new_conf);
|
apply(config, &new_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,19 +222,20 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
if ( (!opts[i].opt->percent) && (opts[i].opt->get_abs_value(diameter) < opts[i].min || opts[i].opt->get_abs_value(diameter) > opts[i].max) ) {
|
if ( (!opts[i].opt->percent) && (opts[i].opt->get_abs_value(diameter) < opts[i].min || opts[i].opt->get_abs_value(diameter) > opts[i].max) ) {
|
||||||
wxString msg_text = _(L("Did you forgot to put a '%' in the "+opts[i].name+" field? "
|
wxString msg_text = _(L("Did you forgot to put a '%' in the "+opts[i].name+" field? "
|
||||||
"it's currently set to "+std::to_string(opts[i].opt->get_abs_value(diameter)) + " mm."));
|
"it's currently set to "+std::to_string(opts[i].opt->get_abs_value(diameter)) + " mm."));
|
||||||
if (is_global_config)
|
if (is_global_config) {
|
||||||
msg_text += "\n\n" + _(L("Shall I add the '%'?"));
|
msg_text += "\n\n" + _(L("Shall I add the '%'?"));
|
||||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")),
|
wxMessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")),
|
||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
DynamicPrintConfig new_conf = *config;
|
DynamicPrintConfig new_conf = *config;
|
||||||
auto answer = dialog.ShowModal();
|
auto answer = dialog.ShowModal();
|
||||||
if (!is_global_config || answer == wxID_YES) {
|
if (answer == wxID_YES) {
|
||||||
new_conf.set_key_value(opts[i].name, new ConfigOptionFloatOrPercent(opts[i].opt->value * 100, true));
|
new_conf.set_key_value(opts[i].name, new ConfigOptionFloatOrPercent(opts[i].opt->value * 100, true));
|
||||||
apply(config, &new_conf);
|
apply(config, &new_conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check changes from FloatOrPercent to percent (useful to migrate config from prusa to SuperSlicer)
|
// check changes from FloatOrPercent to percent (useful to migrate config from prusa to SuperSlicer)
|
||||||
{
|
{
|
||||||
@ -211,7 +257,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
if (config->opt_float("brim_width") > 0 && config->opt_float("brim_offset") >= config->opt_float("brim_width")) {
|
if (config->opt_float("brim_width") > 0 && config->opt_float("brim_offset") >= config->opt_float("brim_width")) {
|
||||||
wxString msg_text = _(L("It's not possible to use a bigger value for the brim offset than the brim width, as it won't extrude anything."
|
wxString msg_text = _(L("It's not possible to use a bigger value for the brim offset than the brim width, as it won't extrude anything."
|
||||||
" Brim offset have to be lower than the brim width."));
|
" Brim offset have to be lower than the brim width."));
|
||||||
if (is_global_config)
|
if (is_global_config) {
|
||||||
msg_text += "\n\n" + _(L("Shall I switch the brim offset to 0?"));
|
msg_text += "\n\n" + _(L("Shall I switch the brim offset to 0?"));
|
||||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Brim configuration")),
|
wxMessageDialog dialog(nullptr, msg_text, _(L("Brim configuration")),
|
||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
@ -222,6 +268,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
apply(config, &new_conf);
|
apply(config, &new_conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool support_material_overhangs_queried = false;
|
static bool support_material_overhangs_queried = false;
|
||||||
|
|
||||||
@ -232,7 +279,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
if (!config->opt_bool("overhangs")/* != 1*/) {
|
if (!config->opt_bool("overhangs")/* != 1*/) {
|
||||||
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
|
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
|
||||||
"- Detect bridging perimeters"));
|
"- Detect bridging perimeters"));
|
||||||
if (is_global_config)
|
if (is_global_config) {
|
||||||
msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?"));
|
msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?"));
|
||||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Support Generator")),
|
wxMessageDialog dialog(nullptr, msg_text, _(L("Support Generator")),
|
||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO | wxCANCEL : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO | wxCANCEL : wxOK));
|
||||||
@ -241,11 +288,9 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
if (!is_global_config || answer == wxID_YES) {
|
if (!is_global_config || answer == wxID_YES) {
|
||||||
// Enable "detect bridging perimeters".
|
// Enable "detect bridging perimeters".
|
||||||
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
|
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
|
||||||
}
|
} else if (answer == wxID_NO) {
|
||||||
else if (answer == wxID_NO) {
|
|
||||||
// Do nothing, leave supports on and "detect bridging perimeters" off.
|
// Do nothing, leave supports on and "detect bridging perimeters" off.
|
||||||
}
|
} else if (answer == wxID_CANCEL) {
|
||||||
else if (answer == wxID_CANCEL) {
|
|
||||||
// Disable supports.
|
// Disable supports.
|
||||||
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||||
support_material_overhangs_queried = false;
|
support_material_overhangs_queried = false;
|
||||||
@ -254,6 +299,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
support_material_overhangs_queried = false;
|
support_material_overhangs_queried = false;
|
||||||
}
|
}
|
||||||
@ -285,7 +331,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
str_fill_pattern = _utf8(config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
|
str_fill_pattern = _utf8(config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
|
||||||
if (!correct_100p_fill) {
|
if (!correct_100p_fill) {
|
||||||
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density."))) % str_fill_pattern).str());
|
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density."))) % str_fill_pattern).str());
|
||||||
if (is_global_config)
|
if (is_global_config) {
|
||||||
msg_text += "\n\n" + _(L("Shall I switch to rectilinear fill pattern?"));
|
msg_text += "\n\n" + _(L("Shall I switch to rectilinear fill pattern?"));
|
||||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Infill")),
|
wxMessageDialog dialog(nullptr, msg_text, _(L("Infill")),
|
||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
@ -294,8 +340,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
if (!is_global_config || answer == wxID_YES) {
|
if (!is_global_config || answer == wxID_YES) {
|
||||||
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
|
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
|
||||||
fill_density = 100;
|
fill_density = 100;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
fill_density = wxGetApp().preset_bundle->prints.get_selected_preset().config.option<ConfigOptionPercent>("fill_density")->value;
|
fill_density = wxGetApp().preset_bundle->prints.get_selected_preset().config.option<ConfigOptionPercent>("fill_density")->value;
|
||||||
new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density));
|
new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density));
|
||||||
apply(config, &new_conf);
|
apply(config, &new_conf);
|
||||||
@ -305,6 +350,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||||
{
|
{
|
||||||
|
@ -1244,7 +1244,7 @@ void Sidebar::update_sliced_info_sizer()
|
|||||||
if (ps.color_extruderid_to_used_filament.size() > 0) {
|
if (ps.color_extruderid_to_used_filament.size() > 0) {
|
||||||
double total_length = 0;
|
double total_length = 0;
|
||||||
for (int i = 0; i < ps.color_extruderid_to_used_filament.size(); i++) {
|
for (int i = 0; i < ps.color_extruderid_to_used_filament.size(); i++) {
|
||||||
new_label+= from_u8((boost::format("\n - %1% %2%") % _utf8(L("Color")) % i ).str());
|
new_label+= from_u8((boost::format("\n - %1% %2%") % _utf8(L("Color")) % (i+1) ).str());
|
||||||
total_length += ps.color_extruderid_to_used_filament[i].second;
|
total_length += ps.color_extruderid_to_used_filament[i].second;
|
||||||
info_text += wxString::Format("\n%.2f (%.2f)", ps.color_extruderid_to_used_filament[i].second / 1000, total_length / 1000);
|
info_text += wxString::Format("\n%.2f (%.2f)", ps.color_extruderid_to_used_filament[i].second / 1000, total_length / 1000);
|
||||||
}
|
}
|
||||||
@ -1260,7 +1260,7 @@ void Sidebar::update_sliced_info_sizer()
|
|||||||
info_text = wxString::Format("%.2f", ps.total_weight);
|
info_text = wxString::Format("%.2f", ps.total_weight);
|
||||||
double total_weight = 0;
|
double total_weight = 0;
|
||||||
for (int i = 0; i < ps.color_extruderid_to_used_weight.size(); i++) {
|
for (int i = 0; i < ps.color_extruderid_to_used_weight.size(); i++) {
|
||||||
new_label += from_u8((boost::format("\n - %1% %2%") % _utf8(L("Color")) % i).str());
|
new_label += from_u8((boost::format("\n - %1% %2%") % _utf8(L("Color")) % (i + 1)).str());
|
||||||
total_weight += ps.color_extruderid_to_used_weight[i].second;
|
total_weight += ps.color_extruderid_to_used_weight[i].second;
|
||||||
info_text += (ps.color_extruderid_to_used_weight[i].second == 0 ? "\nN/A": wxString::Format("\n%.2f", ps.color_extruderid_to_used_weight[i].second / 1000))
|
info_text += (ps.color_extruderid_to_used_weight[i].second == 0 ? "\nN/A": wxString::Format("\n%.2f", ps.color_extruderid_to_used_weight[i].second / 1000))
|
||||||
+ (total_weight == 0 ? " (N/A)" : wxString::Format(" (%.2f)", total_weight / 1000));
|
+ (total_weight == 0 ? " (N/A)" : wxString::Format(" (%.2f)", total_weight / 1000));
|
||||||
@ -1292,25 +1292,23 @@ void Sidebar::update_sliced_info_sizer()
|
|||||||
wxString str_color = _(L("Color"));
|
wxString str_color = _(L("Color"));
|
||||||
wxString str_pause = _(L("Pause"));
|
wxString str_pause = _(L("Pause"));
|
||||||
|
|
||||||
auto fill_labels = [str_color, str_pause](const std::vector<std::pair<CustomGcodeType, std::string>>& times,
|
auto fill_labels = [str_color, str_pause](const std::vector<std::pair<CustomGcodeType, float>>& times,
|
||||||
wxString& new_label, wxString& info_text)
|
wxString& new_label, wxString& info_text)
|
||||||
{
|
{
|
||||||
int color_change_count = 0;
|
int color_change_count = 1;
|
||||||
for (auto time : times)
|
float time_from_beginning = 0;
|
||||||
if (time.first == cgtColorChange)
|
for (size_t i = 0; i < times.size(); ++i)
|
||||||
color_change_count++;
|
|
||||||
|
|
||||||
for (int i = (int)times.size() - 1; i >= 0; --i)
|
|
||||||
{
|
{
|
||||||
if (i == 0 || times[i - 1].first == cgtPausePrint)
|
if (times[i].first == cgtPausePrint)
|
||||||
new_label += from_u8((boost::format("\n - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count).str());
|
new_label += from_u8((boost::format("\n - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count).str());
|
||||||
else if (times[i - 1].first == cgtColorChange)
|
else if (times[i].first == cgtColorChange)
|
||||||
new_label += from_u8((boost::format("\n - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count--).str());
|
new_label += from_u8((boost::format("\n - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count++).str());
|
||||||
|
|
||||||
if (i != (int)times.size() - 1 && times[i].first == cgtPausePrint)
|
if (i != (int)times.size() - 1 && times[i].first == cgtPausePrint)
|
||||||
new_label += from_u8((boost::format(" -> %1%") % std::string(str_pause.ToUTF8())).str());
|
new_label += from_u8((boost::format(" -> %1%") % std::string(str_pause.ToUTF8())).str());
|
||||||
|
|
||||||
info_text += from_u8((boost::format("\n%1%") % times[i].second).str());
|
time_from_beginning += times[i].second;
|
||||||
|
info_text += from_u8((boost::format("\n%1% (%2%)") % get_time_dhm(times[i].second) % get_time_dhm(time_from_beginning)).str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -574,11 +574,15 @@ const std::vector<std::string>& Preset::filament_options()
|
|||||||
"filament_toolchange_part_fan_speed",
|
"filament_toolchange_part_fan_speed",
|
||||||
"filament_dip_insertion_speed",
|
"filament_dip_insertion_speed",
|
||||||
"filament_dip_extraction_speed", //skinnydip params end
|
"filament_dip_extraction_speed", //skinnydip params end
|
||||||
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
|
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature",
|
||||||
"max_fan_speed", "bridge_fan_speed"
|
"cooling",
|
||||||
, "top_fan_speed"
|
"fan_always_on",
|
||||||
, "disable_fan_first_layers"
|
"min_fan_speed",
|
||||||
, "fan_below_layer_time",
|
"max_fan_speed",
|
||||||
|
"bridge_fan_speed",
|
||||||
|
"top_fan_speed",
|
||||||
|
"disable_fan_first_layers",
|
||||||
|
"fan_below_layer_time",
|
||||||
"slowdown_below_layer_time",
|
"slowdown_below_layer_time",
|
||||||
"max_speed_reduction",
|
"max_speed_reduction",
|
||||||
"min_print_speed",
|
"min_print_speed",
|
||||||
|
@ -1889,8 +1889,7 @@ void TabFilament::update()
|
|||||||
this->update_volumetric_flow_preset_hints();
|
this->update_volumetric_flow_preset_hints();
|
||||||
Layout();
|
Layout();
|
||||||
|
|
||||||
bool cooling = m_config->opt_bool("cooling", 0);
|
bool fan_always_on = m_config->opt_bool("fan_always_on", 0);
|
||||||
bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0);
|
|
||||||
|
|
||||||
//get_field("max_fan_speed")->toggle(m_config->opt_int("fan_below_layer_time", 0) > 0);
|
//get_field("max_fan_speed")->toggle(m_config->opt_int("fan_below_layer_time", 0) > 0);
|
||||||
Field* min_print_speed_field = get_field("min_print_speed");
|
Field* min_print_speed_field = get_field("min_print_speed");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user