Merge branch 'master' into dev

This commit is contained in:
supermerill 2020-09-19 20:41:00 +02:00
commit 2022e3fbd6
18 changed files with 296 additions and 186 deletions

View File

@ -21,7 +21,6 @@ group:Filament properties
setting:filament_soluble
setting:filament_shrink
group:Print speed override
setting:filament_max_wipe_tower_speed
setting:filament_max_volumetric_speed
volumetric_speed_description
@ -59,6 +58,7 @@ group:Multimaterial toolchange string reduction
setting:filament_dip_extraction_speed
group:Wipe tower parameters
setting:filament_minimal_purge_on_wipe_tower
setting:filament_max_wipe_tower_speed
group:Toolchange parameters with single extruder MM printers
setting:filament_loading_speed_start
setting:filament_loading_speed

View File

@ -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);
if (! m_config.opt_bool("dont_arrange")) {
//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.center_instances_around_point((! user_center_specified && m_print_config.has("bed_shape")) ?
BoundingBoxf(m_print_config.opt<ConfigOptionPoints>("bed_shape")->values).center() :

View File

@ -420,6 +420,10 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
gcode += tcr_gcode;
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.
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().travel_to_z(current_z, "Travel back up to the topmost object layer.");
gcode += gcodegen.writer().unretract();
}
else {
} else {
// Prepare a future wipe.
gcodegen.m_wipe.path.points.clear();
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
// this->print_machine_envelope(file, print);
// 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_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]);
@ -1073,9 +1076,9 @@ namespace DoExport {
print_statistics.clear();
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_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)
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);
if (! extruders.empty()) {
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)));
}
}
//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);
// 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)
_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);
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.
// 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.));
}
@ -1693,6 +1705,18 @@ void GCode::_do_export(Print &print, FILE *file)
if (m_silent_time_estimator_enabled)
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.
_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)
temp = temp_by_gcode;
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.
if (print.config().single_extruder_multi_material.value) {
// Set temperature of the first printing extruder only.
@ -4339,7 +4363,7 @@ std::string GCode::retract(bool toolchange)
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))
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.
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;
else {
// user provided his own toolchange gcode, no need to do anything

View File

@ -334,7 +334,7 @@ private:
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
std::string retract(bool toolchange = false);
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.
This affects the input arguments supplied to the extrude*() and travel_to()

View File

@ -312,7 +312,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
PerExtruderAdjustments &adj = per_extruder_adjustments[i];
uint16_t extruder_id = extruders[i].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.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);

View File

@ -440,6 +440,8 @@ public:
{
if (m_gcode_flavor == gcfMarlin)
m_gcode += "M220 R\n";
else
m_gcode += "M220 S100\n";
return *this;
}
@ -715,7 +717,8 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
uint16_t tool = tools[idx_tool];
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.
if (idx_tool + 1 == tools.size()) {
// 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);
box_coordinates box = cleaning_box;
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);
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.
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);
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);
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.
++ m_num_tool_changes;
} 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;
@ -952,7 +957,6 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
void WipeTower::toolchange_Unload(
WipeTowerWriter &writer,
const box_coordinates &cleaning_box,
const std::string& current_material,
const int new_temperature,
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.
void WipeTower::toolchange_Change(
WipeTowerWriter &writer,
const size_t new_tool,
const std::string& new_material)
const size_t new_tool)
{
// Ask the writer about how much of the old filament we consumed:
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.
void WipeTower::toolchange_Wipe(
WipeTowerWriter &writer,
@ -1257,6 +1273,9 @@ void WipeTower::toolchange_Wipe(
const float& xl = cleaning_box.ld.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
// 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.
@ -1332,6 +1351,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
// Slow down on the 1st layer.
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();
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);

View File

@ -140,6 +140,8 @@ public:
float width() const { return m_wipe_tower_width; }
// 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; }
// 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.
std::vector<ToolChangeResult> prime(
@ -366,14 +368,12 @@ private:
void toolchange_Unload(
WipeTowerWriter &writer,
const box_coordinates &cleaning_box,
const std::string& current_material,
const int new_temperature,
const size_t temp_tool);
void toolchange_Change(
WipeTowerWriter &writer,
const size_t new_tool,
const std::string& new_material);
const size_t new_tool);
void toolchange_Load(
WipeTowerWriter &writer,

View File

@ -794,27 +794,6 @@ namespace Slic3r {
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.
size_t GCodeTimeEstimator::memory_used() const
{

View File

@ -417,10 +417,6 @@ namespace Slic3r {
// 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;
// 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.
size_t memory_used() const;

View File

@ -67,6 +67,7 @@ public:
std::string postamble() const;
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1);
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);
void set_acceleration(unsigned int acceleration);
std::string write_acceleration();

View File

@ -525,19 +525,19 @@ void PerimeterGenerator::process()
+(float)(min_spacing / 2 - 1));
ExPolygons no_thin_onion = offset_ex(last, double(-good_spacing));
float div = 2;
while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && no_thin_onion.size() + next_onion.size() > 3) {
div -= 0.3;
if (div == 2) div -= 0.3;
std::vector<float> divs { 1.8, 1.6 }; //don't over-extrude, so don't use divider >2
size_t idx_div = 0;
while (next_onion.size() > no_thin_onion.size() && idx_div < divs.size()) {
float div = divs[idx_div];
//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(
last,
-(float)(good_spacing + min_spacing / div - 1),
+(float)(min_spacing / div - 1));
if (next_onion.size() > next_onion_secondTry.size() * 1.1) {
-(float)(good_spacing + (min_spacing / div) - 1),
+(float)((min_spacing / div) - 1));
if (next_onion.size() > next_onion_secondTry.size() * 1.2 && next_onion.size() > next_onion_secondTry.size() + 2) {
next_onion = next_onion_secondTry;
}
if (div > 3 || div < 1.2) break;
idx_div++;
}
} else {
@ -752,7 +752,11 @@ void PerimeterGenerator::process()
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) {
//reverse the hole, and put them in first place.
@ -768,13 +772,19 @@ void PerimeterGenerator::process()
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
if (!entities.empty())
this->loops->append(entities);
if (!entities.empty()) {
//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
// fill gaps

View File

@ -319,8 +319,8 @@ struct PrintStatistics
PrintStatistics() { clear(); }
std::string estimated_normal_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, std::string>> estimated_silent_custom_gcode_print_times;
std::vector<std::pair<CustomGcodeType, float>> estimated_normal_custom_gcode_print_times;
std::vector<std::pair<CustomGcodeType, float>> estimated_silent_custom_gcode_print_times;
double total_used_filament;
std::vector<std::pair<size_t, double>> color_extruderid_to_used_filament;
double total_extruded_volume;

View File

@ -1095,8 +1095,16 @@ void PrintConfigDef::init_fff_params()
def = this->add("filament_max_wipe_tower_speed", coFloats);
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->sidetext = L("% of mm/s");
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."
"\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->max = 200;
def->mode = comExpert;
@ -1304,7 +1312,7 @@ void PrintConfigDef::init_fff_params()
" 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.");
def->sidetext = L("%");
def->min = 0;
def->min = 10;
def->mode = comExpert;
def->set_default_value(new ConfigOptionPercents{ 100 });

View File

@ -337,6 +337,30 @@ inline std::string get_time_dhms(float time_in_secs)
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
#if WIN32

View File

@ -95,7 +95,30 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config;
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("top_solid_layers", new ConfigOptionInt(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));
DynamicPrintConfig new_conf = *config;
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_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") &&
((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")) {
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."));
@ -147,11 +182,21 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal();
if (!is_global_config || answer == wxID_YES) {
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
}
else
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_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);
}
@ -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) ) {
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."));
if (is_global_config)
if (is_global_config) {
msg_text += "\n\n" + _(L("Shall I add the '%'?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal();
if (!is_global_config || answer == wxID_YES) {
new_conf.set_key_value(opts[i].name, new ConfigOptionFloatOrPercent(opts[i].opt->value*100, true));
if (answer == wxID_YES) {
new_conf.set_key_value(opts[i].name, new ConfigOptionFloatOrPercent(opts[i].opt->value * 100, true));
apply(config, &new_conf);
}
}
}
}
}
// 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")) {
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."));
if (is_global_config)
if (is_global_config) {
msg_text += "\n\n" + _(L("Shall I switch the brim offset to 0?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Brim configuration")),
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);
}
}
}
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*/) {
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
"- Detect bridging perimeters"));
if (is_global_config)
if (is_global_config) {
msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Support Generator")),
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) {
// Enable "detect bridging perimeters".
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.
}
else if (answer == wxID_CANCEL) {
} else if (answer == wxID_CANCEL) {
// Disable supports.
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
support_material_overhangs_queried = false;
@ -254,6 +299,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
}
}
}
else {
support_material_overhangs_queried = false;
}
@ -285,17 +331,16 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
str_fill_pattern = _utf8(config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
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());
if (is_global_config)
if (is_global_config) {
msg_text += "\n\n" + _(L("Shall I switch to rectilinear fill pattern?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Infill")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal();
if (!is_global_config || answer == wxID_YES) {
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
fill_density = 100;
}
else
} else
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));
apply(config, &new_conf);
@ -304,6 +349,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
}
}
}
}
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)

View File

@ -1244,7 +1244,7 @@ void Sidebar::update_sliced_info_sizer()
if (ps.color_extruderid_to_used_filament.size() > 0) {
double total_length = 0;
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;
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);
double total_weight = 0;
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;
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));
@ -1292,25 +1292,23 @@ void Sidebar::update_sliced_info_sizer()
wxString str_color = _(L("Color"));
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)
{
int color_change_count = 0;
for (auto time : times)
if (time.first == cgtColorChange)
color_change_count++;
for (int i = (int)times.size() - 1; i >= 0; --i)
int color_change_count = 1;
float time_from_beginning = 0;
for (size_t i = 0; i < times.size(); ++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());
else if (times[i - 1].first == cgtColorChange)
new_label += from_u8((boost::format("\n - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count--).str());
else if (times[i].first == cgtColorChange)
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)
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());
}
};

View File

@ -574,11 +574,15 @@ const std::vector<std::string>& Preset::filament_options()
"filament_toolchange_part_fan_speed",
"filament_dip_insertion_speed",
"filament_dip_extraction_speed", //skinnydip params end
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
"max_fan_speed", "bridge_fan_speed"
, "top_fan_speed"
, "disable_fan_first_layers"
, "fan_below_layer_time",
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature",
"cooling",
"fan_always_on",
"min_fan_speed",
"max_fan_speed",
"bridge_fan_speed",
"top_fan_speed",
"disable_fan_first_layers",
"fan_below_layer_time",
"slowdown_below_layer_time",
"max_speed_reduction",
"min_print_speed",

View File

@ -1889,8 +1889,7 @@ void TabFilament::update()
this->update_volumetric_flow_preset_hints();
Layout();
bool cooling = m_config->opt_bool("cooling", 0);
bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0);
bool fan_always_on = m_config->opt_bool("fan_always_on", 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");