Merge branch 'gcode_preview'

This commit is contained in:
bubnikv 2018-04-04 11:00:49 +02:00
commit 76360d698c
6 changed files with 127 additions and 42 deletions

View File

@ -69,6 +69,7 @@ sub new {
$choice_view_type->Append(L("Height")); $choice_view_type->Append(L("Height"));
$choice_view_type->Append(L("Width")); $choice_view_type->Append(L("Width"));
$choice_view_type->Append(L("Speed")); $choice_view_type->Append(L("Speed"));
$choice_view_type->Append(L("Volumetric flow rate"));
$choice_view_type->Append(L("Tool")); $choice_view_type->Append(L("Tool"));
$choice_view_type->SetSelection(0); $choice_view_type->SetSelection(0);

View File

@ -177,6 +177,16 @@ void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLi
_processG1(line); _processG1(line);
break; break;
} }
case 10: // Retract
{
_processG10(line);
break;
}
case 11: // Unretract
{
_processG11(line);
break;
}
case 22: // Firmware controlled Retract case 22: // Firmware controlled Retract
{ {
_processG22(line); _processG22(line);
@ -305,6 +315,18 @@ void GCodeAnalyzer::_processG1(const GCodeReader::GCodeLine& line)
_store_move(type); _store_move(type);
} }
void GCodeAnalyzer::_processG10(const GCodeReader::GCodeLine& line)
{
// stores retract move
_store_move(GCodeMove::Retract);
}
void GCodeAnalyzer::_processG11(const GCodeReader::GCodeLine& line)
{
// stores unretract move
_store_move(GCodeMove::Unretract);
}
void GCodeAnalyzer::_processG22(const GCodeReader::GCodeLine& line) void GCodeAnalyzer::_processG22(const GCodeReader::GCodeLine& line)
{ {
// stores retract move // stores retract move
@ -648,14 +670,16 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
float z = FLT_MAX; float z = FLT_MAX;
Polyline polyline; Polyline polyline;
Pointf3 position(FLT_MAX, FLT_MAX, FLT_MAX); Pointf3 position(FLT_MAX, FLT_MAX, FLT_MAX);
float volumetric_rate = FLT_MAX;
GCodePreviewData::Range height_range; GCodePreviewData::Range height_range;
GCodePreviewData::Range width_range; GCodePreviewData::Range width_range;
GCodePreviewData::Range feedrate_range; GCodePreviewData::Range feedrate_range;
GCodePreviewData::Range volumetric_rate_range;
// constructs the polylines while traversing the moves // constructs the polylines while traversing the moves
for (const GCodeMove& move : extrude_moves->second) for (const GCodeMove& move : extrude_moves->second)
{ {
if ((data != move.data) || (data.feedrate != move.data.feedrate) || (z != move.start_position.z) || (position != move.start_position)) if ((data != move.data) || (z != move.start_position.z) || (position != move.start_position) || (volumetric_rate != move.data.feedrate * (float)move.data.mm3_per_mm))
{ {
// store current polyline // store current polyline
polyline.remove_duplicate_points(); polyline.remove_duplicate_points();
@ -671,9 +695,11 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
// update current values // update current values
data = move.data; data = move.data;
z = move.start_position.z; z = move.start_position.z;
volumetric_rate = move.data.feedrate * (float)move.data.mm3_per_mm;
height_range.update_from(move.data.height); height_range.update_from(move.data.height);
width_range.update_from(move.data.width); width_range.update_from(move.data.width);
feedrate_range.update_from(move.data.feedrate); feedrate_range.update_from(move.data.feedrate);
volumetric_rate_range.update_from(volumetric_rate);
} }
else else
// append end vertex of the move to current polyline // append end vertex of the move to current polyline
@ -688,9 +714,10 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
Helper::store_polyline(polyline, data, z, preview_data); Helper::store_polyline(polyline, data, z, preview_data);
// updates preview ranges data // updates preview ranges data
preview_data.extrusion.ranges.height.set_from(height_range); preview_data.ranges.height.set_from(height_range);
preview_data.extrusion.ranges.width.set_from(width_range); preview_data.ranges.width.set_from(width_range);
preview_data.extrusion.ranges.feedrate.set_from(feedrate_range); preview_data.ranges.feedrate.set_from(feedrate_range);
preview_data.ranges.volumetric_rate.set_from(volumetric_rate_range);
} }
void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data) void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
@ -717,6 +744,10 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
float feedrate = FLT_MAX; float feedrate = FLT_MAX;
unsigned int extruder_id = -1; unsigned int extruder_id = -1;
GCodePreviewData::Range height_range;
GCodePreviewData::Range width_range;
GCodePreviewData::Range feedrate_range;
// constructs the polylines while traversing the moves // constructs the polylines while traversing the moves
for (const GCodeMove& move : travel_moves->second) for (const GCodeMove& move : travel_moves->second)
{ {
@ -745,11 +776,19 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
type = move_type; type = move_type;
feedrate = move.data.feedrate; feedrate = move.data.feedrate;
extruder_id = move.data.extruder_id; extruder_id = move.data.extruder_id;
height_range.update_from(move.data.height);
width_range.update_from(move.data.width);
feedrate_range.update_from(move.data.feedrate);
} }
// store last polyline // store last polyline
polyline.remove_duplicate_points(); polyline.remove_duplicate_points();
Helper::store_polyline(polyline, type, direction, feedrate, extruder_id, preview_data); Helper::store_polyline(polyline, type, direction, feedrate, extruder_id, preview_data);
// updates preview ranges data
preview_data.ranges.height.set_from(height_range);
preview_data.ranges.width.set_from(width_range);
preview_data.ranges.feedrate.set_from(feedrate_range);
} }
void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_data) void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_data)

View File

@ -127,6 +127,12 @@ private:
// Move // Move
void _processG1(const GCodeReader::GCodeLine& line); void _processG1(const GCodeReader::GCodeLine& line);
// Retract
void _processG10(const GCodeReader::GCodeLine& line);
// Unretract
void _processG11(const GCodeReader::GCodeLine& line);
// Firmware controlled Retract // Firmware controlled Retract
void _processG22(const GCodeReader::GCodeLine& line); void _processG22(const GCodeReader::GCodeLine& line);

View File

@ -85,6 +85,12 @@ void GCodePreviewData::Range::update_from(float value)
max = std::max(max, value); max = std::max(max, value);
} }
void GCodePreviewData::Range::update_from(const Range& other)
{
min = std::min(min, other.min);
max = std::max(max, other.max);
}
void GCodePreviewData::Range::set_from(const Range& other) void GCodePreviewData::Range::set_from(const Range& other)
{ {
min = other.min; min = other.min;
@ -158,9 +164,6 @@ void GCodePreviewData::Extrusion::set_default()
view_type = Default_View_Type; view_type = Default_View_Type;
::memcpy((void*)role_colors, (const void*)Default_Extrusion_Role_Colors, Num_Extrusion_Roles * sizeof(Color)); ::memcpy((void*)role_colors, (const void*)Default_Extrusion_Role_Colors, Num_Extrusion_Roles * sizeof(Color));
::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));
for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i) for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
{ {
@ -198,6 +201,7 @@ void GCodePreviewData::Travel::set_default()
width = Default_Width; width = Default_Width;
height = Default_Height; height = Default_Height;
::memcpy((void*)type_colors, (const void*)Default_Type_Colors, Num_Types * sizeof(Color)); ::memcpy((void*)type_colors, (const void*)Default_Type_Colors, Num_Types * sizeof(Color));
is_visible = false; is_visible = false;
} }
@ -228,6 +232,11 @@ GCodePreviewData::GCodePreviewData()
void GCodePreviewData::set_default() 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.volumetric_rate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
extrusion.set_default(); extrusion.set_default();
travel.set_default(); travel.set_default();
retraction.set_default(); retraction.set_default();
@ -237,6 +246,10 @@ void GCodePreviewData::set_default()
void GCodePreviewData::reset() void GCodePreviewData::reset()
{ {
ranges.width.reset();
ranges.height.reset();
ranges.feedrate.reset();
ranges.volumetric_rate.reset();
extrusion.layers.clear(); extrusion.layers.clear();
travel.polylines.clear(); travel.polylines.clear();
retraction.positions.clear(); retraction.positions.clear();
@ -253,19 +266,24 @@ const GCodePreviewData::Color& GCodePreviewData::get_extrusion_role_color(Extrus
return extrusion.role_colors[role]; return extrusion.role_colors[role];
} }
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_height_color(float height) const const GCodePreviewData::Color& GCodePreviewData::get_height_color(float height) const
{ {
return extrusion.ranges.height.get_color_at(height); return ranges.height.get_color_at(height);
} }
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_width_color(float width) const const GCodePreviewData::Color& GCodePreviewData::get_width_color(float width) const
{ {
return extrusion.ranges.width.get_color_at(width); return ranges.width.get_color_at(width);
} }
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_feedrate_color(float feedrate) const const GCodePreviewData::Color& GCodePreviewData::get_feedrate_color(float feedrate) const
{ {
return extrusion.ranges.feedrate.get_color_at(feedrate); return ranges.feedrate.get_color_at(feedrate);
}
const GCodePreviewData::Color& GCodePreviewData::get_volumetric_rate_color(float rate) const
{
return ranges.volumetric_rate.get_color_at(rate);
} }
void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha) void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha)
@ -334,6 +352,8 @@ std::string GCodePreviewData::get_legend_title() const
return L("Width (mm)"); return L("Width (mm)");
case Extrusion::Feedrate: case Extrusion::Feedrate:
return L("Speed (mm/s)"); return L("Speed (mm/s)");
case Extrusion::VolumetricRate:
return L("Volumetric flow rate (mm3/s)");
case Extrusion::Tool: case Extrusion::Tool:
return L("Tool"); return L("Tool");
} }
@ -348,10 +368,11 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
static void FillListFromRange(LegendItemsList& list, const Range& range, unsigned int decimals, float scale_factor) static void FillListFromRange(LegendItemsList& list, const Range& range, unsigned int decimals, float scale_factor)
{ {
list.reserve(Range::Colors_Count); list.reserve(Range::Colors_Count);
float step = range.step_size(); float step = range.step_size();
for (unsigned int i = 0; i < Range::Colors_Count; ++i) for (unsigned int i = 0; i < Range::Colors_Count; ++i)
{ {
char buf[32]; char buf[1024];
sprintf(buf, "%.*f/%.*f", decimals, scale_factor * (range.min + (float)i * step), decimals, scale_factor * (range.min + (float)(i + 1) * step)); sprintf(buf, "%.*f/%.*f", decimals, scale_factor * (range.min + (float)i * step), decimals, scale_factor * (range.min + (float)(i + 1) * step));
list.emplace_back(buf, range.colors[i]); list.emplace_back(buf, range.colors[i]);
} }
@ -377,17 +398,22 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
} }
case Extrusion::Height: case Extrusion::Height:
{ {
Helper::FillListFromRange(items, extrusion.ranges.height, 3, 1.0f); Helper::FillListFromRange(items, ranges.height, 3, 1.0f);
break; break;
} }
case Extrusion::Width: case Extrusion::Width:
{ {
Helper::FillListFromRange(items, extrusion.ranges.width, 3, 1.0f); Helper::FillListFromRange(items, ranges.width, 3, 1.0f);
break; break;
} }
case Extrusion::Feedrate: case Extrusion::Feedrate:
{ {
Helper::FillListFromRange(items, extrusion.ranges.feedrate, 0, 1.0f); Helper::FillListFromRange(items, ranges.feedrate, 0, 1.0f);
break;
}
case Extrusion::VolumetricRate:
{
Helper::FillListFromRange(items, ranges.volumetric_rate, 3, 1.0f);
break; break;
} }
case Extrusion::Tool: case Extrusion::Tool:

View File

@ -37,6 +37,7 @@ public:
void reset(); void reset();
bool empty() const; bool empty() const;
void update_from(float value); void update_from(float value);
void update_from(const Range& other);
void set_from(const Range& other); void set_from(const Range& other);
float step_size() const; float step_size() const;
@ -44,6 +45,14 @@ public:
const Color& get_color_at_max() const; const Color& get_color_at_max() const;
}; };
struct Ranges
{
Range height;
Range width;
Range feedrate;
Range volumetric_rate;
};
struct LegendItem struct LegendItem
{ {
std::string text; std::string text;
@ -62,6 +71,7 @@ public:
Height, Height,
Width, Width,
Feedrate, Feedrate,
VolumetricRate,
Tool, Tool,
Num_View_Types Num_View_Types
}; };
@ -71,13 +81,6 @@ public:
static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles]; static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles];
static const EViewType Default_View_Type; static const EViewType Default_View_Type;
struct Ranges
{
Range height;
Range width;
Range feedrate;
};
struct Layer struct Layer
{ {
float z; float z;
@ -91,7 +94,6 @@ public:
EViewType view_type; EViewType view_type;
Color role_colors[Num_Extrusion_Roles]; Color role_colors[Num_Extrusion_Roles];
std::string role_names[Num_Extrusion_Roles]; std::string role_names[Num_Extrusion_Roles];
Ranges ranges;
LayersList layers; LayersList layers;
unsigned int role_flags; unsigned int role_flags;
@ -178,6 +180,7 @@ public:
Retraction retraction; Retraction retraction;
Retraction unretraction; Retraction unretraction;
Shell shell; Shell shell;
Ranges ranges;
GCodePreviewData(); GCodePreviewData();
@ -186,9 +189,10 @@ public:
bool empty() const; bool empty() const;
const Color& get_extrusion_role_color(ExtrusionRole role) const; const Color& get_extrusion_role_color(ExtrusionRole role) const;
const Color& get_extrusion_height_color(float height) const; const Color& get_height_color(float height) const;
const Color& get_extrusion_width_color(float width) const; const Color& get_width_color(float width) const;
const Color& get_extrusion_feedrate_color(float feedrate) const; const Color& get_feedrate_color(float feedrate) const;
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); void set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha);
void set_extrusion_paths_colors(const std::vector<std::string>& colors); void set_extrusion_paths_colors(const std::vector<std::string>& colors);

View File

@ -642,20 +642,25 @@ void GLVolumeCollection::update_outside_state(const DynamicPrintConfig* config,
std::vector<double> GLVolumeCollection::get_current_print_zs() const std::vector<double> GLVolumeCollection::get_current_print_zs() const
{ {
// Collect layer top positions of all volumes.
std::vector<double> print_zs; std::vector<double> print_zs;
for (GLVolume *vol : this->volumes) for (GLVolume *vol : this->volumes)
{ append(print_zs, vol->print_zs);
for (coordf_t z : vol->print_zs)
{
double round_z = (double)round(z * 100000.0f) / 100000.0f;
if (std::find(print_zs.begin(), print_zs.end(), round_z) == print_zs.end())
print_zs.push_back(round_z);
}
}
std::sort(print_zs.begin(), print_zs.end()); std::sort(print_zs.begin(), print_zs.end());
// Replace intervals of layers with similar top positions with their average value.
int n = int(print_zs.size());
int k = 0;
for (int i = 0; i < n;) {
int j = i + 1;
coordf_t zmax = print_zs[i] + EPSILON;
for (; j < n && print_zs[j] <= zmax; ++ j) ;
print_zs[k ++] = (j > i + 1) ? (0.5 * (print_zs[i] + print_zs[j - 1])) : print_zs[i];
i = j;
}
if (k < n)
print_zs.erase(print_zs.begin() + k, print_zs.end());
return print_zs; return print_zs;
} }
@ -2039,6 +2044,8 @@ void _3DScene::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data,
return path.width; return path.width;
case GCodePreviewData::Extrusion::Feedrate: case GCodePreviewData::Extrusion::Feedrate:
return path.feedrate; return path.feedrate;
case GCodePreviewData::Extrusion::VolumetricRate:
return path.feedrate * (float)path.mm3_per_mm;
case GCodePreviewData::Extrusion::Tool: case GCodePreviewData::Extrusion::Tool:
return (float)path.extruder_id; return (float)path.extruder_id;
} }
@ -2053,11 +2060,13 @@ void _3DScene::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data,
case GCodePreviewData::Extrusion::FeatureType: case GCodePreviewData::Extrusion::FeatureType:
return data.get_extrusion_role_color((ExtrusionRole)(int)value); return data.get_extrusion_role_color((ExtrusionRole)(int)value);
case GCodePreviewData::Extrusion::Height: case GCodePreviewData::Extrusion::Height:
return data.get_extrusion_height_color(value); return data.get_height_color(value);
case GCodePreviewData::Extrusion::Width: case GCodePreviewData::Extrusion::Width:
return data.get_extrusion_width_color(value); return data.get_width_color(value);
case GCodePreviewData::Extrusion::Feedrate: case GCodePreviewData::Extrusion::Feedrate:
return data.get_extrusion_feedrate_color(value); return data.get_feedrate_color(value);
case GCodePreviewData::Extrusion::VolumetricRate:
return data.get_volumetric_rate_color(value);
case GCodePreviewData::Extrusion::Tool: case GCodePreviewData::Extrusion::Tool:
{ {
static GCodePreviewData::Color color; static GCodePreviewData::Color color;
@ -2337,7 +2346,7 @@ bool _3DScene::_travel_paths_by_feedrate(const GCodePreviewData& preview_data, G
// creates a new volume for each feedrate // creates a new volume for each feedrate
for (Feedrate& feedrate : feedrates) for (Feedrate& feedrate : feedrates)
{ {
GLVolume* volume = new GLVolume(preview_data.get_extrusion_feedrate_color(feedrate.value).rgba); GLVolume* volume = new GLVolume(preview_data.get_feedrate_color(feedrate.value).rgba);
if (volume == nullptr) if (volume == nullptr)
return false; return false;
else else