Merge with master

This commit is contained in:
Lukas Matena 2018-02-21 13:22:51 +01:00
commit de92f45eaf
125 changed files with 38665 additions and 4069 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,152 +1,227 @@
#ifndef slic3r_GCode_PressureEqualizer_hpp_
#define slic3r_GCode_PressureEqualizer_hpp_
#ifndef slic3r_GCode_Analyzer_hpp_
#define slic3r_GCode_Analyzer_hpp_
#include "../libslic3r.h"
#include "../PrintConfig.hpp"
#include "../ExtrusionEntity.hpp"
#include "Point.hpp"
#include "GCodeReader.hpp"
namespace Slic3r {
enum GCodeMoveType
{
GCODE_MOVE_TYPE_NOOP,
GCODE_MOVE_TYPE_RETRACT,
GCODE_MOVE_TYPE_UNRETRACT,
GCODE_MOVE_TYPE_TOOL_CHANGE,
GCODE_MOVE_TYPE_MOVE,
GCODE_MOVE_TYPE_EXTRUDE,
};
class GCodePreviewData;
// For visualization purposes, for the purposes of the G-code analysis and timing.
// The size of this structure is 56B.
// Keep the size of this structure as small as possible, because all moves of a complete print
// may be held in RAM.
struct GCodeMove
{
bool moving_xy(const float* pos_start) const { return fabs(pos_end[0] - pos_start[0]) > 0.f || fabs(pos_end[1] - pos_start[1]) > 0.f; }
bool moving_xy() const { return moving_xy(get_pos_start()); }
bool moving_z (const float* pos_start) const { return fabs(pos_end[2] - pos_start[2]) > 0.f; }
bool moving_z () const { return moving_z(get_pos_start()); }
bool extruding(const float* pos_start) const { return moving_xy() && pos_end[3] > pos_start[3]; }
bool extruding() const { return extruding(get_pos_start()); }
bool retracting(const float* pos_start) const { return pos_end[3] < pos_start[3]; }
bool retracting() const { return retracting(get_pos_start()); }
bool deretracting(const float* pos_start) const { return ! moving_xy() && pos_end[3] > pos_start[3]; }
bool deretracting() const { return deretracting(get_pos_start()); }
float dist_xy2(const float* pos_start) const { return (pos_end[0] - pos_start[0]) * (pos_end[0] - pos_start[0]) + (pos_end[1] - pos_start[1]) * (pos_end[1] - pos_start[1]); }
float dist_xy2() const { return dist_xy2(get_pos_start()); }
float dist_xyz2(const float* pos_start) const { return (pos_end[0] - pos_start[0]) * (pos_end[0] - pos_start[0]) + (pos_end[1] - pos_start[1]) * (pos_end[1] - pos_start[1]) + (pos_end[2] - pos_start[2]) * (pos_end[2] - pos_start[2]); }
float dist_xyz2() const { return dist_xyz2(get_pos_start()); }
float dist_xy(const float* pos_start) const { return sqrt(dist_xy2(pos_start)); }
float dist_xy() const { return dist_xy(get_pos_start()); }
float dist_xyz(const float* pos_start) const { return sqrt(dist_xyz2(pos_start)); }
float dist_xyz() const { return dist_xyz(get_pos_start()); }
float dist_e(const float* pos_start) const { return fabs(pos_end[3] - pos_start[3]); }
float dist_e() const { return dist_e(get_pos_start()); }
float feedrate() const { return pos_end[4]; }
float time(const float* pos_start) const { return dist_xyz(pos_start) / feedrate(); }
float time() const { return time(get_pos_start()); }
float time_inv(const float* pos_start) const { return feedrate() / dist_xyz(pos_start); }
float time_inv() const { return time_inv(get_pos_start()); }
const float* get_pos_start() const { assert(type != GCODE_MOVE_TYPE_NOOP); return this[-1].pos_end; }
// Pack the enums to conserve space. With C++x11 the allocation size could be declared for enums, but for old C++ this is the only portable way.
// GCodeLineType
uint8_t type;
// Index of the active extruder.
uint8_t extruder_id;
// ExtrusionRole
uint8_t extrusion_role;
// For example, is it a bridge flow? Is the fan on?
uint8_t flags;
// X,Y,Z,E,F. Storing the state of the currently active extruder only.
float pos_end[5];
// Extrusion width, height for this segment in um.
uint16_t extrusion_width;
uint16_t extrusion_height;
};
typedef std::vector<GCodeMove> GCodeMoves;
struct GCodeLayer
{
// Index of an object printed.
size_t object_idx;
// Index of an object instance printed.
size_t object_instance_idx;
// Index of the layer printed.
size_t layer_idx;
// Top z coordinate of the layer printed.
float layer_z_top;
// Moves over this layer. The 0th move is always of type GCODELINETYPE_NOOP and
// it sets the initial position and tool for the layer.
GCodeMoves moves;
// Indices into m_moves, where the tool changes happen.
// This is useful, if one wants to display just only a piece of the path quickly.
std::vector<size_t> tool_changes;
};
typedef std::vector<GCodeLayer*> GCodeLayerPtrs;
class GCodeMovesDB
{
public:
GCodeMovesDB() {};
~GCodeMovesDB() { reset(); }
void reset();
GCodeLayerPtrs m_layers;
};
// Processes a G-code to extract moves and their types.
// This information is then used to render the print simulation colored by the extrusion type
// or various speeds.
// The GCodeAnalyzer is employed as a G-Code filter. It reads the G-code as it is generated,
// parses the comments generated by Slic3r just for the analyzer, and removes these comments.
class GCodeAnalyzer
{
public:
GCodeAnalyzer(const Slic3r::GCodeConfig *config);
~GCodeAnalyzer();
static const std::string Extrusion_Role_Tag;
static const std::string Mm3_Per_Mm_Tag;
static const std::string Width_Tag;
static const std::string Height_Tag;
void reset();
static const double Default_mm3_per_mm;
static const float Default_Width;
static const float Default_Height;
// Process a next batch of G-code lines. Flush the internal buffers if asked for.
const char* process(const char *szGCode, bool flush);
// Length of the buffer returned by process().
size_t get_output_buffer_length() const { return output_buffer_length; }
enum EUnits : unsigned char
{
Millimeters,
Inches
};
enum EAxis : unsigned char
{
X,
Y,
Z,
E,
Num_Axis
};
enum EPositioningType : unsigned char
{
Absolute,
Relative
};
struct Metadata
{
ExtrusionRole extrusion_role;
unsigned int extruder_id;
double mm3_per_mm;
float width; // mm
float height; // mm
float feedrate; // mm/s
Metadata();
Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate);
bool operator != (const Metadata& other) const;
};
struct GCodeMove
{
enum EType : unsigned char
{
Noop,
Retract,
Unretract,
Tool_change,
Move,
Extrude,
Num_Types
};
EType type;
Metadata data;
Pointf3 start_position;
Pointf3 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 Pointf3& start_position, const Pointf3& end_position, float delta_extruder);
GCodeMove(EType type, const Metadata& data, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder);
};
typedef std::vector<GCodeMove> GCodeMovesList;
typedef std::map<GCodeMove::EType, GCodeMovesList> TypeToMovesMap;
private:
// Keeps the reference, does not own the config.
const Slic3r::GCodeConfig *m_config;
struct State
{
EUnits units;
EPositioningType positioning_xyz_type;
EPositioningType positioning_e_type;
Metadata data;
Pointf3 start_position;
float start_extrusion;
float position[Num_Axis];
};
// Internal data.
// X,Y,Z,E,F
float m_current_pos[5];
size_t m_current_extruder;
ExtrusionRole m_current_extrusion_role;
uint16_t m_current_extrusion_width;
uint16_t m_current_extrusion_height;
bool m_retracted;
private:
State m_state;
GCodeReader m_parser;
TypeToMovesMap m_moves_map;
GCodeMovesDB *m_moves;
// The output of process_layer()
std::string m_process_output;
// Output buffer will only grow. It will not be reallocated over and over.
std::vector<char> output_buffer;
size_t output_buffer_length;
public:
GCodeAnalyzer();
bool process_line(const char *line, const size_t len);
// Reinitialize the analyzer
void reset();
// Push the text to the end of the output_buffer.
void push_to_output(const char *text, const size_t len, bool add_eol = true);
// Adds the gcode contained in the given string to the analysis and returns it after removing the workcodes
const std::string& process_gcode(const std::string& gcode);
// Calculates all data needed for gcode visualization
void calc_gcode_preview_data(GCodePreviewData& preview_data);
static bool is_valid_extrusion_role(ExtrusionRole role);
private:
// Processes the given gcode line
void _process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line);
// Move
void _processG1(const GCodeReader::GCodeLine& line);
// Firmware controlled Retract
void _processG22(const GCodeReader::GCodeLine& line);
// Firmware controlled Unretract
void _processG23(const GCodeReader::GCodeLine& line);
// Set to Absolute Positioning
void _processG90(const GCodeReader::GCodeLine& line);
// Set to Relative Positioning
void _processG91(const GCodeReader::GCodeLine& line);
// Set Position
void _processG92(const GCodeReader::GCodeLine& line);
// Set extruder to absolute mode
void _processM82(const GCodeReader::GCodeLine& line);
// Set extruder to relative mode
void _processM83(const GCodeReader::GCodeLine& line);
// Processes T line (Select Tool)
void _processT(const GCodeReader::GCodeLine& line);
// Processes the tags
// Returns true if any tag has been processed
bool _process_tags(const GCodeReader::GCodeLine& line);
// Processes extrusion role tag
void _process_extrusion_role_tag(const std::string& comment, size_t pos);
// Processes mm3_per_mm tag
void _process_mm3_per_mm_tag(const std::string& comment, size_t pos);
// Processes width tag
void _process_width_tag(const std::string& comment, size_t pos);
// Processes height tag
void _process_height_tag(const std::string& comment, size_t pos);
void _set_units(EUnits units);
EUnits _get_units() const;
void _set_positioning_xyz_type(EPositioningType type);
EPositioningType _get_positioning_xyz_type() const;
void _set_positioning_e_type(EPositioningType type);
EPositioningType _get_positioning_e_type() const;
void _set_extrusion_role(ExtrusionRole extrusion_role);
ExtrusionRole _get_extrusion_role() const;
void _set_extruder_id(unsigned int id);
unsigned int _get_extruder_id() const;
void _set_mm3_per_mm(double value);
double _get_mm3_per_mm() const;
void _set_width(float width);
float _get_width() const;
void _set_height(float height);
float _get_height() const;
void _set_feedrate(float feedrate_mm_sec);
float _get_feedrate() const;
void _set_axis_position(EAxis axis, float position);
float _get_axis_position(EAxis axis) const;
// Sets axes position to zero
void _reset_axes_position();
void _set_start_position(const Pointf3& position);
const Pointf3& _get_start_position() const;
void _set_start_extrusion(float extrusion);
float _get_start_extrusion() const;
float _get_delta_extrusion() const;
// Returns current xyz position (from m_state.position[])
Pointf3 _get_end_position() const;
// Adds a new move with the given data
void _store_move(GCodeMove::EType type);
// Checks if the given int is a valid extrusion role (contained into enum ExtrusionRole)
bool _is_valid_extrusion_role(int value) const;
void _calc_gcode_preview_extrusion_layers(GCodePreviewData& preview_data);
void _calc_gcode_preview_travel(GCodePreviewData& preview_data);
void _calc_gcode_preview_retractions(GCodePreviewData& preview_data);
void _calc_gcode_preview_unretractions(GCodePreviewData& preview_data);
};
} // namespace Slic3r
#endif /* slic3r_GCode_PressureEqualizer_hpp_ */
#endif /* slic3r_GCode_Analyzer_hpp_ */

View file

@ -0,0 +1,408 @@
#include "Analyzer.hpp"
#include "PreviewData.hpp"
#include <float.h>
namespace Slic3r {
const GCodePreviewData::Color GCodePreviewData::Color::Dummy(0.0f, 0.0f, 0.0f, 0.0f);
GCodePreviewData::Color::Color()
{
rgba[0] = 1.0f;
rgba[1] = 1.0f;
rgba[2] = 1.0f;
rgba[3] = 1.0f;
}
GCodePreviewData::Color::Color(float r, float g, float b, float a)
{
rgba[0] = r;
rgba[1] = g;
rgba[2] = b;
rgba[3] = a;
}
std::vector<unsigned char> GCodePreviewData::Color::as_bytes() const
{
std::vector<unsigned char> ret;
for (unsigned int i = 0; i < 4; ++i)
{
ret.push_back((unsigned char)(255.0f * rgba[i]));
}
return ret;
}
GCodePreviewData::Extrusion::Layer::Layer(float z, const ExtrusionPaths& paths)
: z(z)
, paths(paths)
{
}
GCodePreviewData::Travel::Polyline::Polyline(EType type, EDirection direction, float feedrate, unsigned int extruder_id, const Polyline3& polyline)
: type(type)
, direction(direction)
, feedrate(feedrate)
, extruder_id(extruder_id)
, polyline(polyline)
{
}
const GCodePreviewData::Color GCodePreviewData::Range::Default_Colors[Colors_Count] =
{
Color(0.043f, 0.173f, 0.478f, 1.0f),
Color(0.075f, 0.349f, 0.522f, 1.0f),
Color(0.110f, 0.533f, 0.569f, 1.0f),
Color(0.016f, 0.839f, 0.059f, 1.0f),
Color(0.667f, 0.949f, 0.000f, 1.0f),
Color(0.988f, 0.975f, 0.012f, 1.0f),
Color(0.961f, 0.808f, 0.039f, 1.0f),
Color(0.890f, 0.533f, 0.125f, 1.0f),
Color(0.820f, 0.408f, 0.188f, 1.0f),
Color(0.761f, 0.322f, 0.235f, 1.0f)
};
GCodePreviewData::Range::Range()
{
reset();
}
void GCodePreviewData::Range::reset()
{
min = FLT_MAX;
max = -FLT_MAX;
}
bool GCodePreviewData::Range::empty() const
{
return min == max;
}
void GCodePreviewData::Range::update_from(float value)
{
min = std::min(min, value);
max = std::max(max, value);
}
void GCodePreviewData::Range::set_from(const Range& other)
{
min = other.min;
max = other.max;
}
float GCodePreviewData::Range::step_size() const
{
return (max - min) / (float)Colors_Count;
}
const GCodePreviewData::Color& GCodePreviewData::Range::get_color_at_max() const
{
return colors[Colors_Count - 1];
}
const GCodePreviewData::Color& GCodePreviewData::Range::get_color_at(float value) const
{
return empty() ? get_color_at_max() : colors[clamp((unsigned int)0, Colors_Count - 1, (unsigned int)((value - min) / step_size()))];
}
GCodePreviewData::LegendItem::LegendItem(const std::string& text, const GCodePreviewData::Color& color)
: text(text)
, color(color)
{
}
const GCodePreviewData::Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[Num_Extrusion_Roles] =
{
Color(0.0f, 0.0f, 0.0f, 1.0f), // erNone
Color(1.0f, 0.0f, 0.0f, 1.0f), // erPerimeter
Color(0.0f, 1.0f, 0.0f, 1.0f), // erExternalPerimeter
Color(0.0f, 0.0f, 1.0f, 1.0f), // erOverhangPerimeter
Color(1.0f, 1.0f, 0.0f, 1.0f), // erInternalInfill
Color(1.0f, 0.0f, 1.0f, 1.0f), // erSolidInfill
Color(0.0f, 1.0f, 1.0f, 1.0f), // erTopSolidInfill
Color(0.5f, 0.5f, 0.5f, 1.0f), // erBridgeInfill
Color(1.0f, 1.0f, 1.0f, 1.0f), // erGapFill
Color(0.5f, 0.0f, 0.0f, 1.0f), // erSkirt
Color(0.0f, 0.5f, 0.0f, 1.0f), // erSupportMaterial
Color(0.0f, 0.0f, 0.5f, 1.0f), // erSupportMaterialInterface
Color(0.7f, 0.89f, 0.67f, 1.0f), // erWipeTower
Color(0.0f, 0.0f, 0.0f, 1.0f) // erMixed
};
// todo: merge with Slic3r::ExtrusionRole2String() from GCode.cpp
const std::string GCodePreviewData::Extrusion::Default_Extrusion_Role_Names[Num_Extrusion_Roles]
{
"None",
"Perimeter",
"External perimeter",
"Overhang perimeter",
"Internal infill",
"Solid infill",
"Top solid infill",
"Bridge infill",
"Gap fill",
"Skirt",
"Support material",
"Support material interface",
"Wipe tower",
"Mixed"
};
const GCodePreviewData::Extrusion::EViewType GCodePreviewData::Extrusion::Default_View_Type = GCodePreviewData::Extrusion::FeatureType;
void GCodePreviewData::Extrusion::set_default()
{
view_type = Default_View_Type;
::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)
{
role_names[i] = Default_Extrusion_Role_Names[i];
}
role_flags = 0;
for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
{
role_flags |= 1 << i;
}
}
bool GCodePreviewData::Extrusion::is_role_flag_set(ExtrusionRole role) const
{
return is_role_flag_set(role_flags, role);
}
bool GCodePreviewData::Extrusion::is_role_flag_set(unsigned int flags, ExtrusionRole role)
{
return GCodeAnalyzer::is_valid_extrusion_role(role) && (flags & (1 << (role - erPerimeter))) != 0;
}
const float GCodePreviewData::Travel::Default_Width = 0.075f;
const float GCodePreviewData::Travel::Default_Height = 0.075f;
const GCodePreviewData::Color GCodePreviewData::Travel::Default_Type_Colors[Num_Types] =
{
Color(0.0f, 0.0f, 0.75f, 1.0f), // Move
Color(0.0f, 0.75f, 0.0f, 1.0f), // Extrude
Color(0.75f, 0.0f, 0.0f, 1.0f), // Retract
};
void GCodePreviewData::Travel::set_default()
{
width = Default_Width;
height = Default_Height;
::memcpy((void*)type_colors, (const void*)Default_Type_Colors, Num_Types * sizeof(Color));
is_visible = false;
}
const GCodePreviewData::Color GCodePreviewData::Retraction::Default_Color = GCodePreviewData::Color(1.0f, 1.0f, 1.0f, 1.0f);
GCodePreviewData::Retraction::Position::Position(const Point3& position, float width, float height)
: position(position)
, width(width)
, height(height)
{
}
void GCodePreviewData::Retraction::set_default()
{
color = Default_Color;
is_visible = false;
}
void GCodePreviewData::Shell::set_default()
{
is_visible = false;
}
GCodePreviewData::GCodePreviewData()
{
set_default();
}
void GCodePreviewData::set_default()
{
extrusion.set_default();
travel.set_default();
retraction.set_default();
unretraction.set_default();
shell.set_default();
}
void GCodePreviewData::reset()
{
extrusion.layers.clear();
travel.polylines.clear();
retraction.positions.clear();
unretraction.positions.clear();
}
bool GCodePreviewData::empty() const
{
return extrusion.layers.empty() && travel.polylines.empty() && retraction.positions.empty() && unretraction.positions.empty();
}
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_role_color(ExtrusionRole role) const
{
return extrusion.role_colors[role];
}
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_height_color(float height) const
{
return extrusion.ranges.height.get_color_at(height);
}
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_width_color(float width) const
{
return extrusion.ranges.width.get_color_at(width);
}
const GCodePreviewData::Color& GCodePreviewData::get_extrusion_feedrate_color(float feedrate) const
{
return extrusion.ranges.feedrate.get_color_at(feedrate);
}
void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha)
{
for (unsigned int i = 0; i < Extrusion::Num_Extrusion_Roles; ++i)
{
if (role_name == extrusion.role_names[i])
{
extrusion.role_colors[i] = Color(red, green, blue, alpha);
break;
}
}
}
void GCodePreviewData::set_extrusion_paths_colors(const std::vector<std::string>& colors)
{
unsigned int size = (unsigned int)colors.size();
if (size % 2 != 0)
return;
for (unsigned int i = 0; i < size; i += 2)
{
const std::string& color_str = colors[i + 1];
if (color_str.size() == 6)
{
bool valid = true;
for (int c = 0; c < 6; ++c)
{
if (::isxdigit(color_str[c]) == 0)
{
valid = false;
break;
}
}
if (valid)
{
unsigned int color;
std::stringstream ss;
ss << std::hex << color_str;
ss >> color;
float den = 1.0f / 255.0f;
float r = (float)((color & 0xFF0000) >> 16) * den;
float g = (float)((color & 0x00FF00) >> 8) * den;
float b = (float)(color & 0x0000FF) * den;
this->set_extrusion_role_color(colors[i], r, g, b, 1.0f);
}
}
}
}
std::string GCodePreviewData::get_legend_title() const
{
switch (extrusion.view_type)
{
case Extrusion::FeatureType:
return "Feature type";
case Extrusion::Height:
return "Height (mm)";
case Extrusion::Width:
return "Width (mm)";
case Extrusion::Feedrate:
return "Speed (mm/s)";
case Extrusion::Tool:
return "Tool";
}
return "";
}
GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector<float>& tool_colors) const
{
struct Helper
{
static void FillListFromRange(LegendItemsList& list, const Range& range, unsigned int decimals, float scale_factor)
{
list.reserve(Range::Colors_Count);
float step = range.step_size();
for (unsigned int i = 0; i < Range::Colors_Count; ++i)
{
char buf[32];
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]);
}
}
};
LegendItemsList items;
switch (extrusion.view_type)
{
case Extrusion::FeatureType:
{
items.reserve(erMixed - erPerimeter + 1);
for (unsigned int i = (unsigned int)erPerimeter; i < (unsigned int)erMixed; ++i)
{
items.emplace_back(extrusion.role_names[i], extrusion.role_colors[i]);
}
break;
}
case Extrusion::Height:
{
Helper::FillListFromRange(items, extrusion.ranges.height, 3, 1.0f);
break;
}
case Extrusion::Width:
{
Helper::FillListFromRange(items, extrusion.ranges.width, 3, 1.0f);
break;
}
case Extrusion::Feedrate:
{
Helper::FillListFromRange(items, extrusion.ranges.feedrate, 0, 1.0f);
break;
}
case Extrusion::Tool:
{
unsigned int tools_colors_count = tool_colors.size() / 4;
items.reserve(tools_colors_count);
for (unsigned int i = 0; i < tools_colors_count; ++i)
{
char buf[32];
sprintf(buf, "Extruder %d", i + 1);
GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + i * 4), 4 * sizeof(float));
items.emplace_back(buf, color);
}
break;
}
}
return items;
}
} // namespace Slic3r

View file

@ -0,0 +1,205 @@
#ifndef slic3r_GCode_PreviewData_hpp_
#define slic3r_GCode_PreviewData_hpp_
#include "../libslic3r.h"
#include "../ExtrusionEntity.hpp"
#include "Point.hpp"
namespace Slic3r {
class GCodePreviewData
{
public:
struct Color
{
float rgba[4];
Color();
Color(float r, float g, float b, float a);
std::vector<unsigned char> as_bytes() const;
static const Color Dummy;
};
struct Range
{
static const unsigned int Colors_Count = 10;
static const Color Default_Colors[Colors_Count];
Color colors[Colors_Count];
float min;
float max;
Range();
void reset();
bool empty() const;
void update_from(float value);
void set_from(const Range& other);
float step_size() const;
const Color& get_color_at(float value) const;
const Color& get_color_at_max() const;
};
struct LegendItem
{
std::string text;
Color color;
LegendItem(const std::string& text, const Color& color);
};
typedef std::vector<LegendItem> LegendItemsList;
struct Extrusion
{
enum EViewType : unsigned char
{
FeatureType,
Height,
Width,
Feedrate,
Tool,
Num_View_Types
};
static const unsigned int Num_Extrusion_Roles = (unsigned int)erMixed + 1;
static const Color Default_Extrusion_Role_Colors[Num_Extrusion_Roles];
static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles];
static const EViewType Default_View_Type;
struct Ranges
{
Range height;
Range width;
Range feedrate;
};
struct Layer
{
float z;
ExtrusionPaths paths;
Layer(float z, const ExtrusionPaths& paths);
};
typedef std::vector<Layer> LayersList;
EViewType view_type;
Color role_colors[Num_Extrusion_Roles];
std::string role_names[Num_Extrusion_Roles];
Ranges ranges;
LayersList layers;
unsigned int role_flags;
void set_default();
bool is_role_flag_set(ExtrusionRole role) const;
static bool is_role_flag_set(unsigned int flags, ExtrusionRole role);
};
struct Travel
{
enum EType : unsigned char
{
Move,
Extrude,
Retract,
Num_Types
};
static const float Default_Width;
static const float Default_Height;
static const Color Default_Type_Colors[Num_Types];
struct Polyline
{
enum EDirection
{
Vertical,
Generic,
Num_Directions
};
EType type;
EDirection direction;
float feedrate;
unsigned int extruder_id;
Polyline3 polyline;
Polyline(EType type, EDirection direction, float feedrate, unsigned int extruder_id, const Polyline3& polyline);
};
typedef std::vector<Polyline> PolylinesList;
PolylinesList polylines;
float width;
float height;
Color type_colors[Num_Types];
bool is_visible;
void set_default();
};
struct Retraction
{
static const Color Default_Color;
struct Position
{
Point3 position;
float width;
float height;
Position(const Point3& position, float width, float height);
};
typedef std::vector<Position> PositionsList;
PositionsList positions;
Color color;
bool is_visible;
void set_default();
};
struct Shell
{
bool is_visible;
void set_default();
};
Extrusion extrusion;
Travel travel;
Retraction retraction;
Retraction unretraction;
Shell shell;
GCodePreviewData();
void set_default();
void reset();
bool empty() const;
const Color& get_extrusion_role_color(ExtrusionRole role) const;
const Color& get_extrusion_height_color(float height) const;
const Color& get_extrusion_width_color(float width) const;
const Color& get_extrusion_feedrate_color(float feedrate) const;
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);
std::string get_legend_title() const;
LegendItemsList get_legend_items(const std::vector<float>& tool_colors) const;
};
GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2);
GCodePreviewData::Color operator * (float f, const GCodePreviewData::Color& color);
} // namespace Slic3r
#endif /* slic3r_GCode_PreviewData_hpp_ */

View file

@ -4,17 +4,7 @@
namespace Slic3r {
std::string
_format_z(float z)
{
std::ostringstream ss;
ss << std::fixed << std::setprecision(3)
<< z;
return ss.str();
}
std::string
SpiralVase::process_layer(const std::string &gcode)
std::string SpiralVase::process_layer(const std::string &gcode)
{
/* This post-processor relies on several assumptions:
- all layers are processed through it, including those that are not supposed
@ -27,7 +17,7 @@ SpiralVase::process_layer(const std::string &gcode)
// If we're not going to modify G-code, just feed it to the reader
// in order to update positions.
if (!this->enable) {
this->_reader.parse(gcode, {});
this->_reader.parse_buffer(gcode);
return gcode;
}
@ -38,16 +28,17 @@ SpiralVase::process_layer(const std::string &gcode)
bool set_z = false;
{
//FIXME Performance warning: This copies the GCodeConfig of the reader.
GCodeReader r = this->_reader; // clone
r.parse(gcode, [&total_layer_length, &layer_height, &z, &set_z]
(GCodeReader &, const GCodeReader::GCodeLine &line) {
if (line.cmd == "G1") {
if (line.extruding()) {
total_layer_length += line.dist_XY();
} else if (line.has('Z')) {
layer_height += line.dist_Z();
r.parse_buffer(gcode, [&total_layer_length, &layer_height, &z, &set_z]
(GCodeReader &reader, const GCodeReader::GCodeLine &line) {
if (line.cmd_is("G1")) {
if (line.extruding(reader)) {
total_layer_length += line.dist_XY(reader);
} else if (line.has(Z)) {
layer_height += line.dist_Z(reader);
if (!set_z) {
z = line.new_Z();
z = line.new_Z(reader);
set_z = true;
}
}
@ -59,23 +50,23 @@ SpiralVase::process_layer(const std::string &gcode)
z -= layer_height;
std::string new_gcode;
this->_reader.parse(gcode, [&new_gcode, &z, &layer_height, &total_layer_length]
(GCodeReader &, GCodeReader::GCodeLine line) {
if (line.cmd == "G1") {
if (line.has('Z')) {
this->_reader.parse_buffer(gcode, [&new_gcode, &z, &layer_height, &total_layer_length]
(GCodeReader &reader, GCodeReader::GCodeLine line) {
if (line.cmd_is("G1")) {
if (line.has_z()) {
// If this is the initial Z move of the layer, replace it with a
// (redundant) move to the last Z of previous layer.
line.set('Z', _format_z(z));
new_gcode += line.raw + '\n';
line.set(reader, Z, z);
new_gcode += line.raw() + '\n';
return;
} else {
float dist_XY = line.dist_XY();
float dist_XY = line.dist_XY(reader);
if (dist_XY > 0) {
// horizontal move
if (line.extruding()) {
if (line.extruding(reader)) {
z += dist_XY * layer_height / total_layer_length;
line.set('Z', _format_z(z));
new_gcode += line.raw + '\n';
line.set(reader, Z, z);
new_gcode += line.raw() + '\n';
}
return;
@ -87,7 +78,7 @@ SpiralVase::process_layer(const std::string &gcode)
}
}
}
new_gcode += line.raw + '\n';
new_gcode += line.raw() + '\n';
});
return new_gcode;

View file

@ -13,7 +13,7 @@ class SpiralVase {
SpiralVase(const PrintConfig &config)
: enable(false), _config(&config)
{
this->_reader.Z = this->_config->z_offset;
this->_reader.z() = this->_config->z_offset;
this->_reader.apply_config(*this->_config);
};
std::string process_layer(const std::string &gcode);

View file

@ -21,6 +21,8 @@ TODO LIST
#include <iostream>
#include <vector>
#include "Analyzer.hpp"
#if defined(__linux) || defined(__GNUC__ )
#include <strings.h>
#endif /* __linux */
@ -510,6 +512,11 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
.travel(cleaning_box.ld, 7200)
.set_extruder_trimpot(750); // Increase the extruder driver current to allow fast ramming.
// adds tag for analyzer
char buf[32];
sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
writer.append(buf);
if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
unsigned int tool = tools[idx_tool];
@ -658,6 +665,11 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
writer.set_initial_position(initial_position);
}
// adds tag for analyzer
char buf[32];
sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
writer.append(buf);
if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
// Increase the extruder driver current to allow fast ramming.
writer.set_extruder_trimpot(750);
@ -735,6 +747,11 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(Purpose purpose, b
else
writer.set_initial_position(initial_position);
// adds tag for analyzer
char buf[32];
sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
writer.append(buf);
if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.