mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-14 16:11:47 +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_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
|
||||
|
@ -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() :
|
||||
|
@ -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,19 +432,17 @@ 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 {
|
||||
// Prepare a future wipe.
|
||||
gcodegen.m_wipe.path.points.clear();
|
||||
if (new_extruder_id >= 0) {
|
||||
// Start the wipe at the current position.
|
||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos));
|
||||
// Wipe end point: Wipe direction away from the closer tower edge to the further tower edge.
|
||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen,
|
||||
Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left,
|
||||
end_pos.y())));
|
||||
}
|
||||
} else {
|
||||
// Prepare a future wipe.
|
||||
gcodegen.m_wipe.path.points.clear();
|
||||
if (new_extruder_id >= 0) {
|
||||
// Start the wipe at the current position.
|
||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos));
|
||||
// Wipe end point: Wipe direction away from the closer tower edge to the further tower edge.
|
||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen,
|
||||
Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left,
|
||||
end_pos.y())));
|
||||
}
|
||||
}
|
||||
|
||||
// Let the planner know we are traveling between objects.
|
||||
@ -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)) {
|
||||
// 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.
|
||||
//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
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -135,11 +135,13 @@ public:
|
||||
}
|
||||
|
||||
// Return the wipe tower position.
|
||||
const Vec2f& position() const { return m_wipe_tower_pos; }
|
||||
const Vec2f& position() const { return m_wipe_tower_pos; }
|
||||
// Return the wipe tower width.
|
||||
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.
|
||||
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.
|
||||
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,
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 });
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
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
|
||||
} else {
|
||||
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||
}
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
|
||||
@ -177,15 +222,16 @@ 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));
|
||||
apply(config, &new_conf);
|
||||
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 (answer == wxID_YES) {
|
||||
new_conf.set_key_value(opts[i].name, new ConfigOptionFloatOrPercent(opts[i].opt->value * 100, true));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,15 +257,16 @@ 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));
|
||||
auto answer = dialog.ShowModal();
|
||||
if (!is_global_config || answer == wxID_YES) {
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
new_conf.set_key_value("brim_offset", new ConfigOptionFloat(0));
|
||||
apply(config, &new_conf);
|
||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Brim configuration")),
|
||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||
auto answer = dialog.ShowModal();
|
||||
if (!is_global_config || answer == wxID_YES) {
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
new_conf.set_key_value("brim_offset", new ConfigOptionFloat(0));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,26 +278,25 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
support_material_overhangs_queried = true;
|
||||
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)
|
||||
"- Detect bridging perimeters"));
|
||||
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));
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
auto answer = dialog.ShowModal();
|
||||
if (!is_global_config || answer == wxID_YES) {
|
||||
// Enable "detect bridging perimeters".
|
||||
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
|
||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Support Generator")),
|
||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO | wxCANCEL : wxOK));
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
auto answer = dialog.ShowModal();
|
||||
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) {
|
||||
// Do nothing, leave supports on and "detect bridging perimeters" off.
|
||||
} else if (answer == wxID_CANCEL) {
|
||||
// Disable supports.
|
||||
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||
support_material_overhangs_queried = false;
|
||||
}
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
else if (answer == wxID_NO) {
|
||||
// Do nothing, leave supports on and "detect bridging perimeters" off.
|
||||
}
|
||||
else if (answer == wxID_CANCEL) {
|
||||
// Disable supports.
|
||||
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||
support_material_overhangs_queried = false;
|
||||
}
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,22 +331,22 @@ 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) );
|
||||
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;
|
||||
wxMessageDialog dialog(nullptr, msg_text, _(L("Infill")),
|
||||
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
|
||||
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);
|
||||
if (cb_value_change)
|
||||
cb_value_change("fill_density", fill_density);
|
||||
}
|
||||
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);
|
||||
if (cb_value_change)
|
||||
cb_value_change("fill_density", fill_density);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user