110 lines
2.8 KiB
C++
110 lines
2.8 KiB
C++
|
#include "GCodeReader.hpp"
|
||
|
#include <boost/algorithm/string/classification.hpp>
|
||
|
#include <boost/algorithm/string/split.hpp>
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
|
||
|
namespace Slic3r {
|
||
|
|
||
|
void
|
||
|
GCodeReader::apply_config(const PrintConfigBase &config)
|
||
|
{
|
||
|
this->_config.apply(config, true);
|
||
|
this->_extrusion_axis = this->_config.get_extrusion_axis()[0];
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GCodeReader::parse(const std::string &gcode, callback_t callback)
|
||
|
{
|
||
|
std::istringstream ss(gcode);
|
||
|
std::string line;
|
||
|
while (std::getline(ss, line))
|
||
|
this->parse_line(line, callback);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GCodeReader::parse_line(std::string line, callback_t callback)
|
||
|
{
|
||
|
GCodeLine gline(this);
|
||
|
gline.raw = line;
|
||
|
if (this->verbose)
|
||
|
std::cout << line << std::endl;
|
||
|
|
||
|
// strip comment
|
||
|
{
|
||
|
size_t pos = line.find(';');
|
||
|
if (pos != std::string::npos) {
|
||
|
gline.comment = line.substr(pos+1);
|
||
|
line.erase(pos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// command and args
|
||
|
{
|
||
|
std::vector<std::string> args;
|
||
|
boost::split(args, line, boost::is_any_of(" "));
|
||
|
|
||
|
// first one is cmd
|
||
|
gline.cmd = args.front();
|
||
|
args.erase(args.begin());
|
||
|
|
||
|
for (std::string &arg : args) {
|
||
|
if (arg.size() < 2) continue;
|
||
|
gline.args.insert(std::make_pair(arg[0], arg.substr(1)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// convert extrusion axis
|
||
|
if (this->_extrusion_axis != 'E') {
|
||
|
const auto it = gline.args.find(this->_extrusion_axis);
|
||
|
if (it != gline.args.end()) {
|
||
|
std::swap(gline.args['E'], it->second);
|
||
|
gline.args.erase(it);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (gline.has('E') && this->_config.use_relative_e_distances)
|
||
|
this->E = 0;
|
||
|
|
||
|
if (callback) callback(*this, gline);
|
||
|
|
||
|
// update coordinates
|
||
|
if (gline.cmd == "G0" || gline.cmd == "G1" || gline.cmd == "G92") {
|
||
|
this->X = gline.new_X();
|
||
|
this->Y = gline.new_Y();
|
||
|
this->Z = gline.new_Z();
|
||
|
this->E = gline.new_E();
|
||
|
this->F = gline.new_F();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GCodeReader::parse_file(const std::string &file, callback_t callback)
|
||
|
{
|
||
|
std::ifstream f(file);
|
||
|
std::string line;
|
||
|
while (std::getline(f, line))
|
||
|
this->parse_line(line, callback);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GCodeReader::GCodeLine::set(char arg, std::string value)
|
||
|
{
|
||
|
const std::string space(" ");
|
||
|
if (this->has(arg)) {
|
||
|
size_t pos = this->raw.find(space + arg)+2;
|
||
|
size_t end = this->raw.find(' ', pos+1);
|
||
|
this->raw = this->raw.replace(pos, end-pos, value);
|
||
|
} else {
|
||
|
size_t pos = this->raw.find(' ');
|
||
|
if (pos == std::string::npos) {
|
||
|
this->raw += space + arg + value;
|
||
|
} else {
|
||
|
this->raw = this->raw.replace(pos, 0, space + arg + value);
|
||
|
}
|
||
|
}
|
||
|
this->args[arg] = value;
|
||
|
}
|
||
|
|
||
|
}
|