Skip to content

Commit

Permalink
some fixes, default fan can now be disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed May 21, 2024
2 parents 126843f + 48a3a5b commit c02a986
Show file tree
Hide file tree
Showing 16 changed files with 621 additions and 424 deletions.
53 changes: 53 additions & 0 deletions src/libslic3r/BoundingBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,59 @@ template void BoundingBoxBase<Point>::merge(const BoundingBoxBase<Point> &bb);
template void BoundingBoxBase<Vec2f>::merge(const BoundingBoxBase<Vec2f> &bb);
template void BoundingBoxBase<Vec2d>::merge(const BoundingBoxBase<Vec2d> &bb);

template <class PointClass>
bool BoundingBoxBase<PointClass>::cross(const Line &line) const
{
assert(this->defined || this->min.x() >= this->max.x() || this->min.y() >= this->max.y());
// first just check if one point is inside and the other outside
bool cross = this->contains(line.a) != this->contains(line.b);
// now compre cross for the 4 lines
Point intersect;
if (!cross)
cross = Line(Point(this->min.x(), this->min.y()), Point(this->min.x(), this->max.y())).intersection(line, &intersect);
if (!cross)
cross = Line(Point(this->min.x(), this->min.y()), Point(this->max.x(), this->min.y())).intersection(line, &intersect);
if (!cross)
cross = Line(Point(this->max.x(), this->max.y()), Point(this->min.x(), this->max.y())).intersection(line, &intersect);
if (!cross)
cross = Line(Point(this->max.x(), this->max.y()), Point(this->max.x(), this->min.y())).intersection(line, &intersect);
return cross;
}
template bool BoundingBoxBase<Point>::cross(const Line &line) const;

template <class PointClass>
bool BoundingBoxBase<PointClass>::cross(const Polyline &lines) const
{
assert(this->defined || this->min.x() >= this->max.x() || this->min.y() >= this->max.y());
// first just check if one point is inside and the other outside
size_t nb_in = 0;
size_t nb_out = 0;
for (const Point &pt : lines.points)
if (this->contains(pt))
nb_in++;
else
nb_out++;
if (nb_in > 0 && nb_out > 0)
return true;
bool cross = false;
Point intersect;
// now compare cross for the 4 lines
Line l1 = Line(Point(this->min.x(), this->min.y()), Point(this->min.x(), this->max.y()));
Line l2 = Line(Point(this->min.x(), this->min.y()), Point(this->max.x(), this->min.y()));
Line l3 = Line(Point(this->max.x(), this->max.y()), Point(this->min.x(), this->max.y()));
Line l4 = Line(Point(this->max.x(), this->max.y()), Point(this->max.x(), this->min.y()));
for (size_t next_idx = 1; next_idx < lines.size(); ++next_idx) {
Line line(lines.points[next_idx - 1], lines.points[next_idx]);
Vec2f v;
cross = l1.intersection(line, &intersect) || l2.intersection(line, &intersect) ||
l3.intersection(line, &intersect) || l4.intersection(line, &intersect);
if (cross)
return true;
}
return false;
}
template bool BoundingBoxBase<Point>::cross(const Polyline &lines) const;

template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const PointClass &point)
{
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/BoundingBox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class BoundingBoxBase
return point(0) >= this->min(0) && point(0) <= this->max(0)
&& point(1) >= this->min(1) && point(1) <= this->max(1);
}
bool cross(const Line &line) const;
bool cross(const Polyline &lines) const;
bool contains(const BoundingBoxBase<PointClass> &other) const {
return contains(other.min) && contains(other.max);
}
Expand Down
58 changes: 45 additions & 13 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,9 +764,9 @@ namespace DoExport {
if (extruder == extruders.end())
continue;

double s = PI * sqr(0.5* extruder->filament_diameter());
double section = PI * sqr(0.5 * extruder->filament_diameter());
double weight = volume.second * extruder->filament_density() * 0.001;
total_used_filament += volume.second/s;
total_used_filament += volume.second / section;
total_weight += weight;
total_cost += weight * extruder->filament_cost() * 0.001;
}
Expand Down Expand Up @@ -1308,12 +1308,20 @@ void GCode::_init_multiextruders(const Print& print, std::string& out, GCodeWrit
}
}

struct LockMonitor
{
PrintStatistics &m_status_monitor;
LockMonitor(PrintStatistics &status_monitor) : m_status_monitor(status_monitor) { m_status_monitor.is_computing_gcode = true; }
~LockMonitor(){ m_status_monitor.is_computing_gcode = false; }
};

void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGeneratorCallback thumbnail_cb)
{
PROFILE_FUNC();

const Print &print = print_mod;
Print::StatusMonitor status_monitor{print_mod};
LockMonitor monitor_soft_lock(status_monitor.stats());
this->m_throw_if_canceled =
[&print]() { print.throw_if_canceled(); };

Expand Down Expand Up @@ -1348,6 +1356,7 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene

status_monitor.stats().color_extruderid_to_used_filament.clear();
status_monitor.stats().color_extruderid_to_used_weight.clear();
status_monitor.stats().layer_area_stats.clear();

// How many times will be change_layer() called?
// change_layer() in turn increments the progress bar status.
Expand Down Expand Up @@ -6047,7 +6056,7 @@ Polyline GCode::travel_to(std::string &gcode, const Point &point, ExtrusionRole
if (may_need_avoid_crossing) {
// if a retraction would be needed (with a low min_dist threshold), try to use avoid_crossing_perimeters to
// plan a multi-hop travel path inside the configuration space
if (this->can_cross_perimeter(travel, can_avoid_cross_peri)) {
if (this->can_cross_perimeter(travel, true)) {
this->m_throw_if_canceled();
travel = m_avoid_crossing_perimeters.travel_to(*this, point, &could_be_wipe_disabled);
}
Expand All @@ -6057,7 +6066,7 @@ Polyline GCode::travel_to(std::string &gcode, const Point &point, ExtrusionRole
bool needs_retraction = this->needs_retraction(travel, role);
if (m_config.only_retract_when_crossing_perimeters &&
!(m_config.enforce_retract_first_layer && m_layer_index == 0))
needs_retraction = needs_retraction && can_avoid_cross_peri && this->can_cross_perimeter(travel, false);
needs_retraction = needs_retraction && this->can_cross_perimeter(travel, false);

// Re-allow avoid_crossing_perimeters for the next travel moves
m_avoid_crossing_perimeters.reset_once_modifiers();
Expand Down Expand Up @@ -6273,7 +6282,7 @@ bool GCode::can_cross_perimeter(const Polyline& travel, bool offset)
// FROM 2.7
if (m_layer_slices_offseted.layer != m_layer) {
m_layer_slices_offseted.layer = m_layer;
m_layer_slices_offseted.diameter = scale_t(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0.4));
m_layer_slices_offseted.diameter = scale_t(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0.4)) / 2;
ExPolygons slices = m_layer->lslices;
ExPolygons slices_offsetted = offset_ex(m_layer->lslices, -m_layer_slices_offseted.diameter * 1.5f);
// remove top surfaces
Expand All @@ -6299,13 +6308,38 @@ bool GCode::can_cross_perimeter(const Polyline& travel, bool offset)
}
}
}
//{
// static int aodfjiaqsdz = 0;
// std::stringstream stri;
// stri << this->m_layer->id() << "_avoid_" <<"_"<<(aodfjiaqsdz++) << ".svg";
// SVG svg(stri.str());
// svg.draw(m_layer->lslices, "grey");
// for (auto &entry : offset ? m_layer_slices_offseted.slices_offsetted : m_layer_slices_offseted.slices) {
// bool checked = (travel.size() > 1 &&
// (entry.second.contains(travel.front()) ||
// entry.second.contains(travel.back()) ||
// entry.second.contains(travel.points[travel.size() / 2]) ||
// entry.second.cross(travel) )
// );
// svg.draw((entry.second.polygon().split_at_first_point()), checked?"green":"orange", scale_t(0.03));
// int diff_count =0;
// if(checked)
// diff_count = diff_pl(travel, entry.first.contour).size();
// svg.draw(to_polylines(entry.first), diff_count==0?"blue":diff_count==1?"teal":"yellow", scale_t(0.05));
// }
// svg.draw(travel, "red", scale_t(0.05));
// svg.Close();
//}
// test if a expoly contains the entire travel
for (const std::pair<ExPolygon, BoundingBox> &expoly_2_bb :
offset ? m_layer_slices_offseted.slices_offsetted : m_layer_slices_offseted.slices) {
// first check if it's roughtly inside the bb, to reject quickly.
if (travel.size() > 1 && expoly_2_bb.second.contains(travel.front()) &&
expoly_2_bb.second.contains(travel.back()) &&
expoly_2_bb.second.contains(travel.points[travel.size() / 2])) {
if (travel.size() > 1 &&
(expoly_2_bb.second.contains(travel.front()) ||
expoly_2_bb.second.contains(travel.back()) ||
expoly_2_bb.second.contains(travel.points[travel.size() / 2]) ||
expoly_2_bb.second.cross(travel) )
) {
// first, check if it's inside the contour (still, it can go over holes)
Polylines diff_result = diff_pl(travel, expoly_2_bb.first.contour);
if (diff_result.size() == 1 && diff_result.front() == travel)
Expand Down Expand Up @@ -6333,14 +6367,12 @@ bool GCode::can_cross_perimeter(const Polyline& travel, bool offset)
return true;
}
}
//if (has_intersect)
// break;
}
// if inside contour and does not inersect hole -> inside expoly, you don't need to avoid.
//if (!has_intersect)
return false;
//note: can be inside multiple contours, so we need to checl all of them
}
}
// never crossed a perimeter or a hole
return false;
}

// retract if only_retract_when_crossing_perimeters is disabled or doesn't apply
Expand Down
39 changes: 25 additions & 14 deletions src/libslic3r/GCode/CoolingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -931,9 +931,9 @@ std::string CoolingBuffer::apply_layer_cooldown(
fan_speeds[i] = default_fan_speed[i];
}
//fan_speeds[0] carry the current default value. ensure it's not negative.
if (initial_default_fan_speed <= 0) {
fan_speeds[0] = 0;
}
//if (initial_default_fan_speed <= 0) {
// fan_speeds[0] = 0;
//}
if (layer_time < slowdown_below_layer_time && fan_below_layer_time > 0) {
// Layer time very short. Enable the fan to a full throttle.
//fan_speed_new = std::max(max_fan_speed, fan_speed_new);
Expand All @@ -948,7 +948,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
for (size_t etype_idx = 0; etype_idx < etype_can_increase_fan.size(); etype_idx++) {
uint16_t idx = etype_can_increase_fan[etype_idx];
if (fan_speeds[idx] < max_fan_speed) // if max speed is lower, this will reduce speed, so don't do it.
fan_speeds[idx] = std::clamp(int(t * fan_speeds[idx] + (1. - t) * max_fan_speed + 0.5), 0, 255);
fan_speeds[idx] = std::clamp(int(t * (fan_speeds[idx] < 0 ? 0 : fan_speeds[idx]) + (1. - t) * max_fan_speed + 0.5), 0, 255);
}
}

Expand All @@ -961,7 +961,9 @@ std::string CoolingBuffer::apply_layer_cooldown(
float factor = float(int(layer_id + 1) - disable_fan_first_layers) / float(full_fan_speed_layer - disable_fan_first_layers);
for (size_t etype_idx = 0; etype_idx < etype_can_ramp_up_fan.size(); etype_idx++) {
uint16_t idx = etype_can_ramp_up_fan[etype_idx];
fan_speeds[idx] = std::clamp(int(float(fan_speeds[idx]) * factor + 0.01f), 0, 255);
if (fan_speeds[idx] > 0) {
fan_speeds[idx] = std::clamp(int(float(fan_speeds[idx] < 0 ? 0 : fan_speeds[idx]) * factor + 0.01f), 0, 255);
}
}
}
//only activate fan control if the fan speed is higher than min
Expand Down Expand Up @@ -1020,6 +1022,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
const char *pos = gcode.c_str();
int current_feedrate = 0;
int stored_fan_speed = m_fan_speed < 0 ? 0 : m_fan_speed;
int current_fan_speed = -1;
change_extruder_set_fan();
for (const CoolingLine *line : lines) {
const char *line_start = gcode.c_str() + line->line_start;
Expand Down Expand Up @@ -1139,19 +1142,27 @@ std::string CoolingBuffer::apply_layer_cooldown(
bool fan_set = false;
for (size_t i = extrude_tree.size() - 1; i < extrude_tree.size(); --i) {
if (fan_control[extrude_tree[i]]) {
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments,
fan_speeds[extrude_tree[i]],
EXTRUDER_CONFIG(extruder_fan_offset), m_config.fan_percentage,
std::string("set fan for ") + ExtrusionEntity::role_to_string(extrude_tree[i]));
if (current_fan_speed != fan_speeds[extrude_tree[i]]) {
current_fan_speed = fan_speeds[extrude_tree[i]];
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments,
fan_speeds[extrude_tree[i]],
EXTRUDER_CONFIG(extruder_fan_offset),
m_config.fan_percentage,
std::string("set fan for ") + ExtrusionEntity::role_to_string(extrude_tree[i]));
}
fan_set = true;
break;
}
}
if (!fan_set) {
// return to default
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed < 0 ? 0 : m_fan_speed,
EXTRUDER_CONFIG(extruder_fan_offset), m_config.fan_percentage,
"set default fan");
if (!fan_set && m_fan_speed >= 0 ) {
if (current_fan_speed != m_fan_speed && (default_fan_speed[0] >= 0 || current_fan_speed > 0)) {
current_fan_speed = m_fan_speed;
// return to default
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed,
EXTRUDER_CONFIG(extruder_fan_offset), m_config.fan_percentage,
"set default fan");
}
fan_set = true;
}
fan_need_set = false;
}
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/GCode/GCodeProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ void GCodeProcessorResult::reset() {
#endif // ENABLE_SPIRAL_VASE_LAYERS
time = 0;
computed_timestamp = std::time(0);
print_statistics.reset();
}
#else
void GCodeProcessorResult::reset() {
Expand All @@ -795,6 +796,7 @@ void GCodeProcessorResult::reset() {
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
#endif // ENABLE_SPIRAL_VASE_LAYERS
computed_timestamp = std::time(0);
print_statistics.reset();
}
#endif // ENABLE_GCODE_VIEWER_STATISTICS

Expand Down
3 changes: 1 addition & 2 deletions src/libslic3r/GCode/GCodeProcessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ namespace Slic3r {
std::vector<std::pair<EMoveType, float>> moves_times;
std::vector<std::pair<ExtrusionRole, float>> roles_times;
std::vector<float> layers_times;
std::vector<float> layers_areas;

void reset() {
time = 0.0f;
Expand All @@ -69,7 +68,7 @@ namespace Slic3r {
PrintEstimatedStatistics() { reset(); }

void reset() {
for (auto m : modes) {
for (Mode &m : modes) {
m.reset();
}
volumes_per_color_change.clear();
Expand Down
8 changes: 6 additions & 2 deletions src/libslic3r/Print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <Eigen/Geometry>

#include <atomic>
#include <ctime>
#include <functional>
#include <set>
Expand Down Expand Up @@ -487,7 +488,7 @@ struct PrintStatistics
std::string estimated_normal_print_time;
std::string estimated_silent_print_time;
double total_used_filament;
std::vector<std::pair<size_t, double>> color_extruderid_to_used_filament;
std::vector<std::pair<size_t, double>> color_extruderid_to_used_filament; // id -> mm (length)
double total_extruded_volume;
double total_cost;
int total_toolchanges;
Expand All @@ -499,9 +500,11 @@ struct PrintStatistics
unsigned int initial_extruder_id;
std::string initial_filament_type;
std::string printing_filament_types;
std::map<size_t, double> filament_stats;
std::map<size_t, double> filament_stats; // extruder id -> volume in mm3
std::vector<std::pair<double, float>> layer_area_stats; // print_z to area

std::atomic_bool is_computing_gcode;

// Config with the filled in print statistics.
DynamicConfig config() const;
// Config with the statistics keys populated with placeholder strings.
Expand All @@ -522,6 +525,7 @@ struct PrintStatistics
printing_filament_types.clear();
filament_stats.clear();
printing_extruders.clear();
is_computing_gcode = false;
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5033,7 +5033,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("mm²");
def->min = 0;
def->mode = comExpert | comPrusa;
def->set_default_value(new ConfigOptionFloat(70));
def->set_default_value(new ConfigOptionFloat(4));

def = this->add("solid_infill_below_layer_area", coFloat);
def->label = L("Solid infill layer threshold area");
Expand Down Expand Up @@ -8420,6 +8420,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
"start_gcode_manual",
"solid_infill_below_layer_area",
"solid_infill_below_thickness",
"solid_infill_below_width",
"support_material_angle_height",
"support_material_acceleration",
"support_material_contact_distance_type",
Expand Down
Loading

0 comments on commit c02a986

Please sign in to comment.