Skip to content

Commit

Permalink
Add fan speed visualization in preview
Browse files Browse the repository at this point in the history
This adds an option to preview fan speed as requested in issue prusa3d#1491.
I needed this to verify that patch prusa3d#2781 generates correct output.
  • Loading branch information
jschuh committed Sep 15, 2019
1 parent 2b867b9 commit 5ad6b79
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 12 deletions.
14 changes: 8 additions & 6 deletions src/libslic3r/ExtrusionEntity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,17 @@ class ExtrusionPath : public ExtrusionEntity
unsigned int extruder_id;
// Id of the color, used for visualization purposed in the color printing case.
unsigned int cp_color_id;
// Fan speed for the extrusion, used for visualization purposes.
float fan_speed;

ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), feedrate(0.0f), extruder_id(0), cp_color_id(0), m_role(role) {};
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), feedrate(0.0f), extruder_id(0), cp_color_id(0), m_role(role) {};
ExtrusionPath(const ExtrusionPath &rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), m_role(rhs.m_role) {}
ExtrusionPath(ExtrusionPath &&rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), m_role(rhs.m_role) {}
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), feedrate(0.0f), extruder_id(0), cp_color_id(0), fan_speed(0.0f), m_role(role) {};
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), feedrate(0.0f), extruder_id(0), cp_color_id(0), fan_speed(0.0f), m_role(role) {};
ExtrusionPath(const ExtrusionPath &rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), fan_speed(rhs.fan_speed), m_role(rhs.m_role) {}
ExtrusionPath(ExtrusionPath &&rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), fan_speed(rhs.fan_speed), m_role(rhs.m_role) {}
// ExtrusionPath(ExtrusionRole role, const Flow &flow) : m_role(role), mm3_per_mm(flow.mm3_per_mm()), width(flow.width), height(flow.height), feedrate(0.0f), extruder_id(0) {};

ExtrusionPath& operator=(const ExtrusionPath &rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->polyline = rhs.polyline; return *this; }
ExtrusionPath& operator=(ExtrusionPath &&rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->polyline = std::move(rhs.polyline); return *this; }
ExtrusionPath& operator=(const ExtrusionPath &rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->fan_speed = rhs.fan_speed, this->polyline = rhs.polyline; return *this; }
ExtrusionPath& operator=(ExtrusionPath &&rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->fan_speed = rhs.fan_speed, this->polyline = std::move(rhs.polyline); return *this; }

ExtrusionPath* clone() const { return new ExtrusionPath (*this); }
void reverse() { this->polyline.reverse(); }
Expand Down
55 changes: 51 additions & 4 deletions src/libslic3r/GCode/Analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,19 @@ GCodeAnalyzer::Metadata::Metadata()
, width(GCodeAnalyzer::Default_Width)
, height(GCodeAnalyzer::Default_Height)
, feedrate(DEFAULT_FEEDRATE)
, fan_speed(0.0f)
{
}

GCodeAnalyzer::Metadata::Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, unsigned int cp_color_id/* = 0*/)
GCodeAnalyzer::Metadata::Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, unsigned int cp_color_id/* = 0*/, float fan_speed /* = 0.0f*/)
: extrusion_role(extrusion_role)
, extruder_id(extruder_id)
, mm3_per_mm(mm3_per_mm)
, width(width)
, height(height)
, feedrate(feedrate)
, cp_color_id(cp_color_id)
, fan_speed(fan_speed)
{
}

Expand All @@ -75,12 +77,15 @@ bool GCodeAnalyzer::Metadata::operator != (const GCodeAnalyzer::Metadata& other)
if (cp_color_id != other.cp_color_id)
return true;

if (fan_speed != other.fan_speed)
return true;

return false;
}

GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, unsigned int cp_color_id/* = 0*/)
GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, unsigned int cp_color_id/* = 0*/, float fan_speed)
: type(type)
, data(extrusion_role, extruder_id, mm3_per_mm, width, height, feedrate, cp_color_id)
, data(extrusion_role, extruder_id, mm3_per_mm, width, height, feedrate, cp_color_id, fan_speed)
, start_position(start_position)
, end_position(end_position)
, delta_extruder(delta_extruder)
Expand Down Expand Up @@ -127,6 +132,7 @@ void GCodeAnalyzer::reset()
_set_start_extrusion(DEFAULT_START_EXTRUSION);
_reset_axes_position();
_reset_cached_position();
_set_fan_speed(0.0f);

m_moves_map.clear();
m_extruder_offsets.clear();
Expand Down Expand Up @@ -255,6 +261,16 @@ void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLi
_processM83(line);
break;
}
case 106: // Set fan speed
{
_processM106(line);
break;
}
case 107: // Disable fan
{
_processM107(line);
break;
}
case 108:
case 135:
{
Expand Down Expand Up @@ -444,6 +460,23 @@ void GCodeAnalyzer::_processM83(const GCodeReader::GCodeLine& line)
_set_e_local_positioning_type(Relative);
}

void GCodeAnalyzer::_processM106(const GCodeReader::GCodeLine& line)
{
float new_fan_speed;
if (!line.has('P')) { // The absence of P means the print cooling fan, so ignore anything else.
if (line.has_value('S', new_fan_speed))
_set_fan_speed((100.0f / 256) * new_fan_speed);
else
_set_fan_speed(100.0f);
}

}

void GCodeAnalyzer::_processM107(const GCodeReader::GCodeLine& line)
{
_set_fan_speed(0.0f);
}

void GCodeAnalyzer::_processM108orM135(const GCodeReader::GCodeLine& line)
{
// These M-codes are used by MakerWare and Sailfish to change active tool.
Expand Down Expand Up @@ -708,6 +741,16 @@ float GCodeAnalyzer::_get_feedrate() const
return m_state.data.feedrate;
}

void GCodeAnalyzer::_set_fan_speed(float fan_speed_percentage)
{
m_state.data.fan_speed = fan_speed_percentage;
}

float GCodeAnalyzer::_get_fan_speed() const
{
return m_state.data.fan_speed;
}

void GCodeAnalyzer::_set_axis_position(EAxis axis, float position)
{
m_state.position[axis] = position;
Expand Down Expand Up @@ -780,7 +823,7 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type)

Vec3d start_position = _get_start_position() + extruder_offset;
Vec3d end_position = _get_end_position() + extruder_offset;
it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), _get_cp_color_id());
it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), _get_cp_color_id(), _get_fan_speed());
}

bool GCodeAnalyzer::_is_valid_extrusion_role(int value) const
Expand Down Expand Up @@ -817,6 +860,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
path.feedrate = data.feedrate;
path.extruder_id = data.extruder_id;
path.cp_color_id = data.cp_color_id;
path.fan_speed = data.fan_speed;

get_layer_at_z(preview_data.extrusion.layers, z).paths.push_back(path);
}
Expand All @@ -836,6 +880,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
GCodePreviewData::Range width_range;
GCodePreviewData::Range feedrate_range;
GCodePreviewData::Range volumetric_rate_range;
GCodePreviewData::Range fan_speed_range;

// to avoid to call the callback too often
unsigned int cancel_callback_threshold = (unsigned int)std::max((int)extrude_moves->second.size() / 25, 1);
Expand Down Expand Up @@ -870,6 +915,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
width_range.update_from(move.data.width);
feedrate_range.update_from(move.data.feedrate);
volumetric_rate_range.update_from(volumetric_rate);
fan_speed_range.update_from(move.data.fan_speed);
}
else
// append end vertex of the move to current polyline
Expand All @@ -888,6 +934,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
preview_data.ranges.width.update_from(width_range);
preview_data.ranges.feedrate.update_from(feedrate_range);
preview_data.ranges.volumetric_rate.update_from(volumetric_rate_range);
preview_data.ranges.fan_speed.update_from(fan_speed_range);

// we need to sort the layers by their z as they can be shuffled in case of sequential prints
std::sort(preview_data.extrusion.layers.begin(), preview_data.extrusion.layers.end(), [](const GCodePreviewData::Extrusion::Layer& l1, const GCodePreviewData::Extrusion::Layer& l2)->bool { return l1.z < l2.z; });
Expand Down
14 changes: 12 additions & 2 deletions src/libslic3r/GCode/Analyzer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ class GCodeAnalyzer
float height; // mm
float feedrate; // mm/s
unsigned int cp_color_id;
float fan_speed; // percentage

Metadata();
Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, unsigned int cp_color_id = 0);
Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, unsigned int cp_color_id = 0, float fan_speed = 0.0f);

bool operator != (const Metadata& other) const;
};
Expand All @@ -80,7 +81,7 @@ class GCodeAnalyzer
Vec3d end_position;
float delta_extruder;

GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, unsigned int cp_color_id = 0);
GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, unsigned int cp_color_id = 0, float fan_speed = 0);
GCodeMove(EType type, const Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder);
};

Expand Down Expand Up @@ -168,6 +169,12 @@ class GCodeAnalyzer
// Set extruder to relative mode
void _processM83(const GCodeReader::GCodeLine& line);

// Set fan speed
void _processM106(const GCodeReader::GCodeLine& line);

// Disable fan
void _processM107(const GCodeReader::GCodeLine& line);

// Set tool (MakerWare and Sailfish flavor)
void _processM108orM135(const GCodeReader::GCodeLine& line);

Expand Down Expand Up @@ -230,6 +237,9 @@ class GCodeAnalyzer
void _set_feedrate(float feedrate_mm_sec);
float _get_feedrate() const;

void _set_fan_speed(float fan_speed_percentage);
float _get_fan_speed() const;

void _set_axis_position(EAxis axis, float position);
float _get_axis_position(EAxis axis) const;

Expand Down
13 changes: 13 additions & 0 deletions src/libslic3r/GCode/PreviewData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ void GCodePreviewData::set_default()
::memcpy((void*)ranges.height.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
::memcpy((void*)ranges.width.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
::memcpy((void*)ranges.feedrate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
::memcpy((void*)ranges.fan_speed.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
::memcpy((void*)ranges.volumetric_rate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));

extrusion.set_default();
Expand Down Expand Up @@ -327,6 +328,11 @@ GCodePreviewData::Color GCodePreviewData::get_feedrate_color(float feedrate) con
return ranges.feedrate.get_color_at(feedrate);
}

GCodePreviewData::Color GCodePreviewData::get_fan_speed_color(float fan_speed) const
{
return ranges.fan_speed.get_color_at(fan_speed);
}

GCodePreviewData::Color GCodePreviewData::get_volumetric_rate_color(float rate) const
{
return ranges.volumetric_rate.get_color_at(rate);
Expand Down Expand Up @@ -404,6 +410,8 @@ std::string GCodePreviewData::get_legend_title() const
return L("Tool");
case Extrusion::ColorPrint:
return L("Color Print");
case Extrusion::FanSpeed:
return L("Fan Speed");
case Extrusion::Num_View_Types:
break; // just to supress warning about non-handled value
}
Expand Down Expand Up @@ -510,6 +518,11 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
}
break;
}
case Extrusion::FanSpeed:
{
Helper::FillListFromRange(items, ranges.fan_speed, 0, 1.0f);
break;
}
case Extrusion::Num_View_Types:
break; // just to supress warning about non-handled value
}
Expand Down
4 changes: 4 additions & 0 deletions src/libslic3r/GCode/PreviewData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class GCodePreviewData
Range feedrate;
// Color mapping by volumetric extrusion rate.
Range volumetric_rate;
// Color mapping by fan speed.
Range fan_speed;
};

struct LegendItem
Expand All @@ -77,6 +79,7 @@ class GCodePreviewData
VolumetricRate,
Tool,
ColorPrint,
FanSpeed,
Num_View_Types
};

Expand Down Expand Up @@ -206,6 +209,7 @@ class GCodePreviewData
Color get_height_color(float height) const;
Color get_width_color(float width) const;
Color get_feedrate_color(float feedrate) const;
Color get_fan_speed_color(float fan_speed) const;
Color get_volumetric_rate_color(float rate) const;

void set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha);
Expand Down
4 changes: 4 additions & 0 deletions src/slic3r/GUI/GLCanvas3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4924,6 +4924,8 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
return (float)path.extruder_id;
case GCodePreviewData::Extrusion::ColorPrint:
return (float)path.cp_color_id;
case GCodePreviewData::Extrusion::FanSpeed:
return path.fan_speed;
default:
return 0.0f;
}
Expand Down Expand Up @@ -4964,6 +4966,8 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat

return color;
}
case GCodePreviewData::Extrusion::FanSpeed:
return data.get_fan_speed_color(value);
default:
return GCodePreviewData::Color::Dummy;
}
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/GUI_Preview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view
m_choice_view_type->Append(_(L("Volumetric flow rate")));
m_choice_view_type->Append(_(L("Tool")));
m_choice_view_type->Append(_(L("Color Print")));
m_choice_view_type->Append(_(L("Fan Speed")));
m_choice_view_type->SetSelection(0);

m_label_show_features = new wxStaticText(this, wxID_ANY, _(L("Show")));
Expand Down

0 comments on commit 5ad6b79

Please sign in to comment.