diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index c8e259caa9..52b5e60f17 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -91,6 +91,8 @@ add_library(libslic3r STATIC GCode/ToolOrdering.hpp GCode/WipeTower.cpp GCode/WipeTower.hpp + GCode/GCodeProcessor.cpp + GCode/GCodeProcessor.hpp GCode.cpp GCode.hpp GCodeReader.cpp diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4cbab67a63..e09dc54fe8 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -760,6 +760,14 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ throw std::runtime_error(msg); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER + m_processor.apply_config(print->config()); + m_processor.reset(); + m_processor.process_file(path_tmp); +#endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GCodeTimeEstimator::PostProcessData normal_data = m_normal_time_estimator.get_post_process_data(); GCodeTimeEstimator::PostProcessData silent_data = m_silent_time_estimator.get_post_process_data(); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 0344924a13..8ddf2db61d 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -14,6 +14,11 @@ #include "GCode/SpiralVase.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER +#include "GCode/GCodeProcessor.hpp" +#endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GCodeTimeEstimator.hpp" #include "EdgeGrid.hpp" #include "GCode/Analyzer.hpp" @@ -383,6 +388,13 @@ private: // Analyzer GCodeAnalyzer m_analyzer; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER + // Processor + GCodeProcessor m_processor; +#endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Write a string into a file. void _write(FILE* file, const std::string& what) { this->_write(file, what.c_str()); } void _write(FILE* file, const char *what); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp new file mode 100644 index 0000000000..08066ee57e --- /dev/null +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -0,0 +1,177 @@ +#include "../libslic3r.h" +#include "GCodeProcessor.hpp" + +#if ENABLE_GCODE_VIEWER + +static const float INCHES_TO_MM = 25.4f; +static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; + +namespace Slic3r { + +void GCodeProcessor::apply_config(const PrintConfig& config) +{ + m_parser.apply_config(config); +} + +void GCodeProcessor::reset() +{ + m_units = EUnits::Millimeters; + m_global_positioning_type = EPositioningType::Absolute; + m_e_local_positioning_type = EPositioningType::Absolute; + + ::memset(m_start_position.data(), 0, sizeof(AxisCoords)); + ::memset(m_end_position.data(), 0, sizeof(AxisCoords)); + ::memset(m_origin.data(), 0, sizeof(AxisCoords)); + + m_feedrate = 0.0f; + + m_moves.clear(); +} + +void GCodeProcessor::process_file(const std::string& filename) +{ + MoveStep start_step {}; + m_moves.emplace_back(start_step); + m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); + int a = 0; +} + +void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) +{ +/* + std::cout << line.raw() << std::endl; +*/ + + // update start position + m_start_position = m_end_position; + + std::string cmd = line.cmd(); + std::string comment = line.comment(); + + if (cmd.length() > 1) + { + // process command lines + switch (::toupper(cmd[0])) + { + case 'G': + { + switch (::atoi(&cmd[1])) + { + // Move + case 1: { process_G1(line); } + default: { break; } + } + break; + } + case 'M': + { + switch (::atoi(&cmd[1])) + { + default: { break; } + } + break; + } + case 'T': + { + break; + } + default: { break; } + } + } + else if (comment.length() > 1) + { + // process tags embedded into comments + process_comment(line); + } +} + +void GCodeProcessor::process_comment(const GCodeReader::GCodeLine& line) +{ +} + +void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) +{ + auto axis_absolute_position = [this](Axis axis, const GCodeReader::GCodeLine& lineG1) + { + bool is_relative = (m_global_positioning_type == EPositioningType::Relative); + if (axis == E) + is_relative |= (m_e_local_positioning_type == EPositioningType::Relative); + + if (lineG1.has(Slic3r::Axis(axis))) + { + float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; + float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret; + } + else + return m_start_position[axis]; + }; + + // updates axes positions from line + for (unsigned char a = X; a <= E; ++a) + { + m_end_position[a] = axis_absolute_position((Axis)a, line); + } + + // updates feedrate from line, if present + if (line.has_f()) + m_feedrate = line.f() * MMMIN_TO_MMSEC; + + // calculates movement deltas + float max_abs_delta = 0.0f; + AxisCoords delta_pos; + for (unsigned char a = X; a <= E; ++a) + { + delta_pos[a] = m_end_position[a] - m_start_position[a]; + max_abs_delta = std::max(max_abs_delta, std::abs(delta_pos[a])); + } + + // no displacement, return + if (max_abs_delta == 0.0f) + return; // <<<<<<<<<<<<<<<<< is this correct for time estimate ? + + // detect move type + EMoveType move_type = EMoveType::Noop; + if (delta_pos[E] < 0.0f) + { + if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f) || (delta_pos[Z] != 0.0f)) + move_type = EMoveType::Travel; + else + move_type = EMoveType::Retract; + } + else if (delta_pos[E] > 0.0f) + { + if ((delta_pos[X] == 0.0f) && (delta_pos[Y] == 0.0f) && (delta_pos[Z] == 0.0f)) + move_type = EMoveType::Unretract; + else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f)) + move_type = EMoveType::Extrude; + } + else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f) || (delta_pos[Z] != 0.0f)) + move_type = EMoveType::Travel; + + + MoveStep move_step { m_end_position, m_feedrate, move_type }; + m_moves.emplace_back(move_step); + +/* + std::cout << "start: "; + for (unsigned char a = X; a <= E; ++a) + { + std::cout << m_start_position[a]; + if (a != E) + std::cout << ", "; + } + std::cout << " - end: "; + for (unsigned char a = X; a <= E; ++a) + { + std::cout << m_end_position[a]; + if (a != E) + std::cout << ", "; + } + std::cout << "\n"; +*/ +} + +} /* namespace Slic3r */ + +#endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp new file mode 100644 index 0000000000..0a3dae0327 --- /dev/null +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -0,0 +1,87 @@ +#ifndef slic3r_GCodeProcessor_hpp_ +#define slic3r_GCodeProcessor_hpp_ + +#if ENABLE_GCODE_VIEWER +#include "../GCodeReader.hpp" + +namespace Slic3r { + + class GCodeProcessor + { + using AxisCoords = std::array; + + enum class EUnits : unsigned char + { + Millimeters, + Inches + }; + + enum class EPositioningType : unsigned char + { + Absolute, + Relative + }; + + enum class EMoveType : unsigned char + { + Noop, + Retract, + Unretract, + Tool_change, + Travel, + Extrude, + Num_Types + }; + + struct MoveStep + { + AxisCoords position; // mm + float feedrate; // mm/s + EMoveType type; + }; + + using MoveStepsList = std::vector; + + GCodeReader m_parser; + + EUnits m_units; + EPositioningType m_global_positioning_type; + EPositioningType m_e_local_positioning_type; + + AxisCoords m_start_position; // mm + AxisCoords m_end_position; // mm + AxisCoords m_origin; // mm + + float m_feedrate; // mm/s + + MoveStepsList m_moves; + + + public: + GCodeProcessor() { reset(); } + + void apply_config(const PrintConfig& config); + + void reset(); + + // Process the gcode contained in the file with the given filename + // Return false if any error occourred + void process_file(const std::string& filename); + + private: + void process_gcode_line(const GCodeReader::GCodeLine& line); + + // Process tags embedded into comments + void process_comment(const GCodeReader::GCodeLine& line); + + // Move + void process_G1(const GCodeReader::GCodeLine& line); + }; + +} /* namespace Slic3r */ + +#endif // ENABLE_GCODE_VIEWER + +#endif /* slic3r_GCodeProcessor_hpp_ */ + + diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 0728dedc60..4983787861 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -63,4 +63,15 @@ #define ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK (1 && ENABLE_2_2_0_BETA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//================== +// 2.3.0.alpha1 techs +//================== +#define ENABLE_2_3_0_ALPHA1 1 + +// Enable G-Code viewer +#define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + #endif // _technologies_h_