733{
734
735 std::vector<const CoolingLine*> lines;
736 {
737 size_t n_lines = 0;
738 for (const PerExtruderAdjustments &adj : per_extruder_adjustments)
739 n_lines += adj.lines.size();
740 lines.reserve(n_lines);
741 for (const PerExtruderAdjustments &adj : per_extruder_adjustments)
742 for (const CoolingLine &line : adj.lines)
743 lines.emplace_back(&line);
744 std::sort(lines.begin(), lines.end(), [](const CoolingLine *ln1, const CoolingLine *ln2) { return ln1->line_start < ln2->line_start; } );
745 }
746
747 std::string new_gcode;
748 new_gcode.reserve(
gcode.size() * 2);
749
750
752 bool overhang_fan_control= false;
754 bool internal_bridge_fan_control= false;
755 int internal_bridge_fan_speed = 0;
756 bool supp_interface_fan_control= false;
757 int supp_interface_fan_speed = 0;
758 bool ironing_fan_control= false;
762 &internal_bridge_fan_control, &internal_bridge_fan_speed,
763 &supp_interface_fan_control, &supp_interface_fan_speed,
765 ](bool immediately_apply) {
766#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_current_extruder)
767
771
772 int additional_fan_speed_new =
m_config.additional_cooling_fan_speed.get_at(config_index);
774
776
777
778
779
780
781 int initial_layer_fan_speed =
EXTRUDER_CONFIG(initial_layer_fan_speed);
784
785
786
787
788
789
790
791
792
793
794
795 if (has_initial_layer_override && layer_id == 0) {
796 fan_speed_new = initial_layer_fan_speed;
798 overhang_fan_control = false;
799 internal_bridge_fan_speed = initial_layer_fan_speed;
800 internal_bridge_fan_control = false;
801 supp_interface_fan_speed = initial_layer_fan_speed;
802 supp_interface_fan_control = false;
804 ironing_fan_control = false;
805
806
810 float fan_cooling_layer_time = float(
EXTRUDER_CONFIG(fan_cooling_layer_time));
811
812
814
816 } else if (layer_time < fan_cooling_layer_time) {
817
821 }
822
826
827
828
829
830
831
832
833 const float anchor = float(initial_layer_fan_speed);
835 const float t = float(int(layer_id)) / denom;
836 fan_speed_new = std::clamp(int(anchor + t * (float(fan_speed_new) - anchor) + 0.5f), 0, 255);
838 } else {
839
841 fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
843 }
844 }
846 supp_interface_fan_control = supp_interface_fan_speed >= 0;
847
849
850
851 internal_bridge_fan_speed =
EXTRUDER_CONFIG(internal_bridge_fan_speed);
852 internal_bridge_fan_control = internal_bridge_fan_speed >=0;
853
854 if( internal_bridge_fan_speed < 0 ) {
856 internal_bridge_fan_control = overhang_fan_control;
857 }
858
859
862#undef EXTRUDER_CONFIG
863
864 } else {
865 overhang_fan_control = false;
867 fan_speed_new = 0;
868 additional_fan_speed_new = 0;
869 supp_interface_fan_control = false;
870 supp_interface_fan_speed = 0;
871 internal_bridge_fan_control = false;
872 internal_bridge_fan_speed = 0;
873 ironing_fan_control = false;
875 }
876
877
878
882 if (immediately_apply)
884 }
885
888 if (immediately_apply &&
m_config.auxiliary_fan.value)
890 }
891 };
892
894 int current_feedrate = 0;
895 change_extruder_set_fan(true);
896
897
898
904
905
907
908 for (const CoolingLine *line : lines) {
909 const char *line_start =
gcode.c_str() + line->line_start;
910 const char *line_end =
gcode.c_str() + line->line_end;
911 if (line_start > pos)
912 new_gcode.append(pos, line_start - pos);
914 unsigned int new_extruder = 0;
915 auto ret = std::from_chars(line_start +
m_toolchange_prefix.size(), line_end, new_extruder);
916 if (std::errc::invalid_argument != ret.ec) {
919 change_extruder_set_fan(true);
921 need_set_fan = true;
922 }
923 }
924 new_gcode.append(line_start, line_end - line_start);
927 need_set_fan = true;
929 }
933 }
934 need_set_fan = true;
937 need_set_fan = true;
939 }
943 }
944 need_set_fan = true;
948 need_set_fan = true;
949 }
951 if (supp_interface_fan_control) {
953 }
954 need_set_fan = true;
958 need_set_fan = true;
959 }
963 }
964 need_set_fan = true;
966
967 if (
m_fan_speed != -1 && !std::any_of(fan_speed_change_requests.begin(), fan_speed_change_requests.end(), [](
const std::pair<int, bool>& p) { return p.second; })){
969 need_set_fan = true;
970 }
973 }
976 need_set_fan = true;
979 need_set_fan = true;
980 }
982
984
985 const char *
end = line_start;
986 for (;
end < line_end && *
end !=
';'; ++
end);
987
988 const char *fpos = strstr(line_start + 2, " F") + 2;
989 int new_feedrate = current_feedrate;
990
991 bool modify = false;
992
993 bool remove = false;
994 assert(fpos != nullptr);
995 new_feedrate = line->slowdown ? int(floor(60. * line->feedrate + 0.5)) : atoi(fpos);
996 if (new_feedrate == current_feedrate) {
997
999
1001 else
1002
1003 remove = true;
1004 } else if (line->slowdown) {
1005
1006 modify = true;
1007 } else {
1008
1009
1010 new_gcode.append(line_start, end - line_start);
1011 current_feedrate = new_feedrate;
1012 }
1013 if (modify || remove) {
1014 if (modify) {
1015
1016 new_gcode.append(line_start, fpos - line_start);
1017 current_feedrate = new_feedrate;
1018 char buf[64];
1019 sprintf(buf, "%d", int(current_feedrate));
1020 new_gcode += buf;
1021 } else {
1022
1023 const char *
f = fpos;
1024
1025 for (
f -= 2;
f > line_start && (*
f ==
' ' || *
f ==
'\t'); --
f);
1026
1027 if ((
f - line_start == 1) && *line_start ==
'G' && (*
f ==
'1' || *
f ==
'0')) {
1028
1029 } else {
1030
1031 new_gcode.append(line_start,
f - line_start + 1);
1032 }
1033 }
1034
1035 for (; fpos !=
end && *fpos !=
' ' && *fpos !=
';' && *fpos !=
'\n'; ++ fpos);
1036
1037 if (fpos < end)
1038
1039 new_gcode.append(fpos, end - fpos);
1040 else if (remove && new_gcode == "G1") {
1041
1042 new_gcode.resize(new_gcode.size() - 2);
1044 }
1045 }
1046
1047 if (end < line_end) {
1049
1050 std::string comment(end, line_end);
1051 boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
1053 boost::replace_all(comment, ";_EXTERNAL_PERIMETER", "");
1055 boost::replace_all(comment, ";_WIPE", "");
1056 new_gcode += comment;
1057 } else {
1058
1059 new_gcode.append(end, line_end - end);
1060 }
1061 }
1062 } else {
1063 new_gcode.append(line_start, line_end - line_start);
1064 }
1065
1066 if (need_set_fan) {
1067 const auto set_fan = [&](int speed) {
1071 }
1072 };
1074
1075
1076
1077
1078
1079 set_fan(0);
1084 set_fan(internal_bridge_fan_speed);
1085 }
1087 set_fan(supp_interface_fan_speed);
1088 }
1091 }
1095 }
1096 else {
1098 }
1099 need_set_fan = false;
1100 }
1102 }
1103 const char *gcode_end =
gcode.c_str() +
gcode.size();
1104 if (pos < gcode_end)
1105 new_gcode.append(pos, gcode_end - pos);
1106
1107 return new_gcode;
1108}
#define EXTRUDER_CONFIG(OPT)
Definition GCode.cpp:2155
int m_additional_fan_speed
Definition CoolingBuffer.hpp:50
int m_current_fan_speed
Definition CoolingBuffer.hpp:65
bool m_belt_band_active
Definition CoolingBuffer.hpp:68
int m_fan_speed
Definition CoolingBuffer.hpp:49
static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm=0)
Definition GCodeWriter.cpp:1552
static std::string set_additional_fan(unsigned int speed)
Definition GCodeWriter.cpp:1599
T * end(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:841
@ gcode
Definition Time.hpp:14
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16
zaa_minimize_perimeter_height overhang_fan_speed((ConfigOptionEnumsGeneric, overhang_fan_threshold))((ConfigOptionEnum< PrintSequence >
zaa_minimize_perimeter_height ironing_fan_speed((ConfigOptionStrings, filament_notes))((ConfigOptionString
zaa_minimize_perimeter_height part_cooling_fan_min_pwm((ConfigOptionFloats, filament_diameter))((ConfigOptionBoolsNullable
zaa_minimize_perimeter_height fan_min_speed((ConfigOptionFloats, min_layer_height))((ConfigOptionFloat
zaa_minimize_perimeter_height support_material_interface_fan_speed((ConfigOptionInts, internal_bridge_fan_speed))((ConfigOptionInts
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
zaa_minimize_perimeter_height full_fan_speed_layer((ConfigOptionInts, initial_layer_fan_speed))((ConfigOptionFloats
zaa_minimize_perimeter_height close_fan_the_first_x_layers((ConfigOptionEnum< DraftShield >, draft_shield))((ConfigOptionFloat
zaa_minimize_perimeter_height slow_down_layer_time((ConfigOptionBool, spiral_mode))((ConfigOptionBool
zaa_minimize_perimeter_height fan_max_speed((ConfigOptionFloats, max_layer_height))((ConfigOptionFloats
@ TYPE_OVERHANG_FAN_END
Definition CoolingBuffer.cpp:73
@ TYPE_OVERHANG_FAN_START
Definition CoolingBuffer.cpp:72
@ TYPE_ADJUSTABLE
Definition CoolingBuffer.cpp:76
@ TYPE_IRONING_FAN_END
Definition CoolingBuffer.cpp:94
@ TYPE_WIPE
Definition CoolingBuffer.cpp:80
@ TYPE_BELT_BAND_END
Definition CoolingBuffer.cpp:97
@ TYPE_FORCE_RESUME_FAN
Definition CoolingBuffer.cpp:86
@ TYPE_HAS_F
Definition CoolingBuffer.cpp:79
@ TYPE_EXTRUDE_END
Definition CoolingBuffer.cpp:71
@ TYPE_EXTERNAL_PERIMETER
Definition CoolingBuffer.cpp:77
@ TYPE_SUPPORT_INTERFACE_FAN_END
Definition CoolingBuffer.cpp:88
@ TYPE_SUPPORT_INTERFACE_FAN_START
Definition CoolingBuffer.cpp:87
@ TYPE_INTERNAL_BRIDGE_FAN_START
Definition CoolingBuffer.cpp:90
@ TYPE_BELT_BAND_START
Definition CoolingBuffer.cpp:96
@ TYPE_INTERNAL_BRIDGE_FAN_END
Definition CoolingBuffer.cpp:91
@ TYPE_SET_TOOL
Definition CoolingBuffer.cpp:70
@ TYPE_IRONING_FAN_START
Definition CoolingBuffer.cpp:93