OrcaSlicer/xs/src/libslic3r/GCodeReader.cpp
bubnikv 3731820c48 Optimization of the configuration layer:
The values of StaticPrintConfig derived objects were searched by a name
walking through a huge chained if.
Now they are being mapped with a std::map.
Also initialization of StaticPrintConfig classes from their ConfigOptionDef
defaults is done by maintaining a single global definition of each
StaticPrintConfig derived class, and a new instance is initialized
from this static copy.

Also the ConfigOption instances are casted using static_cast
wherever possible, and their types are verified by a virtual type() method.
This approach avoids insiginificant performance penalty of a dynamic_cast.

Also the compare and clone methods were added to ConfigOption,
and the cloning & compare work on binary values, not by serialization.
2017-10-17 16:01:18 +02:00

110 lines
2.9 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 GCodeConfig &config)
{
m_config = config;
m_extrusion_axis = m_config.get_extrusion_axis()[0];
}
void GCodeReader::apply_config(const DynamicPrintConfig &config)
{
m_config.apply(config, true);
m_extrusion_axis = m_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 (m_extrusion_axis != 'E') {
const auto it = gline.args.find(m_extrusion_axis);
if (it != gline.args.end()) {
std::swap(gline.args['E'], it->second);
gline.args.erase(it);
}
}
if (gline.has('E') && m_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;
}
}