mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 04:49:01 +08:00
GCodeViewer - Update gcode window for binary gcode files
This commit is contained in:
parent
e2472fc78c
commit
cad97bc9a2
@ -464,6 +464,9 @@ void GCodeProcessorResult::reset() {
|
|||||||
#else
|
#else
|
||||||
void GCodeProcessorResult::reset() {
|
void GCodeProcessorResult::reset() {
|
||||||
|
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
is_binary_file = false;
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
moves.clear();
|
moves.clear();
|
||||||
lines_ends.clear();
|
lines_ends.clear();
|
||||||
bed_shape = Pointfs();
|
bed_shape = Pointfs();
|
||||||
@ -564,6 +567,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
|||||||
|
|
||||||
#if ENABLE_BINARIZED_GCODE
|
#if ENABLE_BINARIZED_GCODE
|
||||||
m_binarizer.set_enabled(config.gcode_binary);
|
m_binarizer.set_enabled(config.gcode_binary);
|
||||||
|
m_result.is_binary_file = config.gcode_binary;
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
|
||||||
m_producer = EProducer::PrusaSlicer;
|
m_producer = EProducer::PrusaSlicer;
|
||||||
@ -1104,6 +1108,9 @@ void GCodeProcessor::process_ascii_file(const std::string& filename, std::functi
|
|||||||
|
|
||||||
// process gcode
|
// process gcode
|
||||||
m_result.filename = filename;
|
m_result.filename = filename;
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
m_result.is_binary_file = false;
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
m_result.id = ++s_result_id;
|
m_result.id = ++s_result_id;
|
||||||
initialize_result_moves();
|
initialize_result_moves();
|
||||||
size_t parse_line_callback_cntr = 10000;
|
size_t parse_line_callback_cntr = 10000;
|
||||||
@ -1122,6 +1129,16 @@ void GCodeProcessor::process_ascii_file(const std::string& filename, std::functi
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_BINARIZED_GCODE
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
static void update_out_file_pos(const std::string& out_string, std::vector<size_t>& lines_ends, size_t* out_file_pos)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < out_string.size(); ++i) {
|
||||||
|
if (out_string[i] == '\n')
|
||||||
|
lines_ends.emplace_back((out_file_pos != nullptr) ? *out_file_pos + i + 1 : i + 1);
|
||||||
|
}
|
||||||
|
if (out_file_pos != nullptr)
|
||||||
|
*out_file_pos += out_string.size();
|
||||||
|
}
|
||||||
|
|
||||||
void GCodeProcessor::process_binary_file(const std::string& filename, std::function<void()> cancel_callback)
|
void GCodeProcessor::process_binary_file(const std::string& filename, std::function<void()> cancel_callback)
|
||||||
{
|
{
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
@ -1272,6 +1289,7 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct
|
|||||||
apply_config(config);
|
apply_config(config);
|
||||||
|
|
||||||
m_result.filename = filename;
|
m_result.filename = filename;
|
||||||
|
m_result.is_binary_file = true;
|
||||||
m_result.id = ++s_result_id;
|
m_result.id = ++s_result_id;
|
||||||
initialize_result_moves();
|
initialize_result_moves();
|
||||||
|
|
||||||
@ -1287,7 +1305,8 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct
|
|||||||
if (res != EResult::Success)
|
if (res != EResult::Success)
|
||||||
throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(translate_result(res)) + "\n");
|
throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(translate_result(res)) + "\n");
|
||||||
|
|
||||||
// TODO: Update m_result.lines_ends
|
std::vector<size_t>& lines_ends = m_result.lines_ends.emplace_back(std::vector<size_t>());
|
||||||
|
update_out_file_pos(block.raw_data, lines_ends, nullptr);
|
||||||
|
|
||||||
m_parser.parse_buffer(block.raw_data, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) {
|
m_parser.parse_buffer(block.raw_data, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) {
|
||||||
this->process_gcode_line(line, true);
|
this->process_gcode_line(line, true);
|
||||||
@ -3971,23 +3990,14 @@ void GCodeProcessor::post_process()
|
|||||||
if (res != bgcode::core::EResult::Success)
|
if (res != bgcode::core::EResult::Success)
|
||||||
throw Slic3r::RuntimeError(std::string("Error while sending gcode to the binarizer.\n"));
|
throw Slic3r::RuntimeError(std::string("Error while sending gcode to the binarizer.\n"));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
|
||||||
write_to_file(out, out_string, result, out_path);
|
write_to_file(out, out_string, result, out_path);
|
||||||
#if ENABLE_BINARIZED_GCODE
|
update_out_file_pos(out_string, result.lines_ends.front(), &m_out_file_pos);
|
||||||
update_out_file_pos(out_string, result);
|
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_BINARIZED_GCODE
|
|
||||||
void update_out_file_pos(const std::string& out_string, GCodeProcessorResult& result) {
|
|
||||||
for (size_t i = 0; i < out_string.size(); ++i) {
|
|
||||||
if (out_string[i] == '\n')
|
|
||||||
result.lines_ends.emplace_back(m_out_file_pos + i + 1);
|
|
||||||
}
|
}
|
||||||
m_out_file_pos += out_string.size();
|
#else
|
||||||
}
|
write_to_file(out, out_string, result, out_path);
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
}
|
||||||
|
|
||||||
// flush the current content of the cache to file
|
// flush the current content of the cache to file
|
||||||
void flush(FilePtr& out, GCodeProcessorResult& result, const std::string& out_path) {
|
void flush(FilePtr& out, GCodeProcessorResult& result, const std::string& out_path) {
|
||||||
@ -4007,11 +4017,12 @@ void GCodeProcessor::post_process()
|
|||||||
if (m_binarizer.append_gcode(out_string) != bgcode::core::EResult::Success)
|
if (m_binarizer.append_gcode(out_string) != bgcode::core::EResult::Success)
|
||||||
throw Slic3r::RuntimeError(std::string("Error while sending gcode to the binarizer.\n"));
|
throw Slic3r::RuntimeError(std::string("Error while sending gcode to the binarizer.\n"));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
|
||||||
write_to_file(out, out_string, result, out_path);
|
write_to_file(out, out_string, result, out_path);
|
||||||
#if ENABLE_BINARIZED_GCODE
|
update_out_file_pos(out_string, result.lines_ends.front(), &m_out_file_pos);
|
||||||
update_out_file_pos(out_string, result);
|
}
|
||||||
|
#else
|
||||||
|
write_to_file(out, out_string, result, out_path);
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4312,6 +4323,9 @@ void GCodeProcessor::post_process()
|
|||||||
};
|
};
|
||||||
|
|
||||||
m_result.lines_ends.clear();
|
m_result.lines_ends.clear();
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
m_result.lines_ends.emplace_back(std::vector<size_t>());
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
|
||||||
unsigned int line_id = 0;
|
unsigned int line_id = 0;
|
||||||
// Backtrace data for Tx gcode lines
|
// Backtrace data for Tx gcode lines
|
||||||
|
@ -139,10 +139,17 @@ namespace Slic3r {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
bool is_binary_file;
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
std::vector<MoveVertex> moves;
|
std::vector<MoveVertex> moves;
|
||||||
// Positions of ends of lines of the final G-code this->filename after TimeProcessor::post_process() finalizes the G-code.
|
// Positions of ends of lines of the final G-code this->filename after TimeProcessor::post_process() finalizes the G-code.
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
std::vector<std::vector<size_t>> lines_ends;
|
||||||
|
#else
|
||||||
std::vector<size_t> lines_ends;
|
std::vector<size_t> lines_ends;
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
Pointfs bed_shape;
|
Pointfs bed_shape;
|
||||||
float max_print_height;
|
float max_print_height;
|
||||||
SettingsIds settings_ids;
|
SettingsIds settings_ids;
|
||||||
|
@ -195,11 +195,20 @@ bool GCodeReader::parse_file(const std::string &file, callback_t callback)
|
|||||||
return this->parse_file_internal(file, callback, [](size_t){});
|
return this->parse_file_internal(file, callback, [](size_t){});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
bool GCodeReader::parse_file(const std::string& file, callback_t callback, std::vector<std::vector<size_t>>& lines_ends)
|
||||||
|
{
|
||||||
|
lines_ends.clear();
|
||||||
|
lines_ends.push_back(std::vector<size_t>());
|
||||||
|
return this->parse_file_internal(file, callback, [&lines_ends](size_t file_pos) { lines_ends.front().emplace_back(file_pos); });
|
||||||
|
}
|
||||||
|
#else
|
||||||
bool GCodeReader::parse_file(const std::string &file, callback_t callback, std::vector<size_t> &lines_ends)
|
bool GCodeReader::parse_file(const std::string &file, callback_t callback, std::vector<size_t> &lines_ends)
|
||||||
{
|
{
|
||||||
lines_ends.clear();
|
lines_ends.clear();
|
||||||
return this->parse_file_internal(file, callback, [&lines_ends](size_t file_pos){ lines_ends.emplace_back(file_pos); });
|
return this->parse_file_internal(file, callback, [&lines_ends](size_t file_pos){ lines_ends.emplace_back(file_pos); });
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
|
||||||
bool GCodeReader::parse_file_raw(const std::string &filename, raw_line_callback_t line_callback)
|
bool GCodeReader::parse_file_raw(const std::string &filename, raw_line_callback_t line_callback)
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,11 @@ public:
|
|||||||
bool parse_file(const std::string &file, callback_t callback);
|
bool parse_file(const std::string &file, callback_t callback);
|
||||||
// Collect positions of line ends in the binary G-code to be used by the G-code viewer when memory mapping and displaying section of G-code
|
// Collect positions of line ends in the binary G-code to be used by the G-code viewer when memory mapping and displaying section of G-code
|
||||||
// as an overlay in the 3D scene.
|
// as an overlay in the 3D scene.
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
bool parse_file(const std::string& file, callback_t callback, std::vector<std::vector<size_t>>& lines_ends);
|
||||||
|
#else
|
||||||
bool parse_file(const std::string &file, callback_t callback, std::vector<size_t> &lines_ends);
|
bool parse_file(const std::string &file, callback_t callback, std::vector<size_t> &lines_ends);
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
// Just read the G-code file line by line, calls callback (const char *begin, const char *end). Returns false if reading the file failed.
|
// Just read the G-code file line by line, calls callback (const char *begin, const char *end). Returns false if reading the file failed.
|
||||||
bool parse_file_raw(const std::string &file, raw_line_callback_t callback);
|
bool parse_file_raw(const std::string &file, raw_line_callback_t callback);
|
||||||
|
|
||||||
|
@ -367,18 +367,22 @@ void GCodeViewer::SequentialView::Marker::render()
|
|||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const GCodeProcessorResult& gcode_result)
|
||||||
|
{
|
||||||
|
m_filename = gcode_result.filename;
|
||||||
|
m_is_binary_file = gcode_result.is_binary_file;
|
||||||
|
m_lines_ends = gcode_result.lines_ends;
|
||||||
|
}
|
||||||
|
#else
|
||||||
void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const std::string& filename, const std::vector<size_t>& lines_ends)
|
void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const std::string& filename, const std::vector<size_t>& lines_ends)
|
||||||
{
|
{
|
||||||
#if !ENABLE_BINARIZED_GCODE
|
assert(!m_file.is_open());
|
||||||
assert(! m_file.is_open());
|
|
||||||
if (m_file.is_open())
|
if (m_file.is_open())
|
||||||
return;
|
return;
|
||||||
#endif // !ENABLE_BINARIZED_GCODE
|
|
||||||
|
|
||||||
m_filename = filename;
|
m_filename = filename;
|
||||||
m_lines_ends = lines_ends;
|
m_lines_ends = lines_ends;
|
||||||
|
|
||||||
#if !ENABLE_BINARIZED_GCODE
|
|
||||||
m_selected_line_id = 0;
|
m_selected_line_id = 0;
|
||||||
m_last_lines_size = 0;
|
m_last_lines_size = 0;
|
||||||
|
|
||||||
@ -391,54 +395,150 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const std::string& fil
|
|||||||
BOOST_LOG_TRIVIAL(error) << "Unable to map file " << m_filename << ". Cannot show G-code window.";
|
BOOST_LOG_TRIVIAL(error) << "Unable to map file " << m_filename << ". Cannot show G-code window.";
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
#endif // !ENABLE_BINARIZED_GCODE
|
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
|
||||||
#if ENABLE_BINARIZED_GCODE
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
void GCodeViewer::SequentialView::GCodeWindow::add_gcode_line_to_lines_cache(const std::string& src)
|
||||||
|
{
|
||||||
|
std::string command;
|
||||||
|
std::string parameters;
|
||||||
|
std::string comment;
|
||||||
|
|
||||||
|
// extract comment
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
boost::split(tokens, src, boost::is_any_of(";"), boost::token_compress_on);
|
||||||
|
command = tokens.front();
|
||||||
|
if (tokens.size() > 1)
|
||||||
|
comment = ";" + tokens.back();
|
||||||
|
|
||||||
|
// extract gcode command and parameters
|
||||||
|
if (!command.empty()) {
|
||||||
|
boost::split(tokens, command, boost::is_any_of(" "), boost::token_compress_on);
|
||||||
|
command = tokens.front();
|
||||||
|
if (tokens.size() > 1) {
|
||||||
|
for (size_t i = 1; i < tokens.size(); ++i) {
|
||||||
|
parameters += " " + tokens[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lines_cache.push_back({ command, parameters, comment });
|
||||||
|
}
|
||||||
|
|
||||||
void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, size_t curr_line_id)
|
void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, size_t curr_line_id)
|
||||||
{
|
{
|
||||||
auto update_lines = [this]() {
|
auto update_lines_ascii = [this]() {
|
||||||
m_lines_cache.clear();
|
m_lines_cache.clear();
|
||||||
m_lines_cache.reserve(m_cache_range.size());
|
m_lines_cache.reserve(m_cache_range.size());
|
||||||
|
const std::vector<size_t>& lines_ends = m_lines_ends.front();
|
||||||
FILE* file = boost::nowide::fopen(m_filename.c_str(), "rb");
|
FILE* file = boost::nowide::fopen(m_filename.c_str(), "rb");
|
||||||
if (file != nullptr) {
|
if (file != nullptr) {
|
||||||
for (size_t id = *m_cache_range.start_id; id <= *m_cache_range.end_id; ++id) {
|
for (size_t id = *m_cache_range.min; id <= *m_cache_range.max; ++id) {
|
||||||
assert(id > 0);
|
assert(id > 0);
|
||||||
// read line from file
|
// read line from file
|
||||||
const size_t start = id == 1 ? 0 : m_lines_ends[id - 2];
|
const size_t begin = id == 1 ? 0 : lines_ends[id - 2];
|
||||||
const size_t len = m_lines_ends[id - 1] - start;
|
const size_t len = lines_ends[id - 1] - begin;
|
||||||
std::string gline(len, '\0');
|
std::string gline(len, '\0');
|
||||||
fseek(file, start, SEEK_SET);
|
fseek(file, begin, SEEK_SET);
|
||||||
const size_t rsize = fread((void*)gline.data(), 1, len, file);
|
const size_t rsize = fread((void*)gline.data(), 1, len, file);
|
||||||
if (ferror(file) || rsize != len) {
|
if (ferror(file) || rsize != len) {
|
||||||
m_lines_cache.clear();
|
m_lines_cache.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string command;
|
add_gcode_line_to_lines_cache(gline);
|
||||||
std::string parameters;
|
}
|
||||||
std::string comment;
|
fclose(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// extract comment
|
auto update_lines_binary = [this]() {
|
||||||
std::vector<std::string> tokens;
|
m_lines_cache.clear();
|
||||||
boost::split(tokens, gline, boost::is_any_of(";"), boost::token_compress_on);
|
m_lines_cache.reserve(m_cache_range.size());
|
||||||
command = tokens.front();
|
|
||||||
if (tokens.size() > 1)
|
|
||||||
comment = ";" + tokens.back();
|
|
||||||
|
|
||||||
// extract gcode command and parameters
|
size_t cumulative_lines_count = 0;
|
||||||
if (!command.empty()) {
|
std::vector<size_t> cumulative_lines_counts;
|
||||||
boost::split(tokens, command, boost::is_any_of(" "), boost::token_compress_on);
|
cumulative_lines_counts.reserve(m_lines_ends.size());
|
||||||
command = tokens.front();
|
for (size_t i = 0; i < m_lines_ends.size(); ++i) {
|
||||||
if (tokens.size() > 1) {
|
cumulative_lines_count += m_lines_ends[i].size();
|
||||||
for (size_t i = 1; i < tokens.size(); ++i) {
|
cumulative_lines_counts.emplace_back(cumulative_lines_count);
|
||||||
parameters += " " + tokens[i];
|
}
|
||||||
|
|
||||||
|
size_t first_block_id = 0;
|
||||||
|
for (size_t i = 0; i < cumulative_lines_counts.size(); ++i) {
|
||||||
|
if (*m_cache_range.min <= cumulative_lines_counts[i]) {
|
||||||
|
first_block_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t last_block_id = 0;
|
||||||
|
for (size_t i = 0; i < cumulative_lines_counts.size(); ++i) {
|
||||||
|
if (*m_cache_range.max <= cumulative_lines_counts[i]) {
|
||||||
|
last_block_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(last_block_id >= first_block_id);
|
||||||
|
|
||||||
|
FilePtr file(boost::nowide::fopen(m_filename.c_str(), "rb"));
|
||||||
|
if (file.f != nullptr) {
|
||||||
|
fseek(file.f, 0, SEEK_END);
|
||||||
|
const long file_size = ftell(file.f);
|
||||||
|
rewind(file.f);
|
||||||
|
|
||||||
|
// read file header
|
||||||
|
using namespace bgcode::core;
|
||||||
|
using namespace bgcode::binarize;
|
||||||
|
FileHeader file_header;
|
||||||
|
EResult res = read_header(*file.f, file_header, nullptr);
|
||||||
|
if (res == EResult::Success) {
|
||||||
|
// search first GCode block
|
||||||
|
BlockHeader block_header;
|
||||||
|
res = read_next_block_header(*file.f, file_header, block_header, EBlockType::GCode, nullptr, 0);
|
||||||
|
if (res == EResult::Success) {
|
||||||
|
for (size_t i = 0; i < first_block_id; ++i) {
|
||||||
|
skip_block(*file.f, file_header, block_header);
|
||||||
|
res = read_next_block_header(*file.f, file_header, block_header, nullptr, 0);
|
||||||
|
if (res != EResult::Success || block_header.type != (uint16_t)EBlockType::GCode) {
|
||||||
|
m_lines_cache.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = first_block_id; i <= last_block_id; ++i) {
|
||||||
|
GCodeBlock block;
|
||||||
|
res = block.read_data(*file.f, file_header, block_header);
|
||||||
|
if (res != EResult::Success) {
|
||||||
|
m_lines_cache.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t ref_id = (i == 0) ? 0 : i - 1;
|
||||||
|
const size_t first_line_id = (i == 0) ? *m_cache_range.min :
|
||||||
|
(*m_cache_range.min - 1 >= cumulative_lines_counts[ref_id]) ? *m_cache_range.min - cumulative_lines_counts[ref_id] : 1;
|
||||||
|
const size_t last_line_id = (*m_cache_range.max - 1 <= cumulative_lines_counts[i]) ?
|
||||||
|
(i == 0) ? *m_cache_range.max : *m_cache_range.max - cumulative_lines_counts[ref_id] : m_lines_ends[i].size() - 1;
|
||||||
|
|
||||||
|
for (size_t j = first_line_id; j <= last_line_id; ++j) {
|
||||||
|
const size_t begin = (j == 1) ? 0 : m_lines_ends[i][j - 2];
|
||||||
|
const size_t end = m_lines_ends[i][j - 1];
|
||||||
|
std::string gline;
|
||||||
|
gline.insert(gline.end(), block.raw_data.begin() + begin, block.raw_data.begin() + end);
|
||||||
|
add_gcode_line_to_lines_cache(gline);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftell(file.f) == file_size)
|
||||||
|
break;
|
||||||
|
|
||||||
|
res = read_next_block_header(*file.f, file_header, block_header, nullptr, 0);
|
||||||
|
if (res != EResult::Success || block_header.type != (uint16_t)EBlockType::GCode) {
|
||||||
|
m_lines_cache.clear();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_lines_cache.push_back({ command, parameters, comment });
|
|
||||||
}
|
}
|
||||||
fclose(file);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -463,13 +563,20 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, s
|
|||||||
if (visible_lines_count == 0)
|
if (visible_lines_count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (m_lines_ends.empty() || m_lines_ends.front().empty())
|
||||||
|
return;
|
||||||
|
|
||||||
auto resize_range = [&](Range& range, size_t lines_count) {
|
auto resize_range = [&](Range& range, size_t lines_count) {
|
||||||
const size_t half_lines_count = lines_count / 2;
|
const size_t half_lines_count = lines_count / 2;
|
||||||
range.start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 1;
|
range.min = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 1;
|
||||||
range.end_id = *range.start_id + lines_count - 1;
|
range.max = *range.min + lines_count - 1;
|
||||||
if (*range.end_id >= m_lines_ends.size()) {
|
size_t lines_ends_count = 0;
|
||||||
range.end_id = m_lines_ends.size() - 1;
|
for (const auto& le : m_lines_ends) {
|
||||||
range.start_id = *range.end_id - lines_count + 1;
|
lines_ends_count += le.size();
|
||||||
|
}
|
||||||
|
if (*range.max >= lines_ends_count) {
|
||||||
|
range.max = lines_ends_count - 1;
|
||||||
|
range.min = *range.max - lines_count + 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -480,11 +587,17 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, s
|
|||||||
// update cache if needed
|
// update cache if needed
|
||||||
if (m_cache_range.empty() || !m_cache_range.contains(visible_range)) {
|
if (m_cache_range.empty() || !m_cache_range.contains(visible_range)) {
|
||||||
resize_range(m_cache_range, 4 * visible_range.size());
|
resize_range(m_cache_range, 4 * visible_range.size());
|
||||||
update_lines();
|
if (m_is_binary_file)
|
||||||
|
update_lines_binary();
|
||||||
|
else
|
||||||
|
update_lines_ascii();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_lines_cache.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
// line number's column width
|
// line number's column width
|
||||||
const float id_width = ImGui::CalcTextSize(std::to_string(*visible_range.end_id).c_str()).x;
|
const float id_width = ImGui::CalcTextSize(std::to_string(*visible_range.max).c_str()).x;
|
||||||
|
|
||||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
|
|
||||||
@ -525,8 +638,8 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, s
|
|||||||
|
|
||||||
// render text lines
|
// render text lines
|
||||||
size_t max_line_length = 0;
|
size_t max_line_length = 0;
|
||||||
for (size_t id = *visible_range.start_id; id <= *visible_range.end_id; ++id) {
|
for (size_t id = *visible_range.min; id <= *visible_range.max; ++id) {
|
||||||
const Line& line = m_lines_cache[id - *m_cache_range.start_id];
|
const Line& line = m_lines_cache[id - *m_cache_range.min];
|
||||||
|
|
||||||
// rect around the current selected line
|
// rect around the current selected line
|
||||||
if (id == curr_line_id) {
|
if (id == curr_line_id) {
|
||||||
@ -729,15 +842,13 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
|
|||||||
imgui.end();
|
imgui.end();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
#endif // ENABLE_BINARIZED_GCODE
|
|
||||||
|
|
||||||
#if !ENABLE_BINARIZED_GCODE
|
|
||||||
void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()
|
void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()
|
||||||
{
|
{
|
||||||
if (m_file.is_open())
|
if (m_file.is_open())
|
||||||
m_file.close();
|
m_file.close();
|
||||||
}
|
}
|
||||||
#endif // !ENABLE_BINARIZED_GCODE
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
|
||||||
void GCodeViewer::SequentialView::render(float legend_height)
|
void GCodeViewer::SequentialView::render(float legend_height)
|
||||||
{
|
{
|
||||||
@ -917,7 +1028,11 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
|
|||||||
// release gpu memory, if used
|
// release gpu memory, if used
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
#if ENABLE_BINARIZED_GCODE
|
||||||
|
m_sequential_view.gcode_window.load_gcode(gcode_result);
|
||||||
|
#else
|
||||||
m_sequential_view.gcode_window.load_gcode(gcode_result.filename, gcode_result.lines_ends);
|
m_sequential_view.gcode_window.load_gcode(gcode_result.filename, gcode_result.lines_ends);
|
||||||
|
#endif // ENABLE_BINARIZED_GCODE
|
||||||
|
|
||||||
if (wxGetApp().is_gcode_viewer())
|
if (wxGetApp().is_gcode_viewer())
|
||||||
m_custom_gcode_per_print_z = gcode_result.custom_gcode_per_print_z;
|
m_custom_gcode_per_print_z = gcode_result.custom_gcode_per_print_z;
|
||||||
|
@ -686,29 +686,30 @@ public:
|
|||||||
|
|
||||||
struct Range
|
struct Range
|
||||||
{
|
{
|
||||||
std::optional<size_t> start_id;
|
std::optional<size_t> min;
|
||||||
std::optional<size_t> end_id;
|
std::optional<size_t> max;
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return !start_id.has_value() || !end_id.has_value();
|
return !min.has_value() || !max.has_value();
|
||||||
}
|
}
|
||||||
bool contains(const Range& other) const {
|
bool contains(const Range& other) const {
|
||||||
return !this->empty() && !other.empty() && *this->start_id <= *other.start_id && *this->end_id >= other.end_id;
|
return !this->empty() && !other.empty() && *this->min <= *other.min && *this->max >= other.max;
|
||||||
}
|
}
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return empty() ? 0 : *this->end_id - *this->start_id + 1;
|
return empty() ? 0 : *this->max - *this->min + 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool m_visible{ true };
|
bool m_visible{ true };
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
bool m_is_binary_file{ false };
|
||||||
// map for accessing data in file by line number
|
// map for accessing data in file by line number
|
||||||
std::vector<size_t> m_lines_ends;
|
std::vector<std::vector<size_t>> m_lines_ends;
|
||||||
std::vector<Line> m_lines_cache;
|
std::vector<Line> m_lines_cache;
|
||||||
Range m_cache_range;
|
Range m_cache_range;
|
||||||
size_t m_max_line_length{ 0 };
|
size_t m_max_line_length{ 0 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void load_gcode(const std::string& filename, const std::vector<size_t>& lines_ends);
|
void load_gcode(const GCodeProcessorResult& gcode_result);
|
||||||
void reset() {
|
void reset() {
|
||||||
m_lines_ends.clear();
|
m_lines_ends.clear();
|
||||||
m_lines_cache.clear();
|
m_lines_cache.clear();
|
||||||
@ -716,6 +717,9 @@ public:
|
|||||||
}
|
}
|
||||||
void toggle_visibility() { m_visible = !m_visible; }
|
void toggle_visibility() { m_visible = !m_visible; }
|
||||||
void render(float top, float bottom, size_t curr_line_id);
|
void render(float top, float bottom, size_t curr_line_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void add_gcode_line_to_lines_cache(const std::string& src);
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
class GCodeWindow
|
class GCodeWindow
|
||||||
|
Loading…
x
Reference in New Issue
Block a user